Author: tchemit Date: 2010-05-04 11:47:52 +0200 (Tue, 04 May 2010) New Revision: 1868 Url: http://nuiton.org/repositories/revision/jaxx/1868 Log: - reformat code - remove old comment code - add a unique method in JAXXCompiler to load a file (script or css) Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBindingHelper.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/css/StylesheetHelper.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/ScriptHandler.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/CompiledObject.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -202,7 +202,9 @@ * @param compiler the current <code>JAXXCompiler</code> * @throws NullPointerException if id or class is null */ - public CompiledObject(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { + public CompiledObject(String id, + ClassDescriptor objectClass, + JAXXCompiler compiler) { this(id, objectClass, compiler, false); } @@ -216,7 +218,10 @@ * @param force <code>true</code> to force acceptance of invalid ids * @throws NullPointerException if id or class is null */ - public CompiledObject(String id, ClassDescriptor objectClass, JAXXCompiler compiler, boolean force) { + public CompiledObject(String id, + ClassDescriptor objectClass, + JAXXCompiler compiler, + boolean force) { this(id, id, objectClass, compiler, force); } @@ -232,10 +237,15 @@ * @throws CompilerException if the id is not a valid Java identifier * @throws NullPointerException if id or class is null */ - public CompiledObject(String id, String javaCode, ClassDescriptor objectClass, JAXXCompiler compiler, boolean force) throws CompilerException { + public CompiledObject(String id, + String javaCode, + ClassDescriptor objectClass, + JAXXCompiler compiler, + boolean force) throws CompilerException { if (!force) { if (!isValidID(id)) { - compiler.reportError("the id '" + id + "' is not a valid Java identifier"); + compiler.reportError( + "the id '" + id + "' is not a valid Java identifier"); } } this.id = id; Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXCompiler.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -69,10 +69,12 @@ import javax.xml.transform.sax.SAXSource; import java.io.File; import java.io.FileInputStream; +import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; +import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.Modifier; import java.net.URL; @@ -108,8 +110,9 @@ * inner classes (including enumerations), because currently they don't * always resolve (but will generally run without error anyway). */ - public static final boolean STRICT_CHECKS = false; + public static boolean STRICT_CHECKS = false; + public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/"; @@ -266,6 +269,9 @@ */ protected final JAXXEngine engine; + protected final CompilerConfiguration defaultConfiguration = + new DefaultCompilerConfiguration(); + protected final JAXXCompilerFile jaxxFile; /** @@ -717,21 +723,22 @@ } public void checkOverride(CompiledObject object) throws CompilerException { - if (object.getId().startsWith("$")) { + String fieldName = object.getId(); + if (fieldName.startsWith("$")) { return; } ClassDescriptor ancestor = root.getObjectClass(); - if (ancestor == object.getObjectClass()) { + if (object.getObjectClass().equals(ancestor)) { return; } while (ancestor != null) { try { FieldDescriptor f = - ancestor.getDeclaredFieldDescriptor(object.getId()); + ancestor.getDeclaredFieldDescriptor(fieldName); if (!f.getType().isAssignableFrom(object.getObjectClass())) { reportError( "attempting to redefine superclass member '" + - object.getId() + "' as incompatible type (was " + + fieldName + "' as incompatible type (was " + f.getType() + ", redefined as " + object.getObjectClass() + ")" ); @@ -740,6 +747,9 @@ object.setOverrideType(f.getType()); break; } catch (NoSuchFieldException e) { + if (log.isDebugEnabled()) { + log.debug(">>>>> could not find declared field [" + fieldName + "] in " + ancestor.getName()); + } ancestor = ancestor.getSuperclass(); } } @@ -881,7 +891,8 @@ } } - String content = StylesheetHelper.loadCssFile(this, styleFile); + String content = loadFile(styleFile); +// String content = StylesheetHelper.loadCssFile(this, styleFile); getSourceFiles().push(styleFile); try { Stylesheet stylesheet = StylesheetHelper.processStylesheet(content); @@ -1059,7 +1070,11 @@ } public CompilerConfiguration getConfiguration() { - return getEngine().getConfiguration(); + JAXXEngine engine = getEngine(); + if (engine == null) { + return defaultConfiguration; + } + return engine.getConfiguration(); } public String getOutputClassName() { @@ -1340,6 +1355,40 @@ } /** + * Loads the given file and returns its content. + * <p/> + * <b>Note:</b> If any errors encounters, then report an error in the + * compiler and returns an empty string. + * + * @param file the file to load + * @return the content of the file or empty string if something was wrong + */ + public String loadFile(File file) { + if (!file.exists()) { + reportError("Could not found file " + file); + return ""; + } + try { + FileReader in = new FileReader(file); + try { + StringWriter styleBuffer = new StringWriter(); + char[] readBuffer = new char[2048]; + int c; + while ((c = in.read(readBuffer)) > 0) { + styleBuffer.write(readBuffer, 0, c); + } + return styleBuffer.toString(); + } finally { + in.close(); + } + } catch (IOException e) { + reportError("Could not read file " + file + " for reason " + + e.getMessage()); + return ""; + } + } + + /** * Verifies that a snippet of Java code parses correctly. * <p/> * A warning is generated if the string has enclosing curly braces. Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/JAXXFactory.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -99,7 +99,9 @@ */ public static JAXXCompiler newDummyCompiler(ClassLoader classLoader) { JAXXCompiler compiler = new JAXXCompiler(); - compiler.setClassLoader(classLoader); + if (classLoader != null) { + compiler.setClassLoader(classLoader); + } return compiler; } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBindingHelper.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBindingHelper.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/binding/DataBindingHelper.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -27,7 +27,11 @@ import jaxx.compiler.CompilerException; import jaxx.compiler.JAXXCompiler; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -44,34 +48,28 @@ */ public class DataBindingHelper { - /** - * To debug binding without any log interference - */ + /** To debug binding without any log interference */ public static boolean SHOW_LOG; - /** - * left brace matcher - */ + + /** left brace matcher */ protected static final Matcher leftBraceMatcher = Pattern.compile("^(\\{)|[^\\\\](\\{)").matcher(""); - /** - * right brace matcher - */ + + /** right brace matcher */ protected static final Matcher rightBraceMatcher = Pattern.compile("^(\\})|[^\\\\](\\})").matcher(""); + /** * Registred data binding for the compiler, then after the invocation of method {@link #finalizeBindings()} * only the real data bindings, the simple bindings will be moved to {@link #simpleBindings}. */ protected final List<DataBinding> dataBindings = new ArrayList<DataBinding>(); - /** - * Simpel bindings for the compiler - */ + + /** Simpel bindings for the compiler */ protected final List<DataBinding> simpleBindings = new ArrayList<DataBinding>(); - /** - * Associated compiler - */ + + /** Associated compiler */ protected final JAXXCompiler compiler; - /** - * Counter by unsafe type - */ + + /** Counter by unsafe type */ protected final Map<String, Integer> autoUnsafeGenIds = new TreeMap<String, Integer>(); public DataBindingHelper(JAXXCompiler compiler) { @@ -86,8 +84,7 @@ * * @param stringValue the string value of the property from the XML * @return a processed version of the expression - * @throws CompilerException - * ? + * @throws CompilerException ? */ public static String processDataBindings(String stringValue) throws CompilerException { int pos = getNextLeftBrace(stringValue, 0); @@ -242,8 +239,12 @@ int rightPos; while (openCount > 0) { pos++; - int leftPos = leftBraceMatcher.find(pos) ? Math.max(leftBraceMatcher.start(1), leftBraceMatcher.start(2)) : -1; - rightPos = rightBraceMatcher.find(pos) ? Math.max(rightBraceMatcher.start(1), rightBraceMatcher.start(2)) : -1; + int leftPos = leftBraceMatcher.find(pos) ? + Math.max(leftBraceMatcher.start(1), leftBraceMatcher.start(2)) : + -1; + rightPos = rightBraceMatcher.find(pos) ? + Math.max(rightBraceMatcher.start(1), rightBraceMatcher.start(2)) : + -1; assert leftPos == -1 || leftPos >= pos; assert rightPos == -1 || rightPos >= pos; if (leftPos != -1 && leftPos < rightPos) { Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/css/StylesheetHelper.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/css/StylesheetHelper.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/css/StylesheetHelper.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -49,8 +49,12 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.io.*; -import java.util.*; +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} @@ -65,25 +69,6 @@ /** Logger */ static private final Log log = LogFactory.getLog(StylesheetHelper.class); - public static String loadCssFile(JAXXCompiler compiler, - File styleFile) throws IOException { - FileReader in = new FileReader(styleFile); - try { - StringWriter styleBuffer = new StringWriter(); - char[] readBuffer = new char[2048]; - int c; - while ((c = in.read(readBuffer)) > 0) { - styleBuffer.write(readBuffer, 0, c); - } - return styleBuffer.toString(); - } catch (FileNotFoundException e) { - compiler.reportError("stylesheet file not found: " + styleFile); - return ""; - } finally { - in.close(); - } - } - public static Stylesheet processStylesheet(String stylesheetText) throws CompilerException { CSSParser p = new CSSParser(new StringReader(stylesheetText)); SimpleNode node; @@ -108,7 +93,8 @@ throw new IllegalArgumentException("argument node is not a Rule"); } SimpleNode selectorsNode = ruleNode.getChild(0); - assert selectorsNode.getId() == CSSParserTreeConstants.JJTSELECTORS : "expected node to be of type Selectors"; + assert selectorsNode.getId() == CSSParserTreeConstants.JJTSELECTORS : + "expected node to be of type Selectors"; List<Selector> selectors = new ArrayList<Selector>(); for (int i = 0; i < selectorsNode.jjtGetNumChildren(); i++) { @@ -130,7 +116,8 @@ } } Rule rule; - rule = new Rule(selectors.toArray(new Selector[selectors.size()]), properties); + rule = new Rule(selectors.toArray( + new Selector[selectors.size()]), properties); return rule; } @@ -162,7 +149,9 @@ break; default: - throw new IllegalStateException("unexpected child of Selector node, type=" + child.getId()); + throw new IllegalStateException( + "unexpected child of Selector node, type=" + + child.getId()); } } @@ -199,33 +188,45 @@ public static ClassDescriptor getMouseEventDescriptor() { if (mouseEventDescriptor == null) { - mouseEventDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); + mouseEventDescriptor = + ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); } return mouseEventDescriptor; } public static ClassDescriptor getMouseListenerDescriptor() { if (mouseListenerDescriptor == null) { - mouseListenerDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseListener.class); + mouseListenerDescriptor = + ClassDescriptorLoader.getClassDescriptor(MouseListener.class); } return mouseListenerDescriptor; } public static MethodDescriptor getAddMouseListenerMethod(CompiledObject object) { try { - MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", getMouseListenerDescriptor()); + MethodDescriptor addMouseListener = + object.getObjectClass().getMethodDescriptor( + "addMouseListener", + getMouseListenerDescriptor() + ); return addMouseListener; } catch (NoSuchMethodException e) { - throw new CompilerException("could not find addMouseListener for object " + object); + throw new CompilerException( + "could not find addMouseListener for object " + object); } } public static MethodDescriptor getMouseListenerMethod(CompiledObject object, String property) { try { - MethodDescriptor methodDescriptor = getMouseListenerDescriptor().getMethodDescriptor(property, getMouseEventDescriptor()); + MethodDescriptor methodDescriptor = + getMouseListenerDescriptor().getMethodDescriptor( + property, + getMouseEventDescriptor() + ); return methodDescriptor; } catch (NoSuchMethodException e) { - throw new CompilerException("could not find " + property + " for object " + object); + throw new CompilerException( + "could not find " + property + " for object " + object); } } @@ -241,7 +242,8 @@ overriddenProperties = null; } - Map<String, String> properties = getApplicableProperties(stylesheet, object); + Map<String, String> properties = getApplicableProperties(stylesheet, + object); if (properties != null) { if (overriddenProperties != null) { properties.keySet().removeAll(overriddenProperties.keySet()); @@ -339,35 +341,64 @@ } } - public static void applyPseudoClass(String pseudoClass, Map<String, String> properties, - CompiledObject object, JAXXCompiler compiler, int priority) throws CompilerException { + public static void applyPseudoClass(String pseudoClass, + Map<String, String> properties, + CompiledObject object, + JAXXCompiler compiler, + int priority) throws CompilerException { if (pseudoClass.contains("[")) { pseudoClass = pseudoClass.substring(0, pseudoClass.indexOf("[")); } StringBuffer buffer = new StringBuffer(); - DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + DefaultObjectHandler handler = + TagManager.getTagHandler(object.getObjectClass()); boolean valueDeclared = false; String eol = JAXXCompiler.getLineSeparator(); DataBindingHelper bindingHelper = compiler.getBindingHelper(); for (Map.Entry<String, String> e : properties.entrySet()) { String property = e.getKey(); - ClassDescriptor type = handler.getPropertyType(object, property, compiler); + ClassDescriptor type = handler.getPropertyType(object, + property, + compiler + ); if (log.isDebugEnabled()) { - log.debug("will test if databinding : [" + e.getValue() + "] type=" + type); + log.debug("will test if databinding : [" + e.getValue() + + "] type=" + type); } - String dataBindingCode = DataBindingHelper.processDataBindings(e.getValue()); + String dataBindingCode = + DataBindingHelper.processDataBindings(e.getValue()); String valueCode; if (dataBindingCode != null) { - valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; - DataBinding binding = new DataBinding(object.getId() + "." + property + "." + priority, dataBindingCode, handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBindingCode, compiler), false); + String code = object.getId() + "." + property + "." + priority; + valueCode = "new jaxx.runtime.css.DataBinding(" + + TypeManager.getJavaCode(code) + ")"; + DataBinding binding = new DataBinding( + code, + dataBindingCode, + handler.getSetPropertyCode( + object.getJavaCode(), + property, + "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBindingCode, + compiler + ), + false + ); bindingHelper.registerDataBinding(binding); } else { try { - Class<?> typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; - valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); + 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()); + compiler.reportError( + "could not find class " + type.getName()); return; } } @@ -403,8 +434,19 @@ String dataBindingCode = DataBindingHelper.processDataBindings(e.getValue()); String valueCode; if (dataBindingCode != null) { - valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; - DataBinding binding = new DataBinding(object.getId() + "." + property + "." + priority, dataBindingCode, handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBindingCode, compiler), false); + String code = object.getId() + "." + property + "." + priority; + valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(code) + ")"; + DataBinding binding = new DataBinding( + code, + dataBindingCode, + handler.getSetPropertyCode( + object.getJavaCode(), + property, + "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBindingCode, + compiler + ), + false + ); bindingHelper.registerDataBinding(binding); } else { try { @@ -419,18 +461,63 @@ 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(eol); - buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(eol); + buffer.append("value = jaxx.runtime.css.Pseudoclasses.removeProperty("); + buffer.append(compiler.getOutputClassName()); + buffer.append(".this, "); + buffer.append(object.getJavaCode()); + buffer.append(", "); + buffer.append(TypeManager.getJavaCode(property)); + buffer.append(", "); + buffer.append(valueCode); + buffer.append(", jaxx.runtime.css.Pseudoclasses.wrap("); + buffer.append(handler.getGetPropertyCode(object.getJavaCode(), + property, + compiler) + ); + buffer.append("), "); + buffer.append(priority); + buffer.append(");"); + buffer.append(eol); + buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {"); + buffer.append(eol); String unwrappedValue = unwrap(type, "value"); - buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + unwrappedValue, compiler)).append(eol); + buffer.append(" "); + buffer.append(handler.getSetPropertyCode( + object.getJavaCode(), + property, + "(" + JAXXCompiler.getCanonicalName(type) + ") " + unwrappedValue, + compiler) + ); + buffer.append(eol); buffer.append("}").append(eol); } - compilePseudoClass(pseudoClass, object, buffer.toString(), 1, "remove", compiler, true); + compilePseudoClass(pseudoClass, + object, + buffer.toString(), + 1, + "remove", + compiler, + true + ); } - public static void compilePseudoClass(String pseudoClass, CompiledObject object, String propertyCode, int pos, String methodName, JAXXCompiler compiler, boolean invertTest) throws CompilerException { - PseudoClassDataBinding binding = PseudoClassDataBinding.newPseudoClassDataBinding(pseudoClass, object, propertyCode, methodName, invertTest); + public static void compilePseudoClass(String pseudoClass, + CompiledObject object, + String propertyCode, + int pos, + String methodName, + JAXXCompiler compiler, + boolean invertTest) throws CompilerException { + + PseudoClassDataBinding binding = + PseudoClassDataBinding.newPseudoClassDataBinding( + pseudoClass, + object, + propertyCode, + methodName, + invertTest + ); if (binding != null) { compiler.getBindingHelper().registerDataBinding(binding); return; @@ -438,22 +525,33 @@ MouseEventEnum constant = MouseEventEnum.valueOf(pseudoClass); String property = constant.getProperty(pos); MethodDescriptor addMouseListener = getAddMouseListenerMethod(object); - MethodDescriptor methodDescriptor = getMouseListenerMethod(object, property); - object.addEventHandler("style." + pseudoClass + "." + methodName, addMouseListener, methodDescriptor, propertyCode, compiler); + MethodDescriptor methodDescriptor = + getMouseListenerMethod(object, property); + object.addEventHandler("style." + pseudoClass + "." + methodName, + addMouseListener, + methodDescriptor, + propertyCode, + compiler + ); } - public static Map<String, String> getApplicableProperties(Stylesheet s, CompiledObject object) throws CompilerException { - DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + 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 (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()) { + for (Map.Entry<String, String> entry : + rule.getProperties().entrySet()) { String property = entry.getKey(); - if (apply == Selector.ALWAYS_APPLIES || handler.isPropertyInherited(property)) { + if (apply == Selector.ALWAYS_APPLIES || + handler.isPropertyInherited(property)) { result.put(property, entry.getValue()); } } @@ -462,7 +560,8 @@ return result; } - public static Rule[] getApplicablePseudoClasses(Stylesheet s, CompiledObject object) throws CompilerException { + 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) { @@ -475,17 +574,26 @@ return result != null ? result.toArray(new Rule[result.size()]) : null; } - public static Rule inlineAttribute(CompiledObject object, String propertyName, boolean dataBinding) { + 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); + 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 { + 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) { + if (appliesTo == Selector.ALWAYS_APPLIES || + appliesTo == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { break; } } @@ -506,7 +614,8 @@ ClassDescriptor javaClass = parent.getObjectClass(); do { String name = javaClass.getName(); - if (name.equals(javaClassName) || name.substring(name.lastIndexOf(".") + 1).equals(javaClassName)) { + if (name.equals(javaClassName) || + name.substring(name.lastIndexOf(".") + 1).equals(javaClassName)) { classMatch = true; break; } @@ -524,9 +633,13 @@ if (classMatch && styleClassMatch && idMatch) { if (pseudoClass != null) { - return inheritOnly ? Selector.PSEUDOCLASS_APPLIES_INHERIT_ONLY : Selector.PSEUDOCLASS_APPLIES; + return inheritOnly ? + Selector.PSEUDOCLASS_APPLIES_INHERIT_ONLY : + Selector.PSEUDOCLASS_APPLIES; } else { - return inheritOnly ? Selector.ALWAYS_APPLIES_INHERIT_ONLY : Selector.ALWAYS_APPLIES; + return inheritOnly ? + Selector.ALWAYS_APPLIES_INHERIT_ONLY : + Selector.ALWAYS_APPLIES; } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/DefaultFinalizer.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -275,14 +275,22 @@ } @Override - public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + public void finalizeCompiler(CompiledObject root, + JAXXCompiler compiler, + JavaFile javaFile, + String packageName, + String className) { - String fullClassName = packageName != null ? packageName + "." + className : className; + String fullClassName = packageName != null ? + packageName + "." + className : className; if (root == null) { throw new CompilerException("root tag can not be null"); } ClassDescriptor superclass = root.getObjectClass(); - boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(superclass); + ClassDescriptor descriptor = + ClassDescriptorLoader.getClassDescriptor(JAXXObject.class); + boolean superclassIsJAXXObject = + descriptor.isAssignableFrom(superclass); javaFile.setModifiers(PUBLIC); javaFile.setName(fullClassName); javaFile.setSuperClass(JAXXCompiler.getCanonicalName(superclass)); @@ -293,26 +301,22 @@ javaFile.setGenericType(compiler.getGenericType()); javaFile.setSuperGenericType(compiler.getSuperGenericType()); -// // finalize all objects via their decorator -// for (CompiledObject object : compiler.getObjects().values()) { -// CompiledObjectDecorator decorator = object.getDecorator(); -// decorator.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName); -// } - -// // compile bindings and fill the initDataBindings field of binding helper -// compiler.getBindingHelper().finalizeBindings(); - if (!superclassIsJAXXObject) { javaFile.addInterface(JAXXObject.class.getSimpleName()); } } @Override - public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + public void prepareJavaFile(CompiledObject root, + JAXXCompiler compiler, + JavaFile javaFile, + String packageName, + String className) throws ClassNotFoundException { String fullClassName = javaFile.getName(); - String jaxxContextImplementorClass = compiler.getConfiguration().getJaxxContextClass().getName(); + String jaxxContextImplementorClass = + compiler.getConfiguration().getJaxxContextClass().getName(); boolean superclassIsJAXXObject = javaFile.isSuperclassIsJAXXObject(); if (!superclassIsJAXXObject) { javaFile.addImport(JAXXObject.class); @@ -327,7 +331,13 @@ javaFile.addImport(Log.class); javaFile.addImport(LogFactory.class); //TC-20091127 : let the logger stays protected - javaFile.addSimpleField(newField(PROTECTED | STATIC | FINAL, "Log", "log", false, "LogFactory.getLog(" + fullClassName + ".class)")); + javaFile.addSimpleField(newField( + PROTECTED | STATIC | FINAL, + "Log", + "log", + false, + "LogFactory.getLog(" + fullClassName + ".class)") + ); } // JAXXObject @@ -344,7 +354,13 @@ javaFile.addMethod(createRemoveDataBindingMethod()); // JAXXContext - javaFile.addField(newField(PROTECTED | FINAL, JAXXContext.class.getSimpleName(), FIELD_NAME_DELEGATE_CONTEXT, true, "new " + jaxxContextImplementorClass + "()")); + javaFile.addField(newField( + PROTECTED | FINAL, + JAXXContext.class.getSimpleName(), + FIELD_NAME_DELEGATE_CONTEXT, + true, + "new " + jaxxContextImplementorClass + "()") + ); javaFile.addMethod(SET_CONTEXT_VALUE_METHOD); javaFile.addMethod(SET_CONTEXT_VALUE_NAMED_METHOD); javaFile.addMethod(GET_CONTEXT_VALUE_METHOD); @@ -373,7 +389,8 @@ if (!overrideContextInitialized) { javaFile.addSimpleField(CONTEXT_INITIALIZED); } - javaFile.addSimpleField(createJAXXObjectDescriptorField(compiler, javaFile)); + javaFile.addSimpleField( + createJAXXObjectDescriptorField(compiler, javaFile)); if (compiler.getStylesheet() != null) { boolean needField = true; Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/spi/DefaultInitializer.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -58,6 +58,7 @@ import jaxx.compiler.JAXXCompiler; import jaxx.compiler.beans.BeanInfoUtil; +import jaxx.compiler.reflect.ClassDescriptor; import jaxx.compiler.reflect.ClassDescriptorLoader; import jaxx.compiler.tags.DefaultComponentHandler; @@ -208,15 +209,22 @@ } - protected void registerBean(Class<?> beanClass, Class<? extends TagHandler> handlerClass) { - TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(beanClass), handlerClass); + protected void registerBean(Class<?> beanClass, + Class<? extends TagHandler> handlerClass) { + ClassDescriptor classDescriptor = + ClassDescriptorLoader.getClassDescriptor(beanClass); + + TagManager.registerBean(classDescriptor, handlerClass); } - protected void registerTag(String namespace, String tagName, TagHandler handler) { + protected void registerTag(String namespace, + String tagName, + TagHandler handler) { TagManager.registerTag(namespace, tagName, handler); } - protected void registerDefaultNamespace(String namespace, Class<?>... beanClass) { + protected void registerDefaultNamespace(String namespace, + Class<?>... beanClass) { for (Class<?> c : beanClass) { TagManager.registerDefaultNamespace(c.getSimpleName(), namespace); Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -25,7 +25,11 @@ package jaxx.compiler.tags; -import jaxx.compiler.*; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.CompiledObjectDecorator; +import jaxx.compiler.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.UnsupportedAttributeException; import jaxx.compiler.beans.JAXXBeanInfo; import jaxx.compiler.beans.JAXXEventSetDescriptor; import jaxx.compiler.beans.JAXXIntrospector; @@ -41,13 +45,24 @@ import jaxx.runtime.JAXXObject; import jaxx.runtime.JAXXObjectDescriptor; import jaxx.runtime.css.Stylesheet; -import org.w3c.dom.*; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; import java.beans.IntrospectionException; import java.beans.Introspector; import java.io.IOException; import java.lang.reflect.Modifier; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; /** * Default handler for class tags. Class tags are tags which represent instances of Java classes, @@ -185,13 +200,15 @@ // perform introspection & cache the results jaxxBeanInfo = getJAXXBeanInfo(beanClass); - JAXXPropertyDescriptor[] propertiesArray = jaxxBeanInfo.getJAXXPropertyDescriptors(); + JAXXPropertyDescriptor[] propertiesArray = + jaxxBeanInfo.getJAXXPropertyDescriptors(); properties = new HashMap<String, JAXXPropertyDescriptor>(); for (int i = propertiesArray.length - 1; i >= 0; i--) { properties.put(propertiesArray[i].getName(), propertiesArray[i]); } - JAXXEventSetDescriptor[] eventsArray = jaxxBeanInfo.getJAXXEventSetDescriptors(); + JAXXEventSetDescriptor[] eventsArray = + jaxxBeanInfo.getJAXXEventSetDescriptors(); events = new HashMap<String, JAXXEventSetDescriptor>(); for (int i = eventsArray.length - 1; i >= 0; i--) { MethodDescriptor[] methods = eventsArray[i].getListenerMethods(); @@ -243,14 +260,17 @@ * @return the property's type * @throws CompilerException if the type cannot be determined */ - public ClassDescriptor getPropertyType(CompiledObject object, String propertyName, JAXXCompiler compiler) { + public ClassDescriptor getPropertyType(CompiledObject object, + String propertyName, + JAXXCompiler compiler) { safeInit(); JAXXPropertyDescriptor property = properties.get(propertyName); if (property != null) { return property.getPropertyType(); } - throw new UnsupportedAttributeException("property '" + propertyName + "' not found in " + object); + throw new UnsupportedAttributeException( + "property '" + propertyName + "' not found in " + object); } /** @@ -295,171 +315,6 @@ return listenerClass.getMethodDescriptors()[0].getParameterTypes()[0]; } -// /** -// * @param memberName name of the member -// * @return an array of members on which the given property depends. For -// * example, the JTextField.getText() member depends upon the getModel() -// * member. Returns <code>null</code> if there are no dependencies. -// */ -// public String[] getMemberDependencies(String memberName) { -// ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; -// return eventInfo == null ? null : new String[]{eventInfo.modelName}; -// } - -// /** -// * Returns a snippet of Java code which will cause a <code>PropertyChangeListener</code> to be notified -// * when the member's value changes. The <code>PropertyChangeListener</code> is provided in the form -// * of a Java code snippet that evaluates to a listener object. -// * <p/> -// * For ordinary bound JavaBeans properties, the Java code returned is a simple call to -// * <code>addPropertyChangeListener</code>. Fields and methods which do not actually fire -// * <code>PropertyChangeEvents</code> when they change necessitate more complex code. -// * -// * @param objectCode Java code which evaluates to the object to which to add the listener -// * *@param dataBinding the name of the data binding this listener is a part of -// * @param dataBinding databinding -// * @param memberName the name of the field or method to listen to -// * @param propertyChangeListenerCode Java code which evaluates to a <code>PropertyChangeListener</code> -// * @param compiler the current <code>JAXXCompiler</code> -// * @return Java code snippet which causes the listener to be added to the object -// */ -// public String getAddMemberListenerCode(String objectCode, String dataBinding, String memberName, String propertyChangeListenerCode, JAXXCompiler compiler) { -// if ("getClass".equals(memberName)) { -// return null; -// } -// -// ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; -// if (eventInfo != null) { -// // a "proxied" event is one that doesn't fire PropertyChangeEvent, so we need to convert its native event type into PropertyChangeEvents -// StringBuffer result = new StringBuffer(); -// String methodName = "$pr" + compiler.getUniqueId(propertyChangeListenerCode); -// boolean methodExists = compiler.hasMethod(methodName); -// ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass); -// if (!methodExists) { -// compiler.getJavaFile().addMethod(new JavaMethod(Modifier.PUBLIC, "void", methodName, -// new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(eventClass), "event")}, null, -// propertyChangeListenerCode + ".propertyChange(null);", false)); -// } -// String code = objectCode + (eventInfo.modelName != null ? ".get" + StringUtils.capitalize(eventInfo.modelName) + "()" : ""); -// result.append("$bindingSources.put(\"").append(code).append("\", ").append(code).append(");").append(JAXXCompiler.getLineSeparator()); -// //TC-20091105 JAXXUtil.getEventListener is generic, no more need cast and use simple listener name -// result.append(code).append('.').append(eventInfo.addMethod).append("( JAXXUtil.getEventListener(").append(eventInfo.listenerClass.getSimpleName()).append(".class, ").append(compiler.getRootObject().getJavaCode()).append(", ").append(TypeManager.getJavaCode(methodName)).append("));"); -// result.append(JAXXCompiler.getLineSeparator()); -// if (eventInfo.modelName != null) { -// result.append(getAddMemberListenerCode(objectCode, dataBinding, "get" + StringUtils.capitalize(eventInfo.modelName), -// JAXXUtil.class.getSimpleName() + ".getDataBindingUpdateListener(this , " + dataBinding + ")", -//// JAXXUtil.class.getSimpleName() + ".getDataBindingUpdateListener(this , \"" + dataBinding + "\")", -// compiler)); -// } -// return result.toString(); -// } else { -// String propertyName = null; -// if (memberName.startsWith("get")) { -// propertyName = Introspector.decapitalize(memberName.substring("get".length())); -// } else if (memberName.startsWith("is")) { -// propertyName = Introspector.decapitalize(memberName.substring("is".length())); -// } else { -// try { -// getBeanClass().getFieldDescriptor(memberName); -// propertyName = memberName; -// } catch (NoSuchFieldException e) { -// // ignore ? -// } -// } -// if (propertyName != null) { -// //TC-20091026 when on root object, do not prefix with objectCode -// String prefix = objectCode.trim() + "."; -// if (objectCode.equals(compiler.getRootObject().getJavaCode())) { -// prefix = ""; -// } -// try { -// // check for property-specific addPropertyChangeListener method -// getBeanClass().getMethodDescriptor("addPropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), -// ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); -// return prefix + "addPropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; -// } catch (NoSuchMethodException e) { -// // no property-specific method, use general one -// return prefix + "addPropertyChangeListener(" + propertyChangeListenerCode + ");\n"; -// } -// } -// return null; -// } -// } -// -// public String getRemoveMemberListenerCode(String objectCode, String dataBinding, String memberName, String propertyChangeListenerCode, JAXXCompiler compiler) { -// if ("getClass".equals(memberName)) { -// return null; -// } -// -// ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; -// if (eventInfo != null) { -// // a "proxied" event is one that doesn't fire PropertyChangeEvent, -// // so we need to convert its native event type into PropertyChangeEvents -// StringBuffer result = new StringBuffer(); -// String methodName = "$pr" + compiler.getUniqueId(propertyChangeListenerCode); -// boolean methodExists = compiler.hasMethod(methodName); -// if (!methodExists) { -// ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass); -// compiler.getJavaFile().addMethod(new JavaMethod(Modifier.PUBLIC, "void", methodName, -// new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(eventClass), "event")}, null, -// propertyChangeListenerCode + ".propertyChange(null);", false)); -// } -// try { -// String modelMemberName = eventInfo.modelName != null ? "get" + StringUtils.capitalize(eventInfo.modelName) : null; -// String modelClassName = modelMemberName != null ? getBeanClass().getMethodDescriptor(modelMemberName).getReturnType().getName() : JAXXCompiler.getCanonicalName(getBeanClass()); -// String code = objectCode + (eventInfo.modelName != null ? "." + modelMemberName + "()" : ""); -// String eol = JAXXCompiler.getLineSeparator(); -// result.append(modelClassName).append(" $target = ((").append(modelClassName).append(") $bindingSources.remove(\"").append(code).append("\"));").append(eol); -// //TC-20091105 test if $target is not null -// result.append("if ($target != null) {").append(eol); -// //TC-20091105 JAXXUtil.getEventListener is generic, no more need cast and use simple listener name -// result.append(" $target.").append(eventInfo.removeMethod).append("( JAXXUtil.getEventListener(").append(eventInfo.listenerClass.getSimpleName()).append(".class, ").append(compiler.getRootObject().getJavaCode()).append(", ").append(TypeManager.getJavaCode(methodName)).append("));").append(eol); -// result.append("}").append(eol); -// if (eventInfo.modelName != null) { -//// String bi = dataBinding.startsWith("this.") ? dataBinding : ("\"" + dataBinding + "\""); -// result.append(getRemoveMemberListenerCode(objectCode, dataBinding, "get" + StringUtils.capitalize(eventInfo.modelName), -// JAXXUtil.class.getSimpleName() + ".getDataBindingUpdateListener(this, " + dataBinding + ")", -//// JAXXUtil.class.getSimpleName() + ".getDataBindingUpdateListener(this, \"" + dataBinding + "\")", -// compiler)); -// } -// return result.toString(); -// } catch (NoSuchMethodException e) { -// throw new CompilerException("Internal error: " + e); -// } -// } else { -// String propertyName = null; -// if (memberName.startsWith("get")) { -// propertyName = Introspector.decapitalize(memberName.substring("get".length())); -// } else if (memberName.startsWith("is")) { -// propertyName = Introspector.decapitalize(memberName.substring("is".length())); -// } else { -// try { -// getBeanClass().getFieldDescriptor(memberName); -// propertyName = memberName; -// } catch (NoSuchFieldException e) { -// // ignore ? -// } -// } -// if (propertyName != null) { -// //TC-20091026 when on root object, do not prefix with objectCode -// String prefix = objectCode.trim() + "."; -// if (objectCode.equals(compiler.getRootObject().getJavaCode())) { -// prefix = ""; -// } -// try { -// // check for property-specific removePropertyChangeListener method -// getBeanClass().getMethodDescriptor("removePropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), -// ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); -// return prefix + "removePropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; -// } catch (NoSuchMethodException e) { -// // no property-specific method, use general one -// return prefix + "removePropertyChangeListener(" + propertyChangeListenerCode + ");\n"; -// } -// } -// return null; -// } -// } - /** * Configures the event handling for members which do not fire <code>PropertyChangeEvent</code> when * modified. The default implementation does nothing. Subclasses should override this method to call @@ -507,18 +362,39 @@ * @param listenerClass the type of listener which receives events when the field or method is updated * @param modelName the JavaBeans-style name of the model property */ - public void addProxyEventInfo(String memberName, Class<?> listenerClass, String modelName) { + public void addProxyEventInfo(String memberName, + Class<?> listenerClass, + String modelName) { String listenerName = listenerClass.getName(); - listenerName = listenerName.substring(listenerName.lastIndexOf(".") + 1); - addProxyEventInfo(memberName, listenerClass, modelName, "add" + listenerName, "remove" + listenerName); + listenerName = + listenerName.substring(listenerName.lastIndexOf(".") + 1); + addProxyEventInfo(memberName, + listenerClass, + modelName, + "add" + listenerName, + "remove" + listenerName + ); } // TODO: remove this temporary method, complete switchover to ClassDescriptors - public void addProxyEventInfo(String memberName, Class<?> listenerClass, - String modelName, String addMethod, String removeMethod) { + public void addProxyEventInfo(String memberName, + Class<?> listenerClass, + String modelName, + String addMethod, + String removeMethod) { try { - addProxyEventInfo(memberName, ClassDescriptorLoader.getClassDescriptor(listenerClass.getName()), modelName, addMethod, removeMethod); + ClassDescriptor classDescriptor = + ClassDescriptorLoader.getClassDescriptor( + listenerClass.getName() + ); + + addProxyEventInfo(memberName, + classDescriptor, + modelName, + addMethod, + removeMethod + ); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } @@ -551,8 +427,11 @@ * @param addMethod add method name * @param removeMethod remove method name */ - public void addProxyEventInfo(String memberName, ClassDescriptor listenerClass, - String modelName, String addMethod, String removeMethod) { + public void addProxyEventInfo(String memberName, + ClassDescriptor listenerClass, + String modelName, + String addMethod, + String removeMethod) { ProxyEventInfo info = new ProxyEventInfo(); info.memberName = memberName; info.listenerClass = listenerClass; @@ -576,12 +455,18 @@ safeInit(); CompiledObject object = objectMap.get(tag); if (object == null) { - throw new IllegalStateException("unable to find CompiledObject associated with tag <" + tag.getTagName() + ">; should have been registered before second pass"); + throw new IllegalStateException( + "unable to find CompiledObject associated with tag <" + + tag.getTagName() + ">; should have been registered " + + "before second pass" + ); } compiler.checkOverride(object); - String constructorParams = tag.getAttribute(CONSTRUCTOR_PARAMS_ATTRIBUTE); + String constructorParams = + tag.getAttribute(CONSTRUCTOR_PARAMS_ATTRIBUTE); if (constructorParams != null && constructorParams.length() > 0) { - object.setConstructorParams(compiler.getScriptManager().trimScript(constructorParams)); + object.setConstructorParams( + compiler.getScriptManager().trimScript(constructorParams)); } setDefaults(object, tag, compiler); @@ -619,7 +504,8 @@ * @param compiler compiler to use * @return the <code>CompiledObject</code> to use */ - protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) { + protected CompiledObject createCompiledObject(String id, + JAXXCompiler compiler) { return new CompiledObject(id, getBeanClass(), compiler); } @@ -631,7 +517,9 @@ * @param tag the tag being compiled * @param compiler the current <code>JAXXCompiler</code> */ - protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) { + protected void setDefaults(CompiledObject object, + Element tag, + JAXXCompiler compiler) { } /** @@ -650,7 +538,9 @@ * (e.g. "onActionPerformed"). */ public boolean isEventHandlerName(String name) { - return name.length() > 2 && name.startsWith("on") && Character.isUpperCase(name.charAt(2)); + return name.length() > 2 && + name.startsWith("on") && + Character.isUpperCase(name.charAt(2)); } /** @@ -661,7 +551,8 @@ * @param tag tag to scan * @param compiler compiler to use */ - protected void scanAttributesForDependencies(Element tag, JAXXCompiler compiler) { + protected void scanAttributesForDependencies(Element tag, + JAXXCompiler compiler) { List<Attr> attributes = new ArrayList<Attr>(); NamedNodeMap children = tag.getAttributes(); for (int i = 0; i < children.getLength(); i++) { @@ -676,7 +567,8 @@ //compiler.preprocessScript(value); continue; } - if (name.equals(CONSTRAINTS_ATTRIBUTE) || isEventHandlerName(name)) { + if (name.equals(CONSTRAINTS_ATTRIBUTE) || + isEventHandlerName(name)) { // adds dependencies as a side effect compiler.preprocessScript(value); } else if (name.equals(CONSTRUCTOR_PARAMS_ATTRIBUTE)) { @@ -865,7 +757,11 @@ * @param inline <code>true</code> if the value was directly specified as an inline class tag attribute, <code>false</code> otherwise (a default value, specified in CSS, etc.) * @param compiler the current <code>JAXXCompiler</code> */ - public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) { + public void setAttribute(CompiledObject object, + String propertyName, + String stringValue, + boolean inline, + JAXXCompiler compiler) { try { //--------------------------------------------------------------------- // BE WARE, Test if removing this code hurts..., anyway we have a bug on it: Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/ScriptHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/ScriptHandler.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/ScriptHandler.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -26,8 +26,8 @@ package jaxx.compiler.tags; import jaxx.compiler.CompilerException; +import jaxx.compiler.JAXXCompiler; import jaxx.compiler.UnsupportedAttributeException; -import jaxx.compiler.JAXXCompiler; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -36,10 +36,7 @@ import org.w3c.dom.Text; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.io.StringWriter; /** * Handles the <code><script></code> tag. @@ -51,7 +48,8 @@ public static final String SOURCE_ATTRIBUTE = "source"; @Override - public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + public void compileFirstPass(Element tag, + JAXXCompiler compiler) throws CompilerException, IOException { File scriptFile = null; NamedNodeMap attributes = tag.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { @@ -59,21 +57,28 @@ String name = attribute.getName(); String attrValue = attribute.getValue(); if (name.equals(SOURCE_ATTRIBUTE)) { - scriptFile = new File(compiler.getBaseDir(), attrValue.replace('/', File.separatorChar)); - StringWriter scriptBuffer = new StringWriter(); - try { - FileReader in = new FileReader(scriptFile); - char[] readBuffer = new char[2048]; - int c; - while ((c = in.read(readBuffer)) > 0) { - scriptBuffer.write(readBuffer, 0, c); - } - } catch (FileNotFoundException e) { - compiler.reportError("script file not found: " + scriptFile); - } - compiler.registerScript(scriptBuffer.toString(), scriptFile); + String filename = attrValue.replace('/', File.separatorChar); + scriptFile = new File(compiler.getBaseDir(), filename); + String content = compiler.loadFile(scriptFile); + compiler.registerScript(content, scriptFile); +// StringWriter scriptBuffer = new StringWriter(); +// FileReader in = new FileReader(scriptFile); +// try { +// char[] readBuffer = new char[2048]; +// int c; +// while ((c = in.read(readBuffer)) > 0) { +// scriptBuffer.write(readBuffer, 0, c); +// } +// } catch (FileNotFoundException e) { +// compiler.reportError( +// "script file not found: " + scriptFile); +// } finally { +// in.close(); +// } +// compiler.registerScript(scriptBuffer.toString(), scriptFile); } else if (!name.startsWith(XMLNS_ATTRIBUTE) && - !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) { + !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals( + attribute.getNamespaceURI())) { throw new UnsupportedAttributeException(name); } } @@ -84,7 +89,9 @@ Node child = children.item(i); switch (child.getNodeType()) { case Node.ELEMENT_NODE: - compiler.reportError("<script> tag may not contain child elements: " + tag); + compiler.reportError( + "<script> tag may not contain child elements: " + + tag); case Node.TEXT_NODE: // fall through case Node.CDATA_SECTION_NODE: script.append(((Text) child).getData()); @@ -94,7 +101,9 @@ String scriptString = script.toString().trim(); if (scriptString.length() > 0) { if (scriptFile != null) { - compiler.reportError("<script> tag has both a source attribute and an inline script"); + compiler.reportError( + "<script> tag has both a source attribute and an " + + "inline script"); } compiler.registerScript(script.toString()); } @@ -102,5 +111,6 @@ @Override public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + // nothing to do } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java 2010-05-04 09:19:05 UTC (rev 1867) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/TagManager.java 2010-05-04 09:47:52 UTC (rev 1868) @@ -46,38 +46,37 @@ */ public class TagManager { - /** - * Logger - */ + /** Logger */ protected static final Log log = LogFactory.getLog(TagManager.class); -// /** -// * Namespace for JAXX's non-class tags, such as <script;>. The namespace normally does not -// * need to be specified but can be used to resolve ambiguities. -// */ -// public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/"; + + /** Maps simple tag names to their default namespaces (package names). */ + private static Map<String, String> defaultNamespaces = + new HashMap<String, String>(); + + /** Maps qualified tag names to the TagHandlers responsible for processing them. */ + private static Map<QName, TagHandler> registeredTags = + new HashMap<QName, TagHandler>(); + + /** Keeps track of whether or not named classes exist. */ + private static Map<String, Boolean> classExistenceCache = + new HashMap<String, Boolean>(); + /** - * Maps simple tag names to their default namespaces (package names). + * Maps bean classes to their TagHandler classes. The mapping is to + * TagHandler classes, rather than to TagHandler instances, + * because subclasses of the bean class should be handled by the same + * TagHandler (assuming no more specific mappings exist), which requires + * creating a new instance of the TagHandler. */ - private static Map<String, String> defaultNamespaces = new HashMap<String, String>(); - /** - * Maps qualified tag names to the TagHandlers responsible for processing them. - */ - private static Map<QName, TagHandler> registeredTags = new HashMap<QName, TagHandler>(); - /** - * Keeps track of whether or not named classes exist. - */ - private static Map<String, Boolean> classExistenceCache = new HashMap<String, Boolean>(); - /** - * Maps bean classes to their TagHandler classes. The mapping is to TagHandler classes, rather than to - * TagHandler instances, because subclasses of the bean class should be handled by the same TagHandler - * (assuming no more specific mappings exist), which requires creating a new instance of the TagHandler. - */ - private static ClassMap<Class<? extends TagHandler>> registeredBeans = new ClassMap<Class<? extends TagHandler>>(); + private static ClassMap<Class<? extends TagHandler>> registeredBeans = + new ClassMap<Class<? extends TagHandler>>(); // still targeting 1.4, so I can't use javax.xml.namespace.QName + private static class QName { private String namespaceURI; + private String localPart; public QName(String namespaceURI, String localPart) { @@ -102,12 +101,14 @@ return false; } QName qname = (QName) o; - return qname.getNamespaceURI().equals(getNamespaceURI()) && qname.getLocalPart().equals(getLocalPart()); + return qname.getNamespaceURI().equals(getNamespaceURI()) && + qname.getLocalPart().equals(getLocalPart()); } @Override public int hashCode() { - return (namespaceURI != null ? namespaceURI.hashCode() : 0) ^ getLocalPart().hashCode(); + return (namespaceURI != null ? namespaceURI.hashCode() : 0) ^ + getLocalPart().hashCode(); } } @@ -120,19 +121,24 @@ } /** - * Maps a class tag to a specific <code>TagHandler</code>. When a tag representing the bean class is - * encountered (either the class' simple name, if it is unambiguous, or its fully-qualified name), the specified - * <code>TagHandler</code> will be invoked to run it. + * Maps a class tag to a specific <code>TagHandler</code>. + * <p/> + * When a tag representing the bean class is encountered (either the + * class' simple name, if it is unambiguous, or its fully-qualified name), + * the specified <code>TagHandler</code> will be invoked to run it. * - * @param <T> type of handler + * @param <T> type of handler * @param beanClass the class to associate with a <code>TagHandler</code> - * @param handler the <code>TagHandler</code> class, which must descend from <code>DefaultObjectHandler</code> - * @throws IllegalArgumentException if the handler class does not descend from <code>DefaultObjectHandler</code> + * @param handler the <code>TagHandler</code> class, which must descend + * from <code>DefaultObjectHandler</code> + * @throws IllegalArgumentException if the handler class does not descend + * from <code>DefaultObjectHandler</code> */ public static <T extends TagHandler> void registerBean(ClassDescriptor beanClass, Class<T> handler) { if (!DefaultObjectHandler.class.isAssignableFrom(handler)) { - throw new IllegalArgumentException("handler class must be a subclass of DefaultObjectHandler"); + throw new IllegalArgumentException( + "handler class must be a subclass of DefaultObjectHandler"); } registeredBeans.put(beanClass, handler); if (log.isDebugEnabled()) { @@ -146,21 +152,25 @@ } /** - * Sets the default namespace for a tag. When the tag is encountered with no namespace specified, - * the specified namespace will be assumed. Mapping the same tag to two or more default namespaces - * removes the mapping and marks the entry as being ambiguous (by putting a <code>null</code> - * value into the map); this causes an error to be thrown if the tag is used without a namespace being - * specified. + * Sets the default namespace for a tag. * <p/> - * Java package names on tags are automatically converted into namespaces (e.g. <javax.swing.JButton/> - * and <JButton xmlns="javax.swing.*"/> are equivalent), so tags with package names are considered - * to have namespaces specified. + * When the tag is encountered with no namespace specified, the specified + * namespace will be assumed. Mapping the same tag to two or more default + * namespaces removes the mapping and marks the entry as being ambiguous + * (by putting a <code>null</code> value into the map); this causes an + * error to be thrown if the tag is used without a namespace being specified. + * <p/> + * Java package names on tags are automatically converted into namespaces + * (e.g. <javax.swing.JButton/> and + * <JButton xmlns="javax.swing.*"/> are equivalent), so tags with + * package names are considered to have namespaces specified. * * @param tag tag name * @param namespace namespace */ public static void registerDefaultNamespace(String tag, String namespace) { - if (defaultNamespaces.containsKey(tag) && !defaultNamespaces.get(tag).equals(namespace)) { + if (defaultNamespaces.containsKey(tag) && + !defaultNamespaces.get(tag).equals(namespace)) { defaultNamespaces.put(tag, null); // tag name is now ambiguous } else { defaultNamespaces.put(tag, namespace); @@ -168,19 +178,23 @@ } /** - * Registers a <code>TagHandler</code> for a tag. When a tag with the given name and namespace - * is encountered, the <code>TagHandler's compileFirstPass</code> and <code>compileSecondPass</code> + * Registers a <code>TagHandler</code> for a tag. + * <p/> + * When a tag with the given name and namespace is encountered, the + * <code>TagHandler's compileFirstPass</code> and <code>compileSecondPass</code> * methods will be invoked to handle it. * <p/> - * It is not an error to register an already-registered tag and namespace combination. The new mapping - * will replace the old mapping. + * It is not an error to register an already-registered tag and namespace + * combination. The new mapping will replace the old mapping. * - * @param <T> type of handler + * @param <T> type of handler * @param namespace the tag's namespace * @param tag the simple name of the tag * @param handler the <code>TagHandler</code> which should process the tag */ - public static <T extends TagHandler> void registerTag(String namespace, String tag, T handler) { + public static <T extends TagHandler> void registerTag(String namespace, + String tag, + T handler) { if (namespace == null) { namespace = "*"; } @@ -193,9 +207,11 @@ } /** - * Returns the <code>TagHandler</code> that should be used to process the specified tag. - * If the tag represents the class name of an uncompiled <code>.jaxx</code> file, the - * <code>.jaxx</code> is first compiled. + * Returns the <code>TagHandler</code> that should be used to process the + * specified tag. + * <p/> + * If the tag represents the class name of an uncompiled <code>.jaxx</code> + * file, the <code>.jaxx</code> is first compiled. * * @param namespace the tag's namespace (may be <code>null</code>) * @param tag the tag's simple name @@ -203,7 +219,9 @@ * @return the <code>TagHandler</code> for the tag * @throws CompilerException ? */ - public static TagHandler getTagHandler(String namespace, String tag, JAXXCompiler compiler) throws CompilerException { + public static TagHandler getTagHandler(String namespace, + String tag, + JAXXCompiler compiler) throws CompilerException { return getTagHandler(namespace, tag, false, compiler); } @@ -224,9 +242,10 @@ /** * @param klass the java class - * @return the <code>TagHandler</code> that should be used to process the specified class. - * Only <code>TagHandlers</code> previously registered with <code>registerBean</code> - * are considered. + * @return the <code>TagHandler</code> that should be used to process the + * specified class. + * Only <code>TagHandlers</code> previously registered with + * <code>registerBean</code> are considered. * @throws CompilerException ? */ public static DefaultObjectHandler getTagHandler(Class<?> klass) throws CompilerException { @@ -234,64 +253,49 @@ ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(klass); DefaultObjectHandler tagHandler = getTagHandler(beanClass); return tagHandler; -// -// try { -// if (beanClass == null) { -// throw new NullPointerException("beanClass parameter can not be null"); -// } -// if (beanClass.getName() == null) { -// throw new NullPointerException("beanClass can not be null : "+beanClass); -// } -// -// String namespace = getNamespace(beanClass); -// String tag = getSimpleName(beanClass); -// DefaultObjectHandler handler = (DefaultObjectHandler) registeredTags.get(new QName(namespace, tag)); -// if (handler == null) { -// Class<? extends TagHandler> handlerClass = registeredBeans.get(beanClass); -// if (handlerClass == null) { -// throw new CompilerException("unable to find handler for " + beanClass); -// } -// Constructor<? extends TagHandler> constructor = handlerClass.getConstructor(ClassDescriptor.class); -// handler = (DefaultObjectHandler) constructor.newInstance(beanClass); -// registerTag(namespace, tag, handler); -// } -// return handler; -// } catch (InstantiationException e) { -// throw new RuntimeException(e); -// } catch (NoSuchMethodException e) { -// throw new RuntimeException(e); -// } catch (IllegalAccessException e) { -// throw new RuntimeException(e); -// } catch (InvocationTargetException e) { -// throw new RuntimeException(e); -// } } + /** * @param beanClass the tag class - * @return the <code>TagHandler</code> that should be used to process the specified class. - * Only <code>TagHandlers</code> previously registered with <code>registerBean</code> - * are considered. + * @return the <code>TagHandler</code> that should be used to process the + * specified class. + * <p/> + * Only <code>TagHandlers</code> previously registered with + * <code>registerBean</code> are considered. * @throws CompilerException ? */ public static DefaultObjectHandler getTagHandler(ClassDescriptor beanClass) throws CompilerException { try { if (beanClass == null) { - throw new NullPointerException("beanClass parameter can not be null"); + throw new NullPointerException( + "beanClass parameter can not be null"); } if (beanClass.getName() == null) { - throw new NullPointerException("beanClass can not be null : "+beanClass); + throw new NullPointerException( + "beanClass name can not be null : " + beanClass); } String namespace = getNamespace(beanClass); String tag = getSimpleName(beanClass); - DefaultObjectHandler handler = (DefaultObjectHandler) registeredTags.get(new QName(namespace, tag)); + DefaultObjectHandler handler = (DefaultObjectHandler) + registeredTags.get(new QName(namespace, tag)); if (handler == null) { - Class<? extends TagHandler> handlerClass = registeredBeans.get(beanClass); + Class<? extends TagHandler> handlerClass = + registeredBeans.get(beanClass); if (handlerClass == null) { - throw new CompilerException("unable to find handler for " + beanClass); + if (beanClass.isInterface()) { + + // if an interface is a tag, avoid big problems... + + return null; + } + throw new CompilerException( + "unable to find handler for " + beanClass); } - Constructor<? extends TagHandler> constructor = handlerClass.getConstructor(ClassDescriptor.class); - handler = (DefaultObjectHandler) constructor.newInstance(beanClass); + Constructor<? extends TagHandler> constructor = + handlerClass.getConstructor(ClassDescriptor.class); + handler = (DefaultObjectHandler) + constructor.newInstance(beanClass); registerTag(namespace, tag, handler); } return handler; @@ -319,8 +323,9 @@ } catch (ClassNotFoundException e) { // ignore ? } catch (NoClassDefFoundError e) { - // we obtain this instead of ClassNotFoundException on case-insensitive file systems when - // looking up a class with the wrong case + // we obtain this instead of ClassNotFoundException on + // case-insensitive file systems when looking up a class with the + // wrong case } if (!found) { @@ -340,12 +345,15 @@ return found; } - private static String determinePackage(String simpleClassName, String defaultPackage, JAXXCompiler compiler) { + private static String determinePackage(String simpleClassName, + String defaultPackage, + JAXXCompiler compiler) { String namespace = null; Set<String> classes = compiler.getImportedClasses(); for (String className : classes) { // search class imports (e.g. import java.util.Date;) - if (className.equals(simpleClassName) || className.endsWith("." + simpleClassName)) { + if (className.equals(simpleClassName) || + className.endsWith("." + simpleClassName)) { namespace = className.substring(0, className.lastIndexOf(".") + 1) + "*"; } } @@ -354,9 +362,13 @@ Set<String> searchList = compiler.getImportedPackages(); if (defaultPackage != null) { if (!defaultPackage.endsWith("*")) { - throw new IllegalArgumentException("defaultPackage must end in '*', found '" + defaultPackage + "'"); + throw new IllegalArgumentException( + "defaultPackage must end in '*', found '" + + defaultPackage + "'"); } - if (classExists(defaultPackage.substring(0, defaultPackage.length() - 1) + simpleClassName, compiler)) { + String fqn = defaultPackage.substring( + 0, defaultPackage.length() - 1) + simpleClassName; + if (classExists(fqn, compiler)) { return defaultPackage; } } @@ -365,7 +377,14 @@ if (classExists(className, compiler)) { if (namespace != null) { // we've already found the same name in another package - compiler.reportError("symbol '" + simpleClassName + "' is ambiguous, found matching classes " + namespace.substring(0, namespace.length() - 1) + simpleClassName + " and " + currentPackage + simpleClassName + ". Use fully-qualified name to disambiguate."); + compiler.reportError( + "symbol '" + simpleClassName + + "' is ambiguous, found matching classes " + + namespace.substring(0, namespace.length() - 1) + + simpleClassName + " and " + currentPackage + + simpleClassName + + ". Use fully-qualified name to disambiguate." + ); return null; } namespace = currentPackage + "*"; @@ -377,29 +396,45 @@ } /** - * Returns the <code>TagHandler</code> that should be used to process the specified tag. + * Returns the <code>TagHandler</code> that should be used to process the + * specified tag. * <p/> - * The <code>namespacePrefix</code> parameter is used only for error checking, as it is an - * error to specify conflicting package names using both a fully-qualified tag name and a - * namespace prefix, but it is not an error to specify conflicting package names using a - * fully-qualified tag name and a <i>default</i> namespace (i.e. <awt:javax.swing.JButton xmlns:awt='java.awt.*'/> + * The <code>namespacePrefix</code> parameter is used only for error + * checking, as it is an error to specify conflicting package names using + * both a fully-qualified tag name and a namespace prefix, but it is not + * an error to specify conflicting package names using a fully-qualified + * tag name and a <i>default</i> namespace (i.e. + * <awt:javax.swing.JButton xmlns:awt='java.awt.*'/> * is an error, whereas <javax.swing.JButton xmlns='java.awt.*'/> is not). * * @param namespace the tag's namespace (may be <code>null</code>) - * @param tag the tag's simple name (which can include fully-qualified Java class names) - * @param namespacePrefix <code>true</code> if the namespace was specified by means of a namespace prefix (as opposed to a default namespace) + * @param tag the tag's simple name (which can include + * fully-qualified Java class names) + * @param namespacePrefix <code>true</code> if the namespace was specified + * by means of a namespace prefix (as opposed to a + * default namespace) * @param compiler the current <code>JAXXCompiler</code> * @return the <code>TagHandler</code> for the tag * @throws CompilerException ? */ - public static TagHandler getTagHandler(String namespace, String tag, boolean namespacePrefix, JAXXCompiler compiler) throws CompilerException { + public static TagHandler getTagHandler(String namespace, + String tag, + boolean namespacePrefix, + JAXXCompiler compiler) throws CompilerException { if (tag == null) { throw new NullPointerException("tag parameter can not be null"); } if (namespace == null && defaultNamespaces.containsKey(tag)) { namespace = defaultNamespaces.get(tag); - if (namespace == null) { // defaultNamespaces map contains a null value, which is put there to indicate ambiguity - compiler.reportError("tag '" + tag + "' is ambiguous; specify fully-qualified name (package and class) to disambiguate"); + if (namespace == null) { + + // defaultNamespaces map contains a null value, which is put + // there to indicate ambiguity + compiler.reportError( + "tag '" + tag + "' is ambiguous; specify " + + "fully-qualified name (package and class) to " + + "disambiguate" + ); return null; } } @@ -409,11 +444,21 @@ if (namespace == null || namespace.endsWith("*")) { String className; if (namespace != null) { - className = resolveClassName(namespace.substring(0, namespace.length() - 1) + tag, compiler); + className = resolveClassName( + namespace.substring(0, namespace.length() - 1) + tag, + compiler + ); if (className == null) { className = resolveClassName(tag, compiler); - if (namespacePrefix && !className.startsWith(namespace.substring(0, namespace.length() - 1))) { - className = null; // namespace was specified, but we found it in a different package - ignore + if (namespacePrefix && + !className.startsWith( + namespace.substring( + 0, + namespace.length() - 1))) { + + // namespace was specified, but we found it in a + // different package - ignore + className = null; } } } else { @@ -426,7 +471,11 @@ handler = registeredTags.get(new QName(namespace, tag)); if (handler == null) { try { - ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(className, compiler.getClassLoader()); + ClassDescriptor beanClass = + ClassDescriptorLoader.getClassDescriptor( + className, + compiler.getClassLoader() + ); handler = getTagHandler(beanClass); } catch (ClassNotFoundException e) { log.error(e); @@ -440,11 +489,16 @@ } /** - * Resolves a simple class name (like <code>Object</code> or <code>String</code>) to its fully-qualified name. Inner - * classes should be represented as they would appear in Java source code (e.g. JPopupMenu.Separator). Fully-qualified names, - * such as <code>java.lang.Object</code> are legal and will be returned unmodified (and in fact it is generally impossible to - * even know whether a given reference is fully qualified until it has been resolved). Returns <code>null</code> if no matching - * class could be found. + * Resolves a simple class name (like <code>Object</code> or + * <code>String</code>) to its fully-qualified name. + * <p/> + * Inner classes should be represented as they would appear in Java source + * code (e.g. JPopupMenu.Separator). Fully-qualified names, such as + * <code>java.lang.Object</code> are legal and will be returned unmodified + * (and in fact it is generally impossible to even know whether a given + * reference is fully qualified until it has been resolved). + * <p/> + * Returns <code>null</code> if no matching class could be found. * * @param name name to resolve * @param compiler run to use @@ -452,15 +506,24 @@ */ public static String resolveClassName(String name, JAXXCompiler compiler) { if (name.endsWith("[]")) { - return resolveClassName(name.substring(0, name.length() - 2), compiler) + "[]"; + return resolveClassName( + name.substring(0, name.length() - 2), compiler) + "[]"; } if (name.contains("<")) { - name = name.substring(0, name.indexOf("<")); // strip off generic types + + // strip off generic types + name = name.substring(0, name.indexOf("<")); } name = name.intern(); - if (name.equals("boolean") || name.equals("byte") || name.equals("short") || name.equals("int") || - name.equals("long") || name.equals("float") || name.equals("double") || name.equals("char")) { + if (name.equals("boolean") || + name.equals("byte") || + name.equals("short") || + name.equals("int") || + name.equals("long") || + name.equals("float") || + name.equals("double") || + name.equals("char")) { return name; } @@ -469,48 +532,80 @@ String defaultNamespace = null; if (defaultNamespaces.containsKey(name)) { defaultNamespace = defaultNamespaces.get(name); - if (defaultNamespace == null) { // defaultNamespaces map contains a null value, which is put there to indicate ambiguity - compiler.reportError("class '" + name + "' is ambiguous; specify fully-qualified name (package and class) to disambiguate"); + if (defaultNamespace == null) { + + // defaultNamespaces map contains a null value, which is put + // there to indicate ambiguity + compiler.reportError( + "class '" + name + "' is ambiguous; specify " + + "fully-qualified name (package and class) to " + + "disambiguate" + ); return null; } } if (defaultNamespace != null && defaultNamespace.endsWith("*")) { - result = defaultNamespace.substring(0, defaultNamespace.length() - 1) + name; + result = defaultNamespace.substring( + 0, defaultNamespace.length() - 1) + name; } if (result == null) { - // Inner class names (like JPopupMenu.Separator) present a special challenge. The name before the dot might be - // a package name, or it might be a class name. If it's a class name, it might be fully qualified, or it might - // not. And it's also not actually the correct name of the class, as far as the JVM is concerned -- the correct - // name uses a dollar sign instead of a dot (javax.swing.JPopupMenu$Separator). And there could be more than - // one inner class -- it's possible to have com.mycompany.Outer$Inner$Innerer$Innerest. + // Inner class names (like JPopupMenu.Separator) present a special + // challenge. The name before the dot might be a package name, + // or it might be a class name. + // + // If it's a class name, it might be fully qualified, or it might + // not. And it's also not actually the correct name of the class, + // as far as the JVM is concerned -- the correct name uses a dollar + // sign instead of a dot (javax.swing.JPopupMenu$Separator). + // And there could be more than one inner class -- it's possible to + // have com.mycompany.Outer$Inner$Innerer$Innerest. // - // The basic strategy is to run by treating the part before the last dot as a package name, as that is by far - // the most likely case. If we don't find the class there, change the last dot to a dollar sign and try again. - // Suppose we have the tag <com.mycompany.Outer.Inner.Innerer.Innerest/>, matching the class above. Resolution - // proceeds like this: + // The basic strategy is to run by treating the part before the + // last dot as a package name, as that is by far the most likely case. + // + // If we don't find the class there, change the last dot to a + // dollar sign and try again. + + // Suppose we have the tag + // <com.mycompany.Outer.Inner.Innerer.Innerest/>, + // matching the class above. Resolution proceeds like this: // com.mycompany.Outer.Inner.Innerer.* : Innerest // com.mycompany.Outer.Inner.* : Innerer$Innerest // com.mycompany.Outer.* : Inner$Innerer$Innerest // com.mycompany.* : Outer$Inner$Innerer$Innerest // And at this point we have a match with the class Outer$Inner$Innerer$Innerest in package com.mycompany. int dotPos = originalName.lastIndexOf('.'); - for (;;) { + for (; ;) { String namespace = dotPos != -1 ? originalName.substring(0, dotPos) + ".*" : "*"; name = originalName.substring(dotPos + 1).replace('.', '$'); String packageName = determinePackage(name, namespace, compiler); if (packageName != null) { assert packageName.endsWith("*"); - if (packageName.equals(namespace) || namespace.equals("*")) { + if (packageName.equals(namespace) || + namespace.equals("*")) { // check for an alias (like javax.swing.JComboBox actually being jaxx.runtime.swing.JAXXComboBox) - TagHandler handler = registeredTags.get(new QName(namespace, name)); - if (handler != null) { // determine alias by looking at handler - ClassDescriptor alias = ((DefaultObjectHandler) handler).getBeanClass(); - // make sure the same handler is used for both the aliased and non-aliased names, in order to avoid "no CompiledObject has been registered" error - // the line below doesn't bother to handle the case where the aliased class name doesn't have a package, since it's a pretty safe assumption that + TagHandler handler = + registeredTags.get(new QName(namespace, name)); + + if (handler != null) { + + // determine alias by looking at handler + ClassDescriptor alias = + ((DefaultObjectHandler) handler).getBeanClass(); + + // make sure the same handler is used for both the + // aliased and non-aliased names, in order to avoid + // "no CompiledObject has been registered" error + // the line below doesn't bother to handle the case + // where the aliased class name doesn't have a + // package, since it's a pretty safe assumption that // that will never happen assert alias.getPackageName() != null && alias.getPackageName().length() > 0 : "aliasing with no package name has not been implemented"; - registeredTags.put(new QName(alias.getPackageName() + ".*", alias.getName().substring(alias.getPackageName().length() + 1)), handler); + registeredTags.put( + new QName(alias.getPackageName() + ".*", alias.getName().substring(alias.getPackageName().length() + 1)), + handler + ); result = alias.getName(); break; } else { // no alias @@ -529,19 +624,25 @@ } if (result != null && !result.equals(originalName)) { - result = resolveClassName(result, compiler); // check for aliases against the new name as well + + // check for aliases against the new name as well + result = resolveClassName(result, compiler); } return result; } - public static ClassDescriptor resolveClass(String className, JAXXCompiler compiler) { + public static ClassDescriptor resolveClass(String className, + JAXXCompiler compiler) { try { className = resolveClassName(className, compiler); if (className == null) { return null; } - return ClassDescriptorLoader.getClassDescriptor(className, compiler.getClassLoader()); + return ClassDescriptorLoader.getClassDescriptor( + className, + compiler.getClassLoader() + ); } catch (ClassNotFoundException e) { return null; }
participants (1)
-
tchemit@users.nuiton.org