![JAR search and dependency download from the Maven repository](/logo.png)
com.viaoa.xml.OAXMLReader1 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oa-core Show documentation
Show all versions of oa-core Show documentation
Object Automation library
/* Copyright 1999 Vince Via [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.viaoa.xml;
import java.io.File;
import java.io.StringBufferInputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.viaoa.datasource.OADataSource;
import com.viaoa.datasource.OASelect;
import com.viaoa.hub.Hub;
import com.viaoa.object.OALinkInfo;
import com.viaoa.object.OAObject;
import com.viaoa.object.OAObjectCSDelegate;
import com.viaoa.object.OAObjectCacheDelegate;
import com.viaoa.object.OAObjectInfo;
import com.viaoa.object.OAObjectInfoDelegate;
import com.viaoa.object.OAObjectKey;
import com.viaoa.object.OAObjectKeyDelegate;
import com.viaoa.object.OAThreadLocalDelegate;
import com.viaoa.util.Base64;
import com.viaoa.util.OACompare;
import com.viaoa.util.OAConv;
import com.viaoa.util.OAConverter;
import com.viaoa.util.OAFilter;
import com.viaoa.util.OAString;
/**
* OAXMLReader using a SAXParser to parse and automatically create OAObjects from a XML file. This will do the following to find the
* existing object: 1: if OAProperty.importMatch, then it will search to find a matching object 2: if objectId props, then it will search to
* find a matching object 3: use guid if not found, then a new object will be created.
*
* @see OAXMLWriter
*/
public class OAXMLReader1 extends DefaultHandler {
private String fileName;
String value;
int indent;
String className;
int total;
boolean bWithinTag;
Object[] stack = new Object[10];
private String decodeMessage;
protected boolean bUseRef;
protected Object refValue;
protected Object firstObject;
private Object nullObject = new Object();
private static final String XML_CLASS = "XML_CLASS";
private static final String XML_KEYONLY = "XML_KEYONLY";
private static final String XML_OBJECT = "XML_OBJECT";
private static final String XML_GUID = "XML_GUID";
protected Class conversionClass; // type of class that value needs to be converted to
protected Vector vecIncomplete, vecRoot;
protected HashMap hashGuid;
protected HashMap> hmMatch = new HashMap>();
private boolean bImportMatching = true;
// flag to know if OAXMLWriter wrote the object, which adds an additonal tag for the start of each object.
private int versionOAXML;
// objects that have been removed from a Hub and might not have been saved
// these objects will then be checked and saved at the end of the import
protected Vector vecRemoved = new Vector();
public OAXMLReader1() {
}
public OAXMLReader1(String fileName) {
setFileName(fileName);
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileName() {
return this.fileName;
}
public void setImportMatching(boolean b) {
this.bImportMatching = b;
}
public boolean getImportMatching() {
return this.bImportMatching;
}
/**
* Used to parse and create OAObjects from an XML file.
*
* @return topmost object from XML file.
*/
public Object read(String fileName) throws Exception {
setFileName(fileName);
return read();
}
/**
* Used to parse and create OAObjects from an XML file.
*
* @return topmost object from XML file.
*/
public Object read() throws Exception {
return parse(this.fileName);
}
/**
* Used to parse and create OAObjects from an XML file.
*
* @return topmost object from XML file.
*/
public Object parse() throws Exception {
reset();
Object obj = null;
obj = parse(fileName);
int x = vecRemoved.size();
for (int i = 0; i < x; i++) {
OAObject oa = (OAObject) vecRemoved.elementAt(i);
if (oa.getNew()) {
continue; // object was deleted
}
if (oa.getChanged()) {
endObject(oa, false);
}
}
vecRemoved.removeAllElements();
return obj;
}
protected void reset() {
indent = 0;
total = 0;
bWithinTag = false;
vecRoot = new Vector();
vecIncomplete = new Vector();
firstObject = null;
hashGuid = new HashMap();
versionOAXML = 0;
}
/**
* Used to parse and create OAObjects from an XML file.
*
* @return topmost object from XML file.
*/
public Object parse(String fileName) throws Exception {
if (fileName == null) {
throw new IllegalArgumentException("fileName is required");
}
reset();
URI uri = null;
File f = new File(OAString.convertFileName(fileName));
if (f.exists()) {
uri = f.toURI();
} else {
uri = new URI(fileName);
}
setFileName(fileName);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
// saxParser.parse( new File(OAString.convertFileName(fileName)), this );
saxParser.parse(uri.toString(), this);
if (firstObject == nullObject) {
firstObject = null;
}
if (firstObject == null && vecRoot != null && vecRoot.size() == 1) {
firstObject = vecRoot.elementAt(0);
}
hashGuid = null;
return firstObject;
}
/**
* Used to parse and create OAObjects from an XML string.
*
* @return topmost object from XML file.
*/
public Object parseString(String xmlData) throws Exception {
if (xmlData == null) {
throw new IllegalArgumentException("xmlData is required");
}
reset();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(new StringBufferInputStream(xmlData), this);
if (firstObject == nullObject) {
firstObject = null;
}
if (firstObject == null && vecRoot != null && vecRoot.size() == 1) {
firstObject = vecRoot.elementAt(0);
}
hashGuid = null;
return firstObject;
}
/**
* Returns all root objects from last call to parse.
*/
public Object[] getRootObjects() {
int x = vecRoot == null ? 0 : vecRoot.size();
Object[] objects = new Object[x];
if (vecRoot != null) {
vecRoot.copyInto(objects);
}
return objects;
}
private void replaceRootObject(Object oldValue, Object newValue) {
if (vecRoot == null) {
return;
}
int pos = vecRoot.indexOf(oldValue);
if (pos >= 0) {
vecRoot.set(pos, newValue);
}
}
/**
* Used to unencrypt an XML file created by OAXMLWriter that used an encryption code.
*
* @see OAXMLWriter#setEncodeMessage(String)
*/
public void setDecodeMessage(String msg) {
if (msg != null && msg.length() == 0) {
throw new IllegalArgumentException("DecodeMessage cant be an empty string");
}
decodeMessage = msg;
}
public String getDecodeMessage() {
return decodeMessage;
}
/**
* SAXParser callback method.
*/
public void startElement(String namespaceURI, String sName, String qName, Attributes attrs) throws SAXException {
value = "";
bWithinTag = true;
String eName = sName; // element name
if ("".equals(eName)) {
eName = qName; // not namespaceAware
}
p(eName);
indent++;
if (indent == 1) {
versionOAXML = "OAXML".equalsIgnoreCase(eName) ? 1 : 0;
if (versionOAXML > 0) {
// ex:
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
String aName = attrs.getLocalName(i);
if (!"version".equalsIgnoreCase(aName)) {
continue;
}
String s = attrs.getValue(i);
if ("2.0".equals(s)) {
versionOAXML = 2;
}
break;
}
}
}
//todo later: if (versionOAXML == ??) throw new RuntimeException("OAXML ??? not supported");
stack[0] = null; // place holder
stack[1] = null; // place holder
return;
}
// stack ex: null | null | Department object | "Employees" | Hub object | Employee | "name" ...
// stack ex: null | null | Employee object | "Department" | Department object | "Manager" | Employee ...
if (stack.length <= indent) {
Object[] objs = new Object[stack.length + 20];
System.arraycopy(stack, 0, objs, 0, stack.length);
stack = objs;
}
stack[indent] = eName;
if (stack[indent - 1] == null || (stack[indent - 1] instanceof Vector) || (stack[indent - 1] instanceof Hub)
|| (stack[indent - 1] instanceof String)) {
// start of new object/hub
// whenever startElement() is called and the previous stack element has a String in it,
// then the next property is the reference Object/Hub
Class c = null;
try {
// Note: "INSERTCLASS" is used by JSON, and needs to be resolved by OAXMLReader here
if ("INSERTCLASS".equalsIgnoreCase(eName)) {
for (int i = indent - 1; i >= 0; i--) {
if (stack[i] == null) {
continue;
}
if (stack[i] instanceof Hub) {
eName = ((Hub) stack[i]).getObjectClass().getName();
stack[indent] = eName;
break;
}
if (stack[i] instanceof Hashtable) {
Class cx = (Class) ((Hashtable) stack[i]).get(XML_CLASS);
// find className of property
String prop = (String) stack[i + 1];
OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(cx);
cx = OAObjectInfoDelegate.getPropertyClass(oi, prop);
if (Hub.class.equals(cx)) {
OALinkInfo li = OAObjectInfoDelegate.getLinkInfo(oi, prop);
if (li != null) {
cx = li.getToClass();
}
}
eName = cx.getName();
stack[indent] = eName;
break;
}
}
}
if ("com.viaoa.hub.Hub".equals(eName)) {
c = Hub.class;
} else {
eName = resolveClassName(eName);
if (eName == null) {
eName = "com.viaoa.object.OAObject";
}
c = Class.forName(eName);
}
} catch (Exception e) {
throw new SAXException("cant find class " + eName + " Error: " + e);
}
if (c.equals(Hub.class)) {
String className = attrs.getValue("ObjectClass");
// Note: "INSERTCLASS" is used by JSON, and needs to be resolved by OAXMLReader here
if ("INSERTCLASS".equalsIgnoreCase(className)) {
for (int i = indent - 1; i >= 0; i--) {
if (stack[i] instanceof Hashtable) {
Class cx = (Class) ((Hashtable) stack[i]).get(XML_CLASS);
// find className of property
String prop = (String) stack[i + 1];
OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(cx);
cx = OAObjectInfoDelegate.getPropertyClass(oi, prop);
if (Hub.class.equals(cx)) {
OALinkInfo li = OAObjectInfoDelegate.getLinkInfo(oi, prop);
if (li != null) {
cx = li.getToClass();
}
}
className = cx.getName();
break;
}
}
}
className = resolveClassName(className);
int tot;
String stot = attrs.getValue("total");
if (OAString.isEmpty(stot)) {
tot = 0;
} else {
tot = OAConverter.toInt(stot);
}
startHub(className, tot);
if (indent > 3) {
// get Hub from previous object
Hashtable hash = (Hashtable) stack[indent - 2];
Vector vec = (Vector) hash.get(stack[indent - 1]); // name of Hub property
if (vec == null) {
vec = new Vector(43, 25);
hash.put(stack[indent - 1], vec); // propertyName, vector to hold objects
}
stack[indent] = vec; // add objects to this
} else {
try {
Hub h = new Hub(Class.forName(resolveClassName(className)));
stack[indent] = h;
vecRoot.add(h);
} catch (Exception e) {
throw new SAXException("Error getting Class for Hub: " + e);
}
}
if (firstObject == null && stack[indent - 1] == null) {
firstObject = nullObject;
}
} else {
// create hashtable to hold values
Hashtable hash = new Hashtable(23, .75f);
hash.put(XML_CLASS, c);
stack[indent] = hash;
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
String aName = attrs.getLocalName(i); // Attr name
if ("".equals(aName)) {
aName = attrs.getQName(i);
}
String aValue = attrs.getValue(i);
if (aName.equalsIgnoreCase("keyonly")) {
hash.put(XML_KEYONLY, XML_KEYONLY);
} else if (aName.equalsIgnoreCase("guid")) {
hash.put(XML_GUID, aValue);
} else {
processProperty(aName, aValue, null, hash);
}
}
}
}
} else {
// this needs to check to see if there is a "class" attribute
conversionClass = null;
String sclass = attrs.getValue("class");
if (sclass != null) {
try {
conversionClass = Class.forName(resolveClassName(sclass));
} catch (Exception e) {
throw new SAXException("cant create class " + sclass + " Error:" + e);
}
}
}
}
// 20150730
class Holder {
Class c;
OAObjectKey key;
public Holder(Class c, OAObjectKey key) {
this.c = c;
this.key = key;
}
}
/**
* SAXParser callback method.
*/
public void endElement(String namespaceURI, String sName, String qName) throws SAXException {
bWithinTag = false;
String eName = sName; // element name
if ("".equals(eName)) {
eName = qName; // not namespaceAware
}
Object stackobj = stack[indent];
if (stackobj instanceof Hashtable) {
// ending an object
/*
1: create OAObjectKey using propertyId values
2: call OAObjectCacheDelegate to find object
3: if not found, create new object
4: load/update property values
*/
final Hashtable hash = (Hashtable) stackobj;
final boolean bKeyOnly = hash.remove(XML_KEYONLY) != null;
final String guid = (String) hash.remove(XML_GUID);
final Class c = (Class) hash.get(XML_CLASS);
OAObjectInfo oi = OAObjectInfoDelegate.getOAObjectInfo(c);
String[] ids = oi.getIdProperties();
Object[] values = new Object[ids == null ? 0 : ids.length];
for (int i = 0; i < ids.length; i++) {
String id = ids[i].toUpperCase();
Class c2 = OAObjectInfoDelegate.getPropertyClass(c, id);
values[i] = hash.get(id);
if (values[i] instanceof String) {
values[i] = OAConverter.convert(c2, values[i]);
}
hash.remove(id);
}
final OAObjectKey key = new OAObjectKey(values, OAConv.toInt(guid), false);
final String[] matchProps = getImportMatching() ? oi.getImportMatchPropertyNames() : null;
final String[] matchPropPaths = getImportMatching() ? oi.getImportMatchPropertyPaths() : null;
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy