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

at.spardat.xma.boot.comp.data.XMAAppParser Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

/*
 * Created on : 04.2003
 * Created by : s3595
 */
package at.spardat.xma.boot.comp.data;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.DTDHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import at.spardat.xma.boot.comp.DTDStatics;
import at.spardat.xma.boot.logger.ILogger;
import at.spardat.xma.boot.logger.LogLevel;
import at.spardat.xma.boot.util.Util;

/**
 *
 * class: XMAAppParser
 *
 * @author s3595 Chris Sch?fer (CGS)

* @version $Id: XMAAppParser.java 11295 2013-12-13 10:56:29Z dschwarz $ */ public class XMAAppParser extends DefaultHandler implements DTDHandler { private static String DEFAULT_DTD = "xma-app.dtd"; //$NON-NLS-1$ private static String DEFAULT_DTD_PACKAGE = "at/spardat/xma/boot/comp/"; // "at.spardat.xma.boot.comp."; //$NON-NLS-1$ private static String DTD_PUBLIC_ID = "-//Spardat//IMC-XMA//EN"; //$NON-NLS-1$ private static String SIGNATURE_DTD = "xmldsig-core-schema.dtd"; //$NON-NLS-1$ private static String DTD_SIGNATURE_PUBLIC_ID = "-//W3C/XML Signatures"; //$NON-NLS-1$ /** running on server or on client */ private static boolean onServer_ = false; /** XML signature validator */ protected XMLValidator xmlValidator; /** parser */ private javax.xml.parsers.SAXParser parser_; /** logger */ private ILogger log_; /** parsed application */ private XMAApp xmaApp_; /** current component */ private XMAComponent currentComponent; /** current plugin */ private XMAPluginImpl currentPluginImpl_; /** current SWT description */ private XMASWTDescription currentSWTDescription; private int countUnknownTag = 0; public XMAAppParser( ILogger log_, boolean bOnServer, XMLValidator validator) { init( log_, bOnServer, validator); } public XMAAppParser( ILogger log_, boolean bOnServer) { init( log_, bOnServer, null); } /** constructor */ public XMAAppParser( ILogger log_ ) { init(log_, false, null ); } private void init( ILogger log_, boolean bOnServer, XMLValidator validator) { onServer_ = bOnServer; if( log_ == null ) throw new NullPointerException(); this.log_ = log_; currentComponent = null; currentPluginImpl_ = null; xmaApp_ = null; if (validator != null) { validator.setEntityResolver(this); } this.xmlValidator = validator; try { initParser(); } catch (Exception e) { log_.log(LogLevel.SEVERE,"XML parser configuration error: ",e); throw new RuntimeException("XML parser configuration error: ",e); } } /** initialize parser * @throws SAXException * @throws ParserConfigurationException*/ protected void initParser() throws ParserConfigurationException, SAXException { SAXParserFactory spf = SAXParserFactory.newInstance(); // validate only on server spf.setValidating(onServer_); parser_ = spf.newSAXParser(); XMLReader xmlreader = parser_.getXMLReader(); xmlreader.setDTDHandler(this); xmlreader.setEntityResolver( this ); } /** * get the dtd out of the classloader. * on development, if class-directory is seperated, build should copy the dtd into the classes dir. */ public InputSource resolveEntity(String publicId, String systemId) { log_.log(LogLevel.FINE, "resolvedEntity: \"{0}\" with sysid: \"{1}\"", new Object[] {publicId,systemId} ); //$NON-NLS-1$ String strClass; if (XMAAppParser.DTD_PUBLIC_ID.equals(publicId) ) { strClass = XMAAppParser.DEFAULT_DTD_PACKAGE + XMAAppParser.DEFAULT_DTD; } else if (XMAAppParser.DTD_SIGNATURE_PUBLIC_ID.equals(publicId) ) { strClass = XMAAppParser.DEFAULT_DTD_PACKAGE + XMAAppParser.SIGNATURE_DTD; } else { return null; } InputStream in = getClass().getClassLoader().getResourceAsStream( strClass ); return new InputSource( in ); } /** * parse is the main method for parsing configuration files * @param is the input stream to the data to parse * @throws IOException * @throws SAXException */ public XMAApp parse( InputStream is ) throws IOException, SAXException { try { // XML Signature validator uses DOM parser, but SAX parser is used for unmarshalling. To use the input stream // for both use cases, the input is stored in a temporary buffer for reuse. // FIXME Use DOM parser instead of SAX parser for unmarshalling ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] tmp = new byte[4096]; int cnt = 0; while((cnt = is.read(tmp)) > 0) { bos.write(tmp, 0, cnt); } byte[] myArray = bos.toByteArray(); parser_.parse( new InputSource(new ByteArrayInputStream(myArray)), this ); if (!onServer_ && xmlValidator != null) { boolean valid; try { valid = xmlValidator.validateSignature(new ByteArrayInputStream(myArray)); } catch (Exception e) { log_.log(LogLevel.SEVERE, e.getMessage(), e); valid = false; } if (!valid) { throw new IOException("Unable to verify signature of application descriptor."); } } XMAApp ret = this.xmaApp_; this.xmaApp_ = null; return ret; } catch( IOException e ) { log_.log(LogLevel.SEVERE, "parser error: ", e); //$NON-NLS-1$ throw e; } catch (SAXException e) { log_.log(LogLevel.SEVERE, "parser error: ", e); //$NON-NLS-1$ throw e; } } /** * parse is the main method for parsing configuration files * @param strURI Is a String parameter. It is used as a URI to the XML-file location. */ public XMAApp parse( String strURI ) throws IOException, SAXException { FileInputStream is = null; try { is = new FileInputStream(strURI); return parse( is ); } finally { Util.close(is, strURI); } } /** @see org.xml.sax.ContentHandler#startDocument() */ public void startDocument() throws SAXException { } /** @see org.xml.sax.ContentHandler#endDocument() */ public void endDocument() throws SAXException { } /** @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String nsURI, String localName, String qName, Attributes attrs) throws SAXException { this.switchElementHandler( nsURI,localName,qName,attrs); } /** @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(String nsURI, String localName, String qName) throws SAXException { this.switchElementHandler( nsURI,localName, qName, null); } /** * see element dispatcher */ protected void switchElementHandler(String nsURI, String localName, String qName, Attributes attrs) throws SAXException { if (DTDStatics.XMA_Application.equals(qName)) handleApp(attrs); else if (DTDStatics.COMPONENT.equals(qName)) handleComponent(attrs); else if (DTDStatics.PLUGIN_IMPL.equals(qName)) handlePluginImpl(attrs); else if (DTDStatics.PLUGIN_SPEC.equals(qName)) handlePluginSpec(attrs); else if (DTDStatics.RESOURCE.equals(qName)) handleResource(attrs); else if (DTDStatics.RESOURCE_LINK.equals(qName)) handleResLink(attrs); else if (DTDStatics.SWT_DESCRIPTION.equals(qName)) handleSWTDescription(attrs); else if (DTDStatics.PREINSTALL.equals(qName)) handlePreinstall(attrs); else if (DTDStatics.SSL_RESTRICTION.equals(qName)) handleSSLRestriction(attrs); else if (DTDStatics.CERTIFICATE.equals(qName)) handleCertificate(attrs); else if (DTDStatics.SUBJECT.equals(qName)) handleSubject(attrs); else if (DTDStatics.ISSUER.equals(qName)) handleIssuer(attrs); else if (DTDStatics.SIGNATURE.equals(qName)) handleSignature(attrs); else handleUnknownTag(attrs); } protected void handleUnknownTag(Attributes attrs) throws SAXException { if (isSignature) { // ignore details return; } if (attrs != null) { countUnknownTag++; } else { /* tag close */ countUnknownTag--; } } boolean isSignature = false; protected void handleSignature(Attributes attrs) { isSignature = attrs != null; } private XMASSLRestriction currentSSLRestriction = null; boolean isSubject = false; boolean isIssuer = false; @Override public void characters(char[] ch, int start, int length) throws SAXException { if (isSubject) { currentSSLRestriction.setSubject(new String(ch, start, length)); } else if (isIssuer) { currentSSLRestriction.setIssuer(new String(ch, start, length)); } } /** * * @param attrs Attributes to this element * @throws SAXException */ protected void handleSSLRestriction(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { currentSSLRestriction = new XMASSLRestriction(); currentSSLRestriction.setHostname(attrs.getValue( DTDStatics.SSL_RESTRICTION_HOSTNAME )); } else { xmaApp_.addSSLRestriction(currentSSLRestriction); currentSSLRestriction = null; } } /** * * @param attrs Attributes to this element * @throws SAXException */ protected void handleCertificate(Attributes attrs) throws SAXException { if(isUnknownTag()) return; } /** * * @param attrs Attributes to this element * @throws SAXException */ protected void handleSubject(Attributes attrs) throws SAXException { if(isUnknownTag()) return; isSubject = attrs != null; } /** * * @param attrs Attributes to this element * @throws SAXException */ protected void handleIssuer(Attributes attrs) throws SAXException { if(isUnknownTag()) return; isIssuer = attrs != null; } /** * * @param attrs Attributes to this element * @throws SAXException */ protected void handleApp(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { this.xmaApp_ = new XMAApp( ); } else { /* tag close */ } } /** * handle component parsing */ protected void handleComponent(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { String name = attrs.getValue( DTDStatics.COMPONENT_NAME ); String impl = attrs.getValue( DTDStatics.COMPONENT_IMPLPACKAGE ); if( xmaApp_ == null ) throw new SAXException( "parser error"); //$NON-NLS-1$ currentComponent = new XMAComponent(name, impl); currentComponent.setApplication(xmaApp_); xmaApp_.addComponent(currentComponent); } else { /* tag close */ this.currentComponent = null ; } } /** * e.g.: * * @param attrs Attributes to this element * @throws SAXException */ protected void handleResource(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { Locale locale = null; Version version = null; String strHref = attrs.getValue( DTDStatics.RESOURCE_HREF ); String strVersion = attrs.getValue( DTDStatics.RESOURCE_VERSION ); String strType = attrs.getValue( DTDStatics.RESOURCE_TYPE ); String strLocale = attrs.getValue( DTDStatics.RESOURCE_LOCALE ); String strShared = attrs.getValue( DTDStatics.RESOURCE_SHARED ); String strFdmLoad = attrs.getValue(DTDStatics.RESOURCE_FDMLOAD ); String os = attrs.getValue( DTDStatics.RESOURCE_OSNAME); String arch = attrs.getValue(DTDStatics.RESOURCE_OSARCH); XMAResource.TypeID tid = XMAResource.TypeID.getID(strType); if( strLocale != null ) { locale = Util.getInstance().getLocale(strLocale); } if(strVersion == null ) { throw new SAXException( "missing version"); //$NON-NLS-1$ } else { version = new Version(strVersion); } boolean shared=false; if("true".equalsIgnoreCase(strShared)) { shared=true; } XMAResource res = new XMAResource( strHref, version, tid, locale, shared,os, arch); if("true".equalsIgnoreCase(strFdmLoad)) { res.setFdmload(true); } if( currentComponent != null ) { currentComponent.addResource(res); } else if( currentPluginImpl_ != null ) { currentPluginImpl_.addResource(res); } else if(currentSWTDescription != null) { currentSWTDescription.addResource(res); } else xmaApp_.addResource( res ); }// end if } /** * handle parsing of resource links */ protected void handleResLink(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { String strHref = attrs.getValue( DTDStatics.RESOURCE_HREF ); XMAResourceLink rl = new XMAResourceLink( strHref ); if( currentComponent != null ) { currentComponent.addResourceLink(rl); } else if( currentPluginImpl_ != null ) { currentPluginImpl_.addResourceLink( rl ); } else throw new SAXException( "parser error. resource link not in component or plugin"); //$NON-NLS-1$ } } /** * handles parsing of plug in impl info */ protected void handlePluginImpl(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { String implClient = attrs.getValue( DTDStatics.PLUGIN_IMPL_CLIENT ); String implServer = attrs.getValue( DTDStatics.PLUGIN_IMPL_SERVER ); String strImplements = attrs.getValue( DTDStatics.PLUGIN_IMPL_IMPLEMENTS ); XMAPluginImpl pi = new XMAPluginImpl( implClient, implServer, strImplements); xmaApp_.addPluginImpl(pi); currentPluginImpl_ = pi; } else { currentPluginImpl_ = null; } } /** * handles parsing of tag plugin spec */ protected void handlePluginSpec(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if (attrs != null) { String strRequires = attrs.getValue( DTDStatics.PLUGIN_SPEC_REQUIRES ); XMAPluginSpec pis = new XMAPluginSpec( strRequires ); xmaApp_.addPluginSpec( pis ); } } /** * handles parsing of tag swt-description */ protected void handleSWTDescription(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if(attrs!=null) { XMASWTDescription swtDescription = new XMASWTDescription(); if(xmaApp_.getSwtDescription()!=null) { throw new SAXException("parser error. duplicate <"+DTDStatics.SWT_DESCRIPTION+"> tag detected. Only one <"+DTDStatics.SWT_DESCRIPTION+"> tag is allowed."); } xmaApp_.setSwtDescription(swtDescription); currentSWTDescription=swtDescription; } else { currentSWTDescription=null; } } /** * handles parsing of tag preinstall */ protected void handlePreinstall(Attributes attrs) throws SAXException { if(isUnknownTag()) return; if(attrs!=null) { String version = attrs.getValue(DTDStatics.PREINSTALL_VERSION); SWTPreinstall preinstall = new SWTPreinstall(version); if(currentSWTDescription!=null) { currentSWTDescription.addPreinstall(preinstall); } else { throw new SAXException("parser error. preinstall not in <"+DTDStatics.SWT_DESCRIPTION+"> tag"); } } } /** * This is a helper method to make sure a codebase string will work as a codebase URL * by forcing a "/" on the end of the string. */ protected static final String fixCodebaseString(String s) { if (s == null || s.endsWith("/")) { //$NON-NLS-1$ return s; } return (s + "/"); //$NON-NLS-1$ } /** * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) */ public void fatalError(SAXParseException e) throws SAXParseException { log_.log(LogLevel.SEVERE, "XML parse error at line: {0} with public-id: \"{1}\"", new Object[] { new Integer(e.getLineNumber()),e.getPublicId() } ); //$NON-NLS-1$ throw (SAXParseException) e; } /** * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) */ public void warning(SAXParseException e) { log_.log(LogLevel.WARNING, "XML parse-warning at line: {0} with public-id: \"{1}\"", new Object[] { new Integer(e.getLineNumber()),e.getPublicId() } ); //$NON-NLS-1$ } /** * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) */ public void error(SAXParseException e) throws SAXParseException { log_.log(LogLevel.SEVERE, "XML parse error at line: {0} with public-id: \"{1}\"", new Object[] { new Integer(e.getLineNumber()),e.getPublicId() } ); //$NON-NLS-1$ throw (SAXParseException) e; } /** * Returns true if the parser stands in an unknown tag. * Needed as an unknown tag and anything in it is ignored. * @return true if the parser stands in an unknown tag, otherwise false */ private boolean isUnknownTag(){ return countUnknownTag > 0; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy