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