2002/css-validator/org/w3c/css/properties/css3 CssBackgroundPosition.java,1.5,1.6

Update of /sources/public/2002/css-validator/org/w3c/css/properties/css3
In directory hutz:/tmp/cvs-serv16951/properties/css3

Modified Files:
	CssBackgroundPosition.java 
Log Message:
radial-gradient + static method to check the value of a position (grmbl)

Index: CssBackgroundPosition.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/properties/css3/CssBackgroundPosition.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- CssBackgroundPosition.java	6 Sep 2012 12:37:57 -0000	1.5
+++ CssBackgroundPosition.java	9 Nov 2012 13:31:30 -0000	1.6
@@ -46,10 +46,10 @@
 		allowed_values[3] = right;
 		allowed_values[4] = center;
 
-        defaultPercent0 = new CssPercentage(0);
-        defaultPercent50 = new CssPercentage(50);
-        defaultPercent100 = new CssPercentage(100);
-    }
+		defaultPercent0 = new CssPercentage(0);
+		defaultPercent50 = new CssPercentage(50);
+		defaultPercent100 = new CssPercentage(100);
+	}
 
 	public static boolean isMatchingIdent(CssIdent ident) {
 		for (CssIdent id : allowed_values) {
@@ -69,392 +69,558 @@
 		return null;
 	}
 
-    /**
-     * Create a new CssBackgroundPosition
-     */
-    public CssBackgroundPosition() {
-        value = new CssBackgroundPositionValue();
-    }
+	/**
+	 * Create a new CssBackgroundPosition
+	 */
+	public CssBackgroundPosition() {
+		value = new CssBackgroundPositionValue();
+	}
 
-    /**
-     * Creates a new CssBackgroundPosition
-     *
-     * @param expression The expression for this property
-     * @throws org.w3c.css.util.InvalidParamException Values are incorrect
-     */
-    public CssBackgroundPosition(ApplContext ac, CssExpression expression,
-                                 boolean check) throws InvalidParamException {
-        setByUser();
-        CssValue val;
-        ArrayList<CssValue> values;
-        CssBackgroundPositionValue b_val = null;
-        char op;
+	/**
+	 * Creates a new CssBackgroundPosition
+	 *
+	 * @param expression The expression for this property
+	 * @throws org.w3c.css.util.InvalidParamException
+	 *          Values are incorrect
+	 */
+	public CssBackgroundPosition(ApplContext ac, CssExpression expression,
+								 boolean check) throws InvalidParamException {
+		setByUser();
+		CssValue val;
+		ArrayList<CssValue> values;
+		CssBackgroundPositionValue b_val = null;
+		char op;
 
-        values = new ArrayList<CssValue>();
-        // we just accumulate values and check at validation
-        while (!expression.end()) {
-            val = expression.getValue();
-            op = expression.getOperator();
+		values = new ArrayList<CssValue>();
+		// we just accumulate values and check at validation
+		while (!expression.end()) {
+			val = expression.getValue();
+			op = expression.getOperator();
 
-            if (inherit.equals(val)) {
-                if (expression.getCount() > 1) {
-                    throw new InvalidParamException("value", val,
-                            getPropertyName(), ac);
-                }
-                value = inherit;
-                expression.next();
-                return;
-            }
-            if (b_val == null) {
-                b_val = new CssBackgroundPositionValue();
-            }
-            // we will check later
-            b_val.add(val);
-            expression.next();
+			if (inherit.equals(val)) {
+				if (expression.getCount() > 1) {
+					throw new InvalidParamException("value", val,
+							getPropertyName(), ac);
+				}
+				value = inherit;
+				expression.next();
+				return;
+			}
+			if (b_val == null) {
+				b_val = new CssBackgroundPositionValue();
+			}
+			// we will check later
+			b_val.add(val);
+			expression.next();
 
-            if (!expression.end()) {
-                // incomplete value followed by a comma... it's complete!
-                if (op == COMMA) {
-                    check(b_val, ac);
-                    values.add(b_val);
-                    b_val = null;
-                } else if (op != SPACE) {
-                    throw new InvalidParamException("operator",
-                            ((new Character(op)).toString()), ac);
-                }
-            }
-        }
-        // if we reach the end in a value that can come in pair
-        if (b_val != null) {
-            check(b_val, ac);
-            values.add(b_val);
-        }
-        if (values.size() == 1) {
-            value = values.get(0);
-        } else {
-            value = new CssLayerList(values);
-        }
-    }
+			if (!expression.end()) {
+				// incomplete value followed by a comma... it's complete!
+				if (op == COMMA) {
+					check(b_val, ac);
+					values.add(b_val);
+					b_val = null;
+				} else if (op != SPACE) {
+					throw new InvalidParamException("operator",
+							((new Character(op)).toString()), ac);
+				}
+			}
+		}
+		// if we reach the end in a value that can come in pair
+		if (b_val != null) {
+			check(b_val, ac);
+			values.add(b_val);
+		}
+		if (values.size() == 1) {
+			value = values.get(0);
+		} else {
+			value = new CssLayerList(values);
+		}
+	}
 
-    public CssBackgroundPosition(ApplContext ac, CssExpression expression)
-            throws InvalidParamException {
-        this(ac, expression, false);
-    }
+	public CssBackgroundPosition(ApplContext ac, CssExpression expression)
+			throws InvalidParamException {
+		this(ac, expression, false);
+	}
 
 
-    /**
-     * Is the value of this property is a default value.
-     * It is used by all macro for the function <code>print</code>
-     */
-    public boolean isDefault() {
-        if (!(value instanceof CssBackgroundPositionValue)) {
-            return false;
-        }
-        CssBackgroundPositionValue v = (CssBackgroundPositionValue) value;
-        return ((v.val_vertical == defaultPercent0) &&
-                (v.val_horizontal == defaultPercent0) &&
-                (v.vertical_offset == null) &&
-                (v.horizontal_offset == null));
-    }
+	/**
+	 * Is the value of this property is a default value.
+	 * It is used by all macro for the function <code>print</code>
+	 */
+	public boolean isDefault() {
+		if (!(value instanceof CssBackgroundPositionValue)) {
+			return false;
+		}
+		CssBackgroundPositionValue v = (CssBackgroundPositionValue) value;
+		return ((v.val_vertical == defaultPercent0) &&
+				(v.val_horizontal == defaultPercent0) &&
+				(v.vertical_offset == null) &&
+				(v.horizontal_offset == null));
+	}
 
-    public void check(CssBackgroundPositionValue v, ApplContext ac)
-            throws InvalidParamException {
-        int nb_keyword = 0;
-        int nb_percentage = 0;
-        int nb_length = 0;
-        int nb_values = v.value.size();
+	public void check(CssBackgroundPositionValue v, ApplContext ac)
+			throws InvalidParamException {
+		int nb_keyword = 0;
+		int nb_percentage = 0;
+		int nb_length = 0;
+		int nb_values = v.value.size();
 
-        if (nb_values > 4) {
-            throw new InvalidParamException("unrecognize", ac);
-        }
-        // basic check
-        for (CssValue aValue : v.value) {
-            switch (aValue.getType()) {
-                case CssTypes.CSS_NUMBER:
-                    CssLength l = aValue.getLength();
-                case CssTypes.CSS_LENGTH:
-                    nb_length++;
-                    break;
-                case CssTypes.CSS_PERCENTAGE:
-                    nb_percentage++;
-                    break;
-                case CssTypes.CSS_IDENT:
-                    nb_keyword++;
-                    break;
-                default:
-                    throw new InvalidParamException("unrecognize", aValue,
-                            ac);
-            }
-        }
-        if ((nb_keyword > 2) || (nb_length > 2) || (nb_percentage > 2)) {
-            throw new InvalidParamException("unrecognize", ac);
-        }
-        // this is unnecessary complex, blame it on the CSS3 spec.
-        switch (nb_keyword) {
-            case 0:
-                // no keyword, so it's easy, it depends on the number
-                // of values :)
-                switch (nb_values) {
-                    case 1:
-                        // If only one value is specified, the second value
-                        // is assumed to be 'center'.
-                        v.horizontal = v.value.get(0);
-                        if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
-                            v.horizontal = defaultPercent0;
-                        }
-                        v.val_horizontal = v.horizontal;
-                        v.val_vertical = defaultPercent50;
-                        break;
-                    case 2:
-                        v.horizontal = v.value.get(0);
-                        if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
-                            v.horizontal = defaultPercent0;
-                        }
-                        v.val_horizontal = v.horizontal;
-                        v.vertical = v.value.get(1);
-                        if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
-                            v.vertical = defaultPercent0;
-                        }
-                        v.val_vertical = v.vertical;
-                        break;
-                    default:
-                        // If three or four values are given, then each
-                        // <percentage> or<length> represents an offset and
-                        // must be preceded by a keyword
-                        throw new InvalidParamException("unrecognize",
-                                ac);
+		if (nb_values > 4) {
+			throw new InvalidParamException("unrecognize", ac);
+		}
+		// basic check
+		for (CssValue aValue : v.value) {
+			switch (aValue.getType()) {
+				case CssTypes.CSS_NUMBER:
+					CssLength l = aValue.getLength();
+				case CssTypes.CSS_LENGTH:
+					nb_length++;
+					break;
+				case CssTypes.CSS_PERCENTAGE:
+					nb_percentage++;
+					break;
+				case CssTypes.CSS_IDENT:
+					nb_keyword++;
+					break;
+				default:
+					throw new InvalidParamException("unrecognize", aValue,
+							ac);
+			}
+		}
+		if ((nb_keyword > 2) || (nb_length > 2) || (nb_percentage > 2)) {
+			throw new InvalidParamException("unrecognize", ac);
+		}
+		// this is unnecessary complex, blame it on the CSS3 spec.
+		switch (nb_keyword) {
+			case 0:
+				// no keyword, so it's easy, it depends on the number
+				// of values :)
+				switch (nb_values) {
+					case 1:
+						// If only one value is specified, the second value
+						// is assumed to be 'center'.
+						v.horizontal = v.value.get(0);
+						if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
+							v.horizontal = defaultPercent0;
+						}
+						v.val_horizontal = v.horizontal;
+						v.val_vertical = defaultPercent50;
+						break;
+					case 2:
+						v.horizontal = v.value.get(0);
+						if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
+							v.horizontal = defaultPercent0;
+						}
+						v.val_horizontal = v.horizontal;
+						v.vertical = v.value.get(1);
+						if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
+							v.vertical = defaultPercent0;
+						}
+						v.val_vertical = v.vertical;
+						break;
+					default:
+						// If three or four values are given, then each
+						// <percentage> or<length> represents an offset and
+						// must be preceded by a keyword
+						throw new InvalidParamException("unrecognize",
+								ac);
 
-                }
-                break;
-            // we got one keyword... let's have fun...
-            case 1:
-                switch (nb_values) {
-                    case 1:
-                        CssIdent ident = (CssIdent) v.value.get(0);
-                        // ugly as we need to set values for equality tests
-                        v.val_vertical = defaultPercent50;
-                        v.val_horizontal = defaultPercent50;
-                        ident = getMatchingIdent(ident);
-                        if (ident != null) {
-                            if (isVertical(ident)) {
-                                v.vertical = ident;
-                                v.val_vertical = identToPercent(ident);
-                            } else {
-                                // horizontal || center
-                                v.horizontal = ident;
-                                v.val_horizontal = identToPercent(ident);
-                            }
-                            break;
-                        }
-                        throw new InvalidParamException("unrecognize",
-                                ident, getPropertyName(), ac);
-                    case 2:
-                        // one ident, two values... first MUST be horizontal
-                        // and second vertical
-                        CssValue val0 = v.value.get(0);
-                        if (val0.getType() == CssTypes.CSS_IDENT) {
-                            ident = getMatchingIdent((CssIdent)val0);
-                            if (ident == null) {
-                                throw new InvalidParamException("unrecognize",
-                                        ident, getPropertyName(), ac);
-                            }
-                            if (isVertical(ident)) {
-                                throw new InvalidParamException("incompatible",
-                                        ident, v.value.get(1), ac);
-                            }
-                            v.horizontal = ident;
-                            v.val_horizontal = identToPercent(ident);
-                            // and the vertical value...
-                            v.vertical = v.value.get(1);
-                            if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
-                                v.vertical = defaultPercent0;
-                            }
-                            v.val_vertical = v.vertical;
-                        } else {
+				}
+				break;
+			// we got one keyword... let's have fun...
+			case 1:
+				switch (nb_values) {
+					case 1:
+						CssIdent ident = (CssIdent) v.value.get(0);
+						// ugly as we need to set values for equality tests
+						v.val_vertical = defaultPercent50;
+						v.val_horizontal = defaultPercent50;
+						ident = getMatchingIdent(ident);
+						if (ident != null) {
+							if (isVertical(ident)) {
+								v.vertical = ident;
+								v.val_vertical = identToPercent(ident);
+							} else {
+								// horizontal || center
+								v.horizontal = ident;
+								v.val_horizontal = identToPercent(ident);
+							}
+							break;
+						}
+						throw new InvalidParamException("unrecognize",
+								ident, getPropertyName(), ac);
+					case 2:
+						// one ident, two values... first MUST be horizontal
+						// and second vertical
+						CssValue val0 = v.value.get(0);
+						if (val0.getType() == CssTypes.CSS_IDENT) {
+							ident = getMatchingIdent((CssIdent) val0);
+							if (ident == null) {
+								throw new InvalidParamException("unrecognize",
+										ident, getPropertyName(), ac);
+							}
+							if (isVertical(ident)) {
+								throw new InvalidParamException("incompatible",
+										ident, v.value.get(1), ac);
+							}
+							v.horizontal = ident;
+							v.val_horizontal = identToPercent(ident);
+							// and the vertical value...
+							v.vertical = v.value.get(1);
+							if (v.vertical.getType() == CssTypes.CSS_NUMBER) {
+								v.vertical = defaultPercent0;
+							}
+							v.val_vertical = v.vertical;
+						} else {
 							CssValue value1 = v.value.get(1);
 							if (value1.getType() != CssTypes.CSS_IDENT) {
 								throw new InvalidParamException("unrecognize",
 										value1, getPropertyName(), ac);
 							}
-							ident = getMatchingIdent((CssIdent) value1);                            if (ident == null) {
-                                throw new InvalidParamException("unrecognize",
-                                        ident, getPropertyName(), ac);
-                            }
-                            if (isHorizontal(ident)) {
-                                throw new InvalidParamException("incompatible",
-                                        val0, value1, ac);
-                            }
-                            v.vertical = ident;
-                            v.val_vertical = identToPercent(ident);
-                            // and the first value
-                            v.horizontal = val0;
-                            if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
-                                v.horizontal = defaultPercent0;
-                            }
-                            v.val_horizontal = v.horizontal;
-                        }
-                        break;
-                    default:
-                        // one ident, 3 or 4 values is not allowed
-                        throw new InvalidParamException("unrecognize",
-                                ac);
-                }
-                break;
-            default:
-                // ok so we have two keywords, with possible offsets
-                // we must check that every possible offset is right
-                // after a keyword and also that the two keywords are
-                // not incompatible
-                boolean got_ident = false;
-                CssIdent id1 = null;
-                CssIdent id2 = null;
-                CssValue off1 = null;
-                CssValue off2 = null;
-                for (CssValue aValue : v.value) {
-                    switch (aValue.getType()) {
-                        case CssTypes.CSS_IDENT:
-                            aValue = getMatchingIdent((CssIdent)aValue);
-                            if (aValue == null) {
-                                throw new InvalidParamException("unrecognize",
-                                        aValue, getPropertyName(), ac);
-                            }
-                            got_ident = true;
-                            if (id1 == null) {
-                                id1 = (CssIdent) aValue;
-                            } else {
-                                id2 = (CssIdent) aValue;
-                                // we got both, let's check.
-                                if (((isVertical(id1) && isVertical(id2))) ||
-                                        (isHorizontal(id1) && isHorizontal(id2))) {
-                                    throw new InvalidParamException("incompatible",
-                                            id1, id2, ac);
-                                }
-                            }
-                            break;
-                        case CssTypes.CSS_NUMBER:
-                            aValue = aValue.getPercentage();
-                        case CssTypes.CSS_PERCENTAGE:
-                        case CssTypes.CSS_LENGTH:
-                            if (!got_ident) {
-                                throw new InvalidParamException("unrecognize",
-                                        aValue, getPropertyName(), ac);
-                            }
-                            if (id2 == null) {
-                                off1 = aValue;
-                            } else {
-                                off2 = aValue;
-                            }
-                            got_ident = false;
-                            break;
-                        default:
-                            // should never happen
-                    }
-                }
+							ident = getMatchingIdent((CssIdent) value1);
+							if (ident == null) {
+								throw new InvalidParamException("unrecognize",
+										ident, getPropertyName(), ac);
+							}
+							if (isHorizontal(ident)) {
+								throw new InvalidParamException("incompatible",
+										val0, value1, ac);
+							}
+							v.vertical = ident;
+							v.val_vertical = identToPercent(ident);
+							// and the first value
+							v.horizontal = val0;
+							if (v.horizontal.getType() == CssTypes.CSS_NUMBER) {
+								v.horizontal = defaultPercent0;
+							}
+							v.val_horizontal = v.horizontal;
+						}
+						break;
+					default:
+						// one ident, 3 or 4 values is not allowed
+						throw new InvalidParamException("unrecognize",
+								ac);
+				}
+				break;
+			default:
+				// ok so we have two keywords, with possible offsets
+				// we must check that every possible offset is right
+				// after a keyword and also that the two keywords are
+				// not incompatible
+				boolean got_ident = false;
+				CssIdent id1 = null;
+				CssIdent id2 = null;
+				CssValue off1 = null;
+				CssValue off2 = null;
+				for (CssValue aValue : v.value) {
+					switch (aValue.getType()) {
+						case CssTypes.CSS_IDENT:
+							aValue = getMatchingIdent((CssIdent) aValue);
+							if (aValue == null) {
+								throw new InvalidParamException("unrecognize",
+										aValue, getPropertyName(), ac);
+							}
+							got_ident = true;
+							if (id1 == null) {
+								id1 = (CssIdent) aValue;
+							} else {
+								id2 = (CssIdent) aValue;
+								// we got both, let's check.
+								if (((isVertical(id1) && isVertical(id2))) ||
+										(isHorizontal(id1) && isHorizontal(id2))) {
+									throw new InvalidParamException("incompatible",
+											id1, id2, ac);
+								}
+							}
+							break;
+						case CssTypes.CSS_NUMBER:
+							aValue = aValue.getPercentage();
+						case CssTypes.CSS_PERCENTAGE:
+						case CssTypes.CSS_LENGTH:
+							if (!got_ident) {
+								throw new InvalidParamException("unrecognize",
+										aValue, getPropertyName(), ac);
+							}
+							if (id2 == null) {
+								off1 = aValue;
+							} else {
+								off2 = aValue;
+							}
+							got_ident = false;
+							break;
+						default:
+							// should never happen
+					}
+				}
 
