[Yanel-commits] rev 28724 - public/yanel/trunk/src/core/java/org/wyona/yanel/core

simon at wyona.com simon at wyona.com
Fri Nov 9 14:44:53 CET 2007


Author: simon
Date: 2007-11-09 14:44:53 +0100 (Fri, 09 Nov 2007)
New Revision: 28724

Modified:
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceConfiguration.java
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceManager.java
Log:
fixes bug http://bugzilla.wyona.com/cgi-bin/bugzilla/show_bug.cgi?id=5678 thanks to josias!

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceConfiguration.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceConfiguration.java	2007-11-09 13:44:31 UTC (rev 28723)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceConfiguration.java	2007-11-09 13:44:53 UTC (rev 28724)
@@ -18,53 +18,61 @@
 
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
 import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfiguration;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
-
-import org.apache.log4j.Category;
-
+import org.apache.log4j.Logger;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
 import org.w3c.dom.Element;
-
+import org.w3c.dom.NodeList;
 import org.wyona.yanel.core.util.ConfigurationUtil;
+import org.wyona.yarep.core.Node;
 
 /**
- * Abstraction of a resource configuration.
+ * Resource configuration.
+ * Based on a yarep node.
  */
 public class ResourceConfiguration {
 
-    private Category log = Category.getInstance(ResourceConfiguration.class);
+    private Logger log = Logger.getLogger(ResourceConfiguration.class);
 
-    //protected Map properties;
+    protected Node node;
     protected String name;
     protected String namespace;
-    private String encoding = null;
-    DefaultConfiguration config;
+    protected String encoding = null;
+    protected LinkedHashMap properties;
+    protected Document customConfig;
     
+    
     /**
-     *
+     * Creates a resource configuration from a yarep node.
      */
+    public ResourceConfiguration(Node node) throws Exception {
+        this.node = node;
+        load(node.getInputStream());
+    }
+    
+    /**
+     * Creates a resource configuration from an inpustream.
+     * @deprecated use ResourceConfiguration(Node node) instead. if a rc is created using this constructor, saving won't work.
+     */
     public ResourceConfiguration(InputStream in) throws Exception {
-        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(true);
-        config = (DefaultConfiguration) builder.build(in);
-        Configuration rtiConfig = config.getChild("rti");
-        name = rtiConfig.getAttribute("name");
-        namespace = rtiConfig.getAttribute("namespace");
-        log.debug("Universal Name: " + getUniversalName());
-
-        Configuration encodingConfig = config.getChild("encoding", false);
-        if (encodingConfig != null) encoding = encodingConfig.getValue();
-
-        // TODO: Read properties and set this.properties
+        load(in);
     }
     
     /**
-     * Create a resource from scratch
+     * Create a resource configuration from a property map.
+     * NOTE: if a rc is created using this constructor, saving won't work.
      * @param name Resource Type Name
      * @param namespace Resource Type Namespace
      */
@@ -73,7 +81,11 @@
         this.namespace = namespace;
 
         if (properties != null) {
-            String LOCATION = "resource_config_location";
+            this.properties = new LinkedHashMap(properties);
+        } else {
+            this.properties = new LinkedHashMap();
+            
+/*            String LOCATION = "resource_config_location";
             String PREFIX = "yanel";
             String RC_NAMESPACE = "http://www.wyona.org/yanel/rti/1.0";
             config = new DefaultConfiguration("resource-config", LOCATION, RC_NAMESPACE, PREFIX);
@@ -90,7 +102,64 @@
                 property.setAttribute("value", (String) properties.get(key));
                 config.addChild(property);
             }
+*/        }
+    }
+    
+    /**
+     * Loads resource configuration from a stream.
+     * @param in
+     * @throws Exception
+     */
+    public void load(InputStream in) throws Exception {
+        this.properties = new LinkedHashMap();
+        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(true);
+        DefaultConfiguration config = (DefaultConfiguration) builder.build(in);
+        Configuration rtiConfig = config.getChild("rti");
+        this.name = rtiConfig.getAttribute("name");
+        this.namespace = rtiConfig.getAttribute("namespace");
+        log.debug("Universal Name: " + getUniversalName());
+
+        // encoding seems to be a special case (?)
+        Configuration encodingConfig = config.getChild("encoding", false);
+        if (encodingConfig != null) encoding = encodingConfig.getValue();
+
+        LinkedHashMap listProperties = new LinkedHashMap();
+        
+        // read properties into a map of arraylists:
+        Configuration[] props = config.getChildren("property");
+        for (int i = 0; i < props.length; i++) {
+            String name = props[i].getAttribute("name");
+            String value = props[i].getAttribute("value");
+            if (listProperties.containsKey(name)) {
+                ArrayList arrayList = (ArrayList)listProperties.get(name);
+                arrayList.add(value);
+            } else {
+                ArrayList arrayList = new ArrayList();
+                arrayList.add(value);
+                listProperties.put(name, arrayList);
+            }
         }
+        
+        // now convert the arraylists with a single entry to normal properties:
+        Iterator iter = listProperties.keySet().iterator();
+        while (iter.hasNext()) {
+            String name = (String)iter.next();
+            ArrayList arrayList = (ArrayList)listProperties.get(name);
+            if (arrayList.size() == 1) {
+                this.properties.put(name, arrayList.get(0));
+            } else {
+                String[] values = (String[])arrayList.toArray(new String[arrayList.size()]);
+                this.properties.put(name, values);
+            }
+        }
+
+        // load custom config:
+        Configuration customConfig = config.getChild("custom-config", false);
+        if (customConfig != null) {
+            this.customConfig = ConfigurationUtil.getCustomConfiguration(customConfig, customConfig.getName(), 
+                customConfig.getNamespace());
+        }
+        
     }
     
     /**
@@ -104,86 +173,170 @@
      * Get resource type name
      */
     public String getName() {
-        return name;
+        return this.name;
     }
     
     /**
      * Get resource type namespace
      */
     public String getNamespace() {
-        return namespace;
+        return this.namespace;
     }
     
     /**
      * Get encoding respectively charset
      */
     public String getEncoding() {
-        return encoding;
+        return this.encoding;
     }
     
     /**
+     * Gets a property.
+     * If the property is multivalued, the first value will be returned.
      * @param key
      * @return value for this key or null if no value exists for this key.
      */
     public String getProperty(String key) throws Exception {
-        //return (String)properties.get(key);
-
-        if (config != null) {
-            Configuration[] props = config.getChildren("property");
-            for (int i = 0; i < props.length; i++) {
-                if (props[i].getAttribute("name") != null && props[i].getAttribute("name").equals(key)) {
-                    return props[i].getAttribute("value");
-                }
-            }
+        Object obj = this.properties.get(key);
+        if (obj instanceof String) {
+            return (String)obj; 
+        } else if (obj instanceof String[]) {
+            return ((String[])obj)[0];
+        } else {
+            return null;
         }
-        return null;
     }
     
     /**
+     * Sets a property.
+     * NOTE: does not save the configuration.
      * @param key
-     * @return value for this key or null if no value exists for this key.
+     * @param value
+     * @throws Exception
      */
+    public void setProperty(String key, String value) throws Exception {
+        this.properties.put(key, value);
+    }
+    
+    /**
+     * Gets a multivalued property.
+     * If the property is not multivalued, it will be return as an array of length one.
+     * @param key
+     * @return value for this key or empty array if no value exists for this key.
+     */
     public String[] getProperties(String key) throws Exception {
-        ArrayList properties = new ArrayList(); 
-        if (config != null) {
-            Configuration[] props = config.getChildren("property");
-            for (int i = 0; i < props.length; i++) {
-                if (props[i].getAttribute("name") != null && props[i].getAttribute("name").equals(key)) {
-                	properties.add(props[i].getAttribute("value"));
-                }
-            }
-            if (properties.size() < 1) return null; 
-            return (String[]) properties.toArray(new String[0]);
+        Object obj = this.properties.get(key);
+        if (obj instanceof String[]) {
+            return (String[])obj;
+        } else if (obj instanceof String) {
+            String[] array = new String[1];
+            array[0] = (String)obj;
+            return array;
+        } else {
+            return new String[0];
         }
-        return null;
     }
     
     /**
+     * Sets a multivalued property.
+     * NOTE: does not save the configuration.
+     * @param key
+     * @param values
+     * @throws Exception
+     */
+    public void setProperties(String key, String[] values) throws Exception {
+        this.properties.put(key, values);
+    }
+    
+    /**
      * Check if property exists
      */
     public boolean containsKey(String key) throws Exception {
-        //return properties.containsKey(key);
-        if (config != null) {
-            Configuration[] props = config.getChildren("property");
-            for (int i = 0; i < props.length; i++) {
-                if (props[i].getAttribute("name") != null && props[i].getAttribute("name").equals(key)) return true;
-            }
-        }
-        return false;
+        return properties.containsKey(key);
     }
 
     /**
      * Get yanel:custom-config. Returns null if resource config does not contain a custom-config element.
      */
-    public org.w3c.dom.Document getCustomConfiguration() {
-        Configuration customConfig = config.getChild("custom-config", false);
-        if (customConfig == null) return null;
-        try {
-            return ConfigurationUtil.getCustomConfiguration(customConfig, customConfig.getName(), 
-                customConfig.getNamespace());
-        } catch (ConfigurationException e) {
-            log.warn(e.getMessage(), e);
-            return null;
+    public Document getCustomConfiguration() {
+        return this.customConfig;
+    }
+    
+    /**
+     * Sets the custom config.
+     * NOTE: does not save the configuration.
+     * @param document dom document
+     */
+    public void setCustomConfiguration(Document document) {
+        this.customConfig = document;
+    }
+    
+    /**
+     * Saves the resource configuration to the yarep node.
+     */
+    public void save() throws Exception {
+        if (this.node == null) {
+            throw new Exception("cannot save resource configuration because the node is null.");
         }
+        String ns = "http://www.wyona.org/yanel/rti/1.0";
+        Document document;
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        DocumentBuilder parser = dbf.newDocumentBuilder();
+        DOMImplementation impl = parser.getDOMImplementation();
+        DocumentType doctype = null;
+        document = impl.createDocument(ns, "yanel:resource-config", doctype);
+
+        Element rootElement = document.getDocumentElement();
+        rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:yanel", ns);
+        
+        Element rtiElement = document.createElementNS(ns, "yanel:rti");
+        rtiElement.setAttribute("name", this.name);
+        rtiElement.setAttribute("namespace", this.namespace);
+        rootElement.appendChild(rtiElement);
+        
+        // add encoding:
+        if (this.encoding != null) {
+            Element encodingElement = document.createElementNS(ns, "yanel:encoding");
+            encodingElement.setNodeValue(this.encoding);
+            rootElement.appendChild(encodingElement);
+        }
+
+        // add properties:
+        Iterator keyIterator = properties.keySet().iterator();
+        while (keyIterator.hasNext()) {
+            String key = (String) keyIterator.next();
+            Object obj = properties.get(key);
+            if (obj instanceof String) {
+                Element property = document.createElementNS(ns, "yanel:property");
+                property.setAttribute("name", key);
+                property.setAttribute("value", (String) obj);
+                rootElement.appendChild(property);
+            } else if (obj instanceof String[]) {
+                String[] values = (String[])obj;
+                for (int i = 0; i < values.length; i++) {
+                    Element property = document.createElementNS(ns, "yanel:property");
+                    property.setAttribute("name", key);
+                    property.setAttribute("value", values[i]);
+                    rootElement.appendChild(property);
+                }
+            } 
+        }
+        
+        // add custom config:
+        if (this.customConfig != null) {
+            org.w3c.dom.Node customNode = document.importNode(this.customConfig.getDocumentElement(), true);
+            Element customElement = document.createElementNS(ns, "yanel:custom-config");
+            NodeList children = customNode.getChildNodes();
+            for (int i = 0; i < children.getLength(); i++) {
+                customElement.appendChild(children.item(i));
+            }
+            rootElement.appendChild(customElement);
+        }
+        
+        XMLSerializer serializer = new XMLSerializer();
+        serializer.setOutputByteStream(this.node.getOutputStream());
+        serializer.serialize(document);        
     }
+
 }

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceManager.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceManager.java	2007-11-09 13:44:31 UTC (rev 28723)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/ResourceManager.java	2007-11-09 13:44:53 UTC (rev 28724)
@@ -110,12 +110,12 @@
      * @param path Path relative to realm (e.g. yanel.getMap().getPath(realm, request.getServletPath()))
      */
     public Resource getResource(Environment environment, Realm realm, String path) throws Exception {
-        if (realm.getRTIRepository().exists(new Path(PathUtil.getRCPath(path)))) {
-            ResourceConfiguration rc = new ResourceConfiguration(realm.getRTIRepository().getInputStream(new Path(PathUtil.getRCPath(path))));
+        if (realm.getRTIRepository().existsNode(PathUtil.getRCPath(path))) {
+            ResourceConfiguration rc = new ResourceConfiguration(realm.getRTIRepository().getNode(PathUtil.getRCPath(path)));
             if (rc != null) return getResource(environment, realm, path, rc);
         }
 
-        if (realm.getRTIRepository().exists(new Path(PathUtil.getRTIPath(path)))) {
+        if (realm.getRTIRepository().existsNode(PathUtil.getRTIPath(path))) {
             // Fallback to deprecated RTI
             log.warn("DEPRECATED: RTI should be replaced by ResourceConfiguration: " + realm + ", " + path);
             ResourceTypeIdentifier rti = getResourceTypeIdentifier(realm, path);
@@ -124,8 +124,8 @@
         } 
 
         String rcPath = ResourceConfigurationMap.getRCPath(realm, path);
-        if (rcPath != null && realm.getRTIRepository().exists(new Path(rcPath))) {
-            ResourceConfiguration rc = new ResourceConfiguration(realm.getRTIRepository().getInputStream(new Path(ResourceConfigurationMap.getRCPath(realm, path))));
+        if (rcPath != null && realm.getRTIRepository().existsNode(rcPath)) {
+            ResourceConfiguration rc = new ResourceConfiguration(realm.getRTIRepository().getNode(ResourceConfigurationMap.getRCPath(realm, path)));
             if (rc != null) return getResource(environment, realm, path, rc);
         } 
         



More information about the Yanel-commits mailing list