View Javadoc

1   package org.apache.torque.task;
2   
3   import java.io.File;
4   import java.io.FileWriter;
5   import java.io.IOException;
6   import java.io.StringWriter;
7   
8   import javax.xml.parsers.DocumentBuilder;
9   import javax.xml.parsers.DocumentBuilderFactory;
10  import javax.xml.parsers.ParserConfigurationException;
11  import javax.xml.transform.OutputKeys;
12  import javax.xml.transform.Result;
13  import javax.xml.transform.Transformer;
14  import javax.xml.transform.TransformerFactory;
15  import javax.xml.transform.dom.DOMSource;
16  import javax.xml.transform.stream.StreamResult;
17  import javax.xml.xpath.XPath;
18  import javax.xml.xpath.XPathConstants;
19  import javax.xml.xpath.XPathFactory;
20  
21  import org.apache.tools.ant.BuildException;
22  import org.apache.tools.ant.Task;
23  import org.w3c.dom.Document;
24  import org.w3c.dom.Element;
25  import org.w3c.dom.NodeList;
26  import org.xml.sax.SAXException;
27  
28  /**
29   * This ant task will merge the schema-desc.xml with schema.xml, if
30   * schema-description.xml exists
31   * 
32   * @author Kuali Rice Team (kuali-rice@googlegroups.com)
33   * 
34   */
35  public class TorqueMergeXMLDoc extends Task {
36  	
37  	private static final String DESCRIPTION_ATTR = "description";
38  	private static final String JAVA_NAME_ATTR = "javaName";
39  	private static final String NAME_ATTR = "name";
40  	private static final String COLUMN_ELEMENT = "column";
41  	
42  	private File schemaWithDesc;
43  	private File dbSchema;
44  	private String schemaWithDescString;
45  	private String dbSchemaString;
46  	private Document schemaWithDescDoc;
47  	private Document dbSchemaDoc;
48  	
49  
50  	public void setDbSchemaString(String dbSchemaString) {		
51  		this.dbSchemaString = dbSchemaString;
52  		dbSchema = new File(dbSchemaString);
53  
54  	}
55  
56  	public void setSchemaWithDescString(String schemaWithDescString) {		
57  		this.schemaWithDescString = schemaWithDescString;
58  		schemaWithDesc = new File(schemaWithDescString);
59  
60  	}
61  
62  	public File getDbSchema() {
63  		return dbSchema;
64  	}
65  
66  	public void setSchemaWithDesc(String schemaWithDescString) {
67  		this.schemaWithDesc = new File(schemaWithDescString);
68  
69  	}
70  
71  	public void setDbSchema(String dbSchemaString) {
72  		this.dbSchema = new File(dbSchemaString);
73  	}
74  
75  	/**
76  	 * creates a document object from an input file
77  	 * 
78  	 * @param file
79  	 * @return Document object
80  	 * @throws ParserConfigurationException
81  	 * @throws SAXException
82  	 * @throws IOException
83  	 */
84  	public static Document setDocument(File file)
85  			throws ParserConfigurationException, SAXException, IOException {
86  		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
87  				.newInstance();
88  		DocumentBuilder documentBuilder;
89  		documentBuilder = documentBuilderFactory.newDocumentBuilder();
90  		Document XMLdocument = documentBuilder.parse(file);
91  		XMLdocument.getDocumentElement().normalize();
92  		return XMLdocument;
93  	}
94  
95  	/**
96  	 * performs the merge operation by taking two input files as input and then
97  	 * merges the file with description into the existing schema.xml file
98  	 * 
99  	 * @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 }