
com.draagon.meta.loader.xml.XMLFileMetaDataLoader Maven / Gradle / Ivy
/*
* Copyright 2003 Draagon Software LLC. All Rights Reserved.
*
* This software is the proprietary information of Draagon Software LLC.
* Use is subject to license terms.
*/
package com.draagon.meta.loader.xml;
import com.draagon.meta.attr.MetaAttribute;
import com.draagon.meta.validator.MetaValidator;
import com.draagon.meta.field.MetaField;
import com.draagon.meta.view.MetaView;
import com.draagon.meta.object.MetaObjectNotFoundException;
import com.draagon.meta.object.MetaObject;
import com.draagon.meta.*;
import com.draagon.meta.attr.StringAttribute;
import com.draagon.meta.loader.MetaDataLoader;
//import com.draagon.util.InitializationException;
import com.draagon.util.xml.XMLFileReader;
import java.util.Hashtable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.OperationNotSupportedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.CharacterData;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
//import org.xml.sax.InputSource;
//import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
/**
* Meta Class loader for XML files
*/
public class XMLFileMetaDataLoader extends MetaDataLoader {
private static final long serialVersionUID = 6952160679341572048L;
private static Log log = LogFactory.getLog(XMLFileMetaDataLoader.class);
public final static String ATTR_NAME = "name";
public final static String ATTR_TYPE = "type";
public final static String ATTR_SUPER = "super";
private static List reservedAttributes = new ArrayList();
static {
reservedAttributes.add( ATTR_NAME );
reservedAttributes.add( ATTR_TYPE );
reservedAttributes.add( ATTR_SUPER );
}
/** Used to store the MetaData types and respective Java classes */
public static class MetaDataTypes {
public final Class extends MetaData> baseClass;
private final Map> classes = new HashMap>();
public MetaDataTypes( Class extends MetaData> baseClass ) {
this.baseClass = baseClass;
}
public void put( String name, Class extends MetaData> clazz ) {
classes.put( name, clazz );
}
public Class extends MetaData> get( String name ) {
return classes.get( name );
}
}
private String typesRef = null;
private boolean typesLoaded = false;
private final ConcurrentHashMap typesMap = new ConcurrentHashMap();
private final List sources = new ArrayList();
public XMLFileMetaDataLoader() {
}
/*public void setSourcePaths(List sourcePaths) {
// TODO: Read all XML files in the path
//this.sources = sources;
}*/
public void setSource( String source ) {
this.sources.add( source );
}
public void setSources(List sources) {
this.sources.addAll( sources );
}
public List getSources() {
return sources;
}
public void setTypesRef(String types) {
if ( types.isEmpty() ) types = null;
typesRef = types;
}
public String getTypesRef() {
return typesRef;
}
@Override
public void init() {
if (getSources() == null) {
throw new IllegalStateException("No Metadata Sources defined");
}
super.init();
try {
if ( !typesLoaded && getTypesRef() != null ) {
loadTypesFromFile( getTypesRef() );
}
} catch (MetaException e) {
log.error("Could not load metadata types [" + getTypesRef() + "]: " + e.getMessage());
throw new IllegalStateException("Could not load metadata types [" + getTypesRef() + "]", e);
}
// Load all the Meta sources
for (Iterator i = sources.iterator(); i.hasNext();) {
String source = i.next();
//try {
loadFromFile(source);
//} catch (MetaException e) {
//log.error("Initialization of MetaClassLoader [" + source + "] failed: " + e.getMessage());
//throw new IllegalStateException("Initialization of MetaClassLoader [" + source + "] failed: " + e.getMessage(), e);
//}
}
}
/**
* Loads the specified resource
*/
public void loadTypesFromFile(String file) {
// LOAD THE TYPES XML FILE
if (file == null) {
throw new IllegalArgumentException( "The Types XML reference file was not specified" );
}
InputStream is = null;
File f = new File(file);
if (f.exists()) {
try {
is = new FileInputStream(f);
} catch (Exception e) {
log.error("Can not read Types XML file [" + file + "]: " + e.getMessage());
throw new MetaException("Can not read Types XML file [" + file + "]: " + e.getMessage(), e);
}
} else {
is = getClass().getClassLoader().getResourceAsStream(file);
if (is == null) {
log.error("Types XML file [" + file + "] does not exist");
throw new MetaException("The Types XML item file [" + file + "] was not found");
}
}
try {
loadTypesFromStream(is);
} catch (MetaException e) {
log.error("Meta Types XML [" + file + "]: " + e.getMessage());
throw new MetaException("The Types XML file [ " + file + "] could not be loaded: " + e.getMessage(), e);
}
typesLoaded = true;
}
/**
* Loads all the classes specified in the Filename
*/
public void loadTypesFromStream(InputStream is) {
Document doc = null;
try {
doc = XMLFileReader.loadFromStream(is);
} catch (IOException e) {
log.error("IO Error loading Types XML: " + e.getMessage());
throw new MetaException("IO Error loading Types XML: " + e.getMessage(), e);
} finally {
try {
is.close();
} catch (Exception e) {
}
}
//////////////////////////////////////////////////////
// PARSE THE TYPES XML
try {
// Look for the element
Collection elements = getElementsOfName(doc, "types");
if (elements.isEmpty()) {
throw new MetaException("The root 'types' element was not found");
}
Element el = elements.iterator().next();
loadAllTypes(el);
} catch (SAXException e) {
throw new MetaException("Parse error loading MetaClasses: " + e.getMessage(), e);
}
}
/**
* Gets all elements within that have a sub element
*/
private List getElementsWithType( Element n ) {
List elements = new ArrayList();
// Get the elements under
NodeList list = n.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node instanceof Element) {
// Look for a sub element with
NodeList list2 = node.getChildNodes();
for (int i2 = 0; i2 < list2.getLength(); i2++) {
Node node2 = list2.item(i2);
if (node2 instanceof Element
&& node2.getNodeName().equals( ATTR_TYPE )) {
// A element was found, so add this name
elements.add( (Element) node );
break;
}
}
}
}
return elements;
}
/**
* Loads the specified group types
*/
protected synchronized void loadAllTypes(Element el) throws MetaException, SAXException {
// Get all elements that have elements
for( Element e : getElementsWithType( el )) {
String name = e.getNodeName();
// Get the MetaDataTypes with the specified element name
MetaDataTypes mdts = typesMap.get( name );
// If it doesn't exist, then create it and check for the "class" attribute
if ( mdts == null ) {
// Get the base class for the given element
String clazz = e.getAttribute( "class" );
if ( clazz == null || clazz.isEmpty() ) {
throw new MetaException( "Element section [" + name + "] has no 'class' attribute specified");
}
try {
Class extends MetaData> baseClass = (Class extends MetaData>) Class.forName(clazz);
// Create a new MetaDataTypes and add to the mapping
mdts = new MetaDataTypes( baseClass );
typesMap.put( name, mdts );
}
catch( ClassNotFoundException ex ) {
throw new MetaException( "Element section [" + name + "] has an invalid 'class' attribute: " + ex.getMessage(), ex );
}
}
// Load all the types for the specific element type
loadTypes( e, mdts );
}
}
/**
* Loads the specified group types
*/
protected void loadTypes(Element el, MetaDataTypes typesMap)
throws MetaException, SAXException {
String section = el.getNodeName();
//Collection c = getElementsOfName(root, section);
// Iterate through each section grouping (should just be 1)
//for (Element el : c) {
Collection typeCol = getElementsOfName(el, "type");
// Iterate through each type
for (Element typeEl : typeCol) {
String name = typeEl.getAttribute(ATTR_NAME);
String tclass = typeEl.getAttribute("class");
if (name.length() == 0) {
throw new MetaException("Type of section [" + section + "] has no 'name' attribute specified");
}
try {
Class tcl = (Class) Class.forName(tclass);
// Add the type class with the specified name
typesMap.put(name, tcl);
}
catch (ClassNotFoundException e) {
throw new MetaException("Type of section [" + section + "] with name [" + name + "] has invalid class: " + e.getMessage());
//log.warn( "Type of section [" + section + "] with name [" + name + "] has unknown class: " + e.getMessage() );
}
}
//}
}
/**
* Loads all the classes specified in the Filename
*/
public void loadFromFile(String file) throws MetaException {
// LOAD THE XML FILE
if (file == null) {
throw new MetaException("The Meta XML file was not specified");
}
InputStream is = null;
File f = new File(file);
if (f.exists()) {
try {
is = new FileInputStream(f);
} catch (Exception e) {
log.error("Can not read Meta XML file [" + file + "]: " + e.getMessage());
throw new MetaException("Can not read Meta XML file [" + file + "]", e);
}
}
else {
is = getClass().getClassLoader().getResourceAsStream(file);
if (is == null) {
log.error("Meta XML file [" + file + "] does not exist");
throw new MetaException("The Meta XML item file [" + file + "] was not found");
}
}
try {
loadFromStream(is);
}
catch (MetaException e) {
//log.error("Meta XML file [" + file + "]: " + e.getMessage());
throw new MetaException("The Meta XML file [" + file + "] could not be loaded: " + e.getMessage(), e);
}
//catch (MetaDataException e) {
// log.error("Meta XML file [" + file + "]: " + e.getMessage());
// throw new MetaException("The Meta XML file [ " + file + "] could not be loaded: " + e.getMessage(), e);
//}
}
/**
* Loads all the classes specified in the Filename
*/
public void loadFromStream(InputStream is) throws MetaException {
Document doc = null;
try {
doc = XMLFileReader.loadFromStream(is);
}
catch (IOException e) {
log.error("IO Error loading Meta XML: " + e.getMessage());
throw new MetaException("IO Error loading Meta XML: " + e.getMessage(), e);
}
finally {
try {
is.close();
} catch (Exception e) {
}
}
////////////////////////////////////////////////////////
// LOAD DEFAULT TYPES
// If no types found, then load the default types
if (!typesLoaded) {
loadTypesFromFile("com/draagon/meta/loader/meta.types.xml");
}
//////////////////////////////////////////////////////
// PARSE THE ITEMS XML BLOCK
try {
// Look for the element
Collection elements = getElementsOfName(doc, "metadata");
if (elements.isEmpty()) {
throw new MetaException("The root 'meta' element was not found");
}
Element itemdocElement = elements.iterator().next();
String defaultPackageName = itemdocElement.getAttribute("package");
if (defaultPackageName == null || defaultPackageName.trim().length() == 0) {
defaultPackageName = "";
}
//throw new MetaException( "The Meta XML had no 'package' attribute defined" );
// Load the types
String types = itemdocElement.getAttribute("types");
if (types != null && types.length() > 0) {
loadTypesFromFile(types);
}
// Load any types specified in the Metadata XML
try {
// Look for the element
Collection typeElements = getElementsOfName(itemdocElement, "types");
if (typeElements.size() > 0) {
Element typeEl = typeElements.iterator().next();
String typeFile = typeEl.getAttribute("file");
if (typeFile.length() > 0) {
loadTypesFromFile(typeFile);
} else {
loadAllTypes(typeEl); // Load inner tags
}
}
} catch (SAXException e) {
throw new MetaException("Parse error loading MetaClasses: " + e.getMessage(), e);
}
// Parse the metadata elements
parseMetaData( defaultPackageName, this, itemdocElement, true );
}
catch (SAXException e) {
throw new MetaException("Parse error loading MetaClasses: " + e.getMessage(), e);
}
}
protected void parseMetaData(String defaultPackageName, MetaData parent, Element element, boolean isRoot ) throws SAXException {
// Iterate through all elements
for ( Element el : getElements( element )) {
// Get the MetaDataTypes map for this element
MetaDataTypes types = typesMap.get( el.getNodeName() );
if ( types == null ) {
// TODO: What is the best behavior here?
log.warn( "Ignoring '" + el.getNodeName() + "' element found on parent: " + parent );
continue;
}
// Get the item name
String name = el.getAttribute(ATTR_NAME);
if (name == null || name.equals("")) {
throw new MetaException("MetaClass had no name specfied in XML");
}
// Get the packaging name
String packageName = el.getAttribute("package");
if (packageName == null || packageName.trim().length() == 0) {
packageName = defaultPackageName;
}
// Load or get the MetaData
MetaData md = null;
boolean isNew = false;
try {
if ( isRoot && packageName.length() > 0 ) {
md = parent.getChild( packageName + PKG_SEPARATOR + name, types.baseClass );
} else {
md = parent.getChild( name, types.baseClass );
// If it's not a child from the same parent, we need to wrap it
if ( md.getParent() != parent ) {
md = md.wrap();
isNew = true;
}
}
} catch (MetaDataNotFoundException e) {
}
// If this MetaData doesn't exist yet, then we need to create it
if (md == null) {
isNew = true;
// Set the SuperClass if one is defined
MetaData superData = null;
String superStr = el.getAttribute(ATTR_SUPER);
// If a super class was specified
if (superStr.length() > 0) {
// Try to find it with the name prepended if not fully qualified
try {
if (superStr.indexOf(PKG_SEPARATOR) < 0 && packageName.length() > 0) {
superData = getMetaDataByName( types.baseClass, packageName + PKG_SEPARATOR + superStr );
}
} catch (MetaObjectNotFoundException e) {
log.debug( "Could not find MetaClass [" + packageName + MetaObject.SEPARATOR + superStr + "], assuming fully qualified" );
}
// Try to find it by the provided name in the 'super' attribute
if (superData == null) {
try {
superData = getMetaDataByName( types.baseClass, superStr );
} catch (MetaObjectNotFoundException e) {
log.error("Invalid MetaClass [" + md + "], the SuperClass [" + superStr + "] does not exist");
throw new MetaException("Invalid MetaClass [" + md + "], the SuperClass [" + superStr + "] does not exist");
}
}
}
// Check to make sure people arent' defining attributes when it shouldn't
else {
String s = el.getAttribute(ATTR_SUPER);
if ( s == null || s.isEmpty() ) {
log.warn( "Attribute 'super' defined on metadata '" + name + "' under parent [" + parent + "], but should not be as metadata with that name already existed" );
}
}
// get the class reference and create the class
String typeName = el.getAttribute(ATTR_TYPE);
if ( typeName.isEmpty() ) typeName = null;
Class> c = null;
try {
// Attempt to load the referenced class
if (typeName == null ) {
// Use the Super class type if no type is defined and a super class exists
if (superData != null) {
c = superData.getClass();
}
// Default to StringAttribute if no type is defined for a MetaAttribute
else if ( types.baseClass.isAssignableFrom( MetaAttribute.class )) {
c = StringAttribute.class;
}
// Otherwise throw an error
else {
throw new MetaException("MetaClass [" + name + "] has no type defined");
}
}
else {
c = (Class extends MetaData>) types.get(typeName);
if (c == null) {
throw new MetaException("MetaClass type [" + typeName + "] was not recognized");
}
}
// Figure out the full name for the element, needs package prefix if root
String fullname = name;
if ( isRoot ) fullname = packageName + PKG_SEPARATOR + fullname;
// Create the object
md = (MetaData) c.getConstructor(String.class).newInstance( fullname );
//mc = (MetaClass) c.newInstance();
}
catch (MetaException e) {
throw e;
}
catch (Exception e) {
log.error("Invalid MetaClass [" + c.getName() + "]: " + e.getMessage());
throw new MetaException("Invalid MetaClass [" + c.getName() + "]", e);
}
// Set the name and package name
//mc.setName( packageName + MetaClass.SEPARATOR + name );
//mc.setPackage( packageName );
// Set the super data class if one exists
if ( superData != null ) {
md.setSuperData(superData);
}
}
// Parse and set the Attributes
//Collection attrs = parseAttributes(el);
//for (Iterator j = attrs.iterator(); j.hasNext();) {
// md.addAttribute(j.next());
//}
// Parse the fields
//parseFields(md, el);
// Add the MetaClass to the loader
// NOTE: Add it first to ensure the correct parent is set
if (isNew) {
parent.addChild(md);
}
// Different behavior if it's a MetaAttribute
if ( md instanceof MetaAttribute ) {
parseMetaAttributeValue( (MetaAttribute) md, el );
}
// otherwide, parse as normal recursively
else {
// Parse any extra attributes
parseAttributes( md, el );
// Parse the sub elements
parseMetaData( packageName, md, el, false );
}
}
}
/**
* Parses actual element attributes and adds them as StringAttributes
*/
protected void parseAttributes( MetaData md, Element el ) {
NamedNodeMap attrs = el.getAttributes();
for( int i = 0; i < attrs.getLength(); i++ ) {
Node n = attrs.item( i );
String attrName = n.getNodeName();
if ( !reservedAttributes.contains( attrName )) {
String value = n.getNodeValue();
md.addAttribute( new StringAttribute(attrName, value ));
}
}
}
/**
* Parse the MetaAttribute Value
*/
protected void parseMetaAttributeValue( MetaAttribute attr, Element el ) {
///////////////////////////////////////////////////
// Get the Node value
// Get the first node
Node nv = el.getFirstChild();
// Loop through and ignore the comments
while (nv != null && nv.getNodeType() == Node.COMMENT_NODE) {
nv.getNextSibling();
}
// If a valid node exists, then get the data
if (nv != null) {
switch (nv.getNodeType()) {
// If CDATA just set the whole thing
case Node.CDATA_SECTION_NODE:
attr.setValueAsString(((CharacterData) nv).getData());
break;
// If an Element just pass it in for parsing
case Node.ELEMENT_NODE:
attr.setValue(nv);
break;
// If just text, then pass it in
case Node.TEXT_NODE:
attr.setValueAsString(nv.getNodeValue());
break;
default:
log.warn("Unsupported Node Type for node [" + nv + "]");
}
}
}
/*protected void parseClasses(String defaultPackageName, Element element) throws MetaException, SAXException {
for (Element itemElement : getElementsOfNames(element, new String[]{"metaclass", "class"})) {
// get the item name
String name = itemElement.getAttribute(ATTR_NAME);
if (name == null || name.equals("")) {
throw new MetaException("MetaClass had no name specfied in XML");
}
String packageName = itemElement.getAttribute("package");
if (packageName == null || packageName.trim().length() == 0) {
packageName = defaultPackageName;
}
// Load or get the MetaClass
MetaObject mc = null;
boolean isNewClass = false;
try {
if (packageName.length() > 0) {
mc = getMetaData(packageName + MetaObject.SEPARATOR + name);
} else {
mc = getMetaData(name);
}
} catch (MetaObjectNotFoundException e) {
}
if (mc == null) {
isNewClass = true;
// Set the SuperClass if one is defined
MetaObject superClass = null;
String superStr = itemElement.getAttribute(ATTR_SUPER);
// If a super class was specified
if (superStr.length() > 0) {
// Try to find it with the name prepended if not fully qualified
try {
if (superStr.indexOf(MetaObject.SEPARATOR) < 0 && packageName.length() > 0) {
superClass = getMetaData(packageName + MetaObject.SEPARATOR + superStr);
}
} catch (MetaObjectNotFoundException e) {
log.debug("Could not find MetaClass [" + packageName + MetaObject.SEPARATOR + superStr + "], assuming fully qualified");
}
if (superClass == null) {
try {
superClass = getMetaData(superStr);
} catch (MetaObjectNotFoundException e) {
log.error("Invalid MetaClass [" + mc + "], the SuperClass [" + superStr + "] does not exist");
throw new MetaException("Invalid MetaClass [" + mc + "], the SuperClass [" + superStr + "] does not exist");
}
}
}
// get the class reference and create the class
String typeName = itemElement.getAttribute(ATTR_TYPE);
Class> c = null;
try {
// Attempt to load the referenced class
if (typeName.equals("")) {
if (superClass != null) {
c = superClass.getClass();
} else //c = BeanMetaClass.class;
{
throw new MetaException("MetaClass [" + name + "] has no type defined");
}
} else {
c = (Class>) mClassTypes.get(typeName);
if (c == null) {
throw new MetaException("MetaClass type [" + typeName + "] was not recognized");
}
}
mc = (MetaObject) c.getConstructor(String.class).newInstance(packageName + MetaObject.SEPARATOR + name);
//mc = (MetaClass) c.newInstance();
} catch (MetaException e) {
throw e;
} catch (Exception e) {
log.error("Invalid MetaClass [" + c.getName() + "]: " + e.getMessage());
throw new MetaException("Invalid MetaClass [" + c.getName() + "]", e);
}
// Set the name and package name
//mc.setName( packageName + MetaClass.SEPARATOR + name );
//mc.setPackage( packageName );
mc.setSuperClass(superClass);
}
// Parse and set the Attributes
Collection attrs = parseAttributes(itemElement);
for (Iterator j = attrs.iterator(); j.hasNext();) {
mc.addAttribute(j.next());
}
// Parse the fields
parseFields(mc, itemElement);
// Get the default view settings
Collection def_views = parseViews(name, itemElement, null);
// If not views were defined, then use the default views
if (def_views.size() > 0) {
for (MetaField f : mc.getMetaFields()) {
for (MetaView v : def_views) {
if (!f.hasView(v.getName())) {
f.addMetaView((MetaView) v.clone());
}
}
}
}
// Add the MetaClass to the loader
if (isNewClass) {
addMetaClass(mc);
}
}
}
protected void parseFields(MetaObject mc, Element e) throws MetaException, SAXException {
for (Element fieldElement : getElementsOfNames(e, new String[]{"metafield", "field"})) {
String name = fieldElement.getAttribute(ATTR_NAME);
String type = fieldElement.getAttribute(ATTR_TYPE);
String def = fieldElement.getAttribute("default");
//int type = 0;
// Get the field name
if (name == null || name.equals("")) {
throw new MetaException("Field in MetaClass [" + mc + "] had no name");
}
MetaField field = null;
boolean isNewField = false;
Class> classType = null;
// If the type is defined, then load the class
if (!type.equals("")) {
classType = mFieldTypes.get(type);
if (classType == null) {
throw new MetaException("MetaField [" + name + "] has type [" + type + "] that is not recognized");
}
}
// If a field with that name exists, then load it
if (mc.hasMetaField(name)) {
field = mc.getMetaField(name);
}
// If there is no type or validator, then throw an exception
if (classType == null && field == null) {
throw new MetaException("MetaField [" + name + "] of MetaClass [" + mc + "] had no type");
}
// If the field exists and is of the same class, then wrap it
if (field != null
&& (field.getClass() == classType || classType == null)) {
if (field.getDeclaringMetaClass() != mc) {
field = (MetaField) field.wrap();
isNewField = true;
}
} // Otherwise, create a new field
else {
if (field != null) {
throw new MetaException("MetaField [" + name + "] of MetaClass [" + mc + "] is already defined as type [" + field.getClass() + "]");
}
try {
field = (MetaField) classType.getConstructor(String.class).newInstance(name);
//field.setName( name );
isNewField = true;
} catch (Exception ex) {
throw new RuntimeException("Instantiation exception creating new MetaField of Class [" + classType + "]", ex);
}
}
// Parse and set the Attributes
Collection attrs = parseAttributes(fieldElement);
for (Iterator a = attrs.iterator(); a.hasNext();) {
field.addAttribute(a.next());
}
// Parse the Views
for (MetaView tv : parseViews(name + "@" + mc.getName(), fieldElement, field)) {
if (!field.hasView(tv.getName()) || tv.getDeclaringMetaField() != field) {
field.addMetaView(tv);
}
//ystem.out.println( "VIEW: " + tv );
}
// Add the Validators
for (MetaValidator tv : parseValidators(name + "@" + mc.getName(), fieldElement, field)) {
if (!field.hasValidator(tv.getName())) {
field.addMetaValidator(tv);
}
}
// Set the default value
if (def != null && def.length() > 0) {
field.setDefaultValue(def);
}
// If it's a new field, then add it
if (isNewField) {
mc.addMetaField(field);
}
}
}
protected Collection parseViews(String parent, Element e, MetaField mf)
throws MetaException, SAXException {
try {
Class.forName("com.draagon.web.meta.view.WebView");
} catch (ClassNotFoundException cnfe) {
// The meta-web package is missing, so assume EJB server mode
log.debug("No WebView found, assuming server-side installation");
return new ArrayList();
}
ArrayList vv = new ArrayList();
for (Element viewElement : getElementsOfNames(e, new String[]{"metaview", "view"})) {
String vname = viewElement.getAttribute(ATTR_NAME);
String vtype = viewElement.getAttribute(ATTR_TYPE);
if (vname.equals("")) {
throw new MetaException("View Element [" + e.getNodeName() + "] had no name defined");
}
if (vtype.equals("")) {
throw new MetaException("MetaView [" + vname + "] of [" + parent + "] had no type defined");
}
MetaView view = null;
boolean isNewView = false;
Class> classType = null;
// If the type is defined, then load the class
if (!vtype.equals("")) {
classType = mViewTypes.get(vtype);
if (classType == null) {
log.warn("MetaView [" + vname + "] of [" + parent + "] has type [" + vtype + "] that is not recognized");
//throw new MetaException( "MetaValidator [" + name + "] of [" + parent + "] has type [" + type+ "] that is not recognized" );
continue;
}
}
// If a view with that name exists, then load it
if (mf != null && mf.hasView(vname) && classType == null) {
view = mf.getView(vname);
}
// If there is no type or validator, then throw an exception
if (classType == null && view == null) {
throw new MetaException("View [" + vname + "] MetaField [" + mf + "] had no type");
}
// If the validator exists and is of the same class, then wrap it
if (view != null
&& (view.getClass() == classType || classType == null)) {
if (view.getDeclaringMetaField() != mf) {
view = (MetaView) view.wrap();
isNewView = true;
}
} // Otherwise, create a new view
else {
try {
view = (MetaView) classType.getConstructor(String.class).newInstance(vname);
//view.setName( vname );
isNewView = true;
} catch (Exception ex) {
throw new RuntimeException("Instantiation exception creating new MetaView of Class [" + classType + "]", ex);
}
}
Collection attrs = parseAttributes(viewElement);
for (Iterator j = attrs.iterator(); j.hasNext();) {
view.addAttribute(j.next());
}
if (isNewView) {
vv.add(view);
}
}
return vv;
}
protected Collection parseValidators(String parent, Element e, MetaField mf)
throws MetaException, SAXException {
ArrayList vv = new ArrayList();
for (Element el : getElementsOfNames(e, new String[]{"metavalidator", "validator"})) {
String name = el.getAttribute(ATTR_NAME);
String type = el.getAttribute(ATTR_TYPE);
if (name.equals("")) {
throw new MetaException("Validator Element [" + e.getNodeName() + "] had no name defined");
}
if (type.equals("")) {
throw new MetaException("MetaValidator [" + name + "] of [" + parent + "] had no type defined");
}
Collection attrs = parseAttributes(el);
MetaValidator validator = null;
boolean isNewValidator = false;
Class> classType = null;
// If the type is defined, then load the class
if (!type.equals("")) {
classType = mValidatorTypes.get(type);
if (classType == null) {
log.warn("MetaValidator [" + name + "] of [" + parent + "] has type [" + type + "] that is not recognized");
//throw new MetaException( "MetaValidator [" + name + "] of [" + parent + "] has type [" + type+ "] that is not recognized" );
continue;
}
}
// If a validator with that name exists, then load it
if (mf.hasValidator(name)) {
validator = mf.getValidator(name);
}
// If there is no type or validator, then throw an exception
if (classType == null && validator == null) {
throw new MetaException("Validator [" + name + "] MetaField [" + mf + "] had no type");
}
// If the validator exists and is of the same class, then wrap it
if (validator != null
&& (validator.getClass() == classType || classType == null)) {
if (validator.getDeclaringMetaField() != mf) {
validator = (MetaValidator) validator.wrap();
isNewValidator = true;
}
} // Otherwise, create a new validator
else {
try {
validator = (MetaValidator) classType.getConstructor(String.class).newInstance(name);
//validator.setName( name );
isNewValidator = true;
} catch (Exception ex) {
throw new RuntimeException("Illegal access exception creating new MetaValidator of Class [" + classType + "]", ex);
}
}
// Set the attributes
for (Iterator j = attrs.iterator(); j.hasNext();) {
validator.addAttribute(j.next());
}
if (isNewValidator) {
vv.add(validator);
}
}
return vv;
}
protected Collection parseAttributes(Element e) throws MetaException, SAXException {
ArrayList attrs = new ArrayList();
for (Element el : getElementsOfName(e, "attr")) {
// Get the attribute name
String name = el.getAttribute(ATTR_NAME);
String type = el.getAttribute(ATTR_TYPE);
if (name.equals("")) {
throw new MetaException("Attribute Element [" + e.getNodeName() + "] had no name defined");
}
Class> c = null;
if (type.equals("")) {
c = StringAttribute.class;
} else {
c = mAttrTypes.get(type);
if (c == null) {
throw new MetaException("MetaAttribute [" + name + "] has type [" + type + "] that is not recognized");
}
}
MetaAttribute attr = null;
try {
attr = (MetaAttribute) c.getConstructor(String.class).newInstance(name);
//attr.setName( name );
} catch (Exception ex) {
log.error("Invalid MetaAttribute [" + name + "]: " + ex.getMessage());
throw new MetaException("Invalid MetaAttribute [" + name + "]", ex);
}
///////////////////////////////////////////////////
// Get the Node value
// Get the first node
Node nv = el.getFirstChild();
// Loop through and ignore the comments
while (nv != null && nv.getNodeType() == Node.COMMENT_NODE) {
nv.getNextSibling();
}
// If a valid node exists, then get the data
if (nv != null) {
switch (nv.getNodeType()) {
// If CDATA just set the whole thing
case Node.CDATA_SECTION_NODE:
attr.setValue(((CharacterData) nv).getData());
break;
// If an Element just pass it in for parsing
case Node.ELEMENT_NODE:
attr.setValue(nv);
break;
// If just text, then pass it in
case Node.TEXT_NODE:
attr.setValue(nv.getNodeValue());
break;
default:
log.warn("Unsupported Node Type for node [" + nv + "]");
}
}
// Add the attribute
attrs.add(attr);
}
return attrs;
}*/
/**
* Returns a collection of child elements for the given element
*/
protected Collection getElements(Element e) {
ArrayList elements = new ArrayList();
if (e == null) return elements;
NodeList list = e.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node instanceof Element) {
elements.add((Element) node);
}
}
return elements;
}
/**
* Returns a collection of child elements of the given name
*/
protected Collection getElementsOfName(Node n, String name) {
ArrayList elements = new ArrayList();
if (n == null) {
return elements;
}
NodeList list = n.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node instanceof Element
&& node.getNodeName().equals(name)) {
elements.add((Element) node);
}
}
return elements;
}
/**
* Returns a collection of child elements of the given name
*/
protected Collection getElementsOfNames(Node n, String[] names) {
ArrayList elements = new ArrayList();
if (n == null) {
return elements;
}
NodeList list = n.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node instanceof Element) {
for (int j = 0; j < names.length; j++) {
if (node.getNodeName().equals(names[ j])) {
elements.add((Element) node);
}
}
}
}
return elements;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy