001: /******************************************************************************
002: * ClientSOAPService.java
003: * ****************************************************************************/package org.openlaszlo.remote.json.soap;
004:
005: import java.io.*;
006: import java.util.*;
007: import javax.xml.namespace.QName;
008: import org.openlaszlo.sc.ScriptCompiler;
009: import org.openlaszlo.utils.*;
010: import org.apache.log4j.Logger;
011:
012: public class ClientSOAPService {
013: public static Logger mLogger = Logger
014: .getLogger(ClientSOAPService.class);
015: StringBuffer body = new StringBuffer();
016:
017: public ClientSOAPService() {
018: }
019:
020: public String createObjectProgram(LZSOAPService service) {
021:
022: // object.__LZstubload
023: //------------------------------------------------------------
024: // Tells client data returned is an object
025: // this.__LZstubload = true
026: body.append("{");
027: body.append("__LZstubload: true,");
028:
029: // SOAP specific information
030: // object.stubinfo
031: body.append("stubinfo: ");
032: {
033: body.append("{");
034: //------------------------------------------------------------
035: // this.service = service.getServiceName()
036: body.append("service:"
037: + ScriptCompiler.quote(service.getServiceName())
038: + ", ");
039:
040: //------------------------------------------------------------
041: // this.port = service.getPort()
042: body.append("port: "
043: + ScriptCompiler.quote(service.getPort()) + ",");
044:
045: //------------------------------------------------------------
046: // this.wsdl = service.getWSDL()
047: body.append("wsdl: "
048: + ScriptCompiler.quote(service.getWSDL()) + ",");
049:
050: //------------------------------------------------------------
051: // this.ctypes = <complexTypeInfoObject>
052: body.append("__LZctypes: ");
053: pushComplexTypeInfo(service.getSchemaComplexTypes());
054: body.append(", ");
055:
056: //------------------------------------------------------------
057: // this._namespace = namespace /* target namespace */
058: body.append("__LZnamespace: "
059: + ScriptCompiler.quote(service.getTargetNS()));
060:
061: body.append("},");
062: }
063:
064: // object.stub
065: body.append("stub: ");
066: {
067: body.append("{");
068:
069: int count = 0;
070: //------------------------------------------------------------
071: // Create client-side service operations. Assuming that
072: // operations won't be null.
073: //------------------------------------------------------------
074: Map operations = service.getOperations();
075: Iterator iter = operations.keySet().iterator();
076: while (iter.hasNext()) {
077:
078: String opName = (String) iter.next();
079: LZSOAPOperation op = (LZSOAPOperation) operations
080: .get(opName);
081:
082: if (mLogger.isDebugEnabled()) {
083: mLogger.debug(
084: /* (non-Javadoc)
085: * @i18n.test
086: * @org-mes="adding operation: " + p[0]
087: */
088: org.openlaszlo.i18n.LaszloMessages.getMessage(
089: ClientSOAPService.class.getName(),
090: "051018-99", new Object[] { opName }));
091: }
092:
093: //------------------------------------------------------------
094: //
095: if (count++ > 0) {
096: body.append(",");
097: }
098:
099: body.append(opName + ": function () {");
100: {
101: // arguments.callee.args gets set in the client and includes
102: // secure and secureport information.
103: //
104: // var args = arguments.callee.args;
105: body.append("var args = arguments.callee.args;\n");
106:
107: body.append("return LzSOAPService.invoke(");
108:
109: // _root.LzSOAP.invoke(
110: // delegate,
111: // args
112: // header
113: // opts, /* wsdl, service, port, operation, parts */
114: // this.secure,
115: // this.secureport,
116: // );
117:
118: // 1. arguments[1] (should be delegate)
119: body.append("arguments[1]");
120: body.append(",");
121:
122: // 2. arguments[0] (should be array of arguments)
123: body.append("arguments[0]");
124: body.append(",");
125:
126: // 3. requestheaders
127: body.append("args.superclass.requestheaders");
128: body.append(",");
129:
130: // 4. opts
131: {
132: body.append("{");
133:
134: // 6. argument array of parameter type tuples like:
135: // [
136: // [ name1, element1, type1(qname) ],
137: // [ name2, element2, type2(qname) ]
138: body.append("parts: ");
139: // ]
140:
141: pushParts(op.getInputMessage(), op.getStyle());
142: body.append(",");
143:
144: // 5. operation type
145: body.append("opstyle: ");
146: body
147: .append(ScriptCompiler.quote(op
148: .getStyle()));
149:
150: body.append(",");
151:
152: // 4. operation name
153: body.append("operation: ");
154: body.append(ScriptCompiler.quote(opName));
155: body.append(",");
156:
157: // 3. SOAP port
158: body.append("port: ");
159: body.append(ScriptCompiler.quote(service
160: .getPort()));
161: body.append(",");
162:
163: // 2. SOAP service
164: body.append("service: ");
165: body.append(ScriptCompiler.quote(service
166: .getServiceName()));
167: body.append(",");
168:
169: // 1. SOAP wsdl
170: body.append("wsdl: ");
171: body.append(ScriptCompiler.quote(service
172: .getWSDL()));
173: body.append("}");
174: }
175: body.append(",");
176:
177: // 5. secure
178: body.append("args.superclass.secure");
179: body.append(",");
180:
181: // 6. secureport
182: body.append("args.superclass.secureport");
183:
184: body.append(");");
185: body.append("}");
186: }
187: }
188: body.append("}");
189: }
190: body.append("}");
191: return body.toString();
192: }
193:
194: public String pushQName(QName qname) {
195: if (qname == null) {
196: return "null";
197: }
198: // this can be optimized
199: return ("new QName("
200: + ScriptCompiler.quote(qname.getLocalPart()) + ","
201: + ScriptCompiler.quote(qname.getNamespaceURI()) + ")");
202: }
203:
204: void pushParts(LZSOAPMessage inMesg, String style) {
205: if (inMesg == null) {
206: body.append("null");
207: return;
208: }
209:
210: body.append("[");
211: List parts = inMesg.getParts();
212: int item = 0;
213: for (int i = 0; i < parts.size(); i++) {
214: if (item++ > 0) {
215: body.append(",");
216: }
217:
218: LZSOAPPart part = (LZSOAPPart) parts.get(i);
219: String name = part.getName();
220: String element = part.getElement();
221: ComplexType type = part.getType();
222: QName typeName = (type != null ? type.getName() : null);
223: body.append("[");
224: if (style.equals("rpc")) {
225: // rpc calls use the name of the part as the name of element.
226: body.append(ScriptCompiler.quote(name));
227: } else {
228: // documents use element name
229: body.append(ScriptCompiler.quote(element));
230: }
231: body.append(",");
232: body.append(pushQName(typeName));
233: body.append("]");
234: }
235: body.append("]");
236: }
237:
238: /**
239: * @param program Program
240: * @param ctm complex type map
241: */
242: public void pushComplexTypeInfo(Map ctm) {
243: if (ctm == null) {
244: body.append("null");
245: return;
246: }
247:
248: Iterator iter = ctm.entrySet().iterator();
249: if (!iter.hasNext()) {
250: body.append("null");
251: return;
252: }
253:
254: body.append("{");
255: int count = 0;
256: while (iter.hasNext()) {
257: Map.Entry entry = (Map.Entry) iter.next();
258: ComplexType ct = (ComplexType) entry.getValue();
259: if (count > 0) {
260: body.append(", ");
261: }
262: if (null != (ct.getName().getLocalPart())
263: || !((ct.getName().getLocalPart()).equals(""))) {
264:
265: mLogger.debug("pushComplexTypeInfo ct: "
266: + ct.getName().getLocalPart() + " ,"
267: + ct.getName() + ", " + ct);
268:
269: count++;
270: body.append(ScriptCompiler.quote(ct.getName()
271: .getLocalPart())
272: + ": ");
273: body.append("{");
274: // namespace
275: body.append("ns: ");
276: body.append(ScriptCompiler.quote(ct.getName()
277: .getNamespaceURI()));
278: body.append(",");
279:
280: // type is one of simple, complex, array
281: body.append("type: ");
282: body.append(ScriptCompiler.quote(ct.getTypeString()));
283: body.append(",");
284:
285: // QName for array type; null if complex type is not an array
286: body.append("typeQ: ");
287: body.append(pushQName(ct.getArrayItemTypeQName()));
288: body.append(",");
289:
290: // push members
291: body.append("members: ");
292: pushMembers(ct);
293: body.append(",");
294:
295: // push base
296: ComplexType base = ct.getBase();
297: QName baseQName = (base != null ? base
298: .getArrayItemTypeQName() : null);
299: body.append("base: ");
300: body.append(pushQName(baseQName));
301:
302: body.append("}");
303: }
304: }
305: body.append("}");
306:
307: }
308:
309: /**
310: * Push members of a complex type.
311: */
312: void pushMembers(ComplexType ct) {
313: Map members = ct.getMembers();
314: if (members == null) {
315: body.append("null");
316: return;
317: }
318:
319: Iterator iter = members.entrySet().iterator();
320: if (!iter.hasNext()) {
321: body.append("null");
322: return;
323: }
324:
325: int count = 0;
326: body.append("{");
327: while (iter.hasNext()) {
328: if (count > 0) {
329: body.append(",");
330: }
331: Map.Entry entry = (Map.Entry) iter.next();
332: String key = (String) entry.getKey();
333: QName value = (QName) entry.getValue();
334: body.append(ScriptCompiler.quote(key) + ": ");
335: body.append(pushQName(value));
336: count++;
337: }
338:
339: ComplexType baseType = ct.getBase();
340: if (baseType != null) {
341: count += pushBaseMembers(baseType);
342: }
343: body.append("}");
344:
345: }
346:
347: /**
348: * Push base members and returns count of members added. Helper method for
349: * pushMembers().
350: * @return count of members pushed
351: */
352: int pushBaseMembers(ComplexType ct) {
353:
354: Map members = ct.getMembers();
355: if (members == null)
356: return 0;
357:
358: Iterator iter = members.entrySet().iterator();
359: if (!iter.hasNext())
360: return 0;
361:
362: int count = 0;
363: while (iter.hasNext()) {
364: if (count > 0) {
365: body.append(",");
366: }
367: Map.Entry entry = (Map.Entry) iter.next();
368: String key = (String) entry.getKey();
369: QName value = (QName) entry.getValue();
370: body.append(key + ": ");
371: body.append(pushQName(value));
372: count++;
373: }
374:
375: ComplexType baseType = ct.getBase();
376: if (baseType != null) {
377: count += pushBaseMembers(baseType);
378: }
379: return count;
380: }
381:
382: /**
383: */
384: public String createObjectFile(LZSOAPService service) {
385: // Create FlashFile object nd include action bytes
386: body = new StringBuffer();
387: createObjectProgram(service);
388: return body.toString();
389: }
390:
391: /**
392: */
393: public static byte[] createObject(LZSOAPService service) {
394: ClientSOAPService cobj = new ClientSOAPService();
395: String json = cobj.createObjectFile(service);
396: mLogger.debug("createObjectFile: " + json);
397: try {
398: byte[] buf = json.getBytes("UTF8");
399: return buf;
400: } catch (UnsupportedEncodingException e) {
401: throw new ChainedException(e);
402: }
403: }
404:
405: }
|