r1097 - in lutinjaxx/trunk/jaxx-core: . src/main/java/jaxx/compiler src/main/java/jaxx/css src/main/java/jaxx/tags
Author: tchemit Date: 2008-12-28 15:44:40 +0000 (Sun, 28 Dec 2008) New Revision: 1097 Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/StylesheetHelper.java Modified: lutinjaxx/trunk/jaxx-core/changelog.txt lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Selector.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java Log: use StylesheetHelper Modified: lutinjaxx/trunk/jaxx-core/changelog.txt =================================================================== --- lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/changelog.txt 2008-12-28 15:44:40 UTC (rev 1097) @@ -1,4 +1,10 @@ -0.8 ??? 2009???? +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation * 20081218 [chemit] - improve generation of methods * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -9,6 +9,7 @@ import jaxx.UnsupportedTagException; import jaxx.css.Rule; import jaxx.css.Stylesheet; +import jaxx.css.StylesheetHelper; import jaxx.parser.ParseException; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; @@ -597,7 +598,7 @@ } public void addInlineStyle(CompiledObject object, String propertyName, boolean dataBinding) { - inlineStyles.add(Rule.inlineAttribute(object, propertyName, dataBinding)); + inlineStyles.add(StylesheetHelper.inlineAttribute(object, propertyName, dataBinding)); } /*---------------------------------------------------------------------------------*/ Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -4,15 +4,9 @@ */ package jaxx.css; -import jaxx.CompilerException; -import jaxx.compiler.CompiledObject; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.HashMap; import java.util.Map; -public class Rule implements Serializable, Comparable { +public class Rule implements java.io.Serializable, Comparable<Rule> { public static final String INLINE_ATTRIBUTE = "<inline attribute>"; public static final String DATA_BINDING = "<data binding>"; @@ -23,57 +17,38 @@ public Rule(Selector[] selectors, Map<String, String> properties) { this.selectors = selectors; - Arrays.sort(selectors); + java.util.Arrays.sort(selectors); this.properties = properties; } public Rule(Selector[] selectors, String[] keys, String[] values) { this.selectors = selectors; - Arrays.sort(selectors); - this.properties = new HashMap<String, String>(); - if (keys.length != values.length) + java.util.Arrays.sort(selectors); + this.properties = new java.util.HashMap<String, String>(); + if (keys.length != values.length) { throw new IllegalArgumentException("keys and values must have the same number of entries"); - for (int i = 0; i < keys.length; i++) + } + for (int i = 0; i < keys.length; i++) { properties.put(keys[i], values[i]); + } } - - public static Rule inlineAttribute(CompiledObject object, String propertyName, boolean dataBinding) { - Map<String, String> properties = new HashMap<String, String>(); - properties.put(propertyName, dataBinding ? DATA_BINDING : INLINE_ATTRIBUTE); - return new Rule(new Selector[]{new Selector(null, null, null, object.getId(), true)}, properties); - } - - public Selector[] getSelectors() { return selectors; } - public Map<String, String> getProperties() { return properties; } - - public int appliesTo(CompiledObject object) throws CompilerException { - int appliesTo = Selector.NEVER_APPLIES; - for (Selector selector : selectors) { - appliesTo = Math.max(selector.appliesTo(object), appliesTo); - if (appliesTo == Selector.ALWAYS_APPLIES || appliesTo == Selector.ALWAYS_APPLIES_INHERIT_ONLY) - break; - } - return appliesTo; + @Override + public int compareTo(Rule o) { + return selectors[0].compareTo(o.selectors[0]); // they are already sorted so we only need to compare the highest-ranked from each one } - - public int compareTo(Object o) { - Rule r = (Rule) o; - return selectors[0].compareTo(r.selectors[0]); // they are already sorted so we only need to compare the highest-ranked from each one - } - @Override public String toString() { - return "Rule[" + Arrays.asList(selectors) + ", " + properties + "]"; + return "Rule[" + java.util.Arrays.asList(selectors) + ", " + properties + "]"; } } \ No newline at end of file Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Selector.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Selector.java 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Selector.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -4,12 +4,7 @@ */ package jaxx.css; -import jaxx.compiler.CompiledObject; -import jaxx.reflect.ClassDescriptor; - -import java.io.Serializable; - -public class Selector implements Serializable, Comparable { +public class Selector implements java.io.Serializable, Comparable<Selector> { public static final int NEVER_APPLIES = 0; public static final int PSEUDOCLASS_APPLIES_INHERIT_ONLY = 1; public static final int PSEUDOCLASS_APPLIES = 2; @@ -21,7 +16,7 @@ private String pseudoClass; private String id; private boolean inline; - private static final long serialVersionUID = 2183853334224189438L; + private static final long serialVersionUID = 1L; public Selector(String javaClassName, String styleClass, String pseudoClass, String id) { @@ -38,44 +33,6 @@ } - public int appliesTo(CompiledObject object) { - boolean inheritOnly = false; - CompiledObject parent = object; - while (parent != null) { - boolean classMatch = (javaClassName == null); - if (!classMatch) { - ClassDescriptor javaClass = parent.getObjectClass(); - do { - String name = javaClass.getName(); - if (name.equals(javaClassName) || name.substring(name.lastIndexOf(".") + 1).equals(javaClassName)) { - classMatch = true; - break; - } - javaClass = javaClass.getSuperclass(); - } - while (javaClass != null); - } - - boolean styleClassMatch = (styleClass == null || styleClass.equals(parent.getStyleClass())); - - String objectId = parent.getId(); - objectId = objectId.substring(objectId.lastIndexOf(".") + 1); - boolean idMatch = (id == null || (' ' + objectId + ' ').indexOf(' ' + id + ' ') > -1); - - if (classMatch && styleClassMatch && idMatch) { - if (pseudoClass != null) - return inheritOnly ? PSEUDOCLASS_APPLIES_INHERIT_ONLY : PSEUDOCLASS_APPLIES; - else - return inheritOnly ? ALWAYS_APPLIES_INHERIT_ONLY : ALWAYS_APPLIES; - } - - parent = parent.getParent(); - inheritOnly = true; - } - return NEVER_APPLIES; - } - - public String getJavaClassName() { return javaClassName; } @@ -100,29 +57,38 @@ return inline; } - - public int compareTo(Object o) { - Selector selector = (Selector) o; - if (inline && !selector.inline) + @Override + public int compareTo(Selector selector) { + if (inline && !selector.inline) { return 1; - if (!inline && selector.inline) + } + if (!inline && selector.inline) { return -1; - if (pseudoClass != null && selector.pseudoClass == null) + } + if (pseudoClass != null && selector.pseudoClass == null) { return 1; - if (pseudoClass == null && selector.pseudoClass != null) + } + if (pseudoClass == null && selector.pseudoClass != null) { return -1; - if (id != null && selector.id == null) + } + if (id != null && selector.id == null) { return 1; - if (id == null && selector.id != null) + } + if (id == null && selector.id != null) { return -1; - if (styleClass != null && selector.styleClass == null) + } + if (styleClass != null && selector.styleClass == null) { return 1; - if (styleClass == null && selector.styleClass != null) + } + if (styleClass == null && selector.styleClass != null) { return -1; - if (javaClassName != null && selector.javaClassName == null) + } + if (javaClassName != null && selector.javaClassName == null) { return 1; - if (javaClassName == null && selector.javaClassName != null) + } + if (javaClassName == null && selector.javaClassName != null) { return -1; + } return 0; } Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -4,33 +4,7 @@ */ package jaxx.css; -import jaxx.CompilerException; -import jaxx.compiler.CompiledObject; -import jaxx.compiler.DataBinding; -import jaxx.compiler.DataSource; -import jaxx.compiler.JAXXCompiler; -import jaxx.parser.JavaParser; -import jaxx.parser.JavaParserTreeConstants; -import jaxx.parser.SimpleNode; -import jaxx.reflect.ClassDescriptor; -import jaxx.reflect.ClassDescriptorLoader; -import jaxx.reflect.MethodDescriptor; -import jaxx.tags.DefaultObjectHandler; -import jaxx.tags.TagManager; -import jaxx.types.TypeManager; - -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.io.Serializable; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class Stylesheet implements Serializable { +public class Stylesheet implements java.io.Serializable { private Rule[] rules; private static final long serialVersionUID = 1L; @@ -39,411 +13,33 @@ rules = new Rule[0]; } - public Stylesheet(Rule[] rules) { this.rules = rules; - Arrays.sort(rules); + java.util.Arrays.sort(rules); } - public Rule[] getRules() { return rules; } - public void add(Rule newRule) { Rule[] oldRules = rules; rules = new Rule[oldRules.length + 1]; System.arraycopy(oldRules, 0, rules, 0, oldRules.length); rules[rules.length - 1] = newRule; - Arrays.sort(rules); + java.util.Arrays.sort(rules); } - public void add(Rule[] newRules) { Rule[] oldRules = rules; rules = new Rule[oldRules.length + newRules.length]; System.arraycopy(oldRules, 0, rules, 0, oldRules.length); System.arraycopy(newRules, 0, rules, oldRules.length, newRules.length); - Arrays.sort(rules); + java.util.Arrays.sort(rules); } - - public void applyTo(CompiledObject object, JAXXCompiler compiler, Stylesheet overrides) throws CompilerException { - Map<String, String> overriddenProperties; - if (overrides != null) - overriddenProperties = overrides.getApplicableProperties(object); - else - overriddenProperties = null; - - Map<String, String> properties = getApplicableProperties(object); - if (properties != null) { - if (overriddenProperties != null) - properties.keySet().removeAll(overriddenProperties.keySet()); - DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); - for (Map.Entry<String, String> e : properties.entrySet()) { - String value = e.getValue(); - if (value.equals(Rule.INLINE_ATTRIBUTE) || value.equals(Rule.DATA_BINDING)) - continue; - handler.setAttribute(object, e.getKey(), e.getValue(), false, compiler); - } - } - - Rule[] pseudoClasses = getApplicablePseudoClasses(object); - if (pseudoClasses != null) { - Map<String, Map<String, String>> combinedPseudoClasses = new LinkedHashMap<String, Map<String, String>>(); - for (Rule pseudoClass1 : pseudoClasses) { - Selector[] selectors = pseudoClass1.getSelectors(); - for (Selector selector : selectors) { - if (selector.appliesTo(object) == Selector.PSEUDOCLASS_APPLIES) { - properties = pseudoClass1.getProperties(); - String pseudoClass = selector.getPseudoClass(); - // TODO: overrides by downstream pseudoclasses are not handled - Map<String, String> combinedProperties = combinedPseudoClasses.get(pseudoClass); - if (combinedProperties == null) { - combinedProperties = new HashMap<String, String>(); - combinedPseudoClasses.put(pseudoClass, combinedProperties); - } - combinedProperties.putAll(properties); - } - } - } - - int count = 0; - for (Map.Entry<String, Map<String, String>> e : combinedPseudoClasses.entrySet()) { - applyPseudoClass(e.getKey(), e.getValue(), object, compiler, count++); - } - } - } - - - /** - * Replaces all references to the variable "object" with the actual object ID. - * - * @param code ? - * @param id ? - * @return ? - * @throws jaxx.CompilerException ? - */ - private String replaceObjectReferences(String code, String id) throws CompilerException { - JavaParser p = new JavaParser(new StringReader(code + ";")); - p.Expression(); - SimpleNode node = p.popNode(); - scanNode(node, id); - return node.getText(); - } - - - private void scanNode(SimpleNode node, String id) { - if (node.getId() == JavaParserTreeConstants.JJTNAME) { - String name = node.getText(); - if (name.equals("object") || (name.indexOf(".") != -1 && name.substring(0, name.indexOf(".")).trim().equals("object"))) - node.firstToken.image = id; - } else { - int count = node.jjtGetNumChildren(); - for (int i = 0; i < count; i++) - scanNode(node.getChild(i), id); - } - } - - - private void compilePseudoClassAdd(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { - if (pseudoClass.equals("mouseover")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mouseout")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - compiler.appendInitDataBindings("{" + propertyCode + "}"); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mousedown")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mouseup")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - compiler.appendInitDataBindings("{" + propertyCode + "}"); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.startsWith("{")) { - pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); - pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); - String dest = object.getId() + ".style." + pseudoClass + ".add"; - String destCode = TypeManager.getJavaCode(dest); - if (compiler.haveProcessDataBinding()) { - compiler.appendProcessDataBinding("else "); - } - compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + pseudoClass + ") { "+ propertyCode + "} }"); - new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); - compiler.appendInitDataBindings("applyDataBinding("+ destCode + ");"); - } else - throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass); - } - - - private void compilePseudoClassRemove(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { - if (pseudoClass.equals("mouseover")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mouseout")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mousedown")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.equals("mouseup")) { - try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); - object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, - ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", - new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), - propertyCode, compiler); - } - catch (NoSuchMethodException e) { - compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); - } - } else if (pseudoClass.startsWith("{")) { - pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); - pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); - String dest = object.getId() + ".style." + pseudoClass + ".remove"; - String destCode = TypeManager.getJavaCode(dest); - if (compiler.haveProcessDataBinding()) { - compiler.appendProcessDataBinding("else "); - } - compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + invert(pseudoClass) + ") { " + propertyCode + "} }"); - new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); - compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); - } else - throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass); - } - - - private String invert(String javaCode) { - javaCode = javaCode.trim(); - if (javaCode.startsWith("!")) - return javaCode.substring(1); - else - return "!(" + javaCode + ")"; - } - - - private String unwrap(ClassDescriptor type, String valueCode) { - if (type == ClassDescriptorLoader.getClassDescriptor(boolean.class)) - return "((java.lang.Boolean) " + valueCode + ").booleanValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(byte.class)) - return "((java.lang.Byte) " + valueCode + ").byteValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(short.class)) - return "((java.lang.Short) " + valueCode + ").shortValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(int.class)) - return "((java.lang.Integer) " + valueCode + ").intValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(long.class)) - return "((java.lang.Long) " + valueCode + ").longValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(float.class)) - return "((java.lang.Float) " + valueCode + ").floatValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(double.class)) - return "((java.lang.Double) " + valueCode + ").doubleValue()"; - else if (type == ClassDescriptorLoader.getClassDescriptor(char.class)) - return "((java.lang.Character) " + valueCode + ").charValue()"; - else - return valueCode; - } - - - protected void applyPseudoClass(String pseudoClass, Map<String, String> properties, - CompiledObject object, JAXXCompiler compiler, int priority) throws CompilerException { - if (pseudoClass.indexOf("[") != -1) - pseudoClass = pseudoClass.substring(0, pseudoClass.indexOf("[")); - final StringBuffer buffer = new StringBuffer(); - /*CompiledObject bufferObject = new CompiledObject(object.getId(), object.getJavaCode(), object.getObjectClass(), compiler, true) { - public void appendInitializationCode(String code) { - buffer.append(code); - } - public void registerDataBinding(String src, String property, String assignment, JAXXCompiler compiler) throws CompilerException { - buffer.append(assignment); - } - };*/ - - DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); - boolean valueDeclared = false; - for (Map.Entry<String, String> e : properties.entrySet()) { - String property = e.getKey(); - ClassDescriptor type = handler.getPropertyType(object, property, compiler); - String dataBinding = compiler.processDataBindings(e.getValue(), type); - String valueCode; - if (dataBinding != null) { - valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; - new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), - property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); - } else { - try { - Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; - valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); - } - catch (ClassNotFoundException ex) { - compiler.reportError("could not find class " + type.getName()); - return; - } - } - if (!valueDeclared) { - buffer.append("java.lang.Object "); - valueDeclared = true; - } - buffer.append("value = jaxx.runtime.css.Pseudoclasses.applyProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompiler.getLineSeparator()); - buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompiler.getLineSeparator()); - String unwrappedValue = unwrap(type, "value"); - buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + - ") " + unwrappedValue, compiler)).append(JAXXCompiler.getLineSeparator()); - buffer.append("}").append(JAXXCompiler.getLineSeparator()); - } - - if (pseudoClass.equals("focused")) { - pseudoClass = "{ object.hasFocus() }"; - } else if (pseudoClass.equals("unfocused")) { - pseudoClass = "{ !object.hasFocus() }"; - } else if (pseudoClass.equals("enabled")) { - pseudoClass = "{ object.isEnabled() }"; - } else if (pseudoClass.equals("disabled")) { - pseudoClass = "{ !object.isEnabled() }"; - } else if (pseudoClass.equals("selected")) { - pseudoClass = "{ object.isSelected() }"; - } else if (pseudoClass.equals("deselected")) { - pseudoClass = "{ !object.isSelected() }"; - } - - compilePseudoClassAdd(pseudoClass, object, buffer.toString(), compiler); - - buffer.setLength(0); - valueDeclared = false; - for (Map.Entry<String, String> e : properties.entrySet()) { - String property = e.getKey(); - ClassDescriptor type = handler.getPropertyType(object, property, compiler); - String dataBinding = compiler.processDataBindings(e.getValue(), type); - String valueCode; - if (dataBinding != null) { - valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; - new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), - property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); - } else { - try { - Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; - valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); - } - catch (ClassNotFoundException ex) { - compiler.reportError("could not find class " + type.getName()); - return; - } - } - if (!valueDeclared) { - buffer.append("java.lang.Object "); - valueDeclared = true; - } - buffer.append("value = jaxx.runtime.css.Pseudoclasses.removeProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompiler.getLineSeparator()); - buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompiler.getLineSeparator()); - String unwrappedValue = unwrap(type, "value"); - buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + - ") " + unwrappedValue, compiler)).append(JAXXCompiler.getLineSeparator()); - buffer.append("}").append(JAXXCompiler.getLineSeparator()); - } - compilePseudoClassRemove(pseudoClass, object, buffer.toString(), compiler); - } - - - public Map<String, String> getApplicableProperties(CompiledObject object) throws CompilerException { - DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); - Map<String, String> result = null; - for (Rule rule : rules) { - int apply = rule.appliesTo(object); - if (apply == Selector.ALWAYS_APPLIES || apply == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { - if (result == null) - result = new HashMap<String, String>(); - for (Map.Entry<String, String> entry : rule.getProperties().entrySet()) { - String property = entry.getKey(); - if (apply == Selector.ALWAYS_APPLIES || handler.isPropertyInherited(property)) { - result.put(property, entry.getValue()); - } - } - } - } - return result; - } - - - public Rule[] getApplicablePseudoClasses(CompiledObject object) throws CompilerException { - List<Rule> result = null; - for (Rule rule : rules) { - if (rule.appliesTo(object) == Selector.PSEUDOCLASS_APPLIES) { - if (result == null) { - result = new ArrayList<Rule>(); - } - result.add(rule); - } - } - return result != null ? result.toArray(new Rule[result.size()]) : null; - } - @Override public String toString() { - return "Stylesheet" + Arrays.asList(rules); + return "Stylesheet" + java.util.Arrays.asList(rules); } } \ No newline at end of file Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/StylesheetHelper.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/StylesheetHelper.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/StylesheetHelper.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -0,0 +1,564 @@ +package jaxx.css; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.DataBinding; +import jaxx.compiler.DataSource; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerHelper; +import jaxx.parser.JavaParser; +import jaxx.parser.JavaParserTreeConstants; +import jaxx.parser.SimpleNode; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagManager; +import jaxx.types.TypeManager; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * A helper class to compute {@link Stylesheet}, {@link Rule} and {@link Selector} + * and extract all the compiler logic from this class. + * <p/> + * In that way we can make the compiler as a single module and a runtime as another module. + * + * @author chemit + */ +public class StylesheetHelper { + + public static void applyTo(CompiledObject object, JAXXCompiler compiler, Stylesheet stylesheet, Stylesheet overrides) throws CompilerException { + Map<String, String> overriddenProperties; + if (overrides != null) { + overriddenProperties = getApplicableProperties(overrides, object); + //overriddenProperties = overrides.getApplicableProperties(s,object); + } else { + overriddenProperties = null; + } + + Map<String, String> properties = getApplicableProperties(stylesheet, object); + if (properties != null) { + if (overriddenProperties != null) { + properties.keySet().removeAll(overriddenProperties.keySet()); + } + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + for (Map.Entry<String, String> e : properties.entrySet()) { + String value = e.getValue(); + if (value.equals(Rule.INLINE_ATTRIBUTE) || value.equals(Rule.DATA_BINDING)) { + continue; + } + handler.setAttribute(object, e.getKey(), e.getValue(), false, compiler); + } + } + + Rule[] pseudoClasses = getApplicablePseudoClasses(stylesheet, object); + if (pseudoClasses != null) { + Map<String, Map<String, String>> combinedPseudoClasses = new LinkedHashMap<String, Map<String, String>>(); + for (Rule pseudoClass1 : pseudoClasses) { + Selector[] selectors = pseudoClass1.getSelectors(); + for (Selector selector : selectors) { + if (appliesTo(selector, object) == Selector.PSEUDOCLASS_APPLIES) { + properties = pseudoClass1.getProperties(); + String pseudoClass = selector.getPseudoClass(); + // TODO: overrides by downstream pseudoclasses are not handled + Map<String, String> combinedProperties = combinedPseudoClasses.get(pseudoClass); + if (combinedProperties == null) { + combinedProperties = new HashMap<String, String>(); + combinedPseudoClasses.put(pseudoClass, combinedProperties); + } + combinedProperties.putAll(properties); + } + } + } + + int count = 0; + for (Map.Entry<String, Map<String, String>> e : combinedPseudoClasses.entrySet()) { + applyPseudoClass(e.getKey(), e.getValue(), object, compiler, count++); + } + } + } + + /** + * Replaces all references to the variable "object" with the actual object ID. + * + * @param code ? + * @param id ? + * @return ? + * @throws jaxx.CompilerException ? + */ + public static String replaceObjectReferences(String code, String id) throws CompilerException { + JavaParser p = new JavaParser(new StringReader(code + ";")); + p.Expression(); + jaxx.parser.SimpleNode node = p.popNode(); + scanNode(node, id); + return node.getText(); + } + + public static void scanNode(SimpleNode node, String id) { + if (node.getId() == JavaParserTreeConstants.JJTNAME) { + String name = node.getText(); + if (name.equals("object") || (name.indexOf(".") != -1 && name.substring(0, name.indexOf(".")).trim().equals("object"))) { + node.firstToken.image = id; + } + } else { + int count = node.jjtGetNumChildren(); + for (int i = 0; i < count; i++) { + scanNode(node.getChild(i), id); + } + } + } + + public static void compilePseudoClassAdd(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { + + if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".add"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + pseudoClass + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + return; + } + + MouseEventEnum constant = MouseEventEnum.valueOf(pseudoClass); + + String property = null; + switch (constant) { + case mousedown: + property = "mousePressed"; + break; + case mouseout: + property = "mouseExited"; + break; + case mouseover: + property = "mouseEntered"; + break; + case mouseup: + property = "mouseReleased"; + break; + } + + ClassDescriptor mouseListenerDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseListener.class); + ClassDescriptor mouseEventDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); + + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", mouseListenerDescriptor); + MethodDescriptor methodDescriptor = mouseListenerDescriptor.getMethodDescriptor(property, mouseEventDescriptor); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, methodDescriptor, propertyCode, compiler); + + } catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + + /*if (pseudoClass.equals("mouseover")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseout")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + compiler.appendInitDataBindings("{" + propertyCode + "}"); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mousedown")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseup")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + compiler.appendInitDataBindings("{" + propertyCode + "}"); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".add"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + pseudoClass + ") { "+ propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding("+ destCode + ");"); + } else + throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass);*/ + } + + public static void compilePseudoClassRemove(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { + if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".remove"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + invert(pseudoClass) + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + return; + } + + MouseEventEnum constant = MouseEventEnum.valueOf(pseudoClass); + + String property = null; + switch (constant) { + case mousedown: + property = "mousePressed"; + break; + case mouseout: + property = "mouseReleased"; + break; + case mouseover: + property = "mouseExited"; + break; + case mouseup: + property = "mousePressed"; + break; + } + + ClassDescriptor mouseListenerDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseListener.class); + ClassDescriptor mouseEventDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); + + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", mouseListenerDescriptor); + MethodDescriptor methodDescriptor = mouseListenerDescriptor.getMethodDescriptor(property, mouseEventDescriptor); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, methodDescriptor, propertyCode, compiler); + + } catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + + /*if (pseudoClass.equals("mouseover")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseout")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mousedown")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseup")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".remove"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + invert(pseudoClass) + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + } else { + throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass); + }*/ + } + + public static String invert(String javaCode) { + javaCode = javaCode.trim(); + return javaCode.startsWith("!") ? javaCode.substring(1) : "!(" + javaCode + ")"; + } + + public static String unwrap(ClassDescriptor type, String valueCode) { + if (type == ClassDescriptorLoader.getClassDescriptor(boolean.class)) { + return "((java.lang.Boolean) " + valueCode + ").booleanValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(byte.class)) { + return "((java.lang.Byte) " + valueCode + ").byteValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(short.class)) { + return "((java.lang.Short) " + valueCode + ").shortValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(int.class)) { + return "((java.lang.Integer) " + valueCode + ").intValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(long.class)) { + return "((java.lang.Long) " + valueCode + ").longValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(float.class)) { + return "((java.lang.Float) " + valueCode + ").floatValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(double.class)) { + return "((java.lang.Double) " + valueCode + ").doubleValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(char.class)) { + return "((java.lang.Character) " + valueCode + ").charValue()"; + } else { + return valueCode; + } + } + + public static void applyPseudoClass(String pseudoClass, Map<String, String> properties, + CompiledObject object, JAXXCompiler compiler, int priority) throws CompilerException { + if (pseudoClass.indexOf("[") != -1) { + pseudoClass = pseudoClass.substring(0, pseudoClass.indexOf("[")); + } + final StringBuffer buffer = new StringBuffer(); + /*CompiledObject bufferObject = new CompiledObject(object.getId(), object.getJavaCode(), object.getObjectClass(), compiler, true) { + public void appendInitializationCode(String code) { + buffer.append(code); + } + public void registerDataBinding(String src, String property, String assignment, JAXXCompiler compiler) throws CompilerException { + buffer.append(assignment); + } + };*/ + + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + boolean valueDeclared = false; + for (Map.Entry<String, String> e : properties.entrySet()) { + String property = e.getKey(); + ClassDescriptor type = handler.getPropertyType(object, property, compiler); + String dataBinding = compiler.processDataBindings(e.getValue(), type); + String valueCode; + if (dataBinding != null) { + valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; + new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), + property, "(" + JAXXCompilerHelper.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); + } else { + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); + } + catch (ClassNotFoundException ex) { + compiler.reportError("could not find class " + type.getName()); + return; + } + } + if (!valueDeclared) { + buffer.append("java.lang.Object "); + valueDeclared = true; + } + buffer.append("value = jaxx.runtime.css.Pseudoclasses.applyProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompilerHelper.getLineSeparator()); + buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompilerHelper.getLineSeparator()); + String unwrappedValue = unwrap(type, "value"); + buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompilerHelper.getCanonicalName(type) + + ") " + unwrappedValue, compiler)).append(JAXXCompilerHelper.getLineSeparator()); + buffer.append("}").append(JAXXCompilerHelper.getLineSeparator()); + } + + if (pseudoClass.equals("focused")) { + pseudoClass = "{ object.hasFocus() }"; + } else if (pseudoClass.equals("unfocused")) { + pseudoClass = "{ !object.hasFocus() }"; + } else if (pseudoClass.equals("enabled")) { + pseudoClass = "{ object.isEnabled() }"; + } else if (pseudoClass.equals("disabled")) { + pseudoClass = "{ !object.isEnabled() }"; + } else if (pseudoClass.equals("selected")) { + pseudoClass = "{ object.isSelected() }"; + } else if (pseudoClass.equals("deselected")) { + pseudoClass = "{ !object.isSelected() }"; + } + + compilePseudoClassAdd(pseudoClass, object, buffer.toString(), compiler); + + buffer.setLength(0); + valueDeclared = false; + for (Map.Entry<String, String> e : properties.entrySet()) { + String property = e.getKey(); + ClassDescriptor type = handler.getPropertyType(object, property, compiler); + String dataBinding = compiler.processDataBindings(e.getValue(), type); + String valueCode; + if (dataBinding != null) { + valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; + new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), + property, "(" + JAXXCompilerHelper.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); + } else { + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); + } + catch (ClassNotFoundException ex) { + compiler.reportError("could not find class " + type.getName()); + return; + } + } + if (!valueDeclared) { + buffer.append("java.lang.Object "); + valueDeclared = true; + } + buffer.append("value = jaxx.runtime.css.Pseudoclasses.removeProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompilerHelper.getLineSeparator()); + buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompilerHelper.getLineSeparator()); + String unwrappedValue = unwrap(type, "value"); + buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompilerHelper.getCanonicalName(type) + + ") " + unwrappedValue, compiler)).append(JAXXCompilerHelper.getLineSeparator()); + buffer.append("}").append(JAXXCompilerHelper.getLineSeparator()); + } + compilePseudoClassRemove(pseudoClass, object, buffer.toString(), compiler); + } + + public static Map<String, String> getApplicableProperties(Stylesheet s, CompiledObject object) throws CompilerException { + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + Map<String, String> result = null; + for (Rule rule : s.getRules()) { + int apply = appliesTo(rule, object); + if (apply == Selector.ALWAYS_APPLIES || apply == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { + if (result == null) { + result = new HashMap<String, String>(); + } + for (Map.Entry<String, String> entry : rule.getProperties().entrySet()) { + String property = entry.getKey(); + if (apply == Selector.ALWAYS_APPLIES || handler.isPropertyInherited(property)) { + result.put(property, entry.getValue()); + } + } + } + } + return result; + } + + public static Rule[] getApplicablePseudoClasses(Stylesheet s, CompiledObject object) throws CompilerException { + List<Rule> result = null; + for (Rule rule : s.getRules()) { + if (appliesTo(rule, object) == Selector.PSEUDOCLASS_APPLIES) { + if (result == null) { + result = new ArrayList<Rule>(); + } + result.add(rule); + } + } + return result != null ? result.toArray(new Rule[result.size()]) : null; + } + + public static Rule inlineAttribute(CompiledObject object, String propertyName, boolean dataBinding) { + Map<String, String> properties = new HashMap<String, String>(); + properties.put(propertyName, dataBinding ? Rule.DATA_BINDING : Rule.INLINE_ATTRIBUTE); + return new Rule(new Selector[]{new Selector(null, null, null, object.getId(), true)}, properties); + } + + public static int appliesTo(Rule rule, CompiledObject object) throws CompilerException { + int appliesTo = Selector.NEVER_APPLIES; + for (Selector selector : rule.getSelectors()) { + appliesTo = Math.max(appliesTo(selector, object), appliesTo); + if (appliesTo == Selector.ALWAYS_APPLIES || appliesTo == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { + break; + } + } + return appliesTo; + } + + public static int appliesTo(Selector selector, CompiledObject object) { + boolean inheritOnly = false; + CompiledObject parent = object; + String javaClassName = selector.getJavaClassName(); + String styleClass = selector.getStyleClass(); + String pseudoClass = selector.getPseudoClass(); + String id = selector.getId(); + + while (parent != null) { + boolean classMatch = (javaClassName == null); + if (!classMatch) { + ClassDescriptor javaClass = parent.getObjectClass(); + do { + String name = javaClass.getName(); + if (name.equals(javaClassName) || name.substring(name.lastIndexOf(".") + 1).equals(javaClassName)) { + classMatch = true; + break; + } + javaClass = javaClass.getSuperclass(); + } + while (javaClass != null); + } + + boolean styleClassMatch = (styleClass == null || styleClass.equals(parent.getStyleClass())); + + String objectId = parent.getId(); + objectId = objectId.substring(objectId.lastIndexOf(".") + 1); + boolean idMatch = (id == null || (' ' + objectId + ' ').indexOf(' ' + id + ' ') > -1); + + if (classMatch && styleClassMatch && idMatch) { + if (pseudoClass != null) { + return inheritOnly ? Selector.PSEUDOCLASS_APPLIES_INHERIT_ONLY : Selector.PSEUDOCLASS_APPLIES; + } else { + return inheritOnly ? Selector.ALWAYS_APPLIES_INHERIT_ONLY : Selector.ALWAYS_APPLIES; + } + } + + parent = parent.getParent(); + inheritOnly = true; + } + return Selector.NEVER_APPLIES; + } + + public enum MouseEventEnum { + mouseover, + mouseout, + mousedown, + mouseup + } +} Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-12-28 15:44:10 UTC (rev 1096) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-12-28 15:44:40 UTC (rev 1097) @@ -11,6 +11,7 @@ import jaxx.compiler.JavaArgument; import jaxx.compiler.JavaMethod; import jaxx.css.Stylesheet; +import jaxx.css.StylesheetHelper; import jaxx.introspection.JAXXBeanInfo; import jaxx.introspection.JAXXEventSetDescriptor; import jaxx.introspection.JAXXIntrospector; @@ -328,8 +329,8 @@ if (propertyName != null) { try { // check for property-specific addPropertyChangeListener method - getBeanClass().getMethodDescriptor("addPropertyChangeListener", new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(String.class), - ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)}); + getBeanClass().getMethodDescriptor("addPropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); return objectCode + ".addPropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; } catch (NoSuchMethodException e) { // no property-specific method, use general one @@ -359,7 +360,7 @@ } try { String modelMemberName = eventInfo.modelName != null ? "get" + JAXXCompiler.capitalize(eventInfo.modelName) : null; - String modelClassName = modelMemberName != null ? getBeanClass().getMethodDescriptor(modelMemberName, new ClassDescriptor[0]).getReturnType().getName() : JAXXCompiler.getCanonicalName(getBeanClass()); + String modelClassName = modelMemberName != null ? getBeanClass().getMethodDescriptor(modelMemberName).getReturnType().getName() : JAXXCompiler.getCanonicalName(getBeanClass()); String code = objectCode + (eventInfo.modelName != null ? "." + modelMemberName + "()" : ""); result.append("((").append(modelClassName).append(") $bindingSources.remove(\"").append(code).append("\")).").append(eventInfo.removeMethod).append("((").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(") jaxx.runtime.Util.getEventListener(").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(".class, ").append(compiler.getRootObject().getJavaCode()).append(", ").append(TypeManager.getJavaCode(methodName)).append("));\n"); if (eventInfo.modelName != null) { @@ -389,8 +390,8 @@ if (propertyName != null) { try { // check for property-specific removePropertyChangeListener method - getBeanClass().getMethodDescriptor("removePropertyChangeListener", new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(String.class), - ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)}); + getBeanClass().getMethodDescriptor("removePropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); return objectCode + ".removePropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; } catch (NoSuchMethodException e) { // no property-specific method, use general one @@ -865,7 +866,7 @@ object.appendInitializationCode(child.getInitializationCode(compiler)); } } else if (stylesheet != null) { - stylesheet.applyTo(object, compiler, overrides); + StylesheetHelper.applyTo(object, compiler,stylesheet, overrides); } } catch (ClassNotFoundException e) {
participants (1)
-
tchemit@users.labs.libre-entreprise.org