1/* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The  above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE. */
20
21package org.ksoap2;
22
23import java.io.*;
24import org.ksoap2.kdom.*;
25import org.xmlpull.v1.*;
26
27/**
28 * A SOAP envelope, holding head and body objects. While this basic envelope
29 * supports literal encoding as content format via KDom, The
30 * SoapSerializationEnvelope provides support for the SOAP Serialization format
31 * specification and simple object serialization.
32 */
33
34public class SoapEnvelope {
35
36    /** SOAP Version 1.0 constant */
37    public static final int VER10 = 100;
38    /** SOAP Version 1.1 constant */
39    public static final int VER11 = 110;
40    /** SOAP Version 1.2 constant */
41    public static final int VER12 = 120;
42    public static final String ENV2003 = "http://www.w3.org/2003/05/soap-envelope";
43    public static final String ENC2003 = "http://www.w3.org/2003/05/soap-encoding";
44    /** Namespace constant: http://schemas.xmlsoap.org/soap/envelope/ */
45    public static final String ENV = "http://schemas.xmlsoap.org/soap/envelope/";
46    /** Namespace constant: http://schemas.xmlsoap.org/soap/encoding/ */
47    public static final String ENC = "http://schemas.xmlsoap.org/soap/encoding/";
48    /** Namespace constant: http://www.w3.org/2001/XMLSchema */
49    public static final String XSD = "http://www.w3.org/2001/XMLSchema";
50    /** Namespace constant: http://www.w3.org/2001/XMLSchema */
51    public static final String XSI = "http://www.w3.org/2001/XMLSchema-instance";
52    /** Namespace constant: http://www.w3.org/1999/XMLSchema */
53    public static final String XSD1999 = "http://www.w3.org/1999/XMLSchema";
54    /** Namespace constant: http://www.w3.org/1999/XMLSchema */
55    public static final String XSI1999 = "http://www.w3.org/1999/XMLSchema-instance";
56
57    //public static final String NS20 = "http://www.wi-fi-org/specifications/hotspot2dot0/spp/1.0/";
58    public static final String NS20 = "http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp";
59
60    //public static final String OMADM12 = "http://www.openmobilealliance.org/tech/DTD/dm_ddf-v1_2.dtd";
61
62    /**
63     * Returns true for the string values "1" and "true", ignoring upper/lower
64     * case and whitespace, false otherwise.
65     */
66    public static boolean stringToBoolean(String booleanAsString) {
67        if (booleanAsString == null) {
68            return false;
69        }
70        booleanAsString = booleanAsString.trim().toLowerCase();
71        return (booleanAsString.equals("1") || booleanAsString.equals("true"));
72    }
73
74    /**
75     * The body object received with this envelope. Will be an KDom Node for
76     * literal encoding. For SOAP Serialization, please refer to
77     * SoapSerializationEnvelope.
78     */
79    public Object bodyIn;
80    /**
81     * The body object to be sent with this envelope. Must be a KDom Node
82     * modelling the remote call including all parameters for literal encoding.
83     * For SOAP Serialization, please refer to SoapSerializationEnvelope
84     */
85    public Object bodyOut;
86    /**
87     * Incoming header elements
88     */
89    public Element[] headerIn;
90    /**
91     * Outgoing header elements
92     */
93    public Element[] headerOut;
94    public String encodingStyle;
95    /**
96     * The SOAP version, set by the constructor
97     */
98    public int version;
99    /** Envelope namespace, set by the constructor */
100    public String env;
101    /** Encoding namespace, set by the constructor */
102    public String enc;
103    /** Xml Schema instance namespace, set by the constructor */
104    public String xsi;
105    /** Xml Schema data namespace, set by the constructor */
106    public String xsd;
107
108    ///M: HS20 Add by Jungo
109    public String ns;
110    public String omadm;
111
112    /**
113     * Initializes a SOAP Envelope. The version parameter must be set to one of
114     * VER10, VER11 or VER12
115     */
116    public SoapEnvelope(int version) {
117        this.version = version;
118        if (version == SoapEnvelope.VER10) {
119            xsi = SoapEnvelope.XSI1999;
120            xsd = SoapEnvelope.XSD1999;
121        } else {
122            xsi = SoapEnvelope.XSI;
123            xsd = SoapEnvelope.XSD;
124        }
125        if (version < SoapEnvelope.VER12) {
126            enc = SoapEnvelope.ENC;
127            env = SoapEnvelope.ENV;
128        } else {
129            enc = SoapEnvelope.ENC2003;
130            env = SoapEnvelope.ENV2003;
131        }
132
133        ns = SoapEnvelope.NS20;
134        //omadm = SoapEnvelope.OMADM12;
135
136    }
137
138    /** Parses the SOAP envelope from the given parser */
139    public void parse(XmlPullParser parser) throws IOException, XmlPullParserException {
140        parser.nextTag();
141        parser.require(XmlPullParser.START_TAG, env, "Envelope");
142        encodingStyle = parser.getAttributeValue(env, "encodingStyle");
143        parser.nextTag();
144        if (parser.getEventType() == XmlPullParser.START_TAG
145                && parser.getNamespace().equals(env)
146                && parser.getName().equals("Header")) {
147            parseHeader(parser);
148            parser.require(XmlPullParser.END_TAG, env, "Header");
149            parser.nextTag();
150        }
151        parser.require(XmlPullParser.START_TAG, env, "Body");
152        encodingStyle = parser.getAttributeValue(env, "encodingStyle");
153        parseBody(parser);
154        parser.require(XmlPullParser.END_TAG, env, "Body");
155        parser.nextTag();
156        parser.require(XmlPullParser.END_TAG, env, "Envelope");
157    }
158
159    public void parseHeader(XmlPullParser parser) throws IOException, XmlPullParserException {
160        // consume start header
161        parser.nextTag();
162        // look at all header entries
163        Node headers = new Node();
164        headers.parse(parser);
165        int count = 0;
166        for (int i = 0; i < headers.getChildCount(); i++) {
167            Element child = headers.getElement(i);
168            if (child != null) {
169                count++;
170            }
171        }
172        headerIn = new Element[count];
173        count = 0;
174        for (int i = 0; i < headers.getChildCount(); i++) {
175            Element child = headers.getElement(i);
176            if (child != null) {
177                headerIn[count++] = child;
178            }
179        }
180    }
181
182    public void parseBody(XmlPullParser parser) throws IOException, XmlPullParserException {
183        parser.nextTag();
184        // insert fault generation code here
185        if (parser.getEventType() == XmlPullParser.START_TAG
186                && parser.getNamespace().equals(env)
187                && parser.getName().equals("Fault")) {
188
189            SoapFault fault;
190            if (this.version < SoapEnvelope.VER12) {
191                fault = new SoapFault(this.version);
192            } else {
193                fault = new SoapFault12(this.version);
194            }
195            fault.parse(parser);
196            bodyIn = fault;
197        } else {
198            Node node = (bodyIn instanceof Node) ? (Node) bodyIn : new Node();
199            node.parse(parser);
200            bodyIn = node;
201        }
202    }
203
204    /**
205     * Writes the complete envelope including header and body elements to the
206     * given XML writer.
207     */
208    public void write(XmlSerializer writer) throws IOException {
209        ///M: HS20 modify by Jungo
210        //writer.setPrefix("i", xsi);
211        //writer.setPrefix("d", xsd);
212        //writer.setPrefix("c", enc);
213        writer.setPrefix("soap", env);//the prefix for namespace env in xml output
214        writer.setPrefix("spp", ns);
215        //writer.setPrefix("omadm", omadm);
216
217        writer.startTag(env, "Envelope");
218        writer.startTag(env, "Header");
219        writeHeader(writer);
220        writer.endTag(env, "Header");
221        writer.startTag(env, "Body");
222        writeBody(writer);
223        writer.endTag(env, "Body");
224        writer.endTag(env, "Envelope");
225    }
226
227    /**
228     * Writes the header elements contained in headerOut
229     */
230    public void writeHeader(XmlSerializer writer) throws IOException {
231        if (headerOut != null) {
232            for (int i = 0; i < headerOut.length; i++) {
233                headerOut[i].write(writer);
234            }
235        }
236    }
237
238    /**
239     * Writes the SOAP body stored in the object variable bodyIn, Overwrite this
240     * method for customized writing of the soap message body.
241     */
242    public void writeBody(XmlSerializer writer) throws IOException {
243        if (encodingStyle != null) {
244            writer.attribute(env, "encodingStyle", encodingStyle);
245        }
246        ((Node) bodyOut).write(writer);
247    }
248
249    /**
250     * Assigns the object to the envelope as the outbound message for the soap call.
251     * @param soapObject the object to send in the soap call.
252     */
253    public void setOutputSoapObject(Object soapObject) {
254        bodyOut = soapObject;
255    }
256
257}
258