All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.gov.nationalarchives.droid.xmlReader.SAXModelBuilder Maven / Gradle / Ivy

The newest version!
/*
 * c The National Archives 2005-2006.  All rights reserved.
 * See Licence.txt for full licence details.
 *
 * Developed by:
 * Tessella Support Services plc
 * 3 Vineyard Chambers
 * Abingdon, OX14 3PX
 * United Kingdom
 * http://www.tessella.com
 *
 * Tessella/NPD/4305
 * PRONOM 4
 *
 * SAXModelBuilder.java
 *
 * $Id: SAXModelBuilder.java,v 1.7 2006/03/13 15:15:29 linb Exp $
 *
 * $Logger: SAXModelBuilder.java,v $
 * Revision 1.7  2006/03/13 15:15:29  linb
 * Changed copyright holder from Crown Copyright to The National Archives.
 * Added reference to licence.txt
 * Changed dates to 2005-2006
 *
 * Revision 1.6  2006/02/09 15:31:23  linb
 * Updates to javadoc and code following the code review
 *
 * Revision 1.5  2006/01/31 16:47:30  linb
 * Added log messages that were missing due to the log keyword being added too late
 *
 * Revision 1.4  2006/01/31 16:21:20  linb
 * Removed the dollars from the log lines generated by the previous message, so as not to cause problems with subsequent commits
 *
 * Revision 1.3  2006/01/31 16:19:07  linb
 * Added Logger and Id tags to these files
 *
 * Revision 1.2  2006/01/31 16:11:37  linb
 * Add support for XML namespaces to:
 * 1) The reading of the config file, spec file and file-list file
 * 2) The writing of the config file and file-list file
 * - The namespaces still need to be set to their proper URIs (currently set to example.com...)
 * - Can still read in files without namespaces*
 *
 */
package uk.gov.nationalarchives.droid.xmlReader;

import java.lang.reflect.Method;
import java.util.Stack;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import uk.gov.nationalarchives.droid.base.SimpleElement;

/**
 * reads and parses data from an XML file
 * 
 * @version 4.0.0
 */
public class SAXModelBuilder extends DefaultHandler {
	private Stack stack = new Stack();
	private SimpleElement element;
	private String myObjectPackage = "uk.gov.nationalarchives.droid.signatureFile";
	StringBuffer textBuffer;
	private String namespace = "";
	private boolean useNamespace = false;
	private boolean allowGlobalNamespace = true;
	private static final Logger LOG = LoggerFactory
	.getLogger(SAXModelBuilder.class);

	@Override
	public void characters(final char[] ch, final int start, final int len) {
		if (!this.stack.empty()) { // Ignore character data if we don't have an
			// element to put it in.
			final String text = new String(ch, start, len);
			(this.stack.peek()).setText(text);
		}
	}

	@Override
	public void endElement(final String namespace, final String localname,
			final String qname) throws SAXException {
		final String elementName = handleNameNS(namespace, localname, qname);
		if (elementName == null) {
			return;
		}
		this.element = this.stack.pop();
		this.element.completeElementContent();
		if (!this.stack.empty()) {
			try {
				setProperty(elementName, this.stack.peek(), this.element);
			} catch (final SAXException e) {
				throw new SAXException(e);
			}
		}
	}

	public SimpleElement getModel() {
		return this.element;
	}

	public void setObjectPackage(final String theObjectPackage) {
		this.myObjectPackage = theObjectPackage;
	}

	/**
	 * Set up XML namespace handling.
	 * 

*

* If allowGlobalNamespace is set to true, * elements that do not have a namespace specified are parsed; attributes * that don't have a namespace specified are parsed. If it is * false, for it to be parsed, an element must have a namespace * specifed (by default or with a prefix); an attribute must have a * namespace specified with a prefix. * * @param namespace * the XML namespace to use * @param allowGlobalNamespace * allow the parser to recognise elements/ attributes that aren't * in any namespace */ public void setupNamespace(final String namespace, final boolean allowGlobalNamespace) { if (namespace == null) { throw new IllegalArgumentException("Namespace cannot be null"); } this.namespace = namespace; this.useNamespace = true; this.allowGlobalNamespace = allowGlobalNamespace; } @Override public void startElement(final String namespace, final String localname, final String qname, final Attributes atts) throws SAXException { final String elementName = handleNameNS(namespace, localname, qname); if (elementName == null) { return; } SimpleElement element = null; final String className = this.myObjectPackage + "." + elementName; try { element = (SimpleElement) Class.forName(className).newInstance(); } catch (final Exception e) { } if (element == null) { element = new SimpleElement(); } for (int i = 0; i < atts.getLength(); i++) { final String attributeName = handleNameNS(atts.getURI(i), atts .getLocalName(i), atts.getQName(i)); if (attributeName == null) { continue; } element.setAttributeValue(attributeName, atts.getValue(i)); } this.stack.push(element); } /** * Handle names in a namespace-aware fashion. *

*

* If an element/ attribute is in a namespace, qname is not required to be * set. We must, therefore, use the localname if the namespace is set, and * qname if it isn't. * * @param namespace * the namespace uri * @param localname * the local part of the name * @param qname * a qualified name * @return the local part or the qualified name, as appropriate */ private String handleNameNS(final String namespace, final String localname, final String qname) { if (this.useNamespace && this.namespace.equals(namespace)) { // Name is in the specified namespace return localname; } else if (this.allowGlobalNamespace && "".equals(namespace)) { // Name is in the global namespace return qname; } else { // Ignore return null; } } void setProperty(final String name, final Object target, Object value) throws SAXException { Method method = null; try { method = target.getClass().getMethod("add" + name, new Class[] { value.getClass() }); } catch (final NoSuchMethodException e) { } if (method == null) { try { method = target.getClass().getMethod("set" + name, new Class[] { value.getClass() }); } catch (final NoSuchMethodException e) { } } if (method == null) { try { value = ((SimpleElement) value).getText(); method = target.getClass().getMethod("add" + name, new Class[] { String.class }); } catch (final NoSuchMethodException e) { } } try { if (method == null) { method = target.getClass().getMethod("set" + name, new Class[] { String.class }); } method.invoke(target, value); } catch (final NoSuchMethodException e) { LOG.error("unknown element {} {}",name, ((SimpleElement) target) .getElementName()); } catch (final Exception e) { throw new SAXException(e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy