001: /*=============================================================================
002: * Copyright Texas Instruments 2003-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import java.util.*;
024:
025: import oscript.exceptions.*;
026:
027: /**
028: * Utility code for XmlRpcServer/XmlRpcClient, such as type conversion.
029: * <p>
030: * The type conversion uses the following table to map types from one
031: * domain to another:
032: * <table>
033: * <tr><th>Script Type</th> <th>XML-RPC Type</th></tr>
034: * <tr><td>ExactNumber</td> <td><i4> or <int></td></tr>
035: * <tr><td>InexactNumber</td> <td><double></td></tr>
036: * <tr><td>Boolean</td> <td><boolean></td></tr>
037: * <tr><td>String</td> <td><string></td></tr>
038: * <tr><td>???</td> <td><dateTime.iso8601></td></tr>
039: * <tr><td>script object</td> <td><struct></td></tr>
040: * <tr><td>Array</td> <td><array></td></tr>
041: * <tr><td>???</td> <td><base64></td></tr>
042: * </table>
043: *
044: * @author Rob Clark (rob@ti.com)
045: */
046: public class XmlRpc {
047: /**
048: * Convert script objects to XML-RPC compatible types. Note input
049: * (Value[]) and return (Vector) represent native types used by the
050: * reflective APIs in oscript/xml-rpc libraries (respectively).
051: */
052: static Vector convertScriptToXmlRpcArgs(
053: oscript.util.MemberTable args) {
054: int alen = (args == null) ? 0 : args.length();
055: Vector arr = new Vector(alen);
056: arr.setSize(alen);
057:
058: for (int i = 0; i < alen; i++)
059: arr.setElementAt(
060: convertScriptToXmlRpc(args.referenceAt(i)), i);
061:
062: return arr;
063: }
064:
065: /**
066: * Convert a single script object to an XML-RPC compatible type.
067: */
068: static Object convertScriptToXmlRpc(Value arg) {
069: if (arg.bopInstanceOf(OExactNumber.TYPE).castToBoolean())
070: return new Integer((int) (arg.castToExactNumber()));
071: else if (arg.bopInstanceOf(OInexactNumber.TYPE).castToBoolean())
072: return new Double(arg.castToInexactNumber());
073: else if (arg.bopInstanceOf(OBoolean.TYPE).castToBoolean())
074: return new Boolean(arg.castToBoolean());
075: else if (arg.bopInstanceOf(OString.TYPE).castToBoolean())
076: return arg.castToString();
077: else if (arg.bopInstanceOf(OArray.TYPE).castToBoolean())
078: return arrayToVector(arg);
079: else if (arg.bopInstanceOf(OObject.TYPE).castToBoolean())
080: return objectToHashtable(arg);
081: else
082: return arg.castToJavaObject();
083: }
084:
085: /**
086: * Convert XML-RPC objects to script compatible types. Note input
087: * (Vector) and return (Value[]) represent native types used by the
088: * reflective APIs in oscript/xml-rpc libraries (respectively).
089: */
090: static Value[] convertXmlRpcToScriptArgs(Vector args) {
091: Value[] arr = new Value[args.size()];
092:
093: for (int i = 0; i < arr.length; i++)
094: arr[i] = convertXmlRpcToScript(args.elementAt(i));
095:
096: return arr;
097: }
098:
099: /**
100: * Convert a single XML-RPC compatible object to the corresponding
101: * native script type.
102: */
103: static Value convertXmlRpcToScript(Object arg) {
104: if (arg instanceof Integer)
105: return OExactNumber.makeExactNumber(((Integer) arg)
106: .intValue());
107: else if (arg instanceof Double)
108: return OInexactNumber.makeInexactNumber(((Double) arg)
109: .doubleValue());
110: else if (arg instanceof Boolean)
111: return OBoolean.makeBoolean(((Boolean) arg).booleanValue());
112: else if (arg instanceof String)
113: return new OString((String) arg);
114: else if (arg instanceof Vector)
115: return vectorToArray((Vector) arg);
116: else if (arg instanceof Hashtable)
117: return hashtableToObject((Hashtable) arg);
118: else
119: return JavaBridge.convertToScriptObject(arg);
120: }
121:
122: /*
123: * SOME UTILITY CONVERSION FUNCTIONS:
124: * ---- ------- ---------- ---------
125: */
126:
127: static private Vector arrayToVector(Value arg) {
128: int len = arg.length();
129: Vector arr = new Vector(len);
130: arr.setSize(len);
131:
132: for (int i = 0; i < len; i++)
133: arr.setElementAt(convertScriptToXmlRpc(arg
134: .elementAt(OExactNumber.makeExactNumber(i))), i);
135:
136: return arr;
137: }
138:
139: static private Value vectorToArray(Vector arg) {
140: Value[] arr = new Value[arg.size()];
141:
142: for (int i = 0; i < arr.length; i++)
143: arr[i] = convertXmlRpcToScript(arg.elementAt(i));
144:
145: return new OArray(arr);
146: }
147:
148: static private Hashtable objectToHashtable(Value arg) {
149: Hashtable table = new java.util.Hashtable();
150:
151: for (Enumeration e = Debugger.enumerateMembers(arg); e
152: .hasMoreElements();) {
153: Value symbol = (Value) (e.nextElement());
154: Value member = arg.getMember(symbol);
155:
156: if (!((member instanceof JavaMethodWrapper) || (member instanceof Function))) {
157: System.err.println("symbol=" + symbol + " ("
158: + symbol.getClass().getName() + "), member="
159: + member + " (" + member.getClass().getName()
160: + ")");
161: Object foo = convertScriptToXmlRpc(arg
162: .getMember(symbol));
163: System.err.println("foo=" + foo + " ("
164: + foo.getClass().getName() + ")");
165: table.put(symbol.castToString(),
166: convertScriptToXmlRpc(arg.getMember(symbol)));
167: }
168: }
169:
170: return table;
171: }
172:
173: static private Value hashtableToObject(Hashtable arg) {
174: Scope obj = new XmlRpcStruct();
175:
176: for (Enumeration e = arg.keys(); e.hasMoreElements();) {
177: String symbol = (String) (e.nextElement());
178: obj.createMember(symbol,
179: Reference.ATTR_PUBLIC | Reference.ATTR_CONST)
180: .opAssign(convertXmlRpcToScript(arg.get(symbol)));
181: }
182:
183: return obj;
184: }
185:
186: private static final Scope GLOBAL_SCOPE = oscript.OscriptInterpreter
187: .getGlobalScope();
188: private static final int STRUCT_ID = Symbol.getSymbol(
189: "XmlRpcStruct").getId();
190: public static final Value STRUCT_TYPE = new Function(GLOBAL_SCOPE,
191: OObject.TYPE, new Function.FunctionData(STRUCT_ID,
192: new int[0], false, null, null, null, true, true,
193: null));
194:
195: private static class XmlRpcStruct extends BasicScope {
196: XmlRpcStruct() {
197: super (GLOBAL_SCOPE);
198: }
199:
200: protected Value getTypeImpl() {
201: return STRUCT_TYPE;
202: }
203: }
204: }
205:
206: /*
207: * Local Variables:
208: * tab-width: 2
209: * indent-tabs-mode: nil
210: * mode: java
211: * c-indentation-style: java
212: * c-basic-offset: 2
213: * eval: (c-set-offset 'substatement-open '0)
214: * eval: (c-set-offset 'case-label '+)
215: * eval: (c-set-offset 'inclass '+)
216: * eval: (c-set-offset 'inline-open '0)
217: * End:
218: */
|