-                if (isVertical(id1) || isHorizontal(id2)) {
-                    // if an offset is present and value is 'center'
-                    if (((off1 != null) && !isVertical(id1)) ||
-                            ((off2 != null) && !isHorizontal(id2))) {
-                        throw new InvalidParamException("incompatible",
-                                id1, id2, ac);
-                    }
-                    v.horizontal = id2;
-                    v.val_horizontal = identToPercent(id2);
-                    v.horizontal_offset = off2;
-                    v.vertical = id1;
-                    v.val_vertical = identToPercent(id1);
-                    v.vertical_offset = off1;
-                } else {
-                    if (((off2 != null) && !isVertical(id2)) ||
-                            ((off1 != null) && !isHorizontal(id1))) {
-                        throw new InvalidParamException("incompatible",
-                                id1, id2, ac);
-                    }
-                    v.horizontal = id1;
-                    v.val_horizontal = identToPercent(id1);
-                    v.horizontal_offset = off1;
-                    v.vertical = id2;
-                    v.val_vertical = identToPercent(id2);
-                    v.vertical_offset = off2;
-                }
-        }
-    }
+				if (isVertical(id1) || isHorizontal(id2)) {
+					// if an offset is present and value is 'center'
+					if (((off1 != null) && !isVertical(id1)) ||
+							((off2 != null) && !isHorizontal(id2))) {
+						throw new InvalidParamException("incompatible",
+								id1, id2, ac);
+					}
+					v.horizontal = id2;
+					v.val_horizontal = identToPercent(id2);
+					v.horizontal_offset = off2;
+					v.vertical = id1;
+					v.val_vertical = identToPercent(id1);
+					v.vertical_offset = off1;
+				} else {
+					if (((off2 != null) && !isVertical(id2)) ||
+							((off1 != null) && !isHorizontal(id1))) {
+						throw new InvalidParamException("incompatible",
+								id1, id2, ac);
+					}
+					v.horizontal = id1;
+					v.val_horizontal = identToPercent(id1);
+					v.horizontal_offset = off1;
+					v.vertical = id2;
+					v.val_vertical = identToPercent(id2);
+					v.vertical_offset = off2;
+				}
+		}
+	}
 
