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;
32 private int fieldIndex;
34 /** If true, we retain the full set of IDL objects in memory. This is true by default. */
35 private boolean keepIDLObjects;
37 private int parsedObjectCount;
40 IDLObjects = new HashMap<String, IDLObject>();
41 keepIDLObjects = true;
42 parsedObjectCount = 0;
46 public IDLParser(String fileName) throws IOException {
47 this(new FileInputStream(fileName));
50 public IDLParser(InputStream inStream) {
52 this.inStream = inStream;
59 public void parse() throws IOException, IDLException {
62 XMLInputFactory factory = XMLInputFactory.newInstance();
64 /** disable as many unused features as possible to speed up the parsing */
65 factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
66 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
67 factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
68 factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
69 factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
72 /** create the stream reader */
73 XMLStreamReader reader = factory.createXMLStreamReader(this.inStream);
76 while(reader.hasNext()) {
77 /** cycle through the XML events */
79 eventType = reader.next();
83 case XMLEvent.START_ELEMENT:
84 handleStartElement(reader);
87 case XMLEvent.END_ELEMENT:
88 handleEndElement(reader);
93 } catch(javax.xml.stream.XMLStreamException se) {
94 throw new IDLException("Error parsing IDL XML", se);
99 * Returns the IDLObject with the given IDLClass
101 public IDLObject getObject(String IDLClass) {
102 return (IDLObject) IDLObjects.get(IDLClass);
106 * Returns the full set of IDL objects as a hash from classname to object.
107 * If keepIDLObjects is false, the map will be empty.
109 public HashMap<String, IDLObject> getIDLObjects() {
114 * Returns the number of parsed objects, regardless of the keepIDLObjects setting.
116 public int getObjectCount() {
117 return parsedObjectCount;
121 public void handleStartElement(XMLStreamReader reader) {
123 if(!OILS_NS_BASE.equals(reader.getNamespaceURI())) return;
124 String localpart = reader.getLocalName();
126 if( "class".equals(localpart) ) {
128 current = new IDLObject();
129 current.setIDLClass(reader.getAttributeValue(null, "id"));
130 current.setController(reader.getAttributeValue(null, "controller"));
131 String persist = reader.getAttributeValue(OILS_NS_PERSIST, "virtual");
132 current.setIsVirtual("persist".equals(reader.getAttributeValue(OILS_NS_PERSIST, "virtual")));
136 if( "field".equals(localpart) ) {
137 IDLField field = new IDLField();
138 field.setName(reader.getAttributeValue(null, "name"));
139 field.setArrayPos(fieldIndex++);
140 field.setIsVirtual("true".equals(reader.getAttributeValue(OILS_NS_PERSIST, "virtual")));
141 current.addField(field);
144 if( "link".equals(localpart) ) {
145 IDLLink link = new IDLLink();
146 link.setField(reader.getAttributeValue(null, "field"));
147 link.setReltype(reader.getAttributeValue(null, "reltype"));
148 link.setKey(reader.getAttributeValue(null, "key"));
149 link.setMap(reader.getAttributeValue(null, "map"));
150 link.setIDLClass(reader.getAttributeValue(null, "class"));
151 current.addLink(link);
155 public void handleEndElement(XMLStreamReader reader) throws IDLException {
157 if(!OILS_NS_BASE.equals(reader.getNamespaceURI())) return;
158 String localpart = reader.getLocalName();
160 if("class".equals(localpart)) {
162 String[] vfields = {"isnew", "ischanged", "isdeleted"};
163 for (String fieldName : vfields) {
164 IDLField field = new IDLField();
165 field.setName(fieldName);
166 field.setArrayPos(fieldIndex++);
167 field.setIsVirtual(true);
168 current.addField(field);
172 IDLObjects.put(current.getIDLClass(), current);
174 HashMap fields = current.getFields();
175 String fieldNames[] = new String[fields.size()];
177 for(Iterator itr = fields.keySet().iterator(); itr.hasNext(); ) {
178 String key = (String) itr.next();
179 IDLField field = (IDLField) fields.get(key);
181 fieldNames[ field.getArrayPos() ] = field.getName();
182 } catch(ArrayIndexOutOfBoundsException E) {
183 String msg = "class="+current.getIDLClass()+";field="+key+
184 ";fieldcount="+fields.size()+";currentpos="+field.getArrayPos();
185 throw new IDLException(msg, E);
189 OSRFRegistry.registerObject(
190 current.getIDLClass(), OSRFRegistry.WireProtocol.ARRAY, fieldNames);
199 public String toXML() {
200 StringBuffer sb = new StringBuffer();
201 Set keys = IDLObjects.keySet();
202 Iterator itr = IDLObjects.keySet().iterator();
205 while(itr.hasNext()) {
206 IDLClass = (String) itr.next();
207 obj = IDLObjects.get(IDLClass);
210 return sb.toString();