Home | History | Annotate | Download | only in jbosh
      1 /*
      2  * Copyright 2009 Mike Cumings
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.kenai.jbosh;
     18 
     19 import java.io.ByteArrayOutputStream;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.util.Collections;
     23 import java.util.Map;
     24 
     25 /**
     26  * Implementation of the {@code AbstractBody} class which allows for the
     27  * definition of messages from pre-existing message content.  Instances of
     28  * this class are based on the underlying data and therefore cannot be
     29  * modified.  In order to obtain the wrapper element namespace and
     30  * attribute information, the body content is partially parsed.
     31  * <p/>
     32  * This class does only minimal syntactic and semantic checking with respect
     33  * to what the generated XML will look like.  It is up to the developer to
     34  * protect against the definition of malformed XML messages when building
     35  * instances of this class.
     36  * <p/>
     37  * Instances of this class are immutable and thread-safe.
     38  */
     39 final class StaticBody extends AbstractBody {
     40 
     41     /**
     42      * Selected parser to be used to process raw XML messages.
     43      */
     44     private static final BodyParser PARSER =
     45             new BodyParserXmlPull();
     46 
     47     /**
     48      * Size of the internal buffer when copying from a stream.
     49      */
     50     private static final int BUFFER_SIZE = 1024;
     51 
     52     /**
     53      * Map of all attributes to their values.
     54      */
     55     private final Map<BodyQName, String> attrs;
     56 
     57     /**
     58      * This body message in raw XML form.
     59      */
     60     private final String raw;
     61 
     62     ///////////////////////////////////////////////////////////////////////////
     63     // Constructors:
     64 
     65     /**
     66      * Prevent direct construction.
     67      */
     68     private StaticBody(
     69             final Map<BodyQName, String> attrMap,
     70             final String rawXML) {
     71         attrs = attrMap;
     72         raw = rawXML;
     73     }
     74 
     75     /**
     76      * Creates an instance which is initialized by reading a body
     77      * message from the provided stream.
     78      *
     79      * @param inStream stream to read message XML from
     80      * @return body instance
     81      * @throws BOSHException on parse error
     82      */
     83     public static StaticBody fromStream(
     84             final InputStream inStream)
     85             throws BOSHException {
     86         ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
     87         try {
     88             byte[] buffer = new byte[BUFFER_SIZE];
     89             int read;
     90             do {
     91                 read = inStream.read(buffer);
     92                 if (read > 0) {
     93                     byteOut.write(buffer, 0, read);
     94                 }
     95             } while (read >= 0);
     96         } catch (IOException iox) {
     97             throw(new BOSHException(
     98                     "Could not read body data", iox));
     99         }
    100         return fromString(byteOut.toString());
    101     }
    102 
    103     /**
    104      * Creates an instance which is initialized by reading a body
    105      * message from the provided raw XML string.
    106      *
    107      * @param rawXML raw message XML in string form
    108      * @return body instance
    109      * @throws BOSHException on parse error
    110      */
    111     public static StaticBody fromString(
    112             final String rawXML)
    113             throws BOSHException {
    114         BodyParserResults results = PARSER.parse(rawXML);
    115         return new StaticBody(results.getAttributes(), rawXML);
    116     }
    117 
    118 
    119     /**
    120      * {@inheritDoc}
    121      */
    122     public Map<BodyQName, String> getAttributes() {
    123         return Collections.unmodifiableMap(attrs);
    124     }
    125 
    126     /**
    127      * {@inheritDoc}
    128      */
    129     public String toXML() {
    130         return raw;
    131     }
    132 
    133 }
    134