1 package org.open_ils.idl;
3 import org.opensrf.util.*;
5 import java.util.HashMap;
7 import java.util.Iterator;
9 import java.io.InputStream;
10 import java.io.FileInputStream;
11 import java.io.IOException;
13 import javax.xml.stream.*;
14 import javax.xml.stream.events.* ;
15 import javax.xml.namespace.QName;
18 public class IDLParser {
20 public static final String OILS_NS_BASE="http://opensrf.org/spec/IDL/base/v1";
21 public static final String OILS_NS_OBJ="http://open-ils.org/spec/opensrf/IDL/objects/v1";
22 public static final String OILS_NS_OBJ_PREFIX="oils_obj";
23 public static final String OILS_NS_PERSIST="http://open-ils.org/spec/opensrf/IDL/persistence/v1";
24 public static final String OILS_NS_PERSIST_PREFIX="oils_persist";
25 public static final String OILS_NS_REPORTER="http://open-ils.org/spec/opensrf/IDL/reporter/v1";
26 public static final String OILS_NS_REPORTER_PREFIX="reporter";
28 /** The source for the IDL XML */
30 HashMap<String, IDLObject> IDLObjects;
33 /** If true, we retain the full set of IDL objects in memory. This is true by default. */
34 private boolean keepIDLObjects;
36 private int parsedObjectCount;
39 IDLObjects = new HashMap<String, IDLObject>();
40 keepIDLObjects = true;
41 parsedObjectCount = 0;
44 public IDLParser(String fileName) throws IOException {
45 this(new FileInputStream(fileName));
48 public IDLParser(InputStream inStream) {
50 this.inStream = inStream;
57 public void parse() throws IOException, IDLException {
60 XMLInputFactory factory = XMLInputFactory.newInstance();
62 /** disable as many unused features as possible to speed up the parsing */
63 factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
64 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
65 factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
66 factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
67 factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
70 /** create the stream reader */
71 XMLStreamReader reader = factory.createXMLStreamReader(this.inStream);
74 while(reader.hasNext()) {
75 /** cycle through the XML events */
77 eventType = reader.next();
81 case XMLEvent.START_ELEMENT:
82 handleStartElement(reader);
85 case XMLEvent.END_ELEMENT:
86 handleEndElement(reader);
91 } catch(javax.xml.stream.XMLStreamException se) {
92 throw new IDLException("Error parsing IDL XML", se);
97 * Returns the IDLObject with the given IDLClass
99 public IDLObject getObject(String IDLClass) {
100 return (IDLObject) IDLObjects.get(IDLClass);
104 * Returns the full set of IDL objects as a hash from classname to object.
105 * If keepIDLObjects is false, the map will be empty.
107 public HashMap<String, IDLObject> getIDLObjects() {
112 * Returns the number of parsed objects, regardless of the keepIDLObjects setting.
114 public int getObjectCount() {
115 return parsedObjectCount;
119 public void handleStartElement(XMLStreamReader reader) {
121 if(!OILS_NS_BASE.equals(reader.getNamespaceURI())) return;
122 String localpart = reader.getLocalName();
124 if( "class".equals(localpart) ) {
125 current = new IDLObject();
126 current.setIDLClass(reader.getAttributeValue(null, "id"));
127 current.setController(reader.getAttributeValue(null, "controller"));
128 String persist = reader.getAttributeValue(OILS_NS_PERSIST, "virtual");
129 current.setIsVirtual("persist".equals(reader.getAttributeValue(OILS_NS_PERSIST, "virtual")));
133 if( "field".equals(localpart) ) {
134 IDLField field = new IDLField();
135 field.setName(reader.getAttributeValue(null, "name"));
136 field.setArrayPos(new Integer(reader.getAttributeValue(OILS_NS_OBJ, "array_position")));
137 field.setIsVirtual("true".equals(reader.getAttributeValue(OILS_NS_PERSIST, "virtual")));
138 current.addField(field);
141 if( "link".equals(localpart) ) {
142 IDLLink link = new IDLLink();
143 link.setField(reader.getAttributeValue(null, "field"));
144 link.setReltype(reader.getAttributeValue(null, "reltype"));
145 link.setKey(reader.getAttributeValue(null, "key"));
146 link.setMap(reader.getAttributeValue(null, "map"));
147 link.setIDLClass(reader.getAttributeValue(null, "class"));
148 current.addLink(link);
152 public void handleEndElement(XMLStreamReader reader) throws IDLException {
154 if(!OILS_NS_BASE.equals(reader.getNamespaceURI())) return;
155 String localpart = reader.getLocalName();
157 if("class".equals(localpart)) {
160 IDLObjects.put(current.getIDLClass(), current);
162 HashMap fields = current.getFields();
163 String fieldNames[] = new String[fields.size()];
165 for(Iterator itr = fields.keySet().iterator(); itr.hasNext(); ) {
166 String key = (String) itr.next();
167 IDLField field = (IDLField) fields.get(key);
169 fieldNames[ field.getArrayPos() ] = field.getName();
170 } catch(ArrayIndexOutOfBoundsException E) {
171 String msg = "class="+current.getIDLClass()+";field="+key+
172 ";fieldcount="+fields.size()+";currentpos="+field.getArrayPos();
173 throw new IDLException(msg, E);
177 OSRFRegistry.registerObject(
178 current.getIDLClass(), OSRFRegistry.WireProtocol.ARRAY, fieldNames);
187 public String toXML() {
188 StringBuffer sb = new StringBuffer();
189 Set keys = IDLObjects.keySet();
190 Iterator itr = IDLObjects.keySet().iterator();
193 while(itr.hasNext()) {
194 IDLClass = (String) itr.next();
195 obj = IDLObjects.get(IDLClass);
198 return sb.toString();