001: /* *****************************************************************************
002: * SWFObjectDeserializer.java
003: * ****************************************************************************/
004:
005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006: * Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
007: * Use is subject to license terms. *
008: * J_LZ_COPYRIGHT_END *********************************************************/
009:
010: /*
011: * Copyright 2001-2007 The Apache Software Foundation.
012: *
013: * Licensed under the Apache License, Version 2.0 (the "License");
014: * you may not use this file except in compliance with the License.
015: * You may obtain a copy of the License at
016: *
017: * http://www.apache.org/licenses/LICENSE-2.0
018: *
019: * Unless required by applicable law or agreed to in writing, software
020: * distributed under the License is distributed on an "AS IS" BASIS,
021: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
022: * See the License for the specific language governing permissions and
023: * limitations under the License.
024: */
025: package org.openlaszlo.remote.swf.soap.encoding;
026:
027: import org.openlaszlo.remote.swf.soap.LZSOAPUtils;
028: import org.openlaszlo.iv.flash.util.FlashBuffer;
029: import org.openlaszlo.iv.flash.api.action.Actions;
030: import org.openlaszlo.iv.flash.api.action.Program;
031: import org.apache.axis.Constants;
032: import org.apache.axis.components.logger.LogFactory;
033: import org.apache.axis.encoding.DeserializationContext;
034: import org.apache.axis.encoding.Deserializer;
035: import org.apache.axis.encoding.DeserializerImpl;
036: import org.apache.axis.encoding.DeserializerTarget;
037: import org.apache.axis.message.SOAPHandler;
038: import org.apache.axis.utils.ClassUtils;
039: import org.apache.axis.utils.JavaUtils;
040: import org.apache.axis.utils.Messages;
041: import org.apache.axis.wsdl.symbolTable.SchemaUtils;
042: import org.apache.commons.logging.Log;
043: import org.apache.axis.soap.SOAPConstants;
044: import org.apache.axis.MessageContext;
045:
046: import org.apache.axis.utils.DOM2Writer;
047:
048: import org.xml.sax.Attributes;
049: import org.xml.sax.SAXException;
050:
051: import javax.xml.namespace.QName;
052: import java.io.StringWriter;
053: import java.util.ArrayList;
054: import java.util.HashMap;
055: import java.util.Iterator;
056: import java.util.Map;
057: import java.util.StringTokenizer;
058:
059: import org.apache.axis.message.MessageElement;
060: import org.apache.log4j.Logger;
061: import org.openlaszlo.iv.flash.util.FlashBuffer;
062:
063: public class SWFObjectDeserializer extends DeserializerImpl {
064: public static Logger mLogger = Logger
065: .getLogger(SWFObjectDeserializer.class);
066:
067: static int BUFSIZE = 8192;
068:
069: String mClassName = "";
070: String mClassNameSpace = "";
071:
072: HashMap mMembers = new HashMap();
073:
074: public void onStartElement(String namespace, String localName,
075: String prefix, Attributes attributes,
076: DeserializationContext context) throws SAXException {
077:
078: if (mLogger.isDebugEnabled()) {
079: mLogger.debug(
080: /* (non-Javadoc)
081: * @i18n.test
082: * @org-mes="Enter: SWFObjectDeserializer::onStartChild" + "( namespace: " + p[0] + ", localname: " + p[1] + ", prefix: " + p[2] + ")"
083: */
084: org.openlaszlo.i18n.LaszloMessages.getMessage(
085: SWFObjectDeserializer.class.getName(), "051018-87",
086: new Object[] { namespace, localName, prefix }));
087: }
088:
089: // Use the xsi:type setting on the attribute if it exists.
090: QName itemType = context.getTypeFromAttributes(namespace,
091: localName, attributes);
092:
093: if (itemType == null) {
094: // FIXME: [2007-07-11 pkang] what do we do in this case? ideally
095: // treat the rest this as an element.
096: mLogger.debug(
097: /* (non-Javadoc)
098: * @i18n.test
099: * @org-mes="itemType is null"
100: */
101: org.openlaszlo.i18n.LaszloMessages
102: .getMessage(SWFObjectDeserializer.class.getName(),
103: "051018-104"));
104: } else {
105: mClassName = itemType.getLocalPart();
106: mClassNameSpace = itemType.getNamespaceURI();
107: }
108: }
109:
110: public SOAPHandler onStartChild(String namespace, String localName,
111: String prefix, Attributes attributes,
112: DeserializationContext context) throws SAXException {
113: if (mLogger.isDebugEnabled()) {
114: mLogger.debug(
115: /* (non-Javadoc)
116: * @i18n.test
117: * @org-mes="Enter: SWFObjectDeserializer::onStartChild" + "( namespace: " + p[0] + ", localname: " + p[1] + ", prefix: " + p[2] + ")"
118: */
119: org.openlaszlo.i18n.LaszloMessages.getMessage(
120: SWFObjectDeserializer.class.getName(), "051018-87",
121: new Object[] { namespace, localName, prefix }));
122: }
123:
124: // Use the xsi:type setting on the attribute if it exists.
125: QName itemType = context.getTypeFromAttributes(namespace,
126: localName, attributes);
127:
128: // Get the deserializer for the type.
129: Deserializer dSer = null;
130: if (itemType != null
131: && (context.getCurElement().getHref() == null)) {
132: dSer = context.getDeserializerForType(itemType);
133: }
134:
135: if (dSer == null) {
136: dSer = new SWFObjectDeserializer();
137: }
138:
139: // Register the callback value target, and keep track of this index so
140: // we know when it has been set.
141: dSer
142: .registerValueTarget(new DeserializerTarget(this ,
143: localName));
144:
145: // The framework handles knowing when the value is complete, as long as
146: // we tell it about each child we're waiting on.
147: addChildDeserializer(dSer);
148:
149: return (SOAPHandler) dSer;
150: }
151:
152: public void setChildValue(Object value, Object hint)
153: throws SAXException {
154: mMembers.put(hint, value);
155: }
156:
157: public void valueComplete() throws SAXException {
158:
159: if (mLogger.isDebugEnabled()) {
160: mLogger.debug(
161: /* (non-Javadoc)
162: * @i18n.test
163: * @org-mes="Enter: SWFObjectDeserializer::valueComplete()"
164: */
165: org.openlaszlo.i18n.LaszloMessages
166: .getMessage(SWFObjectDeserializer.class.getName(),
167: "051018-170"));
168: }
169:
170: //----------------------------------------------------------------------
171: // FIXME [2005-03-11 pkang]: if there are targets and this is not an
172: // href, create the object. This is to get around a weird problem
173: // deserializing an object returned by
174: // //depot/qa/test/private/photospace test case.
175: // If top-level SOAP response node is an href, valueComplete() to get
176: // called twice. Understand this code better.
177: //----------------------------------------------------------------------
178: if (targets != null && !isHref) {
179:
180: if (componentsReady()) {
181:
182: FlashBuffer fbuf = new FlashBuffer(BUFSIZE);
183: Program program = new Program(fbuf);
184:
185: // push all members
186: Iterator iter = mMembers.entrySet().iterator();
187: String keys = "";
188: while (iter.hasNext()) {
189: Map.Entry entry = (Map.Entry) iter.next();
190: String k = (String) entry.getKey();
191: Program v = (Program) entry.getValue();
192: program.push(k);
193: if (v == null) {
194: LZSOAPUtils.pushNull(fbuf);
195: } else {
196: // copy the body of each member's program
197: fbuf.writeFOB(v.body());
198: }
199: }
200:
201: program.push("__LZclassnamespace");
202: program.push(mClassNameSpace);
203: program.push("__LZclassname");
204: program.push(mClassName);
205: program.push(mMembers.size() + 2);
206: program.body().writeByte(Actions.InitObject);
207:
208: // Call _root.LzSOAPService.__LZnormObj(). This function will set the
209: // object's prototype to one that exists in the namespace and will
210: // return the object so it stays in the stack
211: program.push(1);
212: program.push("_root");
213: program.getVar();
214: program.push("LzSOAPService");
215: program.body().writeByte(Actions.GetMember);
216: program.push("__LZnormObj");
217: program.callMethod();
218:
219: value = program;
220: }
221:
222: }
223:
224: super.valueComplete();
225:
226: }
227: }
|