-    public static CssPercentage identToPercent(CssIdent ident) {
-        if (center.equals(ident)) {
-            return defaultPercent50;
-        } else if (top.equals(ident) || left.equals(ident)) {
-            return defaultPercent0;
-        } else if (bottom.equals(ident) || right.equals(ident)) {
-            return defaultPercent100;
-        }
-        return defaultPercent0; // FIXME throw an exception ?
-    }
+	public static CssPercentage identToPercent(CssIdent ident) {
+		if (center.equals(ident)) {
+			return defaultPercent50;
+		} else if (top.equals(ident) || left.equals(ident)) {
+			return defaultPercent0;
+		} else if (bottom.equals(ident) || right.equals(ident)) {
+			return defaultPercent100;
+		}
+		return defaultPercent0; // FIXME throw an exception ?
+	}
 
-    public static boolean isHorizontal(CssIdent ident) {
-        return (left.equals(ident) || right.equals(ident));
-    }
+	public static boolean isHorizontal(CssIdent ident) {
+		return (left.equals(ident) || right.equals(ident));
+	}
 
-    public static boolean isVertical(CssIdent ident) {
-        return (top.equals(ident) || bottom.equals(ident));
-    }
+	public static boolean isVertical(CssIdent ident) {
+		return (top.equals(ident) || bottom.equals(ident));
+	}
 
