org.jfree.xml.generator.DefaultModelReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcommon Show documentation
Show all versions of jcommon Show documentation
JCommon is a free general purpose Java class library that is used in several projects at www.jfree.org, including JFreeChart and JFreeReport.
/* ========================================================================
* JCommon : a free general purpose class library for the Java(tm) platform
* ========================================================================
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------
* DefaultModelReader.java
* -----------------------
* (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
*
* Original Author: Thomas Morgner;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: DefaultModelReader.java,v 1.2 2005/10/18 13:32:20 mungady Exp $
*
* Changes
* -------
* 12-Nov-2003 : Initial version (TM);
* 26-Nov-2003 : Updated header and Javadocs (DG);
*
*/
package org.jfree.xml.generator;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import org.jfree.io.IOUtils;
import org.jfree.xml.generator.model.ClassDescription;
import org.jfree.xml.generator.model.Comments;
import org.jfree.xml.generator.model.DescriptionModel;
import org.jfree.xml.generator.model.IgnoredPropertyInfo;
import org.jfree.xml.generator.model.ManualMappingInfo;
import org.jfree.xml.generator.model.MultiplexMappingInfo;
import org.jfree.xml.generator.model.PropertyInfo;
import org.jfree.xml.generator.model.PropertyType;
import org.jfree.xml.generator.model.TypeInfo;
import org.jfree.xml.util.AbstractModelReader;
import org.jfree.xml.util.ObjectDescriptionException;
/**
* A reader for the class model.
*/
public class DefaultModelReader extends AbstractModelReader {
/** A model containing classes and the corresponding class descriptions. */
private DescriptionModel model;
/** The class description under construction. */
private ClassDescription currentClassDescription;
/** Information about the class being processed. */
private BeanInfo currentBeanInfo;
/** The base URL. */
private URL baseURL;
/** The source. */
private String source;
/** The multiplex mapping info. */
private MultiplexMappingInfo multiplexInfo;
/** The multiplex type info.*/
private ArrayList multiplexTypeInfos;
/** Storage for the properties of the current class. */
private ArrayList propertyList;
/** Storage for the constructors of the current class. */
private ArrayList constructorList;
/**
* Creates a new model reader.
*/
public DefaultModelReader() {
super();
}
/**
* Loads a description model.
*
* @param file the file name.
*
* @return A description model.
*
* @throws IOException if there is an I/O problem.
* @throws ObjectDescriptionException if there is a problem reading the object descriptions.
*/
public synchronized DescriptionModel load(final String file) throws IOException,
ObjectDescriptionException {
this.model = new DescriptionModel();
this.baseURL = new File (file).toURL();
parseXml(this.baseURL);
fillSuperClasses();
return this.model;
}
/**
* Iterates through all the class descriptions in the model, setting the superclass
* attribute in all cases where the superclass definitions are contained in the model.
*/
protected void fillSuperClasses() {
for (int i = 0; i < this.model.size(); i++) {
final ClassDescription cd = this.model.get(i);
final Class parent = cd.getObjectClass().getSuperclass();
if (parent == null) {
continue;
}
final ClassDescription superCD = this.model.get(parent);
if (superCD != null) {
cd.setSuperClass(superCD.getObjectClass());
}
}
}
/**
* Begin processing an object definition element.
*
* @param className the class name.
* @param register the register name (null
permitted).
* @param ignore ??
*
* @return true
if the class is available, and false
otherwise.
*/
protected boolean startObjectDefinition(final String className, final String register, final boolean ignore) {
final Class c = loadClass(className);
if (c == null) {
return false;
}
this.currentClassDescription = new ClassDescription(c);
this.currentClassDescription.setPreserve(ignore);
this.currentClassDescription.setRegisterKey(register);
try {
this.currentBeanInfo = Introspector.getBeanInfo(c, Object.class);
}
catch (IntrospectionException ie) {
return false;
}
this.propertyList = new java.util.ArrayList();
this.constructorList = new java.util.ArrayList();
return true;
}
/**
* Finishes processing an object definition (sets the constructor and property info for the
* class description, and adds the class description to the model).
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void endObjectDefinition() throws ObjectDescriptionException {
final PropertyInfo[] pis = (PropertyInfo[])
this.propertyList.toArray(new PropertyInfo[this.propertyList.size()]);
this.currentClassDescription.setProperties(pis);
final TypeInfo[] tis = (TypeInfo[])
this.constructorList.toArray(new TypeInfo[this.constructorList.size()]);
this.currentClassDescription.setConstructorDescription(tis);
this.currentClassDescription.setComments
(new Comments(getOpenComment(), getCloseComment()));
this.currentClassDescription.setSource(this.source);
this.model.addClassDescription(this.currentClassDescription);
this.propertyList = null;
this.currentBeanInfo = null;
this.currentClassDescription = null;
}
/**
* Handles the description of an attribute within an object definition.
*
* @param name the name.
* @param attribName the attribute name.
* @param handlerClass the fully qualified class name for the attribute handler.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void handleAttributeDefinition(final String name, final String attribName, final String handlerClass)
throws ObjectDescriptionException {
final PropertyInfo propertyInfo = ModelBuilder.getInstance().createSimplePropertyInfo
(getPropertyDescriptor(name));
if (propertyInfo == null) {
throw new ObjectDescriptionException("Unable to load property " + name);
}
propertyInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
propertyInfo.setPropertyType(PropertyType.ATTRIBUTE);
propertyInfo.setXmlName(attribName);
propertyInfo.setXmlHandler(handlerClass);
this.propertyList.add(propertyInfo);
}
/**
* Handles the constructor definition.
*
* @param tagName the tag name.
* @param parameterClass the parameter class.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void handleConstructorDefinition(final String tagName, final String parameterClass)
throws ObjectDescriptionException {
final Class c = loadClass(parameterClass);
if (c == null) {
throw new ObjectDescriptionException("Failed to load class " + parameterClass);
}
final TypeInfo ti = new TypeInfo(tagName, c);
ti.setComments(new Comments(getOpenComment(), getCloseComment()));
this.constructorList.add (ti);
}
/**
* Handles the description of an element within an object definition.
*
* @param name the property name.
* @param element the element name.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void handleElementDefinition(final String name, final String element)
throws ObjectDescriptionException {
final PropertyInfo propertyInfo = ModelBuilder.getInstance().createSimplePropertyInfo
(getPropertyDescriptor(name));
if (propertyInfo == null) {
throw new ObjectDescriptionException("Unable to load property " + name);
}
propertyInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
propertyInfo.setPropertyType(PropertyType.ELEMENT);
propertyInfo.setXmlName(element);
propertyInfo.setXmlHandler(null);
this.propertyList.add(propertyInfo);
}
/**
* Handles a lookup definition.
*
* @param name the name.
* @param lookupKey the lookup key.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void handleLookupDefinition(final String name, final String lookupKey)
throws ObjectDescriptionException {
final PropertyInfo propertyInfo = ModelBuilder.getInstance().createSimplePropertyInfo
(getPropertyDescriptor(name));
if (propertyInfo == null) {
throw new ObjectDescriptionException("Unable to load property " + name);
}
propertyInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
propertyInfo.setPropertyType(PropertyType.LOOKUP);
propertyInfo.setXmlName(lookupKey);
propertyInfo.setXmlHandler(null);
this.propertyList.add(propertyInfo);
}
/**
* Returns a property descriptor for the named property, or null
if there is
* no descriptor with the given name.
*
* @param propertyName the property name.
*
* @return a property descriptor.
*/
protected PropertyDescriptor getPropertyDescriptor(final String propertyName) {
final PropertyDescriptor[] pds = this.currentBeanInfo.getPropertyDescriptors();
for (int i = 0; i < pds.length; i++) {
if (pds[i].getName().equals(propertyName)) {
return pds[i];
}
}
return null;
}
/**
* Handles an ignored property.
*
* @param name the name.
*/
protected void handleIgnoredProperty(final String name) {
final IgnoredPropertyInfo propertyInfo = new IgnoredPropertyInfo(name);
propertyInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
this.propertyList.add(propertyInfo);
}
/**
* Handles a manual mapping.
*
* @param className the class name.
* @param readHandler the read handler.
* @param writeHandler the write handler.
*
* @return A boolean.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected boolean handleManualMapping(final String className, final String readHandler, final String writeHandler)
throws ObjectDescriptionException {
final ManualMappingInfo manualMappingInfo =
new ManualMappingInfo(loadClass(className),
loadClass(readHandler), loadClass(writeHandler));
manualMappingInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
manualMappingInfo.setSource(this.source);
this.model.getMappingModel().addManualMapping(manualMappingInfo);
return true;
}
/**
* Start a multiplex mapping.
*
* @param className the class name.
* @param typeAttr the type.
*/
protected void startMultiplexMapping(final String className, final String typeAttr) {
this.multiplexInfo = new MultiplexMappingInfo(loadClass(className), typeAttr);
this.multiplexInfo.setSource(this.source);
this.multiplexTypeInfos = new ArrayList();
}
/**
* Handles a multiplex mapping.
*
* @param typeName the type name.
* @param className the class name.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void handleMultiplexMapping(final String typeName, final String className)
throws ObjectDescriptionException {
final TypeInfo info = new TypeInfo(typeName, loadClass(className));
info.setComments(new Comments(getOpenComment(), getCloseComment()));
this.multiplexTypeInfos.add (info);
}
/**
* Ends a multiplex mapping.
*
* @throws ObjectDescriptionException if there is a problem with the object description.
*/
protected void endMultiplexMapping() throws ObjectDescriptionException {
final TypeInfo[] typeInfos = (TypeInfo[]) this.multiplexTypeInfos.toArray(
new TypeInfo[this.multiplexTypeInfos.size()]
);
this.multiplexInfo.setComments(new Comments(getOpenComment(), getCloseComment()));
this.multiplexInfo.setChildClasses(typeInfos);
this.model.getMappingModel().addMultiplexMapping(this.multiplexInfo);
this.multiplexInfo = null;
}
/**
* Starts include handling.
*
* @param resource the URL.
*/
protected void startIncludeHandling(final URL resource) {
this.source = IOUtils.getInstance().createRelativeURL(resource, this.baseURL);
this.model.addSource(this.source);
this.model.addIncludeComment(
this.source, new Comments(getOpenComment(), getCloseComment())
);
}
/**
* Ends include handling.
*/
protected void endIncludeHandling() {
this.source = "";
}
/**
* Starts the root document.
*/
protected void startRootDocument() {
this.source = "";
}
/**
* Ends the root document.
*/
protected void endRootDocument() {
this.model.setModelComments(new Comments(getOpenComment(), getCloseComment()));
}
}