Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cz.vutbr.web.domassign.DeclarationTransformerImpl Maven / Gradle / Ivy
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 properties, Map