📄 templateprocessor.java
字号:
package cz.cvut.felk.cs.metamorphoses.template;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.StringReader;import java.io.StringWriter;import java.io.UnsupportedEncodingException;import java.sql.ResultSet;import java.sql.SQLException;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import cz.cvut.felk.cs.metamorphoses.mapping.MappingAttribute;import cz.cvut.felk.cs.metamorphoses.mapping.MappingClass;import cz.cvut.felk.cs.metamorphoses.mapping.MappingCondition;import cz.cvut.felk.cs.metamorphoses.mapping.MappingProcessor;import cz.cvut.felk.cs.metamorphoses.mapping.MappingProcessorException;import cz.cvut.felk.cs.metamorphoses.mapping.MappingProperty;/** * <p>The main class of the template layer.</p> * <p> * <b>History:</b><br/> * Created: 5.3.2004<br/> * Last change: 17.8.2006<br/> * </p> * @author Martin Svihla (martin@svihla.net) */public class TemplateProcessor { public static final String TEMPLATE_NS = "http://www.svihla.net/metamorphoses/template.dtd"; /** * <code>XmlFilter</code> - if the results from a database should be checked for XML tags (if true, XML tags are removed from selected data).<br/> * This variable should be set in the MappingDocument and passed to the template processor. */ private boolean XmlFilter = true; private Document template; private BufferedWriter writer; private MappingProcessor mappingProcessor; private SqlLogic sqlLogic = new SqlLogic(); /*private*/ private HashMap classes = new HashMap(); private TemplateVariables templateVariables; public void setWriter(OutputStream outputStream) throws TemplateProcessorException { if (outputStream == null) { this.writer = null; return; } try { this.writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"), 4024); } catch (UnsupportedEncodingException e) { throw new TemplateProcessorException( "Error setting writer (unsupported encoding): " + e, e); } } /** * @param templateStream - template document (raw source - an XML document) * @param outputStream - where resulting RDF is written * @throws TemplateProcessorException * @throws MappingProcessorException */ public TemplateProcessor(InputStream templateStream, OutputStream outputStream) throws MappingProcessorException, TemplateProcessorException { this(templateStream, outputStream, null); } /** * @param templateStream - template document (raw source - an XML document) * @param outputStream - where resulting RDF is written * @param userVariables - substitute values for $variableName$ in template document * @throws TemplateProcessorException * @throws MappingProcessorException */ public TemplateProcessor(InputStream templateStream, OutputStream outputStream, Map userVariables) throws MappingProcessorException, TemplateProcessorException { InputSource is = new InputSource( new StringReader( this.preprocessTemplate(templateStream, userVariables))); this.loadTemplate(is); this.setWriter(outputStream); this.initialize(); } /** * makes DOM out of template document * @param InputSource - */ private void loadTemplate(InputSource is) throws TemplateProcessorException { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); template = builder.parse(is); } catch (Exception e) { throw new TemplateProcessorException( "Error parsing template document: " + e, e); } } /** * initialization of processor. method used by various constructors * @throws TemplateProcessorException */ private void initialize() throws MappingProcessorException, TemplateProcessorException { this.mappingProcessor = new MappingProcessor(this.getMapping()); this.getClassesFromMapping(); this.templateVariables = new TemplateVariables(); // connect to the database this.connectDatabase(); } public void closeDbConnection() throws TemplateProcessorException { try { this.sqlLogic.disconnect(); } catch (SQLException e) { throw new TemplateProcessorException( "Database connection was not closed: SQL state " + e.getSQLState(), e); } } /** * converts template stream to string so that we can do some changes before changing it to DOM. * also calls methods to do these changes (i.e. substituteUserVariables()) * @param templateStream * @param userVariables * @return * @throws TemplateProcessorException */ private String preprocessTemplate( InputStream templateStream, Map userVariables) throws TemplateProcessorException { InputStreamReader isr = new InputStreamReader(templateStream); BufferedReader br = new BufferedReader(isr); StringWriter sw = new StringWriter(); try { String s; while ((s = br.readLine()) != null) { sw.write(s); sw.write('\n'); } //sw.flush(); } catch (IOException e) { throw new TemplateProcessorException( "Converting template stream to string", e); } return substituteUserVariables(sw.getBuffer(), userVariables) .toString(); } /** * method substitutes strings $varName$ in template document for variable value from Map * @param StringBuffer sb - template document * @param Map userVariables - map of variables (varName, varValue) * @return * @throws TemplateProcessorException - when there is syntax error in template document, or no value in map for variable */ private StringBuffer substituteUserVariables( StringBuffer sb, Map userVariables) throws TemplateProcessorException { int start, end; while ((start = sb.indexOf("$")) != -1) { end = sb.indexOf("$", start + 1); if (end == -1) throw new TemplateProcessorException( "User variable not closed. '$' expected near to " + sb.substring(start, start + 8) + "..."); String varName = sb.substring(start + 1, end); String varValue = ""; if (userVariables.containsKey(varName)) varValue = userVariables.get(varName).toString(); else throw new TemplateProcessorException( "There is no value for variable '$" + varName + "$'"); sb.replace(start, end + 1, varValue); } return sb; } /** * connection to database. * parameters from mapping document are used. * @throws TemplateProcessorException */ private void connectDatabase() throws TemplateProcessorException { try { this.sqlLogic.connect( mappingProcessor.getJdbcDriver(), mappingProcessor.getJdbcUrl(), mappingProcessor.getUsername(), mappingProcessor.getPassword()); } catch (SQLException e) { throw new TemplateProcessorException( "Not connected to database: SQL state " + e.getSQLState(), e); } catch (ClassNotFoundException e) { throw new TemplateProcessorException( "Not connected to database: driver not found", e); } } /** * creates all classes mentioned by 'putInstance' in template document. * classes are objects of MappingClass. * classes are stored in hashmap in format 'className' - 'class'. */ private void getClassesFromMapping() { NodeList list = template.getElementsByTagNameNS( TemplateProcessor.TEMPLATE_NS, TemplateTags.PUT_INSTANCE); for (int i = 0, listLength = list.getLength(); i < listLength; i++) { Element elem = (Element) list.item(i); String className = elem.getAttributeNS(TemplateProcessor.TEMPLATE_NS, TemplateTags.NAME); if (!this.classes.containsKey(className)) { this.classes.put( className, mappingProcessor.getClassByTemplateName(className)); } } } /** * produces rdf from the database according to a template document and a mapping. * @return final RDF document * @throws TemplateProcessorException */ public void parse() throws TemplateProcessorException { writeToWriter(mappingProcessor.getHeader()); NodeList list = template.getElementsByTagNameNS( TemplateProcessor.TEMPLATE_NS, TemplateTags.TEMPLATE); Element templateTag = (Element) list.item(0); list = templateTag.getChildNodes(); for (int i = 0, n = list.getLength(); i < n; i++) { if (list.item(i).getNodeType() == Node.ELEMENT_NODE) { Element elem = (Element) list.item(i); if (elem.getLocalName().equals(TemplateTags.PUT_INSTANCE)) { parseInstanceNode(elem, null); } } } writeToWriter(mappingProcessor.getFoot()); try { if (this.writer!=null) this.writer.flush(); } catch (IOException e) { throw new TemplateProcessorException( "Error writing RDF: " + e.getMessage(), e); } } /** * Method parses one instance node, creates SQL query according to mapping (conditions and variables are evaluated here), gets result set and calls writeInstance method. * @param classNode - XML Element * @return RDF fragment with instances of class * @throws Exception */ private void parseInstanceNode(Element instanceNode, MappingProperty parentProperty) throws TemplateProcessorException { String className = instanceNode.getAttributeNS(TemplateProcessor.TEMPLATE_NS, TemplateTags.NAME); MappingClass mp = ((MappingClass) classes.get(className)); if (mp == null) { throw new TemplateProcessorException( "No class with name '" + className + "' in mapping."); } String sqlStatement = mp.getSql(); NodeList list = instanceNode.getChildNodes(); for (int i = 0, n = list.getLength(); i < n; i++) { if (list.item(i).getNodeType() == Node.ELEMENT_NODE) { // condition Element elem = (Element) list.item(i); if (elem.getLocalName().equals(TemplateTags.CONDITION) && elem.getFirstChild() != null) { String conditionName = elem.getAttributeNS( TemplateProcessor.TEMPLATE_NS, TemplateTags.NAME); if (!mp.getConditions().containsKey(conditionName)) { throw new TemplateProcessorException( "No condition with name '" + conditionName + "' in class '" + className + "'."); } MappingCondition cond = (MappingCondition) mp.getConditions().get( conditionName); if (!cond.getWhereSql().equals("")) { sqlStatement += " and " + cond.getWhereSql(); } if (!cond.getTableSql().equals("")) { sqlStatement = addTableToSql(sqlStatement, cond.getTableSql()); } // condition can contain variable or literal String conditionValue = ""; NodeList variableList = elem.getChildNodes(); for (int j = 0, varLength = variableList.getLength(); j < varLength; j++) { // variables in condition if (variableList.item(j).getNodeType() == Node.ELEMENT_NODE) { Element variable = (Element) variableList.item(i); if (variable.getLocalName().equals(TemplateTags.VARIABLE)) { String variableName = variable.getAttributeNS( TemplateProcessor.TEMPLATE_NS, TemplateTags.NAME); String variableId =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -