blob: ba6da6cbe43500e44209a14661fd0f3cb3d5f39f [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;
import java.util.*;
import java.io.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.AttributeList;
/**
* Inner class used by EjbJar to facilitate the parsing of deployment
* descriptors and the capture of appropriate information. Extends
* HandlerBase so it only implements the methods needed. During parsing
* creates a hashtable consisting of entries mapping the name it should be
* inserted into an EJB jar as to a File representing the file on disk. This
* list can then be accessed through the getFiles() method.
*/
public class DescriptorHandler extends org.xml.sax.HandlerBase {
/**
* Bunch of constants used for storing entries in a hashtable, and for
* constructing the filenames of various parts of the ejb jar.
*/
private static final String EJB_REF = "ejb-ref";
private static final String HOME_INTERFACE = "home";
private static final String REMOTE_INTERFACE = "remote";
private static final String BEAN_CLASS = "ejb-class";
private static final String PK_CLASS = "prim-key-class";
/**
* Instance variable used to store the name of the current element being
* processed by the SAX parser. Accessed by the SAX parser call-back methods
* startElement() and endElement().
*/
protected String currentElement = null;
/**
* The text of the current element
*/
protected String currentText = null;
/**
* Instance variable that stores the names of the files as they will be
* put into the jar file, mapped to File objects Accessed by the SAX
* parser call-back method characters().
*/
protected Hashtable ejbFiles = null;
private Hashtable fileDTDs = new Hashtable();
private Hashtable resourceDTDs = new Hashtable();
private boolean inEJBRef = false;
/**
* The directory containing the bean classes and interfaces. This is
* used for performing dependency file lookups.
*/
private File srcDir;
public DescriptorHandler(File srcDir) {
this.srcDir = srcDir;
}
public void registerDTD(String publicId, String location) {
if (location == null) {
return;
}
File fileDTD = new File(location);
if (fileDTD.exists()) {
fileDTDs.put(publicId, fileDTD);
return;
}
if (getClass().getResource(location) != null) {
resourceDTDs.put(publicId, location);
}
}
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException
{
File dtdFile = (File) fileDTDs.get(publicId);
if (dtdFile != null) {
try {
return new InputSource(new FileInputStream(dtdFile));
} catch( FileNotFoundException ex ) {
// ignore
}
}
String dtdResourceName = (String)resourceDTDs.get(publicId);
if (dtdResourceName != null) {
InputStream is = this.getClass().getResourceAsStream(dtdResourceName);
if( is != null ) {
return new InputSource(is);
}
}
return null;
}
/**
* Getter method that returns the set of files to include in the EJB jar.
*/
public Hashtable getFiles() {
return (ejbFiles == null) ? new Hashtable() : ejbFiles;
}
/**
* SAX parser call-back method that is used to initialize the values of some
* instance variables to ensure safe operation.
*/
public void startDocument() throws SAXException {
this.ejbFiles = new Hashtable(10, 1);
this.currentElement = null;
inEJBRef = false;
}
/**
* SAX parser call-back method that is invoked when a new element is entered
* into. Used to store the context (attribute name) in the currentAttribute
* instance variable.
* @param name The name of the element being entered.
* @param attrs Attributes associated to the element.
*/
public void startElement(String name, AttributeList attrs)
throws SAXException {
this.currentElement = name;
currentText = "";
if (name.equals(EJB_REF)) {
inEJBRef = true;
}
}
/**
* SAX parser call-back method that is invoked when an element is exited.
* Used to blank out (set to the empty string, not nullify) the name of
* the currentAttribute. A better method would be to use a stack as an
* instance variable, however since we are only interested in leaf-node
* data this is a simpler and workable solution.
* @param name The name of the attribute being exited. Ignored
* in this implementation.
*/
public void endElement(String name) throws SAXException {
processElement();
currentText = "";
this.currentElement = "";
if (name.equals(EJB_REF)) {
inEJBRef = false;
}
}
/**
* SAX parser call-back method invoked whenever characters are located within
* an element. currentAttribute (modified by startElement and endElement)
* tells us whether we are in an interesting element (one of the up to four
* classes of an EJB). If so then converts the classname from the format
* org.apache.tools.ant.Parser to the convention for storing such a class,
* org/apache/tools/ant/Parser.class. This is then resolved into a file
* object under the srcdir which is stored in a Hashtable.
* @param ch A character array containing all the characters in
* the element, and maybe others that should be ignored.
* @param start An integer marking the position in the char
* array to start reading from.
* @param length An integer representing an offset into the
* char array where the current data terminates.
*/
public void characters(char[] ch, int start, int length)
throws SAXException {
currentText += new String(ch, start, length);
}
protected void processElement() {
if (inEJBRef) {
return;
}
if (currentElement.equals(HOME_INTERFACE) ||
currentElement.equals(REMOTE_INTERFACE) ||
currentElement.equals(BEAN_CLASS) ||
currentElement.equals(PK_CLASS)) {
// Get the filename into a String object
File classFile = null;
String className = currentText;
// If it's a primitive wrapper then we shouldn't try and put
// it into the jar, so ignore it.
if (!className.startsWith("java.lang")) {
// Translate periods into path separators, add .class to the
// name, create the File object and add it to the Hashtable.
className = className.replace('.', File.separatorChar);
className += ".class";
classFile = new File(srcDir, className);
ejbFiles.put(className, classFile);
}
}
}
}