001 package org.apache.torque.task;
002
003 import java.io.File;
004 import java.io.FileWriter;
005 import java.io.IOException;
006 import java.io.StringWriter;
007
008 import javax.xml.parsers.DocumentBuilder;
009 import javax.xml.parsers.DocumentBuilderFactory;
010 import javax.xml.parsers.ParserConfigurationException;
011 import javax.xml.transform.OutputKeys;
012 import javax.xml.transform.Result;
013 import javax.xml.transform.Transformer;
014 import javax.xml.transform.TransformerFactory;
015 import javax.xml.transform.dom.DOMSource;
016 import javax.xml.transform.stream.StreamResult;
017 import javax.xml.xpath.XPath;
018 import javax.xml.xpath.XPathConstants;
019 import javax.xml.xpath.XPathFactory;
020
021 import org.apache.tools.ant.BuildException;
022 import org.apache.tools.ant.Task;
023 import org.w3c.dom.Document;
024 import org.w3c.dom.Element;
025 import org.w3c.dom.NodeList;
026 import org.xml.sax.SAXException;
027
028 /**
029 * This ant task will merge the schema-desc.xml with schema.xml, if
030 * schema-description.xml exists
031 *
032 * @author Kuali Rice Team (kuali-rice@googlegroups.com)
033 *
034 */
035 public class TorqueMergeXMLDoc extends Task {
036
037 private static final String DESCRIPTION_ATTR = "description";
038 private static final String JAVA_NAME_ATTR = "javaName";
039 private static final String NAME_ATTR = "name";
040 private static final String COLUMN_ELEMENT = "column";
041
042 private File schemaWithDesc;
043 private File dbSchema;
044 private String schemaWithDescString;
045 private String dbSchemaString;
046 private Document schemaWithDescDoc;
047 private Document dbSchemaDoc;
048
049
050 public void setDbSchemaString(String dbSchemaString) {
051 this.dbSchemaString = dbSchemaString;
052 dbSchema = new File(dbSchemaString);
053
054 }
055
056 public void setSchemaWithDescString(String schemaWithDescString) {
057 this.schemaWithDescString = schemaWithDescString;
058 schemaWithDesc = new File(schemaWithDescString);
059
060 }
061
062 public File getDbSchema() {
063 return dbSchema;
064 }
065
066 public void setSchemaWithDesc(String schemaWithDescString) {
067 this.schemaWithDesc = new File(schemaWithDescString);
068
069 }
070
071 public void setDbSchema(String dbSchemaString) {
072 this.dbSchema = new File(dbSchemaString);
073 }
074
075 /**
076 * creates a document object from an input file
077 *
078 * @param file
079 * @return Document object
080 * @throws ParserConfigurationException
081 * @throws SAXException
082 * @throws IOException
083 */
084 public static Document setDocument(File file)
085 throws ParserConfigurationException, SAXException, IOException {
086 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
087 .newInstance();
088 DocumentBuilder documentBuilder;
089 documentBuilder = documentBuilderFactory.newDocumentBuilder();
090 Document XMLdocument = documentBuilder.parse(file);
091 XMLdocument.getDocumentElement().normalize();
092 return XMLdocument;
093 }
094
095 /**
096 * performs the merge operation by taking two input files as input and then
097 * merges the file with description into the existing schema.xml file
098 *
099 * @param schemaWithDesc
100 * @param dbSchema
101 */
102 public void mergeSchemas(File schemaWithDesc, File dbSchema) throws Exception {
103
104 schemaWithDescDoc = setDocument(schemaWithDesc);
105 dbSchemaDoc = setDocument(dbSchema);
106 dbSchemaDoc = createNewXML(dbSchemaDoc, schemaWithDescDoc);
107
108 }
109
110 /**
111 * merges the two xml document. The resulting document will be same as
112 * schema.xml except it will have a description attribute for all its tables
113 * and columns.
114 */
115 public Document createNewXML(Document dbSchemaDoc,
116 Document schemaWithDescDoc) throws Exception {
117
118 XPath xpath = XPathFactory.newInstance().newXPath();
119
120 NodeList listOfTablesInSchema = (NodeList)xpath.evaluate("/database/table", dbSchemaDoc, XPathConstants.NODESET);
121
122 for (int tableIndex = 0; tableIndex < listOfTablesInSchema.getLength(); tableIndex++) {
123 Element tableElementInSchema = (Element)listOfTablesInSchema.item(tableIndex);
124 String tableName = tableElementInSchema.getAttribute(NAME_ATTR);
125 // search the schema-description.xml file for a corresponding entry that contains the description
126 Element tableDescElem = (Element)xpath.evaluate("/database/table[@" + NAME_ATTR + "='" + tableName + "']", schemaWithDescDoc, XPathConstants.NODE);
127 if (tableDescElem != null) {
128 String tableDescription = tableDescElem.getAttribute(DESCRIPTION_ATTR);
129 String tableJavaName = tableDescElem.getAttribute(JAVA_NAME_ATTR);
130 tableElementInSchema.setAttribute(DESCRIPTION_ATTR, tableDescription);
131 tableElementInSchema.setAttribute(JAVA_NAME_ATTR, tableJavaName);
132 NodeList columnElements = tableElementInSchema.getElementsByTagName(COLUMN_ELEMENT);
133 for (int columnIndex = 0; columnIndex < columnElements.getLength(); columnIndex++) {
134 // look for the column in the schema description file
135 Element columnElementInSchema = (Element)columnElements.item(columnIndex);
136 String columnName = columnElementInSchema.getAttribute(NAME_ATTR);
137 Element columnDescElement = null;
138 NodeList columnDescElements = tableDescElem.getElementsByTagName(COLUMN_ELEMENT);
139 for (int columnDescIndex = 0; columnDescIndex < columnDescElements.getLength(); columnDescIndex++) {
140 Element element = (Element)columnDescElements.item(columnDescIndex);
141 if (columnName.equals(element.getAttribute(NAME_ATTR))) {
142 columnDescElement = element;
143 break;
144 }
145 }
146 if (columnDescElement != null) {
147 String columnDescription = columnDescElement.getAttribute(DESCRIPTION_ATTR);
148 String columnJavaName = columnDescElement.getAttribute(JAVA_NAME_ATTR);
149 columnElementInSchema.setAttribute(DESCRIPTION_ATTR, columnDescription);
150 columnElementInSchema.setAttribute(JAVA_NAME_ATTR, columnJavaName);
151 }
152 }
153 }
154 }
155 return dbSchemaDoc;
156 }
157
158 /**
159 * writes the document object to an output file
160 *
161 * @param newXMLDocument
162 * output xml document
163 */
164 public void writeXMLToFile(Document newXMLDocument) throws Exception {
165 File dbSchema = this.getDbSchema();
166 TransformerFactory tFactory = TransformerFactory.newInstance();
167
168 Transformer transformer = tFactory.newTransformer();
169 transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
170 "database.dtd");
171 DOMSource domSource = new DOMSource(newXMLDocument);
172 StringWriter writer = new StringWriter();
173 Result result = new StreamResult(writer);
174 transformer.transform(domSource, result);
175 FileWriter fileWriter = new FileWriter(dbSchema);
176
177 if (dbSchema.exists()) {
178 StringBuffer bufferedWriter = new StringBuffer(writer
179 .toString());
180 fileWriter.write(bufferedWriter.toString());
181 fileWriter.close();
182 System.out.println("The data has been written");
183 } else {
184 System.out.println("This file is not exist");
185 }
186 }
187
188 @Override
189 public void execute() throws BuildException {
190 setDbSchema(dbSchemaString);
191 setSchemaWithDesc(schemaWithDescString);
192 if (!schemaWithDesc.exists()) {
193 System.out.println("no schema file with description can be located");
194 return;
195 }
196 try {
197 mergeSchemas(schemaWithDesc, dbSchema);
198 writeXMLToFile(dbSchemaDoc);
199 } catch (Exception e) {
200 throw new BuildException(e);
201 }
202 }
203
204
205
206 }