001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.app.componentxml.propertypeer;
031:
032: import java.lang.reflect.InvocationTargetException;
033: import java.lang.reflect.Method;
034: import java.util.Iterator;
035:
036: import nextapp.echo2.app.LayoutData;
037: import nextapp.echo2.app.Style;
038: import nextapp.echo2.app.componentxml.ComponentIntrospector;
039: import nextapp.echo2.app.componentxml.ComponentXmlException;
040: import nextapp.echo2.app.componentxml.InvalidPropertyException;
041: import nextapp.echo2.app.componentxml.PropertyLoader;
042: import nextapp.echo2.app.componentxml.PropertyXmlPeer;
043: import nextapp.echo2.app.util.DomUtil;
044:
045: import org.w3c.dom.Element;
046:
047: /**
048: * <code>PropertyXmlPeer</code> implementation for
049: * <code>nextapp.echo2.app.LayoutData</code>-derived properties.
050: * <p>
051: * This peer will load properties for arbitrary <code>LayoutData</code>
052: * implementations using class introspection and reflection. The
053: * implementation does not currently support the setting of indexed
054: * properties.
055: */
056: public class LayoutDataPeer implements PropertyXmlPeer {
057:
058: /**
059: * @see nextapp.echo2.app.componentxml.PropertyXmlPeer#getValue(java.lang.ClassLoader,
060: * java.lang.Class, org.w3c.dom.Element)
061: */
062: public Object getValue(ClassLoader classLoader, Class objectClass,
063: Element propertyElement) throws InvalidPropertyException {
064: try {
065: Element layoutDataElement = DomUtil
066: .getChildElementByTagName(propertyElement,
067: "layout-data");
068: String type = layoutDataElement.getAttribute("type");
069:
070: // Load properties from XML into Style.
071: PropertyLoader propertyLoader = PropertyLoader
072: .forClassLoader(classLoader);
073: Element propertiesElement = DomUtil
074: .getChildElementByTagName(layoutDataElement,
075: "properties");
076: Style propertyStyle = propertyLoader.createStyle(
077: propertiesElement, type);
078:
079: // Instantiate LayoutData instance.
080: Class propertyClass = Class
081: .forName(type, true, classLoader);
082: LayoutData layoutData = (LayoutData) propertyClass
083: .newInstance();
084:
085: // Create introspector to analyze LayoutData class.
086: ComponentIntrospector ci = ComponentIntrospector.forName(
087: type, classLoader);
088:
089: // Set property values of LayoutData instance.
090: Iterator it = propertyStyle.getPropertyNames();
091: while (it.hasNext()) {
092: String propertyName = (String) it.next();
093: Method writeMethod = ci.getWriteMethod(propertyName);
094: writeMethod.invoke(layoutData,
095: new Object[] { propertyStyle
096: .getProperty(propertyName) });
097: }
098:
099: return layoutData;
100: } catch (ClassNotFoundException ex) {
101: throw new InvalidPropertyException(
102: "Unable to process properties.", ex);
103: } catch (ComponentXmlException ex) {
104: throw new InvalidPropertyException(
105: "Unable to process properties.", ex);
106: } catch (InstantiationException ex) {
107: throw new InvalidPropertyException(
108: "Unable to process properties.", ex);
109: } catch (IllegalAccessException ex) {
110: throw new InvalidPropertyException(
111: "Unable to process properties.", ex);
112: } catch (IllegalArgumentException ex) {
113: throw new InvalidPropertyException(
114: "Unable to process properties.", ex);
115: } catch (InvocationTargetException ex) {
116: throw new InvalidPropertyException(
117: "Unable to process properties.", ex);
118: }
119: }
120: }
|