![JAR search and dependency download from the Maven repository](/logo.png)
cz.vutbr.web.domassign.DeclarationTransformerImpl 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.
The newest version!
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.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.*;
import cz.vutbr.web.css.Declaration;
import cz.vutbr.web.css.RuleFactory;
import cz.vutbr.web.css.SupportedCSS;
import cz.vutbr.web.css.Term;
import cz.vutbr.web.css.Term.Operator;
import cz.vutbr.web.css.TermBracketedIdents;
import cz.vutbr.web.css.TermColor;
import cz.vutbr.web.css.TermFactory;
import cz.vutbr.web.css.TermFloatValue;
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.TermLengthOrPercent;
import cz.vutbr.web.css.TermList;
import cz.vutbr.web.css.TermPercent;
import cz.vutbr.web.css.TermRect;
import cz.vutbr.web.css.TermString;
import cz.vutbr.web.css.TermTime;
import cz.vutbr.web.css.TermURI;
import cz.vutbr.web.css.TermUnicodeRange;
import cz.vutbr.web.csskit.DeclarationTransformer;
import cz.vutbr.web.domassign.decode.*;
import cz.vutbr.web.domassign.decode.Decoder.ValueRange;
/**
* Contains methods to transform declaration into values applicable to NodeData.
* Uses defaults defined by CSSFactory
*
* @author kapy
*
*/
public class DeclarationTransformerImpl implements DeclarationTransformer {
private static final Logger log = LoggerFactory
.getLogger(DeclarationTransformerImpl.class);
/**
* Cache of parsing methods
*/
private Map methods;
/**
* Singleton instance
*/
private static final DeclarationTransformerImpl instance;
private static final RuleFactory rf = CSSFactory.getRuleFactory();
private static final TermFactory tf = CSSFactory.getTermFactory();
private static final SupportedCSS css = CSSFactory.getSupportedCSS();
static {
instance = new DeclarationTransformerImpl();
}
/**
* Returns instance
*
* @return Singleton instance
*/
public static final DeclarationTransformerImpl 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
*/
@Override
public boolean parseDeclaration(Declaration d,
Map properties, Map> values) {
final String propertyName = d.getProperty();
// no such declaration is supported or declaration is empty
if (!css.isSupportedCSSProperty(propertyName) || d.isEmpty())
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
*/
private DeclarationTransformerImpl() {
this.methods = parsingMethods();
}
protected Map parsingMethods() {
Map map = new HashMap(css
.getTotalProperties(), 1.0f);
for (String key : css.getDefinedPropertyNames()) {
try {
Method m = DeclarationTransformerImpl.class.getDeclaredMethod(
DeclarationTransformerImpl.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;
}
// =============================================================
// processing methods
@SuppressWarnings("unused")
private boolean processColor(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrColor(Color.class, Color.color, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processBackground(Declaration d,
Map properties, Map> values) {
Variator background = new BackgroundVariator();
return background.varyList(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBackgroundAttachment(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryListOfOneTermVariant(BackgroundVariator.ATTACHMENT, d,
properties, values, BackgroundAttachment.nested_list);
}
@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.tryListOfOneTermVariant(BackgroundVariator.IMAGE, d,
properties, values, BackgroundImage.nested_list);
}
@SuppressWarnings("unused")
private boolean processBackgroundRepeat(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryListOfOneTermVariant(BackgroundVariator.REPEAT, d,
properties, values, BackgroundRepeat.nested_list);
}
@SuppressWarnings("unused")
private boolean processBackgroundPosition(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryListOfMultiTermVariant(BackgroundVariator.POSITION, d,
properties, values, BackgroundPosition.nested_list);
}
@SuppressWarnings("unused")
private boolean processBackgroundSize(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryListOfMultiTermVariant(BackgroundVariator.SIZE, d,
properties, values, BackgroundSize.nested_list);
}
@SuppressWarnings("unused")
private boolean processBackgroundOrigin(Declaration d,
Map properties, Map> values) {
final Variator background = new BackgroundVariator();
return background.tryListOfOneTermVariant(BackgroundVariator.ORIGIN, d,
properties, values, BackgroundOrigin.nested_list);
}
@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 Decoder.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 (Decoder.genericTermIdent(BorderSpacing.class, term, Decoder.ALLOW_INH,
propertyName, properties)
|| Decoder.genericTermLength(term, propertyName,
BorderSpacing.list_values, ValueRange.DISALLOW_NEGATIVE, 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 (Decoder.genericTermLength(term1, propertyName,
BorderSpacing.list_values, ValueRange.DISALLOW_NEGATIVE, properties, values)
&& Decoder.genericTermLength(term2, propertyName,
BorderSpacing.list_values, ValueRange.DISALLOW_NEGATIVE, 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 Decoder.genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderTopRightRadius(Declaration d,
Map properties, Map> values) {
return Decoder.genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomRightRadius(Declaration d,
Map properties, Map> values) {
return Decoder.genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderBottomLeftRadius(Declaration d,
Map properties, Map> values) {
return Decoder.genericTwoIdentsOrLengthsOrPercents(BorderRadius.class,
BorderRadius.list_values, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBorderRadius(Declaration d,
Map properties, Map> values) {
BorderRadiusRepeater radius = new BorderRadiusRepeater();
return radius.repeatOverMultiTermDeclaration(d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBoxShadow(Declaration d,
Map properties, Map> values) {
if (d.size() == 1 && Decoder.genericOneIdent(BoxShadow.class, d, properties)) {
return true;
}
// inset? && {2,4} && ?
TermList list = tf.createList();
int lengthCount = 0;
int lastLengthIndex = -1;
int insetIndex = -1;
int colorIndex = -1;
for (int i = 0; i < d.size(); i++) {
Term> t = d.get(i);
if (t.getOperator() == Operator.COMMA) {
if (lengthCount < 2) {
return false;
}
lengthCount = 0;
lastLengthIndex = -1;
insetIndex = -1;
colorIndex = -1;
}
if (t instanceof TermColor && colorIndex < 0) {
colorIndex = i;
} else if (t instanceof TermIdent
&& ((TermIdent) t).getValue().equalsIgnoreCase("inset")
&& insetIndex < 0) {
insetIndex = i;
} else if (t instanceof TermLength
&& lastLengthIndex < 0
|| (lastLengthIndex > insetIndex && lastLengthIndex > colorIndex)) {
if (lengthCount >= 4) {
return false;
}
lastLengthIndex = i;
lengthCount++;
} else {
return false;
}
list.add(t);
}
if (lengthCount < 2) {
return false;
}
properties.put(d.getProperty(), BoxShadow.component_values);
values.put(d.getProperty(), list);
return true;
}
@SuppressWarnings("unused")
private boolean processBoxSizing(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(BoxSizing.class, d, properties);
}
@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 processTabSize(Declaration d,
Map properties, Map> values) {
return Decoder.genericIntegerOrLength(TabSize.class, TabSize.integer,
TabSize.length, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processTop(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Top.class, Top.length,
Top.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processRight(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Right.class, Right.length,
Right.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processBottom(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Bottom.class, Bottom.length,
Bottom.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processLeft(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Left.class, Left.length,
Left.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processTransform(Declaration d,
Map properties, Map> values) {
// just a simple value (e.g. "none")
if (d.size() == 1 && Decoder.genericOneIdent(Transform.class, d, properties)) {
return true;
} else {
TermList list = tf.createList();
for (Term> t : d.asList()) {
if (t instanceof TermFunction.TransformFunction)
list.add(t);
else
return false;
}
// there is nothing in list after parsing
if (list.isEmpty())
return false;
properties.put("transform", Transform.list_values);
values.put("transform", list);
return true;
}
}
@SuppressWarnings("unused")
private boolean processTransformOrigin(Declaration d,
Map properties, Map> values) {
if (d.size() == 1
&& Decoder.genericTermIdent(BorderSpacing.class, d.get(0), Decoder.ALLOW_INH, d.getProperty(), properties))
{
return true; //must be 'inherit'
}
else if (d.size() >= 1 && d.size() <= 3)
{
TermLengthOrPercent hpos = null;
TermLengthOrPercent vpos = null;
TermLength zpos = null;
//generic check and assign recognizable keywords
for (int i = 0; i < d.size(); i++)
{
Term> term = d.get(i);
if (term instanceof TermIdent)
{
String value = ((TermIdent) term).getValue();
if ("top".equals(value))
{
if (vpos == null)
vpos = tf.createPercent(0.0f);
else
return false;
}
else if ("bottom".equals(value))
{
if (vpos == null)
vpos = tf.createPercent(100.0f);
else
return false;
}
else if ("left".equals(value))
{
if (hpos == null)
hpos = tf.createPercent(0.0f);
else
return false;
}
else if ("right".equals(value))
{
if (hpos == null)
hpos = tf.createPercent(100.0f);
else
return false;
}
else if ("center".equals(value))
{
//skip for this iteration
}
else
return false; //unknown keyword
}
else if (term instanceof TermLengthOrPercent)
{
if (i > 1 && ((TermLengthOrPercent) term).isPercentage())
return false; //percentages are only allowed for arguments 1 and 2
}
else
return false; //invalid value (not keyword nor length nor percentage)
}
//assign 'center' or numeric values
for (int i = 0; i < d.size(); i++)
{
TermLengthOrPercent value = null;
Term> term = d.get(i);
if (i < 2) //first two arguments
{
if (term instanceof TermIdent)
{
if ("center".equals(((TermIdent) term).getValue()))
value = tf.createPercent(50.0f);
}
else
value = (TermLengthOrPercent) term;
if (value != null)
{
if (hpos == null)
hpos = value;
else if (vpos == null)
vpos = value;
else
return false;
}
}
else //last argument, must be length
{
zpos = (TermLength) term;
}
}
//replace null values by defaults
if (hpos == null)
hpos = tf.createPercent(50.0f);
if (vpos == null)
vpos = tf.createPercent(50.0f);
if (zpos == null)
zpos = tf.createLength(0.0f);
//publish the values
TermList list = tf.createList();
list.add(hpos);
list.add(vpos);
list.add(zpos);
properties.put("transform-origin", TransformOrigin.list_values);
values.put("transform-origin", list);
return true;
}
else
return false; //invalid number of arguments
}
@SuppressWarnings("unused")
private boolean processWidth(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Width.class, Width.length,
Width.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processHeight(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Height.class, Height.length,
Height.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processCaptionSide(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(CaptionSide.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processClear(Declaration d,
Map properties, Map> values) {
return Decoder.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 = Decoder.genericPropertyRaw(Clip.class, allowedClips, (TermIdent) term);
if (clip != null) {
properties.put("clip", clip);
return true;
}
return false;
} else if (term instanceof TermRect) {
return Decoder.genericTerm(TermRect.class, term, "clip", Clip.shape, ValueRange.ALLOW_ALL, properties, values);
}
return false;
}
@SuppressWarnings("unused")
private boolean processCounterIncrement(Declaration d,
Map properties, Map> values) {
if (d.size() == 1
&& Decoder.genericOneIdent(CounterIncrement.class, d, properties)) {
return true;
}
// counter with increments
else {
List> termList = decodeCounterList(d.asList(), 1);
if (termList != null && !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 && Decoder.genericOneIdent(CounterReset.class, d, properties)) {
return true;
}
// counter with resets
else {
// counters are stored there
List> termList = decodeCounterList(d.asList(), 0);
if (termList != null && !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;
}
}
private List> decodeCounterList(List> terms, int defaultValue)
{
List> ret = new ArrayList<>();
int i = 0;
while (i < terms.size()) {
final Term> term = terms.get(i);
if (term instanceof TermIdent) {
final String counterName = ((TermIdent) term).getValue();
if (i + 1 < terms.size() && terms.get(i + 1) instanceof TermInteger)
{
//integer value specified after the counter name
int counterValue = ((TermInteger) terms.get(i + 1)).getIntValue();
ret.add(tf.createPair(counterName, counterValue));
i += 2;
}
else
{
//only the counter name, use the default value
ret.add(tf.createPair(counterName, defaultValue));
i++;
}
} else {
return null;
}
}
return ret;
}
@SuppressWarnings("unused")
private boolean processCursor(Declaration d,
Map properties, Map> values) {
if (d.size() == 1 && Decoder.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 = Decoder.genericPropertyRaw(Cursor.class,
allowedCursors, (TermIdent) term)) != null) {
// this have to be the last cursor in sequence
// and only one Decoder.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 Decoder.genericOneIdent(Direction.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processDisplay(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(Display.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processEmptyCells(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(EmptyCells.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processFloat(Declaration d,
Map properties, Map> values) {
return Decoder.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 Decoder.genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginRight(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginBottom(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processMarginLeft(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Margin.class, Margin.length,
Margin.percentage, ValueRange.ALLOW_ALL, 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 Decoder.genericOneIdentOrLengthOrPercent(MaxHeight.class,
MaxHeight.length, MaxHeight.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMaxWidth(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(MaxWidth.class,
MaxWidth.length, MaxWidth.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMinHeight(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(MinHeight.class,
MinHeight.length, MinHeight.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processMinWidth(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(MinWidth.class,
MinWidth.length, MinWidth.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processOpacity(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrIntegerOrNumber(Opacity.class, Opacity.number, Opacity.number, ValueRange.TRUNCATE_NEGATIVE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processOrphans(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrInteger(Orphans.class, Orphans.integer, ValueRange.DISALLOW_NEGATIVE,
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) {
if (d.size() == 1) {
Term> term = d.get(0);
if (term instanceof TermIdent) {
return Decoder.genericProperty(Overflow.class, (TermIdent) term, Decoder.ALLOW_INH, properties, "overflow-x")
&& Decoder.genericProperty(Overflow.class, (TermIdent) term, Decoder.ALLOW_INH, properties, "overflow-y");
}
else
return false;
}
else
return false;
}
@SuppressWarnings("unused")
private boolean processOverflowX(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(Overflow.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processOverflowY(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(Overflow.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPaddingTop(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingRight(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingBottom(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processPaddingLeft(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(Padding.class, Padding.length,
Padding.percentage, ValueRange.DISALLOW_NEGATIVE, 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 Decoder.genericOneIdent(PageBreak.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPageBreakBefore(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(PageBreak.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPageBreakInside(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(PageBreakInside.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processPosition(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(Position.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processQuotes(Declaration d,
Map properties, Map> values) {
if (d.size() == 1
&& Decoder.genericTermIdent(Quotes.class, d.get(0), Decoder.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 Decoder.genericOneIdent(TableLayout.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processTextAlign(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(TextAlign.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processTextDecoration(Declaration d,
Map properties, Map> values) {
final Set availableDecorations = EnumSet.of(
TextDecoration.BLINK, TextDecoration.LINE_THROUGH,
TextDecoration.OVERLINE, TextDecoration.UNDERLINE);
// it one term
if (d.size() == 1) {
return Decoder.genericOneIdent(TextDecoration.class, d, properties);
}
// there are more terms, we have to construct list
else {
TermList list = tf.createList();
TextDecoration dec = null;
for (Term> term : d.asList()) {
if (term instanceof TermIdent
&& (dec = Decoder.genericPropertyRaw(TextDecoration.class,
availableDecorations, (TermIdent) term)) != null) {
// construct term with value of parsed decoration
list.add(tf.createTerm(dec));
} else
return false;
}
if (!list.isEmpty()) {
properties.put("text-decoration", TextDecoration.list_values);
values.put("text-decoration", list);
return true;
}
return false;
}
}
@SuppressWarnings("unused")
private boolean processTextIndent(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(TextIndent.class,
TextIndent.length, TextIndent.percentage, ValueRange.ALLOW_ALL, d, properties,
values);
}
@SuppressWarnings("unused")
private boolean processTextTransform(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(TextTransform.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processUnicodeBidi(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(UnicodeBidi.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processUnicodeRange(Declaration d,
Map properties, Map> values) {
if (d.size() > 0) {
TermList list = tf.createList();
for (int i = 0; i < d.size(); i++) {
Term> term = d.get(i);
if (term instanceof TermUnicodeRange
&& ((i == 0 && term.getOperator() == null) || (i != 0 && term.getOperator() == Operator.COMMA))) {
list.add(term);
} else {
return false;
}
}
properties.put("unicode-range", UnicodeRange.list_values);
values.put("unicode-range", list);
return true;
}
else
return false;
}
@SuppressWarnings("unused")
private boolean processVerticalAlign(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(VerticalAlign.class,
VerticalAlign.length, VerticalAlign.percentage, ValueRange.ALLOW_ALL, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processVisibility(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(Visibility.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processWhiteSpace(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdent(WhiteSpace.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processWidows(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrInteger(Widows.class, Widows.integer, ValueRange.DISALLOW_NEGATIVE, d,
properties, values);
}
@SuppressWarnings("unused")
private boolean processWordSpacing(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLength(WordSpacing.class, WordSpacing.length,
ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processLetterSpacing(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrLength(LetterSpacing.class,
LetterSpacing.length, ValueRange.ALLOW_ALL, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processZIndex(Declaration d,
Map properties, Map> values) {
return Decoder.genericOneIdentOrInteger(ZIndex.class, ZIndex.integer, ValueRange.ALLOW_ALL, d,
properties, values);
}
/**
* Processes an unknown property and stores its value. Unknown properties containing
* multiple values are ignored (the interpretation is not clear).
*
* @param d the declaration.
* @param properties the properties.
* @param values the values.
*
* @return true
, if the property has been pared successfully
*/
private boolean processAdditionalCSSGenericProperty(Declaration d, Map properties, Map> values)
{
if (d.size() == 1)
{
Term> term = d.get(0);
if (term instanceof TermIdent)
return Decoder.genericProperty(GenericCSSPropertyProxy.class, (TermIdent) term, true, properties, d.getProperty());
else
return Decoder.genericTerm(TermLength.class, term, d.getProperty(), null, ValueRange.ALLOW_ALL, properties, values)
|| Decoder.genericTerm(TermPercent.class, term, d.getProperty(), null, ValueRange.ALLOW_ALL, properties, values)
|| Decoder.genericTerm(TermInteger.class, term, d.getProperty(), null, ValueRange.ALLOW_ALL, properties, values)
|| Decoder.genericTermColor(term, d.getProperty(), null, properties, values);
}
else
{
log.warn("Ignoring unsupported property " + d.getProperty() + " with multiple values");
return false;
}
}
@SuppressWarnings("unused")
private boolean processFlex(Declaration d, Map properties, Map> values) {
Variator variator = new FlexVariator();
variator.assignTermsFromDeclaration(d);
variator.assignDefaults(properties, values);
return variator.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processFlexFlow(Declaration d, Map properties, Map> values) {
Variator variator = new FlexFlowVariator();
variator.assignTermsFromDeclaration(d);
variator.assignDefaults(properties, values);
return variator.vary(properties, values);
}
@SuppressWarnings("unused")
private boolean processFlexBasis(Declaration d, Map properties, Map> values) {
return Decoder.genericOneIdentOrLengthOrPercent(FlexBasis.class, FlexBasis.length, FlexBasis.percentage, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processFlexDirection(Declaration d, Map properties, Map> values) {
return Decoder.genericOneIdent(FlexDirection.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processFlexWrap(Declaration d, Map properties, Map> values) {
return Decoder.genericOneIdent(FlexWrap.class, d, properties);
}
@SuppressWarnings("unused")
private boolean processFlexGrow(Declaration d, Map properties, Map> values) {
return Decoder.genericOneIdentOrIntegerOrNumber(FlexGrow.class, FlexGrow.number, FlexGrow.number, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
@SuppressWarnings("unused")
private boolean processFlexShrink(Declaration d, Map