package org.objectweb.speedo.generation.parser;
import java.io.File;
import java.util.Iterator;
import java.util.Properties;
import org.apache.tools.ant.types.DTDLocation;
import org.objectweb.jorm.xml2mi.lib.SAXParserHelper;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoPackage;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.util.monolog.api.BasicLevel;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public abstract class AbstractParser extends AbstractGeneratorComponent {
public static String LOGGER_NAME
= SpeedoProperties.LOGGER_NAME + ".generation.parser.";
SAXParserHelper parser;
int parsedfiles;
abstract protected String getLoggerName();
public AbstractParser(Personality p) {
super(p);
}
/**
* Create the XML file descriptor.
* It throws an exception if the XML file doesn't follow the relevant dtd.
* @param node root node of the descriptor which will be return.
* @param o default descriptor to return.
* @return descriptor.
*/
abstract protected Object treatDocument(Node node, Object o) throws SpeedoException;
/**
* The parser instance is reused at each process method call
*/
// IMPLEMENTATION OF THE GeneratorComponent INTERFACE //
//----------------------------------------------------//
public boolean init() throws SpeedoException {
logger = scp.loggerFactory.getLogger(LOGGER_NAME + getLoggerName());
logger.log(BasicLevel.DEBUG, "- " + getLoggerName() + " XML descriptor Parsing -");
if (scp.xml.isEmpty())
return false;
Properties p = new Properties();
for (Iterator iter = scp.dtdLocations.iterator(); iter.hasNext();) {
DTDLocation element = (DTDLocation) iter.next();
p.setProperty(element.getPublicId(), element.getLocation());
}
try {
parser = new SAXParserHelper(p, logger, getClass().getClassLoader(), false);
} catch (SAXException e) {
throw new SpeedoException(e);
}
parsedfiles = 0;
return true;
}
public void process() throws SpeedoException {
if (scp.xml.isEmpty())
return;
logger.log(BasicLevel.DEBUG, scp.xml.size() + " files to parse");
for (Iterator it = scp.xml.iterator(); it.hasNext();) {
String xmlFileName = (String) it.next();
logger.log(BasicLevel.DEBUG, "Parse " + xmlFileName);
scp.getXmldescriptor().put(xmlFileName, createObjectModel(xmlFileName));
}
parsedfiles += scp.xml.size();
}
public String getTitle() {
return "Loading " + getLoggerName() + " descriptor files...";
}
public String getSummary() {
return parsedfiles + " descriptor(s) parsed";
}
// PRIVATE METHODS //
//-----------------//
/**
* This method constructs an object descriptor from a XML file.
* It returns the new object descriptor.
* If the file isn't well formed, a SpeedoXMLError is thrown.
* @param xmlFile file name.
* @return object descriptor for this file
* @exception SpeedoException if the XML file doesn't follow the
* relevant dtd.
*/
private SpeedoXMLDescriptor createObjectModel(String xmlFile)
throws SpeedoException {
try {
// parse the document
Document document = parser.parse(scp.xmlDir + File.separator + xmlFile);
//create a descriptor for the document
SpeedoXMLDescriptor desc = new SpeedoXMLDescriptor(scp.smi);
desc.xmlFile = xmlFile;
//fill and return the file descriptor
return (SpeedoXMLDescriptor) treatDocument(document, desc);
} catch (SpeedoException e) {
throw e;
} catch (Exception e) {
String msg = "Error with the construction of file "
+ scp.xmlDir + File.separator + xmlFile;
logger.log(BasicLevel.ERROR, msg);
throw new SpeedoException(msg, e);
}
}
}