001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.command;
018    
019    import java.io.DataInputStream;
020    import java.io.DataOutputStream;
021    import java.io.IOException;
022    import java.util.Arrays;
023    import java.util.Collections;
024    import java.util.HashMap;
025    import java.util.Map;
026    import org.apache.activemq.state.CommandVisitor;
027    import org.apache.activemq.util.ByteArrayInputStream;
028    import org.apache.activemq.util.ByteArrayOutputStream;
029    import org.apache.activemq.util.ByteSequence;
030    import org.apache.activemq.util.MarshallingSupport;
031    import org.apache.activemq.wireformat.WireFormat;
032    
033    /**
034     * @openwire:marshaller code="1"
035     * 
036     */
037    public class WireFormatInfo implements Command, MarshallAware {
038    
039        public static final byte DATA_STRUCTURE_TYPE = CommandTypes.WIREFORMAT_INFO;
040        private static final int MAX_PROPERTY_SIZE = 1024 * 4;
041        private static final byte MAGIC[] = new byte[] {'A', 'c', 't', 'i', 'v', 'e', 'M', 'Q'};
042    
043        protected byte magic[] = MAGIC;
044        protected int version;
045        protected ByteSequence marshalledProperties;
046    
047        protected transient Map<String, Object> properties;
048        private transient Endpoint from;
049        private transient Endpoint to;
050    
051        public byte getDataStructureType() {
052            return DATA_STRUCTURE_TYPE;
053        }
054    
055        public boolean isWireFormatInfo() {
056            return true;
057        }
058    
059        public boolean isMarshallAware() {
060            return true;
061        }
062    
063        /**
064         * @openwire:property version=1 size=8 testSize=-1
065         */
066        public byte[] getMagic() {
067            return magic;
068        }
069    
070        public void setMagic(byte[] magic) {
071            this.magic = magic;
072        }
073    
074        /**
075         * @openwire:property version=1
076         */
077        public int getVersion() {
078            return version;
079        }
080    
081        public void setVersion(int version) {
082            this.version = version;
083        }
084    
085        /**
086         * @openwire:property version=1
087         */
088        public ByteSequence getMarshalledProperties() {
089            return marshalledProperties;
090        }
091    
092        public void setMarshalledProperties(ByteSequence marshalledProperties) {
093            this.marshalledProperties = marshalledProperties;
094        }
095    
096        /**
097         * The endpoint within the transport where this message came from.
098         */
099        public Endpoint getFrom() {
100            return from;
101        }
102    
103        public void setFrom(Endpoint from) {
104            this.from = from;
105        }
106    
107        /**
108         * The endpoint within the transport where this message is going to - null
109         * means all endpoints.
110         */
111        public Endpoint getTo() {
112            return to;
113        }
114    
115        public void setTo(Endpoint to) {
116            this.to = to;
117        }
118    
119        // ////////////////////
120        // 
121        // Implementation Methods.
122        //
123        // ////////////////////
124    
125        public Object getProperty(String name) throws IOException {
126            if (properties == null) {
127                if (marshalledProperties == null) {
128                    return null;
129                }
130                properties = unmarsallProperties(marshalledProperties);
131            }
132            return properties.get(name);
133        }
134    
135        @SuppressWarnings("unchecked")
136        public Map<String, Object> getProperties() throws IOException {
137            if (properties == null) {
138                if (marshalledProperties == null) {
139                    return Collections.EMPTY_MAP;
140                }
141                properties = unmarsallProperties(marshalledProperties);
142            }
143            return Collections.unmodifiableMap(properties);
144        }
145    
146        public void clearProperties() {
147            marshalledProperties = null;
148            properties = null;
149        }
150    
151        public void setProperty(String name, Object value) throws IOException {
152            lazyCreateProperties();
153            properties.put(name, value);
154        }
155    
156        protected void lazyCreateProperties() throws IOException {
157            if (properties == null) {
158                if (marshalledProperties == null) {
159                    properties = new HashMap<String, Object>();
160                } else {
161                    properties = unmarsallProperties(marshalledProperties);
162                    marshalledProperties = null;
163                }
164            }
165        }
166    
167        private Map<String, Object> unmarsallProperties(ByteSequence marshalledProperties) throws IOException {
168            return MarshallingSupport.unmarshalPrimitiveMap(new DataInputStream(new ByteArrayInputStream(marshalledProperties)), MAX_PROPERTY_SIZE);
169        }
170    
171        public void beforeMarshall(WireFormat wireFormat) throws IOException {
172            // Need to marshal the properties.
173            if (marshalledProperties == null && properties != null) {
174                ByteArrayOutputStream baos = new ByteArrayOutputStream();
175                DataOutputStream os = new DataOutputStream(baos);
176                MarshallingSupport.marshalPrimitiveMap(properties, os);
177                os.close();
178                marshalledProperties = baos.toByteSequence();
179            }
180        }
181    
182        public void afterMarshall(WireFormat wireFormat) throws IOException {
183        }
184    
185        public void beforeUnmarshall(WireFormat wireFormat) throws IOException {
186        }
187    
188        public void afterUnmarshall(WireFormat wireFormat) throws IOException {
189        }
190    
191        public boolean isValid() {
192            return magic != null && Arrays.equals(magic, MAGIC);
193        }
194    
195        public void setResponseRequired(boolean responseRequired) {
196        }
197    
198        /**
199         * @throws IOException
200         */
201        public boolean isCacheEnabled() throws IOException {
202            return Boolean.TRUE == getProperty("CacheEnabled");
203        }
204    
205        public void setCacheEnabled(boolean cacheEnabled) throws IOException {
206            setProperty("CacheEnabled", cacheEnabled ? Boolean.TRUE : Boolean.FALSE);
207        }
208    
209        /**
210         * @throws IOException
211         */
212        public boolean isStackTraceEnabled() throws IOException {
213            return Boolean.TRUE == getProperty("StackTraceEnabled");
214        }
215    
216        public void setStackTraceEnabled(boolean stackTraceEnabled) throws IOException {
217            setProperty("StackTraceEnabled", stackTraceEnabled ? Boolean.TRUE : Boolean.FALSE);
218        }
219    
220        /**
221         * @throws IOException
222         */
223        public boolean isTcpNoDelayEnabled() throws IOException {
224            return Boolean.TRUE == getProperty("TcpNoDelayEnabled");
225        }
226    
227        public void setTcpNoDelayEnabled(boolean tcpNoDelayEnabled) throws IOException {
228            setProperty("TcpNoDelayEnabled", tcpNoDelayEnabled ? Boolean.TRUE : Boolean.FALSE);
229        }
230    
231        /**
232         * @throws IOException
233         */
234        public boolean isSizePrefixDisabled() throws IOException {
235            return Boolean.TRUE == getProperty("SizePrefixDisabled");
236        }
237    
238        public void setSizePrefixDisabled(boolean prefixPacketSize) throws IOException {
239            setProperty("SizePrefixDisabled", prefixPacketSize ? Boolean.TRUE : Boolean.FALSE);
240        }
241    
242        /**
243         * @throws IOException
244         */
245        public boolean isTightEncodingEnabled() throws IOException {
246            return Boolean.TRUE == getProperty("TightEncodingEnabled");
247        }
248    
249        public void setTightEncodingEnabled(boolean tightEncodingEnabled) throws IOException {
250            setProperty("TightEncodingEnabled", tightEncodingEnabled ? Boolean.TRUE : Boolean.FALSE);
251        }
252    
253        /**
254         * @throws IOException
255         */
256        public long getMaxInactivityDuration() throws IOException {
257            Long l = (Long)getProperty("MaxInactivityDuration");
258            return l == null ? 0 : l.longValue();
259        }
260    
261        public void setMaxInactivityDuration(long maxInactivityDuration) throws IOException {
262            setProperty("MaxInactivityDuration", new Long(maxInactivityDuration));
263        }
264        
265        public long getMaxInactivityDurationInitalDelay() throws IOException {
266            Long l = (Long)getProperty("MaxInactivityDurationInitalDelay");
267            return l == null ? 0 : l.longValue();
268        }
269    
270        public void setMaxInactivityDurationInitalDelay(long maxInactivityDurationInitalDelay) throws IOException {
271            setProperty("MaxInactivityDurationInitalDelay", new Long(maxInactivityDurationInitalDelay));
272        }
273    
274        public long getMaxFrameSize() throws IOException {
275            Long l = (Long)getProperty("MaxFrameSize");
276            return l == null ? 0 : l.longValue();
277        }
278    
279        public void setMaxFrameSize(long maxFrameSize) throws IOException {
280            setProperty("MaxFrameSize", new Long(maxFrameSize));
281        }
282        
283       
284    
285        /**
286         * @throws IOException
287         */
288        public int getCacheSize() throws IOException {
289            Integer i = (Integer)getProperty("CacheSize");
290            return i == null ? 0 : i.intValue();
291        }
292    
293        public void setCacheSize(int cacheSize) throws IOException {
294            setProperty("CacheSize", new Integer(cacheSize));
295        }
296    
297        public Response visit(CommandVisitor visitor) throws Exception {
298            return visitor.processWireFormat(this);
299        }
300    
301        @Override
302        public String toString() {
303            Map<String, Object> p = null;
304            try {
305                p = getProperties();
306            } catch (IOException ignore) {
307            }
308            return "WireFormatInfo { version=" + version + ", properties=" + p + ", magic=" + toString(magic) + "}";
309        }
310    
311        private String toString(byte[] data) {
312            StringBuffer sb = new StringBuffer();
313            sb.append('[');
314            for (int i = 0; i < data.length; i++) {
315                if (i != 0) {
316                    sb.append(',');
317                }
318                sb.append((char)data[i]);
319            }
320            sb.append(']');
321            return sb.toString();
322        }
323    
324        // /////////////////////////////////////////////////////////////
325        //
326        // This are not implemented.
327        //
328        // /////////////////////////////////////////////////////////////
329    
330        public void setCommandId(int value) {
331        }
332    
333        public int getCommandId() {
334            return 0;
335        }
336    
337        public boolean isResponseRequired() {
338            return false;
339        }
340    
341        public boolean isResponse() {
342            return false;
343        }
344    
345        public boolean isBrokerInfo() {
346            return false;
347        }
348    
349        public boolean isMessageDispatch() {
350            return false;
351        }
352    
353        public boolean isMessage() {
354            return false;
355        }
356    
357        public boolean isMessageAck() {
358            return false;
359        }
360    
361        public boolean isMessageDispatchNotification() {
362            return false;
363        }
364    
365        public boolean isShutdownInfo() {
366            return false;
367        }
368        
369        public boolean isConnectionControl() {
370            return false;
371        }
372    
373        public void setCachedMarshalledForm(WireFormat wireFormat, ByteSequence data) {
374        }
375    
376        public ByteSequence getCachedMarshalledForm(WireFormat wireFormat) {
377            return null;
378        }
379    
380    }