KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nextapp > echo2 > app > componentxml > PropertyLoader


1 /*
2  * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3  * Copyright (C) 2002-2005 NextApp, Inc.
4  *
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * Alternatively, the contents of this file may be used under the terms of
18  * either the GNU General Public License Version 2 or later (the "GPL"), or
19  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20  * in which case the provisions of the GPL or the LGPL are applicable instead
21  * of those above. If you wish to allow use of your version of this file only
22  * under the terms of either the GPL or the LGPL, and not to allow others to
23  * use your version of this file under the terms of the MPL, indicate your
24  * decision by deleting the provisions above and replace them with the notice
25  * and other provisions required by the GPL or the LGPL. If you do not delete
26  * the provisions above, a recipient may use your version of this file under
27  * the terms of any one of the MPL, the GPL or the LGPL.
28  */

29
30 package nextapp.echo2.app.componentxml;
31
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import nextapp.echo2.app.MutableStyle;
36 import nextapp.echo2.app.Style;
37 import nextapp.echo2.app.util.DomUtil;
38 import nextapp.echo2.app.util.PeerFactory;
39
40 import org.w3c.dom.Element JavaDoc;
41
42 /**
43  * Parses "properties" <code>Element</code>s into maps associating property
44  * names with instantiated property values.
45  */

46 public class PropertyLoader {
47     
48     private static final String JavaDoc PROPERTY_XML_PEERS_PATH = "META-INF/nextapp/echo2/PropertyXmlPeers.properties";
49     
50     /**
51      * Map of <code>ClassLoader</code>s to <code>PropertyLoader</code>s.
52      */

53     private static final Map JavaDoc classLoaderToPropertyLoaderMap = new HashMap JavaDoc();
54     
55     /**
56      * Creates or retrieves a <code>PropertyLoader</code>.
57      *
58      * @param classLoader the <code>ClassLoader</code> to use for
59      * dynamically loading property classes
60      * @return the <code>PropertyLoader</code>
61      */

62     public static PropertyLoader forClassLoader(ClassLoader JavaDoc classLoader) {
63         synchronized(classLoaderToPropertyLoaderMap) {
64             PropertyLoader propertyLoader = (PropertyLoader) classLoaderToPropertyLoaderMap.get(classLoader);
65             if (propertyLoader == null) {
66                 propertyLoader = new PropertyLoader(classLoader);
67                 classLoaderToPropertyLoaderMap.put(classLoader, propertyLoader);
68             }
69             return propertyLoader;
70         }
71     }
72     
73     private ClassLoader JavaDoc classLoader;
74     private PeerFactory propertyXmlPeerFactory;
75     
76     /**
77      * Creates a new <code>PropertyLoader</code>.
78      *
79      * @param classLoader the <code>ClassLoader</code> to use for
80      * dynamically loading property classes
81      */

82     private PropertyLoader(ClassLoader JavaDoc classLoader) {
83         super();
84         this.classLoader = classLoader;
85         propertyXmlPeerFactory = new PeerFactory(PROPERTY_XML_PEERS_PATH, classLoader);
86     }
87     
88     /**
89      * Parses a "properties" <code>Element</code> and returns a
90      * <code>Style</code> mapping between property names and values.
91      *
92      * @param propertiesElement the properties <code>Element</code> to be
93      * parsed
94      * @param type the fully-qualified component type name
95      * @return a style representing the retrieved property names and values
96      * @throws ComponentXmlException
97      */

98     public Style createStyle(Element JavaDoc propertiesElement, String JavaDoc type)
99     throws ComponentXmlException {
100         MutableStyle propertyStyle = new MutableStyle();
101         
102         if (propertiesElement == null) {
103             // No properties.
104
return new MutableStyle();
105         }
106         
107         ComponentIntrospector ci;
108         try {
109             ci = ComponentIntrospector.forName(type, classLoader);
110         } catch (ClassNotFoundException JavaDoc ex) {
111             throw new ComponentXmlException("Unable to introspect component: " + type, ex);
112         }
113         
114         Element JavaDoc[] propertyElements = DomUtil.getChildElementsByTagName(propertiesElement, "property");
115         for (int i = 0; i < propertyElements.length; ++i) {
116             String JavaDoc propertyName = propertyElements[i].getAttribute("name");
117             Class JavaDoc propertyClass;
118             if (propertyElements[i].hasAttribute("type")) {
119                 try {
120                     propertyClass = Class.forName(propertyElements[i].getAttribute("type"));
121                 } catch (ClassNotFoundException JavaDoc ex) {
122                     throw new ComponentXmlException("Custom property class not found: "
123                             + propertyElements[i].getAttribute("type"), ex);
124                 }
125             } else {
126                 propertyClass = ci.getPropertyClass(propertyName);
127             }
128             
129             if (propertyClass == null) {
130                 throw new ComponentXmlException("Property does not exist: " + propertyName, null);
131             }
132             
133             Object JavaDoc propertyValue = getPropertyValue(ci.getObjectClass(), propertyClass, propertyElements[i]);
134             
135             if (ci.isIndexedProperty(propertyName)) {
136                 try {
137                     int index = Integer.parseInt(propertyElements[i].getAttribute("index"));
138                     propertyStyle.setIndexedProperty(propertyName, index, propertyValue);
139                 } catch (NumberFormatException JavaDoc ex) {
140                     throw new ComponentXmlException("Index not set.", ex);
141                 }
142             } else {
143                 propertyStyle.setProperty(propertyName, propertyValue);
144             }
145         }
146         
147         return propertyStyle;
148     }
149     
150     /**
151      * Retrieves a property value from an property element.
152      *
153      * @param objectClass the object containing the property
154      * @param propertyClass the class of the property
155      * @param propertyElement the property element to analyze
156      * @return the property value
157      * @throws InvalidPropertyException
158      */

159     public Object JavaDoc getPropertyValue(Class JavaDoc objectClass, Class JavaDoc propertyClass, Element JavaDoc propertyElement)
160     throws InvalidPropertyException {
161         PropertyXmlPeer propertyXmlPeer
162                = (PropertyXmlPeer) propertyXmlPeerFactory.getPeerForObject(propertyClass, false);
163         if (propertyXmlPeer == null) {
164             throw new InvalidPropertyException("Peer not found for property class: " + propertyClass, null);
165         }
166         Object JavaDoc propertyValue = propertyXmlPeer.getValue(classLoader, objectClass, propertyElement);
167         return propertyValue;
168     }
169
170     /**
171      * Returns the <code>PropertyXmlPeer</code> for the given property class.
172      *
173      * @param propertyClass the property class
174      * @return the XML parsing peer
175      */

176     public PropertyXmlPeer getPropertyXmlPeer(Class JavaDoc propertyClass) {
177         return (PropertyXmlPeer) propertyXmlPeerFactory.getPeerForObject(propertyClass, false);
178     }
179 }
180
Popular Tags