| package jpos.config.simple.xml; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // This software is provided "AS IS". The JavaPOS working group (including |
| // each of the Corporate members, contributors and individuals) MAKES NO |
| // REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, |
| // EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED |
| // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| // NON-INFRINGEMENT. The JavaPOS working group shall not be liable for |
| // any damages suffered as a result of using, modifying or distributing this |
| // software or its derivatives. Permission to use, copy, modify, and distribute |
| // the software and its documentation for any purpose is hereby granted. |
| // |
| // The JavaPOS Config/Loader (aka JCL) is now under the CPL license, which |
| // is an OSS Apache-like license. The complete license is located at: |
| // http://oss.software.ibm.com/developerworks/opensource/license-cpl.html |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| import java.io.*; |
| import java.util.*; |
| import java.net.URL; |
| import java.text.DateFormat; |
| |
| import java.io.PrintWriter; |
| |
| import org.apache.xerces.dom.DOMImplementationImpl; |
| import org.apache.xerces.parsers.DOMParser; |
| import org.apache.xml.serialize.OutputFormat; |
| import org.apache.xml.serialize.XMLSerializer; |
| |
| import org.w3c.dom.*; |
| |
| import jpos.config.*; |
| import jpos.config.simple.*; |
| import jpos.util.*; |
| import jpos.util.tracing.Tracer; |
| import jpos.util.tracing.TracerFactory; |
| |
| /** |
| * This class is an abstract super class for all Xerces based parser/reg |
| * populator with functionality to serialize an enumeration of JposEntry |
| * objects into XML |
| * <p> |
| * <b>NOTE</b>: this class must define a public no-argument ctor so that it may be |
| * created via reflection when its defined in the jpos.properties as the |
| * jpos.config.regPopulatorClass |
| * </p> |
| * @see jpos.util.JposProperties#JPOS_REG_POPULATOR_CLASS_PROP_NAME |
| * @since 2.1.0 |
| * @author E. Michael Maximilien (maxim@us.ibm.com) |
| */ |
| public abstract class AbstractXercesRegPopulator |
| extends AbstractRegPopulator |
| implements XmlRegPopulator |
| { |
| //------------------------------------------------------------------------- |
| // Ctor(s) |
| // |
| |
| /** |
| * 1-arg constructor that takes the unique ID |
| * @param s the unique ID string |
| * @since 1.3 (Washington DC 2001) |
| */ |
| public AbstractXercesRegPopulator( String s ) { super( s ); } |
| |
| //------------------------------------------------------------------------- |
| // Public methods |
| // |
| |
| /** |
| * Tell the populator to save the current entries |
| * @param entries an enumeration of JposEntry objects |
| * @since 1.2 (NY 2K meeting) |
| * @throws java.lang.Exception if any error occurs while saving |
| */ |
| public void save( Enumeration entries ) throws Exception |
| { |
| if( isPopulatorFileDefined() ) |
| convertJposEntriesToXml( entries, getPopulatorFileOS() ); |
| else |
| convertJposEntriesToXml( entries, |
| new FileOutputStream( getDefaultXmlFileName() ) ); |
| } |
| |
| /** |
| * Tell the populator to save the current entries in the file specified |
| * @param entries an enumeration of JposEntry objects |
| * @param xmlFileName the XML file name to save entries |
| * @since 1.3 (SF 2K meeting) |
| * @throws java.lang.Exception if any error occurs while saving |
| */ |
| public void save( Enumeration entries, String xmlFileName ) |
| throws Exception |
| { |
| File xmlFile = new File( xmlFileName ); |
| FileOutputStream fos = new FileOutputStream( xmlFile ); |
| |
| convertJposEntriesToXml( entries, fos ); |
| |
| fos.close(); |
| } |
| |
| /** |
| * @return the URL pointing to the entries file loaded or saved |
| * @since 1.2 (NY 2K meeting) |
| */ |
| public URL getEntriesURL() |
| { |
| URL url = null; |
| |
| if( getPopulatorFileURL() != null && |
| !getPopulatorFileURL().equals( "" ) ) |
| try |
| { url = new URL( getPopulatorFileURL() ); } |
| catch( Exception e ) |
| { |
| tracer.println( "getEntriesURL: Exception.message=" + |
| e.getMessage() ); |
| } |
| else |
| url = createURLFromFile( new File( getPopulatorFileName() ) ); |
| |
| //<temp> |
| tracer.println( "getPopulatorFileURL()=" + getPopulatorFileURL() ); |
| tracer.println( "getPopulatorFileName()=" + getPopulatorFileName() ); |
| //</temp> |
| |
| return url; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Protected methods |
| // |
| |
| /** @return the Tracer object */ |
| protected Tracer getTracer() { return tracer; } |
| |
| /** |
| * @return the default XML file name that this populator will save |
| * entries to |
| */ |
| protected String getDefaultXmlFileName() { return xmlFileName; } |
| |
| /** |
| * Converts an Enumeration of JposEntry objects to XML |
| * @param entries an Enumeration of JposEntry objects |
| * @param os the OutputStream to stream the entries to |
| * @exception java.lang.Exception if something goes wrong serializing |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void convertJposEntriesToXml( Enumeration entries, |
| OutputStream os ) |
| throws Exception |
| { |
| Document document = getParser().getDocument(); |
| serializeDocument( document, entries, os ); |
| } |
| |
| /** |
| * @return the DOM parser object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected DOMParser getParser() { return domParser; } |
| |
| /** |
| * Serializes the JposEntry objects to an XML document and save to OutputStream |
| * @param document the XML document object |
| * @param entries an Enumeration of JposEntry objects |
| * @param os the OuputStream object |
| * @exception java.lang.Exception anything goes wrong while saving |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void serializeDocument( Document document, |
| Enumeration entries, |
| OutputStream os ) throws Exception |
| { |
| Document newDoc = createEmptyDocument(); |
| |
| insertJposEntriesInDoc( newDoc, entries ); |
| |
| insertDateSavedComment( newDoc ); |
| |
| OutputFormat outFormat = new OutputFormat( "xml", "UTF-8", true ); |
| |
| outFormat.setStandalone( false ); |
| outFormat.setIndenting( true ); |
| outFormat.setIndent( 4 ); |
| outFormat.setPreserveSpace( true ); |
| outFormat.setLineWidth( 0 ); |
| |
| insertDTDInfo( newDoc, outFormat ); |
| |
| PrintWriter outWriter = null; |
| try |
| { |
| outWriter = new PrintWriter |
| (new BufferedWriter(new OutputStreamWriter(os, "UTF-8"))); |
| } |
| catch( UnsupportedEncodingException ex ) |
| { |
| tracer.println( "Error making PrintWriter: " + |
| "UnsupportedEncodingException.message = " + |
| ex.getMessage() ); |
| } |
| |
| if( outWriter != null ) |
| { |
| XMLSerializer xmlSerializer = new XMLSerializer( outWriter, outFormat ); |
| xmlSerializer.serialize( newDoc ); |
| } |
| } |
| |
| /** |
| * @return a String with the document type definition value. For DTD this |
| * would be the DTD relative path/file and for schemas the XSD |
| * relative path/file |
| * @since 2.1.0 |
| */ |
| protected String getDoctypeValue() { return "jpos/res/jcl.dtd"; } |
| |
| /** |
| * Inset DTD information in the XML Document object |
| * @param doc the XML Document object |
| * @param outFormat the OuputFormat object |
| * @exception java.lang.Exception in case something goes wrong |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void insertDTDInfo( Document doc, OutputFormat outFormat ) throws Exception |
| { |
| String publicId = OutputFormat.whichDoctypePublic( doc ); |
| String systemId = OutputFormat.whichDoctypeSystem( doc ); |
| |
| outFormat.setDoctype( "JposEntries", getDoctypeValue() ); |
| } |
| |
| /** |
| * @return an empty XML Document object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected Document createEmptyDocument() |
| { |
| DOMImplementationImpl domImpImpl = (DOMImplementationImpl) |
| DOMImplementationImpl.getDOMImplementation(); |
| DocumentType docType = domImpImpl. |
| createDocumentType( "JposEntries", |
| "-//JavaPOS//DTD//EN", |
| getDoctypeValue() ); |
| |
| Document doc = domImpImpl.createDocument( null, "JposEntries", docType ); |
| |
| return doc; |
| } |
| |
| /** |
| * Inserts date and info saved in the XML Document object |
| * @param document the XML Document object |
| * @exception java.lang.Exception in case something goes wrong |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void insertDateSavedComment( Document document ) |
| throws Exception |
| { |
| String dateString = DateFormat.getInstance(). |
| format( new Date( System.currentTimeMillis() ) ); |
| |
| String commentString = |
| "Saved by JavaPOS jpos.config/loader (JCL) version " + |
| Version.getVersionString() + " on " + dateString; |
| |
| Comment comment = document.createComment( commentString ); |
| |
| document.getDocumentElement(). |
| insertBefore( comment, document.getDocumentElement().getFirstChild() ); |
| |
| document.getDocumentElement(). |
| insertBefore( document.createTextNode( "\n" ), comment ); |
| |
| document.getDocumentElement(). |
| appendChild( document.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends the <creation> element to the document |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendCreationElement( Document doc, |
| Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| jposEntryElement.appendChild( doc.createTextNode( " " + " " ) ); |
| |
| Element creationElement = doc.createElement( "creation" ); |
| |
| Attr factoryClassAttr = doc.createAttribute( "factoryClass" ); |
| Attr serviceClassAttr = doc.createAttribute( "serviceClass" ); |
| |
| factoryClassAttr.setValue( (String)jposEntry. |
| getPropertyValue( "serviceInstanceFactoryClass" ) ); |
| |
| serviceClassAttr.setValue( (String)jposEntry. |
| getPropertyValue( "serviceClass" ) ); |
| |
| creationElement.setAttributeNode( factoryClassAttr ); |
| creationElement.setAttributeNode( serviceClassAttr ); |
| |
| jposEntryElement.appendChild( creationElement ); |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends the <vendor> element to the document |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendVendorElement( Document doc, Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| jposEntryElement.appendChild( doc.createTextNode( " " + " " ) ); |
| |
| Element vendorElement = doc.createElement( "vendor" ); |
| |
| Attr nameAttr = doc.createAttribute( "name" ); |
| Attr urlAttr = doc.createAttribute( "url" ); |
| |
| nameAttr.setValue( (String)jposEntry.getPropertyValue( "vendorName" ) ); |
| urlAttr.setValue( (String)jposEntry.getPropertyValue( "vendorURL" ) ); |
| |
| vendorElement.setAttributeNode( nameAttr ); |
| vendorElement.setAttributeNode( urlAttr ); |
| |
| jposEntryElement.appendChild( vendorElement ); |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends the <jpos> element to the document |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendJposElement( Document doc, Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| jposEntryElement.appendChild( doc.createTextNode( " " + " " ) ); |
| |
| Element jposElement = doc.createElement( "jpos" ); |
| |
| Attr versionAttr = doc.createAttribute( "version" ); |
| Attr categoryAttr = doc.createAttribute( "category" ); |
| |
| versionAttr.setValue( (String)jposEntry. |
| getPropertyValue( "jposVersion" ) ); |
| |
| categoryAttr.setValue( (String)jposEntry. |
| getPropertyValue( "deviceCategory" ) ); |
| |
| jposElement.setAttributeNode( versionAttr ); |
| jposElement.setAttributeNode( categoryAttr ); |
| |
| jposEntryElement.appendChild( jposElement ); |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends the <product> element to the document |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendProductElement( Document doc, |
| Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| jposEntryElement.appendChild( doc.createTextNode( " " + " " ) ); |
| |
| Element productElement = doc.createElement( "product" ); |
| |
| Attr nameAttr = doc.createAttribute( "name" ); |
| Attr descriptionAttr = doc.createAttribute( "description" ); |
| Attr urlAttr = doc.createAttribute( "url" ); |
| |
| nameAttr.setValue( (String)jposEntry.getPropertyValue( "productName" ) ); |
| |
| descriptionAttr. |
| setValue( (String)jposEntry.getPropertyValue( "productDescription" ) ); |
| |
| urlAttr.setValue( (String)jposEntry.getPropertyValue( "productURL" ) ); |
| |
| productElement.setAttributeNode( nameAttr ); |
| productElement.setAttributeNode( descriptionAttr ); |
| productElement.setAttributeNode( urlAttr ); |
| |
| jposEntryElement.appendChild( productElement ); |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends the <prop> element to the document |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param propName the property name |
| * @param propValue the property value |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendPropElement( Document doc, Element jposEntryElement, |
| String propName, Object propValue ) |
| { |
| jposEntryElement.appendChild( doc.createTextNode( " " + " " ) ); |
| |
| Element propElement = doc.createElement( "prop" ); |
| |
| Attr nameAttr = doc.createAttribute( "name" ); |
| Attr valueAttr = doc.createAttribute( "value" ); |
| Attr typeAttr = doc.createAttribute( "type" ); |
| |
| nameAttr.setValue( propName ); |
| valueAttr.setValue( propValue.toString() ); |
| typeAttr.setValue( JposEntryUtility. |
| shortClassName( propValue.getClass() ) ); |
| |
| propElement.setAttributeNode( nameAttr ); |
| propElement.setAttributeNode( valueAttr ); |
| propElement.setAttributeNode( typeAttr ); |
| |
| jposEntryElement.appendChild( propElement ); |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| } |
| |
| /** |
| * Appends non-required properties name and value |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void appendPropElements( Document doc, Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| jposEntryElement.appendChild( doc. |
| createTextNode( "\n" + " " + " " ) ); |
| |
| String comment = "Other non JavaPOS required property" + |
| " (mostly vendor properties and bus specific " + |
| "properties i.e. RS232 )"; |
| |
| jposEntryElement.appendChild( doc.createComment( comment ) ); |
| |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| |
| Enumeration props = jposEntry.getPropertyNames(); |
| |
| while( props.hasMoreElements() ) |
| { |
| String propName = (String)props.nextElement(); |
| |
| if( !JposEntryUtility.isRequiredPropName( propName ) ) |
| appendPropElement( doc, jposEntryElement, propName, |
| jposEntry.getPropertyValue( propName ) ); |
| } |
| } |
| |
| /** |
| * Insert the <JposEntryElement> in the XML document object |
| * @param doc the XML Document object |
| * @param jposEntryElement the <JposEntryElement> XML Element object |
| * @param jposEntry the JposEntry object |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void insertJposEntryInDoc( Document doc, Element jposEntryElement, |
| JposEntry jposEntry ) |
| { |
| appendCreationElement( doc, jposEntryElement, jposEntry ); |
| appendVendorElement( doc, jposEntryElement, jposEntry ); |
| appendJposElement( doc, jposEntryElement, jposEntry ); |
| appendProductElement( doc, jposEntryElement, jposEntry ); |
| appendPropElements( doc, jposEntryElement, jposEntry ); |
| |
| doc.getDocumentElement(). |
| appendChild( doc.createTextNode( "\n" + " " ) ); |
| doc.getDocumentElement(). |
| appendChild( jposEntryElement ); |
| doc.getDocumentElement(). |
| appendChild( doc.createTextNode( "\n" + " " ) ); |
| } |
| |
| /** |
| * Insert an Enumeration of <JposEntryElement> objects in the XML document |
| * @param doc the XML Document object |
| * @param entries an Enumeration of JposEntry objects |
| * @since 1.2 (NY 2K meeting) |
| */ |
| protected void insertJposEntriesInDoc( Document doc, Enumeration entries ) |
| { |
| while( entries.hasMoreElements() ) |
| { |
| JposEntry jposEntry = (JposEntry)entries.nextElement(); |
| |
| if( JposEntryUtility.isValidJposEntry( jposEntry ) ) |
| { |
| doc.getDocumentElement(). |
| appendChild( doc.createTextNode( "\n" + " " ) ); |
| |
| Element jposEntryElement = doc.createElement( "JposEntry" ); |
| |
| Attr logicalNameAttr = doc.createAttribute( "logicalName" ); |
| logicalNameAttr.setValue( (String)jposEntry. |
| getPropertyValue( "logicalName" ) ); |
| |
| jposEntryElement.setAttributeNode( logicalNameAttr ); |
| |
| jposEntryElement.appendChild( doc.createTextNode( "\n" ) ); |
| |
| insertJposEntryInDoc( doc, jposEntryElement, jposEntry ); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Instance variables |
| // |
| |
| protected String xmlFileName = DEFAULT_XML_FILE_NAME; |
| |
| protected DOMParser domParser = new DOMParser(); |
| |
| private Tracer tracer = TracerFactory.getInstance(). |
| createTracer( "AbstractXercesRegPopulator" ); |
| |
| //-------------------------------------------------------------------------- |
| // Public constants |
| // |
| |
| public static final String DTD_FILE_PATH = "jpos" + File.separator + "res"; |
| public static final String DTD_FILE_NAME = DTD_FILE_PATH + File.separator + "jcl.dtd"; |
| } |