-    // placeholder for the different values
+	// placeholder for the different values
 
-    public class CssBackgroundPositionValue extends CssValueList {
-        public CssValue vertical = null;
-        public CssValue horizontal = null;
-        public CssValue vertical_offset = null;
-        public CssValue horizontal_offset = null;
+	public class CssBackgroundPositionValue extends CssValueList {
+		public CssValue vertical = null;
+		public CssValue horizontal = null;
+		public CssValue vertical_offset = null;
+		public CssValue horizontal_offset = null;
 
-        public CssValue val_vertical = defaultPercent0;
-        public CssValue val_horizontal = defaultPercent0;
+		public CssValue val_vertical = defaultPercent0;
+		public CssValue val_horizontal = defaultPercent0;
 
-        public boolean equals(CssBackgroundPositionValue v) {
-            // check vertical compatibility (with optional values)
-            if (!val_vertical.equals(v.val_vertical)) {
-                return false;
-            }
-            if (vertical_offset != null) {
-                if (!vertical_offset.equals(v.vertical_offset)) {
-                    return false;
-                }
-            } else if (v.vertical_offset != null) {
-                return false;
-            }
+		public boolean equals(CssBackgroundPositionValue v) {
+			// check vertical compatibility (with optional values)
+			if (!val_vertical.equals(v.val_vertical)) {
+				return false;
+			}
+			if (vertical_offset != null) {
+				if (!vertical_offset.equals(v.vertical_offset)) {
+					return false;
+				}
+			} else if (v.vertical_offset != null) {
+				return false;
+			}
 
-            if (!val_horizontal.equals(v.val_horizontal)) {
-                return false;
-            }
-            if (horizontal_offset != null) {
-                if (!horizontal_offset.equals(v.horizontal_offset)) {
-                    return false;
-                }
-            } else if (v.horizontal_offset != null) {
-                return false;
-            }
-            // yeah!    
-            return true;
-        }
+			if (!val_horizontal.equals(v.val_horizontal)) {
+				return false;
+			}
+			if (horizontal_offset != null) {
+				if (!horizontal_offset.equals(v.horizontal_offset)) {
+					return false;
+				}
+			} else if (v.horizontal_offset != null) {
+				return false;
+			}
+			// yeah!
+			return true;
+		}
 
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            if (vertical != null) {
-                sb.append(vertical);
-                if (vertical_offset != null) {
-                    sb.append(' ').append(vertical_offset);
-                }
-                if (horizontal != null) {
-                    sb.append(' ');
-                }
-            }
-            if (horizontal != null) {
-                sb.append(horizontal);
-                if (horizontal_offset != null) {
-                    sb.append(' ').append(horizontal_offset);
-                }
-            }
-            return sb.toString();
-        }
-    }
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			if (vertical != null) {
+				sb.append(vertical);
+				if (vertical_offset != null) {
+					sb.append(' ').append(vertical_offset);
+				}
+				if (horizontal != null) {
+					sb.append(' ');
+				}
+			}
+			if (horizontal != null) {
+				sb.append(horizontal);
+				if (horizontal_offset != null) {
+					sb.append(' ').append(horizontal_offset);
+				}
+			}
+			return sb.toString();
+		}
+	}
+
+	public static CssValue checkSyntax(CssExpression expression, ApplContext ac, String caller)
+			throws InvalidParamException {
+		ArrayList<CssValue> v = new ArrayList<CssValue>();
+		int nb_values = expression.getCount();
+		CssValue val, ret;
+		int nb_length, nb_percentage, nb_keyword;
+		char op;
+
+		nb_length = nb_percentage = nb_keyword = 0;
+
+		while (!expression.end()) {
+			val = expression.getValue();
+			op = expression.getOperator();
+			switch (val.getType()) {
+				case CssTypes.CSS_NUMBER:
+					CssLength l = val.getLength();
+				case CssTypes.CSS_LENGTH:
+					nb_length++;
+					break;
+				case CssTypes.CSS_PERCENTAGE:
+					nb_percentage++;
+					break;
+				case CssTypes.CSS_IDENT:
+					nb_keyword++;
+					break;
+				default:
+					throw new InvalidParamException("unrecognize", val,
+							ac);
+			}
+			v.add(val);
+			if (op != SPACE) {
+				throw new InvalidParamException("operator",
+						((new Character(op)).toString()), ac);
+			}
+			expression.next();
+		}
+		ret = new CssValueList(v);
+		// basic checks
+		if ((nb_keyword > 2) || (nb_length > 2) || (nb_percentage > 2)) {
+			throw new InvalidParamException("value", ret,
+					caller, ac);
+		}
+		// test based on the number of keywords
+		switch (nb_keyword) {
+			case 0:
+				if (nb_keyword > 2) {
+					throw new InvalidParamException("value", ret,
+							caller, ac);
+				}
+				break;
+			case 1:
+				switch (nb_values) {
+					case 1:
+						// one value, one keyword... easy :)
+						if (getMatchingIdent((CssIdent) v.get(0)) == null) {
+							throw new InvalidParamException("value", v.get(0),
+									caller, ac);
+						}
+						break;
+					case 2:
+						// one ident, two values... first MUST be horizontal
+						// and second vertical
+						CssValue val0 = v.get(0);
+						CssIdent ident;
+						if (val0.getType() == CssTypes.CSS_IDENT) {
+							ident = getMatchingIdent((CssIdent) val0);
+							if (ident == null) {
+								throw new InvalidParamException("value", val0,
+										caller, ac);
+							}
+							if (isVertical(ident)) {
+								throw new InvalidParamException("incompatible",
+										ident, v.get(1), ac);
+							}
+						} else {
+							CssValue value1 = v.get(1);
+							if (value1.getType() != CssTypes.CSS_IDENT) {
+								throw new InvalidParamException("value", value1,
+										caller, ac);
+							}
+							ident = getMatchingIdent((CssIdent) value1);
+							if (ident == null) {
+								throw new InvalidParamException("value", value1,
+										caller, ac);
+							}
+							if (isHorizontal(ident)) {
+								throw new InvalidParamException("incompatible",
+										val0, value1, ac);
+							}
+						}
+						break;
+					default:
+						// one ident, 3 or 4 values is not allowed
+						throw new InvalidParamException("value", ret,
+								caller, ac);
+				}
+				break;
+			default:
+				// ok so we have two keywords, with possible offsets
+				// we must check that every possible offset is right
+				// after a keyword and also that the two keywords are
+				// not incompatible
+				boolean got_ident = false;
+				CssIdent id1 = null;
+				CssIdent id2 = null;
+				CssValue off1 = null;
+				CssValue off2 = null;
+				for (CssValue aValue : v) {
+					switch (aValue.getType()) {
+						case CssTypes.CSS_IDENT:
+							if (getMatchingIdent((CssIdent) aValue) == null) {
+								throw new InvalidParamException("value", aValue,
+										caller, ac);
+							}
+							got_ident = true;
+							if (id1 == null) {
+								id1 = (CssIdent) aValue;
+							} else {
+								id2 = (CssIdent) aValue;
+								// we got both, let's check.
+								if (((isVertical(id1) && isVertical(id2))) ||
+										(isHorizontal(id1) && isHorizontal(id2))) {
+									throw new InvalidParamException("incompatible",
+											id1, id2, ac);
+								}
+							}
+							break;
+						case CssTypes.CSS_NUMBER:
+						case CssTypes.CSS_PERCENTAGE:
+						case CssTypes.CSS_LENGTH:
+							if (!got_ident) {
+								throw new InvalidParamException("unrecognize",
+										aValue, caller, ac);
+							}
+							if (id2 == null) {
+								off1 = aValue;
+							} else {
+								off2 = aValue;
+							}
+							got_ident = false;
+							break;
+						default:
+							// should never happen
+					}
+				}
+
+				if (isVertical(id1) || isHorizontal(id2)) {
+					// if an offset is present and value is 'center'
+					if (((off1 != null) && !isVertical(id1)) ||
+							((off2 != null) && !isHorizontal(id2))) {
+						throw new InvalidParamException("incompatible",
+								id1, id2, ac);
+					}
+				} else {
+					if (((off2 != null) && !isVertical(id2)) ||
+							((off1 != null) && !isHorizontal(id1))) {
+						throw new InvalidParamException("incompatible",
+								id1, id2, ac);
+					}
+				}
+		}
+		return ret;
+	}
 }

Received on Friday, 9 November 2012 13:31:40 UTC