aboutsummaryrefslogtreecommitdiff
path: root/src/com/kenai/jbosh/StaticBody.java
blob: fe225fb5835ca223ab6789db1d95f3aeb0bb4a40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright 2009 Mike Cumings
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kenai.jbosh;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;

/**
 * Implementation of the {@code AbstractBody} class which allows for the
 * definition of messages from pre-existing message content.  Instances of
 * this class are based on the underlying data and therefore cannot be
 * modified.  In order to obtain the wrapper element namespace and
 * attribute information, the body content is partially parsed.
 * <p/>
 * This class does only minimal syntactic and semantic checking with respect
 * to what the generated XML will look like.  It is up to the developer to
 * protect against the definition of malformed XML messages when building
 * instances of this class.
 * <p/>
 * Instances of this class are immutable and thread-safe.
 */
final class StaticBody extends AbstractBody {

    /**
     * Selected parser to be used to process raw XML messages.
     */
    private static final BodyParser PARSER =
            new BodyParserXmlPull();

    /**
     * Size of the internal buffer when copying from a stream.
     */
    private static final int BUFFER_SIZE = 1024;

    /**
     * Map of all attributes to their values.
     */
    private final Map<BodyQName, String> attrs;

    /**
     * This body message in raw XML form.
     */
    private final String raw;

    ///////////////////////////////////////////////////////////////////////////
    // Constructors:

    /**
     * Prevent direct construction.
     */
    private StaticBody(
            final Map<BodyQName, String> attrMap,
            final String rawXML) {
        attrs = attrMap;
        raw = rawXML;
    }

    /**
     * Creates an instance which is initialized by reading a body
     * message from the provided stream.
     *
     * @param inStream stream to read message XML from
     * @return body instance
     * @throws BOSHException on parse error
     */
    public static StaticBody fromStream(
            final InputStream inStream)
            throws BOSHException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            int read;
            do {
                read = inStream.read(buffer);
                if (read > 0) {
                    byteOut.write(buffer, 0, read);
                }
            } while (read >= 0);
        } catch (IOException iox) {
            throw(new BOSHException(
                    "Could not read body data", iox));
        }
        return fromString(byteOut.toString());
    }

    /**
     * Creates an instance which is initialized by reading a body
     * message from the provided raw XML string.
     *
     * @param rawXML raw message XML in string form
     * @return body instance
     * @throws BOSHException on parse error
     */
    public static StaticBody fromString(
            final String rawXML)
            throws BOSHException {
        BodyParserResults results = PARSER.parse(rawXML);
        return new StaticBody(results.getAttributes(), rawXML);
    }


    /**
     * {@inheritDoc}
     */
    public Map<BodyQName, String> getAttributes() {
        return Collections.unmodifiableMap(attrs);
    }

    /**
     * {@inheritDoc}
     */
    public String toXML() {
        return raw;
    }

}