001: /*
002: * MessageQueueClient: The message queue client library
003: * Copyright (C) 2007 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * RPCXMLParser.java
020: */
021:
022: // package path
023: package com.rift.coad.daemon.messageservice.message.rpc;
024:
025: // java imports
026: import java.io.ByteArrayInputStream;
027: import java.io.Serializable;
028: import java.util.ArrayList;
029: import java.util.List;
030: import javax.xml.parsers.SAXParserFactory;
031: import javax.xml.parsers.SAXParser;
032: import org.xml.sax.InputSource;
033: import org.xml.sax.helpers.DefaultHandler;
034: import org.xml.sax.SAXException;
035: import org.xml.sax.Attributes;
036:
037: /**
038: * This object is responsible for parsing the RPC xml.
039: *
040: * @author Brett Chaldecott
041: */
042: public class RPCXMLParser implements Serializable {
043:
044: /**
045: *
046: */
047:
048: /**
049: * This method will handle the parsing of the RPC xml.
050: */
051: public class RPCXMLHandler extends DefaultHandler implements
052: Serializable {
053: // class constants
054: private final static String METHOD = "method";
055: private final static String NAME = "name";
056: private final static String TYPE = "type";
057: private final static String ARGUMENT = "argument";
058:
059: // private member variables
060: private List argumentNameList = new ArrayList();
061: private List argumentTypeList = new ArrayList();
062: private boolean inMethod = false;
063:
064: /**
065: * The constructor of the rpc xml handler
066: */
067: public RPCXMLHandler() {
068:
069: }
070:
071: /**
072: * Parse the start of an element
073: *
074: * @param uri The uri of the start element
075: * @param localName The name of local object.
076: * @param qName The quick name
077: * @param attributes The attributes associated with this element.
078: * @exception SAXException
079: */
080: public void startElement(String uri, String localName,
081: String qName, Attributes attributes)
082: throws SAXException {
083: try {
084: // handle a package and retrieve the value information
085: if (qName.compareToIgnoreCase(METHOD) == 0) {
086: method = attributes.getValue(NAME);
087: if (isPrimitive(attributes.getValue(TYPE))) {
088: returnType = getPrimitive(attributes
089: .getValue(TYPE));
090: } else {
091: try {
092: returnType = Class.forName(attributes
093: .getValue(TYPE));
094: } catch (Exception ex) {
095: returnType = Thread.currentThread()
096: .getContextClassLoader().loadClass(
097: attributes.getValue(TYPE));
098: }
099: }
100: inMethod = true;
101: } else if (inMethod
102: && qName.compareToIgnoreCase(ARGUMENT) == 0) {
103: argumentNameList.add(attributes.getValue(NAME));
104: argumentTypeList.add(attributes.getValue(TYPE));
105: }
106: } catch (Exception ex) {
107: throw new SAXException("Failed to parse the element : "
108: + ex.getMessage(), ex);
109: }
110: }
111:
112: /**
113: * Handle the end of an element
114: *
115: * @param uri The uri of the element
116: * @param localName The local name of the element.
117: * @param qName The quick name of the element
118: * @exception SAXException
119: */
120: public void endElement(String uri, String localName,
121: String qName) throws SAXException {
122: try {
123: // handle a package and retrieve the value information
124: if (qName.compareToIgnoreCase(METHOD) == 0) {
125: inMethod = false;
126: argumentTypes = new Class[argumentTypeList.size()];
127: argumentNames = new String[argumentNameList.size()];
128: for (int index = 0; index < argumentTypeList.size(); index++) {
129: String name = (String) argumentTypeList
130: .get(index);
131: if (isPrimitive(name)) {
132: argumentTypes[index] = getPrimitive(name);
133: } else {
134: try {
135: argumentTypes[index] = Class
136: .forName(name);
137: } catch (Exception ex) {
138: argumentTypes[index] = Thread
139: .currentThread()
140: .getContextClassLoader()
141: .loadClass(name);
142: }
143: }
144: argumentNames[index] = (String) argumentNameList
145: .get(index);
146: }
147: }
148: } catch (Exception ex) {
149: throw new SAXException("Failed to parse the element : "
150: + ex.getMessage(), ex);
151: }
152: }
153:
154: /**
155: * This method returns true if the name identifies a primitive.
156: *
157: * @return TRUE if a primitive, FALSE if not.
158: * @param name The name of the primitive.
159: */
160: private boolean isPrimitive(String name) {
161: if (name.equals("byte") || name.equals("short")
162: || name.equals("int") || name.equals("long")
163: || name.equals("float") || name.equals("double")
164: || name.equals("boolean") || name.equals("char")
165: || name.equals("void")) {
166: return true;
167: }
168: return false;
169: }
170:
171: /**
172: * This method returns the primitive for the name.
173: *
174: * @return The reference to the class definition for the primitive
175: * @param name The name of the primitive.
176: * @exception SAXException
177: */
178: private Class getPrimitive(String name) throws SAXException {
179: if (name.equals("byte")) {
180: return byte.class;
181: } else if (name.equals("short")) {
182: return short.class;
183: } else if (name.equals("int")) {
184: return int.class;
185: } else if (name.equals("long")) {
186: return long.class;
187: } else if (name.equals("float")) {
188: return float.class;
189: } else if (name.equals("double")) {
190: return double.class;
191: } else if (name.equals("boolean")) {
192: return boolean.class;
193: } else if (name.equals("char")) {
194: return char.class;
195: } else if (name.equals("void")) {
196: return void.class;
197: }
198: throw new SAXException("Unrecognised basic type : " + name);
199: }
200: }
201:
202: // the classes private member variables
203: private String rpcXML = null;
204: private Object returnType = null;
205: private String method = null;
206: private Class[] argumentTypes = null;
207: private String[] argumentNames = null;
208:
209: /**
210: * Creates a new instance of RPCXMLParser.
211: *
212: * @param rpcXML The string to parse.
213: * @exception RPCXMLException
214: */
215: public RPCXMLParser(String rpcXML) throws RPCXMLException {
216: this .rpcXML = rpcXML;
217: try {
218: RPCXMLHandler handler = new RPCXMLHandler();
219: SAXParser parser = SAXParserFactory.newInstance()
220: .newSAXParser();
221: InputSource source = new InputSource(
222: new ByteArrayInputStream(rpcXML.getBytes()));
223: parser.parse(source, handler);
224: } catch (Exception ex) {
225: throw new RPCXMLException("Failed to parse the xml : "
226: + ex.getMessage(), ex);
227: }
228: }
229:
230: /**
231: * This method returns the RPC xml.
232: *
233: * @return The string containing the RPC xml.
234: */
235: public String getRPCXML() {
236: return rpcXML;
237: }
238:
239: /**
240: * This method returns the return type of the rpc call.
241: *
242: * @return The object containing the return type.
243: * @exception RPCXMLException
244: */
245: public Object getReturnType() {
246: return returnType;
247: }
248:
249: /**
250: * This method returns the name of the method that the XML defines.
251: *
252: * @return The name of this method.
253: */
254: public String getMethodName() {
255: return method;
256: }
257:
258: /**
259: * This method returns the list of argument types.
260: *
261: * @return The array of argument types.
262: */
263: public Class[] getArgumentTypes() {
264: return argumentTypes;
265: }
266:
267: /**
268: * This method returns the list of argument names
269: *
270: * @return The array of argument names.
271: */
272: private String[] argumentNames() {
273: return argumentNames;
274: }
275: }
|