📄 xmlwriter.java
字号:
/*
Copyright (C) 2003 Together
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.webdocwf.util.xml;
//xml imports
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.enhydra.xml.SearchElement;
import org.enhydra.xml.XMLDocumentFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.sql.*;
import java.io.File;
import java.util.Properties;
import java.io.RandomAccessFile;
import java.util.ArrayList;
/**
* Load existing XML file , creating DOM from file or creating
* new DOM.Class has methods for insert,update,delete data from XML file and save new DOM in XML file.
*
* @author Zoran Milakovic
*/
public class XmlWriter {
/**
* Document made from XML file, and in which will
* be made changes.Document will be saved in XML file.
*/
public static SearchElement searchDocumentStatic;
private SearchElement searchDocument;
private Document document;
private static boolean isError = false;
/**
* If parameter is true document will be saved in xml file after each query,other wise
* document will be saved when Connection.commit() method is called.
*/
private boolean autoCommit = false;
/**
* Full path of the XML file.
*/
private String fileName;
/**
* Constructor used when autoCommit is set to false or true.
* @param fileName name of xml file.
* @param isAutoCommit define is mod auto commit or not.
*/
public XmlWriter(String fileName, boolean isAutoCommit) throws SQLException {
try {
XmlWriter.isError = false;
this.autoCommit = isAutoCommit;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//check if database exist, and if not, create one
this.fileName = fileName;
File file = new File( fileName );
if( !file.exists() ) {
file.getParentFile().mkdirs();
this.document = builder.newDocument();
Element newDatabaseElement = document.createElement("database");
newDatabaseElement.appendChild( document.createElement("dml") );
document.insertBefore( newDatabaseElement , null );
this.searchDocument = (SearchElement)SearchElement.newInstance( document );
this.createDatabase();
}
if( isAutoCommit ) {
this.document = builder.parse( file );
this.searchDocument = (SearchElement)SearchElement.newInstance( document );
} else {
if( this.searchDocumentStatic == null ) {
this.document = builder.parse( file );
this.searchDocument = (SearchElement)SearchElement.newInstance( this.document );
} else {
this.searchDocument = searchDocumentStatic;
}
}
/* set document to new value, to prevent exist of two same documents
in database to decrease memory usage */
this.document = builder.newDocument();
} catch( Exception e ) { throw new SQLException("Error in constructor : "+e.getMessage()); }
}
/**
* Adds sql statement CREATE TABLE in XML file.
* Method will throw SQLException with appropriate message if table already exist
*
* @param sqlStatement CREATE TABLE statement which will be add into XML file
* @param tableName name of table which will be created
* @throws SQLException
*/
protected void createTable(String sqlStatement, String tableName) throws SQLException {
try {
boolean allreadyExist = false;
NodeList sqlStatements = searchDocument.getSubElementsByTagName("ddl");
XmlSqlParser parser = new XmlSqlParser();
for( int i = 0; i < sqlStatements.getLength(); i++ ) {
Node node = sqlStatements.item(i);
parser.parse( node.getFirstChild().toString() );
if ( parser.getTableName().equalsIgnoreCase( tableName ) ) {
allreadyExist = true;
}
}
NodeList existingTables = searchDocument.getSubElementsByTagName("dml/"+tableName);
if( existingTables.getLength() != 0 ) {
allreadyExist = true;
}
if( allreadyExist ) {
this.isError = true;
throw new SQLException("Table with specified name already exist ! ");
} else {
Element newDDLElement = document.createElement("ddl");
newDDLElement.appendChild( document.createTextNode( sqlStatement ) );
SearchElement newDDL = new SearchElement( newDDLElement );
NodeList dml = searchDocument.getSubElementsByTagName("dml");
Element before = null;
if( dml.getLength() != 0 )
before = (Element)dml.item(0);
searchDocument.insertBefore( newDDL , before );
}
saveDOM();
} catch( Exception e ) {
this.isError = true;
throw new SQLException("Error in creating table : "+e.getMessage());
}
}
/**
* Delete row(s) from XML file.
*
* @param tableName name of table from which will be deleted rows.
* @param whereColumnNames names of columns in WHERE clause.
* @param whereColumnValues values of columns in WHERE clause.
* @throws SQLException
*/
protected void delete(String tableName, String[] whereColumnNames , String[] whereColumnValues) throws SQLException {
try {
NodeList tableRows = searchDocument.getSubElementsByTagName("dml/"+tableName);
//check if table row match conditions
for(int i = 0; i < tableRows.getLength(); i++) {
boolean isMatch = true;
if( whereColumnNames != null && whereColumnValues != null ) {
for(int k = 0; k < whereColumnNames.length; k++) {
NodeList columns = ( (SearchElement)tableRows.item(i) ).getSubElementsByCondition(whereColumnNames[k]+"="+whereColumnValues[k]);
if( columns.getLength() == 0 )
isMatch = false;
}
}
if( whereColumnNames.length == 0 )
isMatch=true;
if( isMatch ) {
//deleting row from XML database
SearchElement parent = new SearchElement( tableRows.item(i).getParentNode() );
parent.removeChild( tableRows.item(i) );
}
}
saveDOM();
} catch( Exception e ) {
this.isError = true;
throw new SQLException("Error in delete data: "+e.getMessage());
}
}
/**
* Delete table from XML file.
*
* @param tableName name of table which will be deleted.
* @throws SQLException
*/
protected void dropTable( String tableName ) throws SQLException {
try {
//delete data
NodeList tableRows = searchDocument.getSubElementsByTagName("dml/"+tableName);
for( int i = 0; i < tableRows.getLength(); i++ ) {
SearchElement parent = new SearchElement( tableRows.item(i).getParentNode() );
parent.removeChild( tableRows.item(i) );
}
//delete CREATE TABLE statement if exist
NodeList sqlStatements = searchDocument.getSubElementsByTagName("ddl");
XmlSqlParser parser = new XmlSqlParser();
for( int i = 0; i < sqlStatements.getLength(); i++ ) {
Node node = sqlStatements.item(i);
try {
parser.parse( node.getFirstChild().toString() );
} catch(Exception e) {
this.isError = true;
throw new SQLException("Error in parsing statement : "+e.getMessage());
}
if ( parser.getTableName().equalsIgnoreCase( tableName ) && parser.sqlType.equalsIgnoreCase( parser.CREATE_TABLE ) ) {
SearchElement parent = new SearchElement( sqlStatements.item(i).getParentNode() );
parent.removeChild( sqlStatements.item(i) );
}
}
saveDOM();
} catch( Exception e ) {
this.isError = true;
throw new SQLException("Error in drop table : "+e.getMessage());
}
}
/**
* Insert row in XML file.
*
* @param tableName name of table in which will be added rows.
* @param columnNames names of columns in which will be added data.
* @param columnValues value which will be insert into table.
* @throws SQLException
*/
protected void insert(String tableName, String[] columnNames , String[] columnValues) throws SQLException {
try {
String[] allColumnNames = (String[])this.getTableProperties( tableName ).get(0);
boolean hasCreateTable =
!this.getTableProperties( tableName ).get(1).toString().equalsIgnoreCase("NO CREATE TABLE");
if( hasCreateTable ) {
String[] primaryKeys = (String[])this.getTableProperties( tableName ).get(1);
//check if column is primarykey and if is it duplicate value
for(int k = 0; k < columnNames.length; k++) {
boolean isPrimarykey = false;
for(int i = 0; i < primaryKeys.length; i++) {
if( columnNames[k].equals( primaryKeys[i] ) )
isPrimarykey = true;
}
if( isPrimarykey ) {
NodeList columns = searchDocument.getSubElementsByCondition("dml/"+tableName+"/"+columnNames[k]+"="+columnValues[k]);
if( columns.getLength() != 0 ) {
this.isError = true;
throw new SQLException("Can not insert duplicate value in primary key column "+columnNames[k]+" !");
}
}
}
}
//create new table
Element newTable = document.createElement(tableName);
if( hasCreateTable ) {
//has CREATE TABLE statement
Element newColumn;
for( int i = 0; i < columnNames.length; i++ ) {
newColumn = document.createElement( columnNames[i] );
if( columnValues[i].equals("null") ) {
String[] notNullCols = (String[])this.getTableProperties( tableName ).get(2);
for( int ii=0; ii < notNullCols.length; ii++ ) {
if( notNullCols[ii].equalsIgnoreCase(columnNames[i]) )
throw new SQLException("Column '" + columnNames[i] + "' can not be NULL.");
}
//do not add empty column, because there are CREATE TABLE statement
continue;
}
else {
newColumn.appendChild( document.createTextNode( columnValues[i] ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -