You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/06/12 16:53:29 UTC

svn commit: r784144 - /incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java

Author: gbrown
Date: Fri Jun 12 14:53:29 2009
New Revision: 784144

URL: http://svn.apache.org/viewvc?rev=784144&view=rev
Log:
Clean up element handling in WTKXSerializer; temporarily disable script processing (to be re-added later).

Modified:
    incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java

Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java?rev=784144&r1=784143&r2=784144&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java Fri Jun 12 14:53:29 2009
@@ -180,7 +180,6 @@
     private HashMap<String, WTKXSerializer> includeSerializers = new HashMap<String, WTKXSerializer>();
 
     private ScriptEngineManager scriptEngineManager = null;
-    private NamedObjectBindings namedObjectBindings = null;
 
     private XMLInputFactory xmlInputFactory;
 
@@ -197,6 +196,7 @@
 
     public static final String SCRIPT_TAG = "script";
     public static final String SCRIPT_SRC_ATTRIBUTE = "src";
+    public static final String SCRIPT_LANGUAGE_ATTRIBUTE = "language";
 
     public static final String MIME_TYPE = "application/wtkx";
 
@@ -209,11 +209,6 @@
 
         xmlInputFactory = XMLInputFactory.newInstance();
         xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
-
-        scriptEngineManager = new javax.script.ScriptEngineManager();
-        namedObjectBindings = new NamedObjectBindings();
-
-        scriptEngineManager.setBindings(namedObjectBindings);
     }
 
     public Resources getResources() {
@@ -327,10 +322,16 @@
                                         break;
                                     }
 
+                                    case SCRIPT:
                                     case WRITABLE_PROPERTY: {
                                         element.value = text;
                                         break;
                                     }
+
+                                    default: {
+                                        throw new SerializationException("Unexpected characters in "
+                                            + element.type + " element.");
+                                    }
                                 }
                             }
                         }
