1 package org.webdocwf.util.xml;
2
3 //xml imports
4 import org.w3c.dom.Document;
5 import org.w3c.dom.NodeList;
6 import org.w3c.dom.Node;
7 import org.w3c.dom.Element;
8 import org.enhydra.xml.*;
9 import javax.xml.parsers.DocumentBuilder;
10 import javax.xml.parsers.DocumentBuilderFactory;
11 //XMLdriver imports
12 import org.enhydra.xml.SearchElement;
13
14 import java.sql.*;
15 import java.io.File;
16 import java.util.ArrayList;
17
18 /***
19 * Load existing XML file , creating DOM from file or creating
20 * new DOM.Methods will change DOM and save new DOM in XML file.
21 *
22 * @version 1.0
23 * @author Zoran Milakovic
24 */
25
26 public class XmlWriter {
27
28 /***
29 * Document made from XML file, and in which will
30 * be made changes.Document will be saved in XML file.
31 */
32 private SearchElement searchDocument;
33 private Document document;
34 /***
35 * Full path of the XML file.
36 */
37 private String fileName;
38
39 /***
40 * Constructor will build Document from the specified file
41 * if file exist, or will create new Document if file not exist.
42 *
43 * @param fileName full pathname of the XML file
44 * @throws SQLException
45 */
46 public XmlWriter(String fileName) throws SQLException {
47 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
48 try {
49 this.fileName = fileName;
50 File file = new File( fileName );
51 DocumentBuilder builder = factory.newDocumentBuilder();
52 try {
53 this.document = builder.parse( file );
54 } catch( Exception e ) {
55 this.document = builder.newDocument();
56 Element newDatabaseElement = document.createElement("database");
57 newDatabaseElement.appendChild( document.createElement("dml") );
58 document.insertBefore( newDatabaseElement , null );
59 }
60 this.searchDocument = (SearchElement)SearchElement.newInstance( document );
61 this.document = builder.newDocument();
62 } catch( Exception e ) { throw new SQLException("Error in creating DOM : "+e.getMessage()); }
63 }
64
65 /***
66 * Adds sql statement CREATE TABLE in XML file.
67 * Method will throw SQLException with appropriate message if table allready exist
68 *
69 * @param sqlStatement CREATE TABLE statement which will be add into XML file
70 * @param tableName name of table which will be created
71 * @param sqlStatement sql statement which will be proceeded
72 * @throws SQLException
73 */
74
75 protected void createTable(String sqlStatement, String tableName) throws SQLException {
76 try {
77 boolean allreadyExist = false;
78 NodeList sqlStatements = searchDocument.getSubElementsByTagName("ddl");
79 SqlParser parser = new SqlParser( this.fileName );
80 for( int i = 0; i < sqlStatements.getLength(); i++ ) {
81 Node node = sqlStatements.item(i);
82 parser.parse( node.getFirstChild().toString() );
83 if ( parser.getTableName().equalsIgnoreCase( tableName ) ) {
84 allreadyExist = true;
85 }
86 }
87 NodeList existingTables = searchDocument.getSubElementsByTagName("dml/"+tableName);
88 if( existingTables.getLength() != 0 ) {
89 allreadyExist = true;
90 }
91 if( allreadyExist ) {
92 throw new SQLException("Table with specified name allready exist ! ");
93 } else {
94 Element newDDLElement = document.createElement("ddl");
95 newDDLElement.appendChild( document.createTextNode( sqlStatement ) );
96 HashMapElement newDDL = new HashMapElement( newDDLElement );
97 NodeList dml = searchDocument.getSubElementsByTagName("dml");
98 Element before = null;
99 if( dml.getLength() != 0 )
100 before = (Element)dml.item(0);
101 searchDocument.insertBefore( newDDL , before );
102 }
103 saveDOM( searchDocument );
104 } catch( Exception e ) { throw new SQLException("Error in creating table : "+e.getMessage()); }
105 }
106
107 /***
108 * Method will delete row(s) from XML file.
109 *
110 * @param sqlStatement CREATE TABLE statement which will be add into XML file
111 * @param tableName name of table from which will be deleted rows.
112 * @param whereColumnNames names of columns in WHERE clause.
113 * @param whereColumnValues values of columns in WHERE clause.
114 * @throws SQLException
115 */
116 protected void delete(String tableName, String[] whereColumnNames , String[] whereColumnValues) throws SQLException {
117 try {
118 NodeList tableRows = searchDocument.getSubElementsByTagName("dml/"+tableName);
119 //check if table row match conditions
120 for(int i = 0; i < tableRows.getLength(); i++) {
121 boolean isMatch = true;
122 if( whereColumnNames != null && whereColumnValues != null ) {
123 for(int k = 0; k < whereColumnNames.length; k++) {
124 NodeList columns = ( (SearchElement)tableRows.item(i) ).getSubElementsByCondition(whereColumnNames[k]+"="+whereColumnValues[k]);
125 if( columns.getLength() == 0 )
126 isMatch = false;
127 }
128 }
129 if( whereColumnNames.length == 0 )
130 isMatch=true;
131 if( isMatch ) {
132 //deleting row from XML database
133 HashMapElement parent = new HashMapElement( tableRows.item(i).getParentNode() );
134 parent.removeChild( tableRows.item(i) );
135 }
136 }
137 saveDOM( searchDocument );
138 } catch( Exception e ) { throw new SQLException("Error in delete data: "+e.getMessage()); }
139 }
140
141 /***
142 * Method will delete row(s) from XML file.
143 *
144 * @param sqlStatement CREATE TABLE statement which will be add into XML file
145 * @param tableName name of table which will be deleted.
146 * @throws SQLException
147 */
148 protected void dropTable( String tableName ) throws SQLException {
149 try {
150 //delete data
151 NodeList tableRows = searchDocument.getSubElementsByTagName("dml/"+tableName);
152 for( int i = 0; i < tableRows.getLength(); i++ ) {
153 HashMapElement parent = new HashMapElement( tableRows.item(i).getParentNode() );
154 parent.removeChild( tableRows.item(i) );
155 }
156 //delete CREATE TABLE statement if exist
157 NodeList sqlStatements = searchDocument.getSubElementsByTagName("ddl");
158 SqlParser parser = new SqlParser( this.fileName );
159 for( int i = 0; i < sqlStatements.getLength(); i++ ) {
160 Node node = sqlStatements.item(i);
161 try {
162 parser.parse( node.getFirstChild().toString() );
163 } catch(Exception e) { throw new SQLException("Error in parsing statement : "+e.getMessage()); }
164 if ( parser.getTableName().equalsIgnoreCase( tableName ) && parser.sqlType.equalsIgnoreCase( parser.CREATE_TABLE ) ) {
165 HashMapElement parent = new HashMapElement( sqlStatements.item(i).getParentNode() );
166 parent.removeChild( sqlStatements.item(i) );
167 }
168 }
169 saveDOM( searchDocument );
170 } catch( Exception e ) { throw new SQLException("Error in drop table : "+e.getMessage()); }
171 }
172
173
174 /***
175 * Method will insert row in XML file.
176 *
177 * @param sqlStatement CREATE TABLE statement which will be add into XML file
178 * @param tableName name of table in which will be added rows.
179 * @param columnNames names of columns in which will be added data.
180 * @param columnValues value which will be insert into table.
181 * @throws SQLException
182 */
183 protected void insert(String tableName, String[] columnNames , String[] columnValues) throws SQLException {
184 try {
185 String[] allColumnNames = (String[])this.getTableProperties( tableName ).get(0);
186 boolean noCreateTable = false;
187 if( this.getTableProperties( tableName ).get(1).toString().equalsIgnoreCase("NO CREATE TABLE") ) {
188 noCreateTable = true;
189 }
190 if( !noCreateTable ) {
191 String[] primaryKeys = (String[])this.getTableProperties( tableName ).get(1);
192 //check if column is primarykey and if is it duplicate value
193 for(int k = 0; k < columnNames.length; k++) {
194 boolean isPrimarykey = false;
195 for(int i = 0; i < primaryKeys.length; i++) {
196 if( columnNames[k].equals( primaryKeys[i] ) )
197 isPrimarykey = true;
198 }
199 if( isPrimarykey ) {
200 NodeList columns = searchDocument.getSubElementsByCondition("dml/"+tableName+"/"+columnNames[k]+"="+columnValues[k]);
201 if( columns.getLength() != 0 )
202 throw new SQLException("Can not insert duplicate value in primary key column "+columnNames[k]+" !");
203 }
204 }
205 }
206 //create new table
207 Element newTable = document.createElement(tableName);
208 if( !noCreateTable ) {
209 Element newColumn;
210 for( int i = 0; i < columnNames.length; i++ ) {
211 newColumn = document.createElement( columnNames[i] );
212 if( columnValues[i].equalsIgnoreCase("null") )
213 newColumn.appendChild( document.createTextNode( "" ) );
214 else
215 newColumn.appendChild( document.createTextNode( columnValues[i] ) );
216 newTable.appendChild( newColumn );
217 }
218 } else {
219 Element newColumn;
220 for( int i = 0; i < allColumnNames.length; i++ ) {
221 newColumn = document.createElement( allColumnNames[i] );
222 for( int j = 0; j < columnNames.length; j++ ) {
223 if( allColumnNames[i].equalsIgnoreCase( columnNames[j] ) ){
224 if( columnValues[i].equalsIgnoreCase("null") )
225 newColumn.appendChild( document.createTextNode( "" ) );
226 else
227 newColumn.appendChild( document.createTextNode( columnValues[i] ) );
228 }
229 else {
230 newColumn.appendChild( document.createTextNode("") );
231 }
232 }
233 newTable.appendChild( newColumn );
234 }
235 }
236
237 HashMapElement newTableHash = new HashMapElement( newTable );
238 NodeList tables = searchDocument.getSubElementsByTagName("dml/"+tableName);
239 Element before = null;
240 if( tables.getLength() != 0 ) {
241 before = (Element)tables.item(0);
242 searchDocument.insertBefore( newTableHash , before );
243 } else {
244 searchDocument.getSubElementsByTagName("dml").item(0).appendChild( newTableHash );
245 }
246 saveDOM( searchDocument );
247 } catch( Exception e ) { throw new SQLException("Error in insert data : "+e.getMessage()); }
248 }
249
250 /***
251 * Method will update row in in XML file.
252 *
253 * @param sqlStatement CREATE TABLE statement which will be add into XML file
254 * @param tableName name of table which will be updatad.
255 * @param columnNames names of columns in which will be added data.
256 * @param columnValues value which will be insert into table.
257 * @param whereColumnNames names of columns in WHERE clause.
258 * @param whereColumnValues values of columns in WHERE clause.
259 * @throws SQLException
260 */
261 protected void update(String tableName, String[] columnNames , String[] columnValues , String[] whereColumnNames , String[] whereColumnValues ) throws SQLException {
262 try {
263 if( !this.getTableProperties( tableName ).get(1).toString().equalsIgnoreCase("NO CREATE TABLE") ) {
264 String[] primaryKeys = (String[])this.getTableProperties( tableName ).get(1);
265 boolean isPrimarykey = false;
266 for(int i = 0; i < primaryKeys.length; i++) {
267 if( columnNames[0].equals( primaryKeys[i] ) )
268 isPrimarykey = true;
269 }
270 if( isPrimarykey ) {
271 NodeList columns = searchDocument.getSubElementsByCondition("dml/"+tableName+"/"+columnNames[0]+"="+columnValues[0]);
272 if( columns.getLength() != 0 )
273 throw new SQLException("Can not insert duplicate value in primarykey column "+columnNames[0]+" !");
274 }
275 }
276 NodeList tableRows = searchDocument.getSubElementsByTagName("dml/"+tableName);
277 //check if table row match conditions
278 for(int i = 0; i < tableRows.getLength(); i++) {
279 boolean isMatch = true;
280 if( whereColumnNames != null && whereColumnValues != null ) {
281 for(int k = 0; k < whereColumnNames.length; k++) {
282 NodeList columns = ( (SearchElement)tableRows.item(i) ).getSubElementsByCondition(whereColumnNames[k]+"="+whereColumnValues[k]);
283 if( columns.getLength() == 0 )
284 isMatch = false;
285 }
286 }
287 if( isMatch ) {
288 for( int k = 0; k < columnNames.length; k++ ) {
289 NodeList columns = ( (SearchElement)tableRows.item(i) ).getSubElementsByTagName(columnNames[k]);
290 if( columns.getLength() == 0 ) {
291 Element newColumn = document.createElement( columnNames[k] );
292 if( columnValues[k].equalsIgnoreCase("null") )
293 newColumn.appendChild( document.createTextNode( "" ) );
294 else
295 newColumn.appendChild( document.createTextNode( columnValues[k] ) );
296 tableRows.item(i).appendChild( new HashMapElement(newColumn) );
297 } else {
298 HashMapElement column = (HashMapElement)columns.item(0);
299 Node textNode = column.getFirstChild();
300 if( textNode == null ) {
301 Element newColumn = document.createElement( columnNames[k] );
302 if( columnValues[k].equalsIgnoreCase("null") )
303 newColumn.appendChild( document.createTextNode( "" ) );
304 else
305 newColumn.appendChild( document.createTextNode( columnValues[k] ) );
306 SearchElement parent = new SearchElement( column.getParentNode() );
307 parent.replaceChild( new HashMapElement(newColumn) , column );
308 }
309 else
310 column.getFirstChild().setNodeValue( columnValues[k] );
311 }
312 }
313 }
314 }
315 saveDOM( searchDocument );
316 } catch( Exception e ) { throw new SQLException("Error in update data : "+e.getMessage()); }
317 }
318
319 /***
320 * Gets table properties in form ArrayList.
321 * ArrayList[0] is string array with ALL column names in table.
322 * ArrayList[1] is string array with colmn names which are PRIMARYKEYs.
323 * ArrayList[2] is string array with colmn names which can not be NULL.
324 *
325 * If table has no CREATE TABLE statement , ArrayList[1] will have value "NO CREATE TABLE"
326 *
327 * @param tableName name of table.
328 * @return list of table properties.
329 * @throws SQLException
330 */
331 public ArrayList getTableProperties(String tableName) throws SQLException {
332 ArrayList properties = new ArrayList();
333 NodeList sqlStatements = searchDocument.getSubElementsByTagName("ddl");
334 SqlParser parser = new SqlParser( this.fileName );
335 for( int i = 0; i < sqlStatements.getLength(); i++ ) {
336 Node node = sqlStatements.item(i);
337 try {
338 parser.parse( node.getFirstChild().toString() );
339 } catch(Exception e) { throw new SQLException("Error in parsing statement : "+e.getMessage()); }
340 if ( parser.getTableName().equalsIgnoreCase( tableName ) && parser.sqlType.equalsIgnoreCase( parser.CREATE_TABLE ) ) {
341 properties.add( parser.getColumnNames() );
342 properties.add( parser.getPrimaryKeys() );
343 properties.add( parser.getNotnullColumns() );
344 }
345 }
346 // no CREATE TABLE statement
347 if( properties.size() == 0 ) {
348 NodeList tableTags = searchDocument.getSubElementsByTagName("dml/"+tableName);
349 if( tableTags.getLength() == 0 ) {
350 throw new SQLException("No existing table with specified name : "+tableName);
351 }
352 if( tableTags.getLength() != 0 ) {
353 NodeList tableColumns = tableTags.item(0).getChildNodes();
354 ArrayList arrColumns = new ArrayList();
355 for( int i = 0; i < tableColumns.getLength(); i++ ) {
356 String value = tableColumns.item(i).getNodeName();
357 if( value != null && !value.equalsIgnoreCase("#text") ) {
358 arrColumns.add( tableColumns.item(i).getNodeName() );
359 }
360 }
361 properties.add( arrColumns.toArray(new String[0]) );
362 properties.add( "NO CREATE TABLE" );
363 }
364 }
365 return properties;
366 }
367
368 /***
369 * Save DOM as XML file.
370 *
371 * @param document DOM which will be saved in XML file.
372 * @throws SQLException
373 */
374 protected void saveDOM(Node document) throws SQLException {
375 try {
376 XMLDocumentFactory.serialize( document , fileName , null );
377 } catch( Exception e ) { throw new SQLException("Error in saving DOM in XML file : "+e.getMessage()); }
378 }
379
380 }
381
This page automatically generated by Maven