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 */ 017package org.apache.activemq.transport.xstream; 018 019import java.io.IOException; 020import java.io.Reader; 021 022import com.thoughtworks.xstream.converters.Converter; 023import com.thoughtworks.xstream.converters.MarshallingContext; 024import com.thoughtworks.xstream.converters.UnmarshallingContext; 025import com.thoughtworks.xstream.io.HierarchicalStreamReader; 026import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 027 028import org.apache.activemq.command.ConsumerInfo; 029import org.apache.activemq.command.MarshallAware; 030import org.apache.activemq.command.MessageDispatch; 031import org.apache.activemq.command.TransientInitializer; 032import org.apache.activemq.transport.stomp.XStreamSupport; 033import org.apache.activemq.transport.util.TextWireFormat; 034import org.apache.activemq.util.ByteSequence; 035import org.apache.activemq.wireformat.WireFormat; 036 037import com.thoughtworks.xstream.XStream; 038 039/** 040 * A {@link WireFormat} implementation which uses the <a 041 * href="http://xstream.codehaus.org/>XStream</a> library to marshall commands 042 * onto the wire 043 * 044 * 045 */ 046public class XStreamWireFormat extends TextWireFormat { 047 private XStream xStream; 048 private int version; 049 050 @Override 051 public int getVersion() { 052 return version; 053 } 054 055 @Override 056 public void setVersion(int version) { 057 this.version = version; 058 } 059 060 public WireFormat copy() { 061 return new XStreamWireFormat(); 062 } 063 064 @Override 065 public Object unmarshalText(String text) { 066 return getXStream().fromXML(text); 067 } 068 069 @Override 070 public Object unmarshalText(Reader reader) { 071 Object val = getXStream().fromXML(reader); 072 if (val instanceof TransientInitializer) { 073 ((TransientInitializer)val).initTransients(); 074 } 075 return val; 076 } 077 078 @Override 079 public String marshalText(Object command) throws IOException { 080 if (command instanceof MarshallAware) { 081 ((MarshallAware)command).beforeMarshall(this); 082 } else if(command instanceof MessageDispatch) { 083 MessageDispatch dispatch = (MessageDispatch) command; 084 if (dispatch != null && dispatch.getMessage() != null) { 085 dispatch.getMessage().beforeMarshall(this); 086 } 087 } 088 089 return getXStream().toXML(command); 090 } 091 092 /** 093 * Can this wireformat process packets of this version 094 * 095 * @param version the version number to test 096 * @return true if can accept the version 097 */ 098 public boolean canProcessWireFormatVersion(int version) { 099 return true; 100 } 101 102 /** 103 * @return the current version of this wire format 104 */ 105 public int getCurrentWireFormatVersion() { 106 return 1; 107 } 108 109 // Properties 110 // ------------------------------------------------------------------------- 111 public XStream getXStream() { 112 if (xStream == null) { 113 xStream = createXStream(); 114 // make it work in OSGi env 115 xStream.setClassLoader(getClass().getClassLoader()); 116 } 117 return xStream; 118 } 119 120 public void setXStream(XStream xStream) { 121 this.xStream = xStream; 122 } 123 124 // Implementation methods 125 // ------------------------------------------------------------------------- 126 protected XStream createXStream() { 127 final XStream xstream = XStreamSupport.createXStream(); 128 xstream.ignoreUnknownElements(); 129 xstream.registerConverter(new Converter() { 130 final Converter delegate = xstream.getConverterLookup().lookupConverterForType(ByteSequence.class); 131 @Override 132 public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) { 133 ByteSequence byteSequence = (ByteSequence)o; 134 byteSequence.compact(); 135 delegate.marshal(byteSequence, hierarchicalStreamWriter, marshallingContext); 136 } 137 138 @Override 139 public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) { 140 return delegate.unmarshal(hierarchicalStreamReader, unmarshallingContext); 141 } 142 143 @Override 144 public boolean canConvert(Class aClass) { 145 return aClass == ByteSequence.class; 146 } 147 }); 148 return xstream; 149 } 150 151}