
cz.vutbr.web.domassign.DeclarationTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jstyleparser Show documentation
Show all versions of jstyleparser Show documentation
jStyleParser is a CSS parser written in Java. It has its own application interface that is designed to allow an efficient CSS processing in Java and mapping the values to the Java data types. It parses CSS 2.1 style sheets into structures that can be efficiently assigned to DOM elements. It is intended be the primary CSS parser for the CSSBox library. While handling errors, it is user agent conforming according to the CSS specification.
package cz.vutbr.web.domassign;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cz.vutbr.web.css.CSSFactory;
import cz.vutbr.web.css.CSSProperty;
import cz.vutbr.web.css.CSSProperty.BackgroundSize;
import cz.vutbr.web.css.CSSProperty.BorderRadius;
import cz.vutbr.web.css.CSSProperty.GenericCSSPropertyProxy;
import cz.vutbr.web.css.CSSProperty.Opacity;
import cz.vutbr.web.css.Declaration;
import cz.vutbr.web.css.SupportedCSS;
import cz.vutbr.web.css.Term;
import cz.vutbr.web.css.TermColor;
import cz.vutbr.web.css.TermFactory;
import cz.vutbr.web.css.TermFunction;
import cz.vutbr.web.css.TermIdent;
import cz.vutbr.web.css.TermInteger;
import cz.vutbr.web.css.TermLength;
import cz.vutbr.web.css.TermList;
import cz.vutbr.web.css.TermNumber;
import cz.vutbr.web.css.TermPercent;
import cz.vutbr.web.css.TermString;
import cz.vutbr.web.css.TermURI;
import cz.vutbr.web.css.CSSProperty.BackgroundAttachment;
import cz.vutbr.web.css.CSSProperty.BackgroundColor;
import cz.vutbr.web.css.CSSProperty.BackgroundImage;
import cz.vutbr.web.css.CSSProperty.BackgroundPosition;
import cz.vutbr.web.css.CSSProperty.BackgroundRepeat;
import cz.vutbr.web.css.CSSProperty.BorderCollapse;
import cz.vutbr.web.css.CSSProperty.BorderColor;
import cz.vutbr.web.css.CSSProperty.BorderSpacing;
import cz.vutbr.web.css.CSSProperty.BorderStyle;
import cz.vutbr.web.css.CSSProperty.BorderWidth;
import cz.vutbr.web.css.CSSProperty.Bottom;
import cz.vutbr.web.css.CSSProperty.CaptionSide;
import cz.vutbr.web.css.CSSProperty.Clear;
import cz.vutbr.web.css.CSSProperty.Clip;
import cz.vutbr.web.css.CSSProperty.Color;
import cz.vutbr.web.css.CSSProperty.Content;
import cz.vutbr.web.css.CSSProperty.CounterIncrement;
import cz.vutbr.web.css.CSSProperty.CounterReset;
import cz.vutbr.web.css.CSSProperty.CounterSet;
import cz.vutbr.web.css.CSSProperty.Cursor;
import cz.vutbr.web.css.CSSProperty.Direction;
import cz.vutbr.web.css.CSSProperty.Display;
import cz.vutbr.web.css.CSSProperty.EmptyCells;
import cz.vutbr.web.css.CSSProperty.Font;
import cz.vutbr.web.css.CSSProperty.FontFamily;
import cz.vutbr.web.css.CSSProperty.FontSize;
import cz.vutbr.web.css.CSSProperty.FontStyle;
import cz.vutbr.web.css.CSSProperty.FontVariant;
import cz.vutbr.web.css.CSSProperty.FontWeight;
import cz.vutbr.web.css.CSSProperty.Height;
import cz.vutbr.web.css.CSSProperty.Left;
import cz.vutbr.web.css.CSSProperty.LetterSpacing;
import cz.vutbr.web.css.CSSProperty.LineHeight;
import cz.vutbr.web.css.CSSProperty.ListStyleImage;
import cz.vutbr.web.css.CSSProperty.ListStylePosition;
import cz.vutbr.web.css.CSSProperty.ListStyleType;
import cz.vutbr.web.css.CSSProperty.Margin;
import cz.vutbr.web.css.CSSProperty.MaxHeight;
import cz.vutbr.web.css.CSSProperty.MaxWidth;
import cz.vutbr.web.css.CSSProperty.MinHeight;
import cz.vutbr.web.css.CSSProperty.MinWidth;
import cz.vutbr.web.css.CSSProperty.Orphans;
import cz.vutbr.web.css.CSSProperty.OutlineColor;
import cz.vutbr.web.css.CSSProperty.OutlineStyle;
import cz.vutbr.web.css.CSSProperty.OutlineWidth;
import cz.vutbr.web.css.CSSProperty.Overflow;
import cz.vutbr.web.css.CSSProperty.Padding;
import cz.vutbr.web.css.CSSProperty.PageBreak;
import cz.vutbr.web.css.CSSProperty.PageBreakInside;
import cz.vutbr.web.css.CSSProperty.Position;
import cz.vutbr.web.css.CSSProperty.Quotes;
import cz.vutbr.web.css.CSSProperty.Right;
import cz.vutbr.web.css.CSSProperty.TableLayout;
import cz.vutbr.web.css.CSSProperty.TextAlign;
import cz.vutbr.web.css.CSSProperty.TextDecoration;
import cz.vutbr.web.css.CSSProperty.TextIndent;
import cz.vutbr.web.css.CSSProperty.TextTransform;
import cz.vutbr.web.css.CSSProperty.Top;
import cz.vutbr.web.css.CSSProperty.UnicodeBidi;
import cz.vutbr.web.css.CSSProperty.VerticalAlign;
import cz.vutbr.web.css.CSSProperty.Visibility;
import cz.vutbr.web.css.CSSProperty.WhiteSpace;
import cz.vutbr.web.css.CSSProperty.Widows;
import cz.vutbr.web.css.CSSProperty.Width;
import cz.vutbr.web.css.CSSProperty.WordSpacing;
import cz.vutbr.web.css.CSSProperty.ZIndex;
import cz.vutbr.web.css.Term.Operator;
/**
* Contains methods to transform declaration into values applicable to NodeData.
* Uses defaults defined by CSSFactory
*
* @author kapy
*
*/
public class DeclarationTransformer {
protected static Logger log = LoggerFactory
.getLogger(DeclarationTransformer.class);
/**
* Inherit acceptance flags
*/
protected static final boolean AVOID_INH = true;
protected static final boolean ALLOW_INH = false;
/**
* Cache of parsing methods
*/
protected Map methods;
/**
* Singleton instance
*/
private static final DeclarationTransformer instance;
protected static final TermFactory tf = CSSFactory.getTermFactory();
protected final SupportedCSS css = CSSFactory.getSupportedCSS();
static {
instance = new DeclarationTransformer();
}
/**
* Returns instance
*
* @return Singleton instance
*/
public static final DeclarationTransformer getInstance() {
return instance;
}
/**
* Converts string divided by dash ('-') characters into camelCase such as
* convenient for Java method names
*
* @param string
* String to convert
* @return CamelCase version of string
*/
public static final String camelCase(String string) {
StringBuilder sb = new StringBuilder();
boolean upperFlag = false;
for (int i = 0; i < string.length(); i++) {
char ch = string.charAt(i);
if (ch == '-')
upperFlag = true;
else if (upperFlag && Character.isLetter(ch)) {
sb.append(Character.toUpperCase(ch));
upperFlag = false;
} else if (!upperFlag && Character.isLetter(ch))
sb.append(ch);
else if (ch == '_') // vendor extension
sb.append(ch);
}
return sb.toString();
}
/**
* Core function. Parses CSS declaration into structure applicable to
* DataNodeImpl
*
* @param d
* Declaration
* @param properties
* Wrap of parsed declaration's properties
* @param values
* Wrap of parsed declaration's value
* @return true
in case of success, false
* otherwise
*/
public boolean parseDeclaration(Declaration d,
Map properties, Map> values) {
String propertyName = d.getProperty().toLowerCase();
// no such declaration is supported
if (!css.isSupportedCSSProperty(propertyName))
return false;
try {
Method m = methods.get(propertyName);
if (m != null) {
boolean result = (Boolean) m
.invoke(this, d, properties, values);
log.debug("Parsing /{}/ {}", result, d);
return result;
}
else
{
boolean result = processAdditionalCSSGenericProperty(d, properties, values);
log.debug("Parsing with proxy /{}/ {}", result, d);
return result;
}
} catch (IllegalArgumentException e) {
log.warn("Illegal argument", e);
} catch (IllegalAccessException e) {
log.warn("Illegal access", e);
} catch (InvocationTargetException e) {
log.warn("Invocation target", e);
log.warn("Invotation target cause", e.getCause());
}
return false;
}
/**
* Sole constructor
*/
protected DeclarationTransformer() {
this.methods = parsingMethods();
}
protected Map parsingMethods() {
Map map = new HashMap(css
.getTotalProperties(), 1.0f);
for (String key : css.getDefinedPropertyNames()) {
try {
Method m = DeclarationTransformer.class.getDeclaredMethod(
DeclarationTransformer.camelCase("process-" + key),
Declaration.class, Map.class, Map.class);
map.put(key, m);
} catch (Exception e) {
log.warn("Unable to find method for property {}.", key);
}
}
log.info("Totally found {} parsing methods", map.size());
return map;
}
/****************************************************************
* GENERIC METHODS *
****************************************************************/
/**
* Converts TermIdent into CSSProperty using intersection set.
* CSSProperty.Translator is used.
*
* @param
* Subclass of CSSProperty to be returned
* @param type
* Class of property to be used to retrive value
* @param intersection
* Intersection set or null
if no intersection is
* used
* @param term
* TermIdent to be transfered to property
* @return CSSProperty of type or null
*/
public T genericPropertyRaw(Class type,
Set intersection, TermIdent term) {
try {
String name = term.getValue().replace("-", "_").toUpperCase();
T property = CSSProperty.Translator.valueOf(type, name);
if (intersection != null && intersection.contains(property))
return property;
return property;
} catch (Exception e) {
return null;
}
}
/**
* Converts TermIdent into value of enum of given class and stores it into
* properties map under key property
*
* @param
* Enum & CSSProperty limitation
* @param type
* Type of enum which instance is retrieved
* @param term
* Term with value to be converted
* @param avoidInherit
* If true
inherit value is not considered valid
* @param properties
* Properties map where to store value
* @param propertyName
* Name under which property is stored in map
* @return true
in case of success, false
* otherwise
*/
protected boolean genericProperty(Class type,
TermIdent term, boolean avoidInherit,
Map properties, String propertyName) {
T property = genericPropertyRaw(type, null, term);
if (property == null || (avoidInherit && property.equalsInherit()))
return false;
properties.put(propertyName, property);
return true;
}
/**
* Converts TermIdent into value of CSSProperty for given class
*
*/
protected boolean genericTermIdent(Class type,
Term> term, boolean avoidInherit, String propertyName,
Map properties) {
if (term instanceof TermIdent) {
return genericProperty(type, (TermIdent) term, avoidInherit,
properties, propertyName);
}
return false;
}
/**
* Converts term into Color and stored values and types in maps
*
* @param
* CSSProperty
* @param term
* Term to be parsed
* @param propertyName
* How to store colorIdentificiton
* @param colorIdentification
* What to store under propertyName
* @param properties
* Map to store property types
* @param values
* Map to store property values
* @return true
in case of success, false
* otherwise
*/
protected boolean genericTermColor(Term> term,
String propertyName, T colorIdentification,
Map properties, Map> values) {
if (term instanceof TermColor) {
properties.put(propertyName, colorIdentification);
values.put(propertyName, term);
return true;
}
return false;
}
/**
* Converts term into TermLength and stores values and types in maps
*
* @param
* CSSProperty
* @param term
* Term to be parsed
* @param propertyName
* How to store colorIdentificiton
* @param lengthIdentification
* What to store under propertyName
* @param properties
* Map to store property types
* @param values
* Map to store property values
* @return true
in case of success, false
* otherwise
*/
protected boolean genericTermLength(Term> term,
String propertyName, T lengthIdentification, boolean sanify,
Map properties, Map> values) {
if (term instanceof TermInteger && ((TermInteger) term).getUnit().equals(TermNumber.Unit.none)) {
if (CSSFactory.getImplyPixelLength() || ((TermInteger) term).getValue() == 0) { //0 is always allowed with no units
// convert to length with units of px
TermLength tl = tf.createLength(((TermInteger) term).getValue(), TermNumber.Unit.px);
return genericTerm(TermLength.class, tl, propertyName, lengthIdentification, sanify, properties, values);
} else {
return false;
}
}
else if (term instanceof TermLength) {
return genericTerm(TermLength.class, term, propertyName, lengthIdentification, sanify, properties, values);
}
return false;
}
/**
* Check whether given declaration contains one term of given type. It is
* able to check even whether is above zero for numeric values
*
* @param
* Class of CSSProperty to be used for result
* @param termType
* Supposed type of term
* @param term
* Term of which is supposed to be of type termType
,
* that is input data
* @param propertyName
* Name under which property's value and type is stored in maps
* @param typeIdentification
* How this type of term is described in type T
* @param sanify
* Check if value is positive
* @param properties
* Where to store property type
* @param values
* Where to store property value
* @return true
if succeeded in recognition, false
* otherwise
*/
protected boolean genericTerm(
Class extends Term>> termType, Term> term,
String propertyName, T typeIdentification, boolean sanify,
Map properties, Map> values) {
// check type
if (termType.isInstance(term)) {
// sanity check
if (sanify) {
// check for integer
if (term.getValue() instanceof Integer) {
final Integer zero = new Integer(0);
if (zero.compareTo((Integer) term.getValue()) > 0) {
// return false is also possibility
// but we will change to zero
((TermInteger) term).setValue(zero);
}
}
// check for float
else if (term.getValue() instanceof Float) {
final Float zero = new Float(0.0f);
if (zero.compareTo((Float) term.getValue()) > 0) {
// return false is also possibility
// but we will change to zero
((TermNumber) term).setValue(zero);
}
}
}
// passed both type check and (optional) sanity check,
// store
properties.put(propertyName, typeIdentification);
values.put(propertyName, term);
return true;
}
return false;
}
/**
* Processes declaration which is supposed to contain one identification
* term
*
* @param
* Type of CSSProperty
* @param type
* Class of CSSProperty to be stored
* @param d
* Declaration to be parsed
* @param properties
* Properties map where to store enum
* @return true
in case of success, false
* elsewhere
*/
protected boolean genericOneIdent(Class type,
Declaration d, Map properties) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(),
properties);
}
/**
* Processes declaration which is supposed to contain one identification
* term or one TermColor
*
* @param
* Type of CSSProperty
* @param type
* Class of enum to be stored
* @param colorIdentification
* Instance of CSSProperty stored into properties to indicate
* that additional value of type TermColor is stored in values
* @param d
* Declaration to be parsed
* @param properties
* Properties map where to store enum
* @param values
* @return true
in case of success, false
* elsewhere
*/
protected boolean genericOneIdentOrColor(
Class type, T colorIdentification, Declaration d,
Map properties, Map> values) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(),
properties)
|| genericTermColor(d.get(0), d.getProperty(),
colorIdentification, properties, values);
}
protected boolean genericOneIdentOrInteger(
Class type, T integerIdentification, boolean sanify,
Declaration d, Map properties,
Map> values) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(),
properties)
|| genericTerm(TermInteger.class, d.get(0), d.getProperty(),
integerIdentification, sanify, properties, values);
}
protected boolean genericOneIdentOrIntegerOrNumber(
Class type, T integerIdentification, T numberIdentification, boolean sanify,
Declaration d, Map properties,
Map> values) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(), properties)
|| genericTerm(TermInteger.class, d.get(0), d.getProperty(),
integerIdentification, sanify, properties, values)
|| genericTerm(TermNumber.class, d.get(0), d.getProperty(),
numberIdentification, sanify, properties, values);
}
protected boolean genericOneIdentOrLength(
Class type, T lengthIdentification, boolean sanify,
Declaration d, Map properties,
Map> values) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(),
properties)
|| genericTermLength(d.get(0), d.getProperty(),
lengthIdentification, sanify, properties, values);
}
protected & CSSProperty> boolean genericOneIdentOrLengthOrPercent(
Class type, T lengthIdentification, T percentIdentification,
boolean sanify, Declaration d, Map properties,
Map> values) {
if (d.size() != 1)
return false;
return genericTermIdent(type, d.get(0), ALLOW_INH, d.getProperty(),
properties)
|| genericTermLength(d.get(0), d.getProperty(),
lengthIdentification, sanify, properties, values)
|| genericTerm(TermPercent.class, d.get(0), d.getProperty(),
percentIdentification, sanify, properties, values);
}
protected & CSSProperty> boolean genericTwoIdentsOrLengthsOrPercents(
Class type, T listIdentification,
boolean sanify, Declaration d, Map properties,
Map> values) {
if (d.size() == 1) {
Term> term = d.get(0);
String propertyName = d.getProperty();
// is it identifier or length ?
if (genericTermIdent(type, term, ALLOW_INH, propertyName, properties)
|| genericTermLength(term, propertyName,
listIdentification, sanify, properties, values)
|| genericTerm(TermPercent.class, term, propertyName,
listIdentification, sanify, properties, values)) {
// one term with length was inserted, double it
if (properties.get(propertyName) == listIdentification) {
TermList terms = tf.createList(2);
terms.add(term);
terms.add(term);
values.put(propertyName, terms);
}
return true;
}
else
return false;
}
// two numerical values
else if (d.size() == 2) {
Term> term1 = d.get(0);
Term> term2 = d.get(1);
String propertyName = d.getProperty();
// two lengths ?
if ((genericTermLength(term1, propertyName,
listIdentification, sanify, properties, values)
|| genericTerm(TermPercent.class, term1, propertyName,
listIdentification, sanify, properties, values))
&& (genericTermLength(term2, propertyName,
listIdentification, sanify, properties, values)
|| genericTerm(TermPercent.class, term2, propertyName,
listIdentification, sanify, properties, values))) {
TermList terms = tf.createList(2);
terms.add(term1);
terms.add(term2);
values.put(propertyName, terms);
return true;
}
else
return false;
}
else
return false;
}
// =============================================================
// processing methods
@SuppressWarnings("unused")
private boolean processColor(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrColor(Color.class, Color.color, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processBackground(Declaration d,
Map properties, Map> values) {
Variator background = new BackgroundVariator();
background.assignTermsFromDeclaration(d);
background.assignDefaults(properties, values);
return background.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundAttachment(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryOneTermVariant(BackgroundVariator.ATTACHMENT, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundColor(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryOneTermVariant(BackgroundVariator.COLOR, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundImage(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryOneTermVariant(BackgroundVariator.IMAGE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundRepeat(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryOneTermVariant(BackgroundVariator.REPEAT, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundPosition(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryMultiTermVariant(BackgroundVariator.POSITION,
properties, values, d.toArray(new Term>[0]));
}
@SuppressWarnings("unused")
private boolean processBackgroundSize(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryMultiTermVariant(BackgroundVariator.SIZE,
properties, values, d.toArray(new Term>[0]));
}
@SuppressWarnings("unused")
private boolean processBorder(Declaration d,
Map properties, Map> values) {
Variator border = new BorderVariator();
border.assignTermsFromDeclaration(d);
border.assignDefaults(properties, values);
return border.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderCollapse(Declaration d,
Map properties, Map> values) {
return genericOneIdent(BorderCollapse.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processBorderTopColor(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("top");
return borderSide.tryOneTermVariant(BorderSideVariator.COLOR, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRightColor(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("right");
return borderSide.tryOneTermVariant(BorderSideVariator.COLOR, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomColor(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("bottom");
return borderSide.tryOneTermVariant(BorderSideVariator.COLOR, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderLeftColor(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("left");
return borderSide.tryOneTermVariant(BorderSideVariator.COLOR, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTopStyle(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("top");
return borderSide.tryOneTermVariant(BorderSideVariator.STYLE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRightStyle(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("right");
return borderSide.tryOneTermVariant(BorderSideVariator.STYLE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomStyle(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("bottom");
return borderSide.tryOneTermVariant(BorderSideVariator.STYLE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderLeftStyle(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("left");
return borderSide.tryOneTermVariant(BorderSideVariator.STYLE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderSpacing(Declaration d,
Map properties, Map> values) {
if (d.size() == 1) {
Term> term = d.get(0);
String propertyName = d.getProperty();
// is it identifier or length ?
if (genericTermIdent(BorderSpacing.class, term, ALLOW_INH,
propertyName, properties)
|| genericTermLength(term, propertyName,
BorderSpacing.list_values, true, properties, values)) {
// one term with length was inserted, double it
if (properties.get(propertyName) == BorderSpacing.list_values) {
TermList terms = tf.createList(2);
terms.add(term);
terms.add(term);
values.put(propertyName, terms);
}
return true;
}
}
// two numerical values
else if (d.size() == 2) {
Term> term1 = d.get(0);
Term> term2 = d.get(1);
String propertyName = d.getProperty();
// two lengths ?
if (genericTermLength(term1, propertyName,
BorderSpacing.list_values, true, properties, values)
&& genericTermLength(term2, propertyName,
BorderSpacing.list_values, true, properties, values)) {
TermList terms = tf.createList(2);
terms.add(term1);
terms.add(term2);
values.put(propertyName, terms);
return true;
}
return false;
}
return false;
}
@SuppressWarnings("unused")
private boolean processBorderColor(Declaration d,
Map properties, Map> values) {
Repeater borderColor = new BorderColorRepeater();
return borderColor.repeatOverFourTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderStyle(Declaration d,
Map properties, Map> values) {
Repeater borderStyle = new BorderStyleRepeater();
return borderStyle.repeatOverFourTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTopWidth(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("top");
return borderSide.tryOneTermVariant(BorderSideVariator.WIDTH, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRightWidth(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("right");
return borderSide.tryOneTermVariant(BorderSideVariator.WIDTH, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomWidth(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("bottom");
return borderSide.tryOneTermVariant(BorderSideVariator.WIDTH, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderLeftWidth(Declaration d,
Map properties, Map> values) {
final Variator borderSide = new BorderSideVariator("left");
return borderSide.tryOneTermVariant(BorderSideVariator.WIDTH, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderWidth(Declaration d,
Map properties, Map> values) {
Repeater borderWidth = new BorderWidthRepeater();
return borderWidth.repeatOverFourTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTop(Declaration d,
Map properties, Map> values) {
Variator borderSide = new BorderSideVariator("top");
borderSide.assignTermsFromDeclaration(d);
borderSide.assignDefaults(properties, values);
return borderSide.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRight(Declaration d,
Map properties, Map> values) {
Variator borderSide = new BorderSideVariator("right");
borderSide.assignTermsFromDeclaration(d);
borderSide.assignDefaults(properties, values);
return borderSide.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottom(Declaration d,
Map properties, Map> values) {
Variator borderSide = new BorderSideVariator("bottom");
borderSide.assignTermsFromDeclaration(d);
borderSide.assignDefaults(properties, values);
return borderSide.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderLeft(Declaration d,
Map properties, Map> values) {
Variator borderSide = new BorderSideVariator("left");
borderSide.assignTermsFromDeclaration(d);
borderSide.assignDefaults(properties, values);
return borderSide.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTopLeftRadius(Declaration d,
Map properties, Map> values) {
return genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTopRightRadius(Declaration d,
Map properties, Map> values) {
return genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomRightRadius(Declaration d,
Map properties, Map> values) {
return genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomLeftRadius(Declaration d,
Map properties, Map> values) {
return genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRadius(Declaration d,
Map properties, Map> values) {
BorderRadiusRepeater radius = new BorderRadiusRepeater();
return radius.repeatOverMultiTermDeclaration(d, properties, values);
}
/*
*
* private Boolean processBorder(Declaration d) { NodeData trans =
* beginTransaction(); //Nastavení na výchozí hodnoty borderColorTopType =
* null; borderColorRightType = null; borderColorBottomType = null;
* borderColorLeftType = null; borderColorTopValue = null;
* borderColorRightValue = null; borderColorBottomValue = null;
* borderColorLeftValue = null; borderStyleTopType = null;
* borderStyleRightType = null; borderStyleBottomType = null;
* borderStyleLeftType = null; borderWidthTopType = null;
* borderWidthRightType = null; borderWidthBottomType = null;
* borderWidthLeftType = null; borderWidthTopValue = null;
* borderWidthRightValue = null; borderWidthBottomValue = null;
* borderWidthLeftValue = null;
*
* //Každou z částí lze nastavit pouze jednou. Není přípustné aby se v jedné
* deklaraci //objevila například 2x barva. K určení slouží následující
* proměnné boolean processedColor = false; boolean processedStyle = false;
* boolean processedWidth = false;
*
* for(Term t : d.getTerms()) { //Pokud je první (a jediný) identifikátor
* inherit, pak se nastaví všecm hodnotám inherit //Pokud by se inherit
* objevilo až například jako třetí term, dojde k ignorování celé deklarace
* if((t instanceof TermIdent) &&
* ((TermIdent)t).getValue().equalsIgnoreCase("inherit")) {
* if(d.getTerms().size() == 1) { borderColorTopType =
* EnumColorTransparent.inherit; borderColorRightType =
* EnumColorTransparent.inherit; borderColorBottomType =
* EnumColorTransparent.inherit; borderColorLeftType =
* EnumColorTransparent.inherit; borderColorTopValue = null;
* borderColorRightValue = null; borderColorBottomValue = null;
* borderColorLeftValue = null; borderStyleTopType =
* EnumBorderStyle.inherit; borderStyleRightType = EnumBorderStyle.inherit;
* borderStyleBottomType = EnumBorderStyle.inherit; borderStyleLeftType =
* EnumBorderStyle.inherit; borderWidthTopType = EnumBorderWidth.inherit;
* borderWidthRightType = EnumBorderWidth.inherit; borderWidthBottomType =
* EnumBorderWidth.inherit; borderWidthLeftType = EnumBorderWidth.inherit;
* borderWidthTopValue = null; borderWidthRightValue = null;
* borderWidthBottomValue = null; borderWidthLeftValue = null; return true;
* } else { rollbackTransaction(trans); return false; } }
*
* //Vytvořím pomocnou deklaraci, která obsahuje jeden jediný term (ten
* aktuální) //a v jednotlivých blocích se pokouším tuto deklaraci
* zpracovat. Declaration tmpDeclaration = new DataDeclaration("border");
* tmpDeclaration.getTerms().add(t);
*
* //Vyzkouším, jestli se jedná o barvu
* tmpDeclaration.setProperty("border-color");
* if(processBorderColor(tmpDeclaration)) { //Jedná se o barvu. Zjistím,
* jestli barva už nebyla jednou zadána if(processedColor) { //Barva už byla
* jednou zadáno, deklarace je chybná, rollback a konec
* rollbackTransaction(trans); return false; } else { //Barva ještě nebyla
* zadána, pokračujeme dalším termem processedColor = true; continue; } }
* tmpDeclaration.setProperty("border-style");
* if(processBorderStyle(tmpDeclaration)) { if(processedStyle) {
* rollbackTransaction(trans); return false; } else { processedStyle = true;
* continue; } } tmpDeclaration.setProperty("border-width");
* if(processBorderWidth(tmpDeclaration)) { if(processedWidth) {
* rollbackTransaction(trans); return false; } else { processedWidth = true;
* continue; } }
*
* //Pokud program dojde sem, znamená to že term není ani color, style nebo
* width - ignorace celé deklarace rollbackTransaction(trans); return false;
* } return true; }
*/
@SuppressWarnings("unused")
private boolean processFontFamily(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font.tryMultiTermVariant(FontVariator.FAMILY, properties,
values, d.toArray(new Term>[0]));
}
@SuppressWarnings("unused")
private boolean processFontSize(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font.tryOneTermVariant(FontVariator.SIZE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processFontStyle(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font
.tryOneTermVariant(FontVariator.STYLE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processFontVariant(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font.tryOneTermVariant(FontVariator.VARIANT, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processFontWeight(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font.tryOneTermVariant(FontVariator.WEIGHT, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processFont(Declaration d,
Map properties, Map> values) {
Variator font = new FontVariator();
font.assignTermsFromDeclaration(d);
font.assignDefaults(properties, values);
return font.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processLineHeight(Declaration d,
Map properties, Map> values) {
final Variator font = new FontVariator();
return font.tryOneTermVariant(FontVariator.LINE_HEIGHT, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processTop(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Top.class, Top.length,
Top.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processRight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Right.class, Right.length,
Right.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBottom(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Bottom.class, Bottom.length,
Bottom.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processLeft(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Left.class, Left.length,
Left.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processWidth(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Width.class, Width.length,
Width.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processHeight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Height.class, Height.length,
Height.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processCaptionSide(Declaration d,
Map properties, Map> values) {
return genericOneIdent(CaptionSide.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processClear(Declaration d,
Map properties, Map> values) {
return genericOneIdent(Clear.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processClip(Declaration d,
Map properties, Map> values) {
if (d.size() != 1)
return false;
Term> term = d.get(0);
if (term instanceof TermIdent) {
final Set allowedClips = EnumSet.allOf(Clip.class);
Clip clip = genericPropertyRaw(Clip.class, allowedClips, (TermIdent) term);
if (clip != null) {
properties.put("clip", clip);
return true;
}
return false;
} else if (term instanceof TermFunction) {
return genericTerm(TermFunction.class, term, "clip", Clip.shape, false, properties, values);
}
return false;
}
@SuppressWarnings("unused")
private boolean processCounterIncrement(Declaration d,
Map properties, Map> values) {
if (d.size() == 1
&& genericOneIdent(CounterIncrement.class, d, properties)) {
return true;
}
// counter with increments
else {
// counters are stored there
Set> termList = new LinkedHashSet>();
String counterName = null;
for (Term> term : d.asList()) {
// counter name
if (term instanceof TermIdent) {
counterName = ((TermIdent) term).getValue();
termList.add(tf.createPair(counterName, new Integer(1)));
}
// counter reset value follows counter name
else if (term instanceof TermInteger && counterName != null) {
termList.add(tf.createPair(counterName,
((TermInteger) term).getIntValue()));
counterName = null;
} else {
return false;
}
}
if (!termList.isEmpty()) {
TermList list = tf.createList(termList.size());
list.addAll(termList);
properties.put("counter-increment",
CounterIncrement.list_values);
values.put("counter-increment", list);
return true;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processCounterReset(Declaration d,
Map properties, Map> values) {
if (d.size() == 1 && genericOneIdent(CounterReset.class, d, properties)) {
return true;
}
// counter with resets
else {
// counters are stored there
Set> termList = new LinkedHashSet>();
String counterName = null;
for (Term> term : d.asList()) {
// counter name
if (term instanceof TermIdent) {
counterName = ((TermIdent) term).getValue();
termList.add(tf.createPair(counterName, new Integer(0)));
}
// counter reset value follows counter name
else if (term instanceof TermInteger && counterName != null) {
termList.add(tf.createPair(counterName,
((TermInteger) term).getIntValue()));
counterName = null;
} else {
return false;
}
}
if (!termList.isEmpty()) {
TermList list = tf.createList(termList.size());
list.addAll(termList);
properties.put("counter-reset", CounterReset.list_values);
values.put("counter-reset", list);
return true;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processCounterSet(Declaration d,
Map properties, Map> values) {
if (d.size() == 1 && genericOneIdent(CounterSet.class, d, properties)) {
return true;
}
// counter with sets
else {
// counters are stored there
Set> termList = new LinkedHashSet>();
String counterName = null;
for (Term> term : d.asList()) {
// counter name
if (term instanceof TermIdent) {
counterName = ((TermIdent) term).getValue();
termList.add(tf.createPair(counterName, new Integer(0)));
}
// counter set value follows counter name
else if (term instanceof TermInteger && counterName != null) {
termList.add(tf.createPair(counterName,
((TermInteger) term).getIntValue()));
counterName = null;
} else {
return false;
}
}
if (!termList.isEmpty()) {
TermList list = tf.createList(termList.size());
list.addAll(termList);
properties.put("counter-set", CounterReset.list_values);
values.put("counter-set", list);
return true;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processCursor(Declaration d,
Map properties, Map> values) {
if (d.size() == 1 && genericOneIdent(Cursor.class, d, properties)) {
return true;
} else {
final Set allowedCursors = EnumSet.complementOf(EnumSet
.of(Cursor.INHERIT));
TermList list = tf.createList();
Cursor cur = null;
for (Term> term : d.asList()) {
if (term instanceof TermURI) {
list.add(term);
} else if (term instanceof TermIdent
&& (cur = genericPropertyRaw(Cursor.class,
allowedCursors, (TermIdent) term)) != null) {
// this have to be the last cursor in sequence
// and only one generic cursor is allowed
if (d.indexOf(term) != d.size() - 1)
return false;
// passed as last cursor, insert into properties and values
properties.put("cursor", cur);
if (!list.isEmpty())
values.put("cursor", list);
return true;
} else
return false;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processDirection(Declaration d,
Map properties, Map> values) {
return genericOneIdent(Direction.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processDisplay(Declaration d,
Map properties, Map> values) {
return genericOneIdent(Display.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processEmptyCells(Declaration d,
Map properties, Map> values) {
return genericOneIdent(EmptyCells.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processFloat(Declaration d,
Map properties, Map> values) {
return genericOneIdent(CSSProperty.Float.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processListStyleImage(Declaration d,
Map properties, Map> values) {
final Variator listStyle = new ListStyleVariator();
return listStyle.tryOneTermVariant(ListStyleVariator.IMAGE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processListStylePosition(Declaration d,
Map properties, Map> values) {
final Variator listStyle = new ListStyleVariator();
return listStyle.tryOneTermVariant(ListStyleVariator.POSITION, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processListStyleType(Declaration d,
Map properties, Map> values) {
final Variator listStyle = new ListStyleVariator();
return listStyle.tryOneTermVariant(ListStyleVariator.TYPE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processListStyle(Declaration d,
Map properties, Map> values) {
Variator listStyle = new ListStyleVariator();
listStyle.assignTermsFromDeclaration(d);
listStyle.assignDefaults(properties, values);
return listStyle.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginTop(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginRight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginBottom(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginLeft(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, false, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMargin(Declaration d,
Map properties, Map> values) {
Repeater margin = new MarginRepeater();
return margin.repeatOverFourTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMaxHeight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(MaxHeight.class,
MaxHeight.length, MaxHeight.percentage, true, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMaxWidth(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(MaxWidth.class,
MaxWidth.length, MaxWidth.percentage, true, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMinHeight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(MinHeight.class,
MinHeight.length, MinHeight.percentage, true, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMinWidth(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(MinWidth.class,
MinWidth.length, MinWidth.percentage, true, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processOpacity(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrIntegerOrNumber(Opacity.class, Opacity.number, Opacity.number, false, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processOrphans(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrInteger(Orphans.class, Orphans.integer, true,
d, properties, values);
}
@SuppressWarnings("unused")
private boolean processOutlineColor(Declaration d,
Map properties, Map> values) {
final Variator outline = new OutlineVariator();
return outline.tryOneTermVariant(OutlineVariator.COLOR, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processOutlineStyle(Declaration d,
Map properties, Map> values) {
final Variator outline = new OutlineVariator();
return outline.tryOneTermVariant(OutlineVariator.STYLE, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processOutlineWidth(Declaration d,
Map properties, Map> values) {
final Variator outline = new OutlineVariator();
return outline.tryOneTermVariant(OutlineVariator.WIDTH, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processOutline(Declaration d,
Map properties, Map> values) {
Variator outline = new OutlineVariator();
outline.assignTermsFromDeclaration(d);
outline.assignDefaults(properties, values);
return outline.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processOverflow(Declaration d,
Map properties, Map> values) {
return genericOneIdent(Overflow.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPaddingTop(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, true, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingRight(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, true, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingBottom(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, true, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingLeft(Declaration d,
Map properties, Map> values) {
return genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, true, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPadding(Declaration d,
Map properties, Map> values) {
Repeater padding = new PaddingRepeater();
return padding.repeatOverFourTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPageBreakAfter(Declaration d,
Map properties, Map> values) {
return genericOneIdent(PageBreak.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPageBreakBefore(Declaration d,
Map properties, Map> values) {
return genericOneIdent(PageBreak.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPageBreakInside(Declaration d,
Map properties, Map> values) {
return genericOneIdent(PageBreakInside.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPosition(Declaration d,
Map properties, Map> values) {
return genericOneIdent(Position.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processQuotes(Declaration d,
Map properties, Map> values) {
if (d.size() == 1
&& genericTermIdent(Quotes.class, d.get(0), ALLOW_INH,
"quotes", properties)) {
return true;
} else {
TermList list = tf.createList();
for (Term> term : d.asList()) {
if (term instanceof TermString)
list.add(term);
else
return false;
}
// there are pairs of quotes
if (!list.isEmpty() && list.size() % 2 == 0) {
properties.put("quotes", Quotes.list_values);
values.put("quotes", list);
return true;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processTableLayout(Declaration d,
Map properties, Map> values) {
return genericOneIdent(TableLayout.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processTextAlign(Declaration d,
Map properties, Map> values) {
return genericOneIdent(TextAlign.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processTextDecoration(Declaration d,
Map properties, Map