/**
* EasyBeans
* Copyright (C) 2006 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id:XMLMappingBuilder.java 1477 2007-06-16 16:50:19Z benoitf $
* --------------------------------------------------------------------------
*/
package org.ow2.easybeans.xmlconfig.mapping;
import java.net.URL;
import org.ow2.easybeans.util.xml.DocumentParser;
import org.ow2.easybeans.util.xml.DocumentParserException;
import org.ow2.easybeans.util.xml.XMLUtils;
import org.ow2.easybeans.xmlconfig.XMLConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Allows to build the Mapping object for a set of classes.
* @author Florent Benoit
*/
public class XMLMappingBuilder {
/**
* Namespace used for the mapping file (for validation).
*/
private static final String MAPPING_NS = "http://easybeans.ow2.org/xml/ns/mapping";
/**
* Name of the <package> element.
*/
private static final String PACKAGE_ELEMENT = "package";
/**
* Name of the <class> element.
*/
private static final String CLASS_ELEMENT = "class";
/**
* Name of the <attribute> element.
*/
private static final String ATTRIBUTE_ELEMENT = "attribute";
/**
* URL that reference the mapping file.
*/
private URL mappingURL = null;
/**
* The mapping used for the given namespace.
*/
private XMLMapping xmlMapping = null;
/**
* Builds a new mapping builder.
* @param mappingURL the given url that reference the mapping file.
*/
public XMLMappingBuilder(final URL mappingURL) {
this.mappingURL = mappingURL;
xmlMapping = new XMLMapping();
}
/**
* Build the XMLMapping object by analyzing the mapping file.
* @throws XMLConfigurationException if there is a failure when analyzing
* the XML file.
*/
public void build() throws XMLConfigurationException {
// Parse the XML file and build all configuration process.
Document xmlMappingConfigurationDocument = null;
try {
xmlMappingConfigurationDocument = DocumentParser.getDocument(mappingURL, false, null);
} catch (DocumentParserException e) {
throw new XMLConfigurationException("Cannot get a document on the given url '" + mappingURL + "'.", e);
}
// Get the root element
Element rootMappingElement = xmlMappingConfigurationDocument.getDocumentElement();
// <package> element ?
NodeList packageList = rootMappingElement.getElementsByTagNameNS(MAPPING_NS, PACKAGE_ELEMENT);
for (int i = 0; i < packageList.getLength(); i++) {
Element packageElement = (Element) packageList.item(i);
// get name
String packageName = XMLUtils.getAttributeValue(packageElement, "name");
// Create class mapping
NodeList classList = packageElement.getElementsByTagNameNS(MAPPING_NS, CLASS_ELEMENT);
addClassMapping(classList, packageName + ".", true);
}
// Now analyze single <class> element
NodeList classList = rootMappingElement.getElementsByTagNameNS(MAPPING_NS, CLASS_ELEMENT);
addClassMapping(classList, "", false);
}
/**
* Add the mapping for the given list of class elements.
* @param classList the list of elements
* @param packageName the name of the package to use as prefix.
* @param packageParent if true, package as parent node is accepted, else it
* is denied.
*/
private void addClassMapping(final NodeList classList, final String packageName, final boolean packageParent) {
// class elements ?
for (int c = 0; c < classList.getLength(); c++) {
Element classElement = (Element) classList.item(c);
// if package element is parent but packageElement boolean is false,
// stop
if (classElement.getParentNode().getNodeName().equals(PACKAGE_ELEMENT) && !packageParent) {
continue;
}
// Build mapping object
ClassMapping classMapping = new ClassMapping();
// class name
String name = XMLUtils.getAttributeValue(classElement, "name");
String className = packageName + name;
classMapping.setName(className);
// alias
String alias = XMLUtils.getAttributeValue(classElement, "alias");
classMapping.setAlias(alias);
// Mapping of the content of an element to an attribute
String elementAttribute = XMLUtils.getAttributeValue(classElement, "element-attribute");
classMapping.setElementAttribute(elementAttribute);
// Attributes ?
NodeList attributeList = classElement.getElementsByTagNameNS(MAPPING_NS, ATTRIBUTE_ELEMENT);
for (int a = 0; a < attributeList.getLength(); a++) {
Element attributeElement = (Element) attributeList.item(a);
// Build mapping object
AttributeMapping attributeMapping = new AttributeMapping();
// name
String attributeName = XMLUtils.getAttributeValue(attributeElement, "name");
attributeMapping.setName(attributeName);
// is Element ?
String isElementName = XMLUtils.getAttributeValue(attributeElement, "element");
if (Boolean.parseBoolean(isElementName)) {
attributeMapping.setElement();
}
// is List Element ?
String isListElementName = XMLUtils.getAttributeValue(attributeElement, "isList");
if (Boolean.parseBoolean(isListElementName)) {
attributeMapping.setListElement();
}
// getter
String getter = XMLUtils.getAttributeValue(attributeElement, "getter");
attributeMapping.setGetter(getter);
// setter
String setter = XMLUtils.getAttributeValue(attributeElement, "setter");
attributeMapping.setSetter(setter);
// alias
String attributeAlias = XMLUtils.getAttributeValue(attributeElement, "alias");
attributeMapping.setAlias(attributeAlias);
// add attribute
classMapping.addAttributeMapping(attributeMapping);
}
xmlMapping.addClassMapping(classMapping);
}
}
/**
* Gets the XML mapping object.
* @return the mapping object between classname/alias and their mapping
* description.
*/
public XMLMapping getXmlMapping() {
return xmlMapping;
}
}
|