@@ -339,161 +340,49 @@
                     }
 
                     case XMLStreamConstants.START_ELEMENT: {
+                        // Get element properties
                         String namespaceURI = reader.getNamespaceURI();
                         String prefix = reader.getPrefix();
                         String localName = reader.getLocalName();
 
-                        String id = null;
+                        // Build attribute list; these will be processed in the close tag
+                        ArrayList<Attribute> attributes = new ArrayList<Attribute>();
+
+                        for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
+                            String attributeNamespaceURI = reader.getAttributeNamespace(i);
+                            if (attributeNamespaceURI == null) {
+                                attributeNamespaceURI = reader.getNamespaceURI("");
+                            }
+
+                            String attributePrefix = reader.getAttributePrefix(i);
+                            String attributeLocalName = reader.getAttributeLocalName(i);
+                            String attributeValue = reader.getAttributeValue(i);
+
+                            attributes.add(new Attribute(attributeNamespaceURI,
+                                attributePrefix, attributeLocalName, attributeValue));
+                        }
+
+                        // Determine the type and value of this element
+                        Element.Type elementType = null;
+                        Object value = null;
 
                         if (prefix != null
                             && prefix.equals(WTKX_PREFIX)) {
+                            // The element represents a WTKX operation
                             if (element == null) {
                                 throw new SerializationException(prefix + ":" + localName
                                     + " is not a valid root element.");
                             }
 
                             if (localName.equals(INCLUDE_TAG)) {
-                                // The element represents an include
-                                String src = null;
-                                Resources resources = this.resources;
-
-                                ArrayList<Attribute> attributes = new ArrayList<Attribute>();
-
-                                for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
-                                    String attributeNamespaceURI = reader.getAttributeNamespace(i);
-                                    if (attributeNamespaceURI == null) {
-                                        attributeNamespaceURI = reader.getNamespaceURI("");
-                                    }
-
-                                    String attributePrefix = reader.getAttributePrefix(i);
-                                    String attributeLocalName = reader.getAttributeLocalName(i);
-                                    String attributeValue = reader.getAttributeValue(i);
-
-                                    if (attributePrefix != null
-                                        && attributePrefix.equals(WTKX_PREFIX)) {
-                                        if (attributeLocalName.equals(ID_ATTRIBUTE)) {
-                                            id = attributeValue;
-                                        }
-                                    } else {
-                                        if (attributeLocalName.equals(INCLUDE_SRC_ATTRIBUTE)) {
-                                            src = attributeValue;
-                                        } else if (attributeLocalName.equals(INCLUDE_RESOURCES_ATTRIBUTE)) {
-                                            resources = new Resources(attributeValue);
-                                        } else {
-                                            attributes.add(new Attribute(attributeNamespaceURI,
-                                                attributePrefix, attributeLocalName, attributeValue));
-                                        }
-                                    }
-                                }
-
-                                if (src == null) {
-                                    throw new SerializationException(INCLUDE_SRC_ATTRIBUTE
-                                        + " attribute is required for " + WTKX_PREFIX + ":" + INCLUDE_TAG
-                                        + " tag.");
-                                }
-
-                                // Process the include
-                                WTKXSerializer serializer = new WTKXSerializer(resources);
-                                if (id != null) {
-                                    includeSerializers.put(id, serializer);
-                                }
-
-                                Object value;
-                                if (src.charAt(0) == '/') {
-                                    value = serializer.readObject(src.substring(1));
-                                } else {
-                                    value = serializer.readObject(new URL(location, src));
-                                }
-
-                                element = new Element(element, Element.Type.INCLUDE, attributes, value);
+                                elementType = Element.Type.INCLUDE;
                             } else if (localName.equals(SCRIPT_TAG)) {
-                                // TODO Also look for language attribute, in case the script is inline
-                                String src = null;
-
-                                for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
-                                    String attributeLocalName = reader.getAttributeLocalName(i);
-                                    String attributeValue = reader.getAttributeValue(i);
-
-                                    if (attributeLocalName.equals(SCRIPT_SRC_ATTRIBUTE)) {
-                                        src = attributeValue;
-                                    } else {
-                                        throw new SerializationException(attributeLocalName + " is not a valid "
-                                            + " attribute for the " + WTKX_PREFIX + ":" + SCRIPT_TAG + ".");
-                                    }
-                                }
-
-                                if (src == null) {
-                                    throw new SerializationException(INCLUDE_SRC_ATTRIBUTE
-                                        + " attribute is required for " + WTKX_PREFIX + ":" + SCRIPT_TAG
-                                        + " tag.");
-                                }
-
-                                int i = src.lastIndexOf(".");
-                                if (i == -1) {
-                                    throw new SerializationException("Cannot determine type of script \""
-                                        + src + "\".");
-                                }
-
-                                String extension = src.substring(i + 1);
-                                ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension(extension);
-
-                                if (scriptEngine == null) {
-                                    throw new SerializationException("Unable to find scripting engine for "
-                                        + " extension " + extension + ".");
-                                }
-
-                                // TODO If the parent element is a read-only property that refers to
-                                // a listener list, temporarily bind to an invocation handler and set the
-                                // handler as the current element (don't set the element to the script tag,
-                                // as below):
-                                // element = new Element(element, Element.Type.INSTANCE, attributes, handler);
-
-                                scriptEngine.setBindings(namedObjectBindings, ScriptContext.ENGINE_SCOPE);
-
-                                try {
-                                    URL scriptLocation;
-                                    if (src.charAt(0) == '/') {
-                                        ClassLoader classLoader = ThreadUtilities.getClassLoader();
-                                        scriptLocation = classLoader.getResource(src);
-                                    } else {
-                                        scriptLocation = new URL(location, src);
-                                    }
-
-                                    BufferedReader scriptReader = new BufferedReader(new InputStreamReader(scriptLocation.openStream()));
-                                    scriptEngine.eval(scriptReader);
-                                } catch (Exception exception) {
-                                    throw new SerializationException(exception);
-                                }
-
-                                element = new Element(element, Element.Type.SCRIPT, null, null);
+                                elementType = Element.Type.SCRIPT;
                             } else {
                                 throw new SerializationException(prefix + ":" + localName
-                                    + " is not a valid tag.");
+                                    + " is not a valid element.");
                             }
                         } else {
-                            ArrayList<Attribute> attributes = new ArrayList<Attribute>();
-
-                            for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
-                                String attributeNamespaceURI = reader.getAttributeNamespace(i);
-                                if (attributeNamespaceURI == null) {
-                                    attributeNamespaceURI = reader.getNamespaceURI("");
-                                }
-
-                                String attributePrefix = reader.getAttributePrefix(i);
-                                String attributeLocalName = reader.getAttributeLocalName(i);
-                                String attributeValue = reader.getAttributeValue(i);
-
-                                if (attributePrefix != null
-                                    && attributePrefix.equals(WTKX_PREFIX)) {
-                                    if (attributeLocalName.equals(ID_ATTRIBUTE)) {
-                                        id = attributeValue;
-                                    }
-                                } else {
-                                    attributes.add(new Attribute(attributeNamespaceURI,
-                                        attributePrefix, attributeLocalName, attributeValue));
-                                }
-                            }
-
                             if (Character.isUpperCase(localName.charAt(0))) {
                                 // The element represents a typed object
                                 if (namespaceURI == null) {
@@ -505,45 +394,116 @@
 
                                 try {
                                     Class<?> type = Class.forName(className);
-                                    element = new Element(element, Element.Type.INSTANCE, attributes, type.newInstance());
+                                    elementType = Element.Type.INSTANCE;
+                                    value = type.newInstance();
                                 } catch (Exception exception) {
                                     throw new SerializationException(exception);
                                 }
                             } else {
-                                // This element represents a property
-                                if (element == null) {
-                                    throw new SerializationException("Root node must represent a typed object.");
+                                // The element represents a property
+                                if (element == null
+                                    || element.type != Element.Type.INSTANCE) {
+                                    throw new SerializationException("Parent element must be a typed object.");
+                                }
+
+                                if (prefix != null) {
+                                    throw new SerializationException("Property elements cannot have a namespace prefix.");
                                 }
 
-                                BeanDictionary propertyDictionary = new BeanDictionary(element.value);
+                                BeanDictionary beanDictionary = new BeanDictionary(element.value);
 
-                                if (propertyDictionary.isReadOnly(localName)) {
-                                    Object value = propertyDictionary.get(localName);
+                                if (beanDictionary.isReadOnly(localName)) {
+                                    elementType = Element.Type.READ_ONLY_PROPERTY;
+                                    value = beanDictionary.get(localName);
                                     assert (value != null) : "Read-only properties cannot be null.";
-                                    element = new Element(element, Element.Type.READ_ONLY_PROPERTY, attributes, value);
+
+                                    if (attributes.getLength() > 0
+                                        && !(value instanceof Dictionary<?, ?>)) {
+                                        throw new SerializationException("Only read-only dictionaries can have attributes.");
+                                    }
                                 } else {
                                     if (attributes.getLength() > 0) {
                                         throw new SerializationException("Writable property elements cannot have attributes.");
                                     }
 
-                                    element = new Element(element, Element.Type.WRITABLE_PROPERTY, null, null);
+                                    elementType = Element.Type.WRITABLE_PROPERTY;
                                 }
                             }
                         }
 
+                        // Set the current element
+                        element = new Element(element, elementType, attributes, value);
+                        break;
+                    }
+
+                    case XMLStreamConstants.END_ELEMENT: {
+                        String localName = reader.getLocalName();
+
                         switch (element.type) {
-                            case INCLUDE:
-                            case INSTANCE: {
-                                // If the element's parent is a sequence or a listener list, add
-                                // the element value to it
-                                if (element.parent != null) {
-                                    if (element.parent.value instanceof Sequence) {
-                                        Sequence<Object> sequence = (Sequence<Object>)element.parent.value;
-                                        sequence.add(element.value);
+                            case INSTANCE:
+                            case INCLUDE: {
+                                String id = null;
+                                ArrayList<Attribute> attributes = new ArrayList<Attribute>();
+
+                                if (element.type == Element.Type.INCLUDE) {
+                                    // Process attributes looking for src, wtkx:id, and static property
+                                    // setters only
+                                    String src = null;
+
+                                    for (Attribute attribute : element.attributes) {
+                                        if (attribute.prefix != null
+                                            && attribute.prefix.equals(WTKX_PREFIX)) {
+                                            if (attribute.localName.equals(ID_ATTRIBUTE)) {
+                                                id = attribute.value;
+                                            } else {
+                                                throw new SerializationException(WTKX_PREFIX + ":" + attribute.localName
+                                                    + " is not a valid attribute.");
+                                            }
+                                        } else {
+                                            if (attribute.localName.equals(INCLUDE_SRC_ATTRIBUTE)) {
+                                                src = attribute.value;
+                                            } else {
+                                                if (attribute.namespaceURI == null) {
+                                                    throw new SerializationException("Instance property setters are not"
+                                                        + " supported for " + WTKX_PREFIX + ":" + INCLUDE_TAG
+                                                        + " " + " tag.");
+                                                }
+
+                                                attributes.add(attribute);
+                                            }
+                                        }
+                                    }
+
+                                    if (src == null) {
+                                        throw new SerializationException(INCLUDE_SRC_ATTRIBUTE
+                                            + " attribute is required for " + WTKX_PREFIX + ":" + INCLUDE_TAG
+                                            + " tag.");
+                                    }
+
+                                    // Read the object
+                                    WTKXSerializer serializer = new WTKXSerializer(resources);
+                                    if (id != null) {
+                                        includeSerializers.put(id, serializer);
+                                    }
+
+                                    if (src.charAt(0) == '/') {
+                                        element.value = serializer.readObject(src.substring(1));
                                     } else {
-                                        if (element.parent.value instanceof ListenerList) {
-                                            ListenerList<Object> listenerList = (ListenerList<Object>)element.parent.value;
-                                            listenerList.add(element.value);
+                                        element.value = serializer.readObject(new URL(location, src));
+                                    }
+                                } else {
+                                    // Process attributes looking for wtkx:id and all property setters
+                                    for (Attribute attribute : element.attributes) {
+                                        if (attribute.prefix != null
+                                            && attribute.prefix.equals(WTKX_PREFIX)) {
+                                            if (attribute.localName.equals(ID_ATTRIBUTE)) {
+                                                id = attribute.value;
+                                            } else {
+                                                throw new SerializationException(WTKX_PREFIX + ":" + attribute.localName
+                                                    + " is not a valid attribute.");
+                                            }
+                                        } else {
+                                            attributes.add(attribute);
                                         }
                                     }
                                 }
@@ -558,35 +518,29 @@
                                     namedObjects.put(id, element.value);
                                 }
 
-                                break;
-                            }
-                        }
-
-                        break;
-                    }
-
-                    case XMLStreamConstants.END_ELEMENT: {
-                        String localName = reader.getLocalName();
-
-                        switch (element.type) {
-                            case WRITABLE_PROPERTY: {
-                                BeanDictionary propertyDictionary = new BeanDictionary(element.parent.value);
-                                propertyDictionary.put(localName, element.value);
-                                break;
-                            }
-
-                            case SCRIPT: {
-                                break;
-                            }
+                                // If the element's parent is a sequence or a listener list, add
+                                // the element value to it
+                                if (element.parent != null) {
+                                    if (element.parent.value instanceof Sequence) {
+                                        Sequence<Object> sequence = (Sequence<Object>)element.parent.value;
+                                        sequence.add(element.value);
+                                    } else {
+                                        if (element.parent.value instanceof ListenerList) {
+                                            ListenerList<Object> listenerList = (ListenerList<Object>)element.parent.value;
+                                            listenerList.add(element.value);
+                                        }
+                                    }
+                                }
 
-                            default: {
+                                // Apply remaining attributes
                                 if (element.value instanceof Dictionary) {
                                     // The element is an untyped object
                                     Dictionary<String, Object> dictionary = (Dictionary<String, Object>)element.value;
 
-                                    for (Attribute attribute : element.attributes) {
+                                    for (Attribute attribute : attributes) {
                                         if (Character.isUpperCase(attribute.localName.charAt(0))) {
-                                            throw new SerializationException("Static setters are only supported for typed instances.");
+                                            throw new SerializationException("Static setters are only supported"
+                                                + " for typed objects.");
                                         }
 
                                         // Resolve and apply the attribute
@@ -594,36 +548,15 @@
                                     }
                                 } else {
                                     // The element represents a typed object; apply the attributes
-                                    BeanDictionary valueDictionary = new BeanDictionary(element.value);
+                                    BeanDictionary beanDictionary = new BeanDictionary(element.value);
 
-                                    for (Attribute attribute : element.attributes) {
+                                    for (Attribute attribute : attributes) {
                                         if (Character.isUpperCase(attribute.localName.charAt(0))) {
                                             // The property represents an attached value
                                             setStaticProperty(attribute, element.value);
                                         } else {
-                                            Class<?> type = valueDictionary.getType(attribute.localName);
-
-                                            if (type != null
-                                                && ListenerList.class.isAssignableFrom(type)) {
-                                                // The property represents a listener list
-                                                ListenerList<Object> listenerList = (ListenerList<Object>)valueDictionary.get(attribute.localName);
-
-                                                // The attribute value is a comma-separated list of listener IDs
-                                                String[] listenerIDs = attribute.value.split(",");
-
-                                                for (int i = 0, n = listenerIDs.length; i < n; i++) {
-                                                    String listenerID = listenerIDs[i].trim();
-
-                                                    if (listenerID.length() > 0) {
-                                                        if (listenerID.length() > 0) {
-                                                            listenerList.add(get(listenerID));
-                                                        }
-                                                    }
-                                                }
-                                            } else {
-                                                valueDictionary.put(attribute.localName,
-                                                    resolve(attribute.value, valueDictionary.getType(attribute.localName)));
-                                            }
+                                            beanDictionary.put(attribute.localName,
+                                                resolve(attribute.value, beanDictionary.getType(attribute.localName)));
                                         }
                                     }
                                 }
@@ -634,6 +567,38 @@
                                     && element.parent.type == Element.Type.WRITABLE_PROPERTY) {
                                     element.parent.value = element.value;
                                 }
+
+                                break;
+                            }
+
+                            case READ_ONLY_PROPERTY: {
+                                if (element.value instanceof Dictionary<?, ?>) {
+                                    // Process attributes looking for instance property setters
+                                    for (Attribute attribute : element.attributes) {
+                                        if (Character.isUpperCase(attribute.localName.charAt(0))) {
+                                            throw new SerializationException("Static setters are not supported"
+                                                + " for read-only properties.");
+                                        }
+
+                                        Dictionary<String, Object> dictionary =
+                                            (Dictionary<String, Object>)element.value;
+                                        dictionary.put(attribute.localName, resolve(attribute.value, null));
+                                    }
+                                }
+
+                                break;
+                            }
+
+                            case WRITABLE_PROPERTY: {
+                                BeanDictionary beanDictionary = new BeanDictionary(element.parent.value);
+                                beanDictionary.put(localName, element.value);
+                                break;
+                            }
+
+                            case SCRIPT: {
+                                // TODO Process attributes looking for src and language; create invocation
+                                // handler if parent element is a listener list
+                                break;
                             }
                         }
 
@@ -802,7 +767,8 @@
 
         Method __bindMethod = null;
         try {
-            __bindMethod = type.getDeclaredMethod("__bind", new Class<?>[] {Dictionary.class});
+            __bindMethod = type.getDeclaredMethod("__bind", new Class<?>[] {type, WTKXSerializer.class});
+            assert ((__bindMethod.getModifiers() & Modifier.STATIC) > 0);
         } catch (NoSuchMethodException exception) {
             // No-op
         }
@@ -849,7 +815,7 @@
             }
         } else {
             try {
-                __bindMethod.invoke(null, new Object[] {this});
+                __bindMethod.invoke(null, new Object[] {object, this});
             } catch (IllegalAccessException exception) {
                 throw new BindException(exception);
             } catch (InvocationTargetException exception) {