KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > marshall > VersionAwareMarshaller


1 /*
2  * JBoss, Home of Professional Open Source
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.cache.marshall;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.jboss.cache.RegionManager;
12 import org.jgroups.blocks.RpcDispatcher;
13
14 import java.io.ByteArrayOutputStream JavaDoc;
15 import java.io.ObjectInputStream JavaDoc;
16 import java.io.ObjectOutputStream JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 /**
22  * A facade to various other marshallers like {@link org.jboss.cache.marshall.CacheMarshaller200}
23  * which is version-aware.
24  *
25  * @author <a HREF="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
26  */

27 public class VersionAwareMarshaller implements RpcDispatcher.Marshaller
28 {
29    private RegionManager manager;
30    private boolean defaultInactive, useRegionBasedMarshalling;
31    private Log log = LogFactory.getLog(VersionAwareMarshaller.class);
32
33    Marshaller defaultMarshaller;
34    Map JavaDoc<Integer JavaDoc, Marshaller> marshallers = new HashMap JavaDoc<Integer JavaDoc, Marshaller>();
35
36    private static final int VERSION_200 = 20;
37
38    private int versionInt;
39
40
41    public VersionAwareMarshaller(RegionManager manager, boolean defaultInactive, boolean useRegionBasedMarshalling, String JavaDoc version)
42    {
43       this.manager = manager;
44       this.defaultInactive = defaultInactive;
45       this.useRegionBasedMarshalling = useRegionBasedMarshalling;
46
47       // convert the replication version passed in to the MINOR version.
48
// E.g., 1.4.1.SP3 -> 1.4.0
49

50       versionInt = toMinorVersionInt(version);
51
52       switch (versionInt)
53       {
54          case VERSION_200:
55          default:
56             defaultMarshaller = new CacheMarshaller200(manager, defaultInactive, useRegionBasedMarshalling);
57             marshallers.put(VERSION_200, defaultMarshaller);
58             break;
59       }
60
61       if (log.isDebugEnabled())
62       {
63          log.debug("Initialised with version " + version + " and versionInt " + versionInt);
64          log.debug("Using default marshaller " + defaultMarshaller.getClass());
65       }
66    }
67
68    /**
69     * Converts versions to known compatible version ids.
70     * <p/>
71     * Typical return values:
72     * <p/>
73     * < 1.4.0 = "1"
74     * 1.4.x = "14"
75     * 1.5.x = "15"
76     * 2.0.x = "20"
77     * 2.1.x = "21"
78     * <p/>
79     * etc.
80     *
81     * @param version
82     * @return a version integer
83     */

84    private int toMinorVersionInt(String JavaDoc version)
85    {
86       try
87       {
88          StringTokenizer JavaDoc strtok = new StringTokenizer JavaDoc(version, ".");
89
90          // major, minor, micro, patch
91
String JavaDoc[] versionComponents = {null, null, null, null};
92          int i = 0;
93          while (strtok.hasMoreTokens())
94          {
95             versionComponents[i++] = strtok.nextToken();
96          }
97
98          int major = Integer.parseInt(versionComponents[0]);
99          int minor = Integer.parseInt(versionComponents[1]);
100
101          return (major > 1 || minor > 3) ? (10 * major) + minor : 1;
102       }
103       catch (Exception JavaDoc e)
104       {
105          throw new IllegalArgumentException JavaDoc("Unsupported replication version string " + version);
106       }
107    }
108
109    /**
110     * Marshals the object passed in to a byte buffer using an appropriate {@link Marshaller} based on
111     * the version information passed in to this instance upon construction (See {@link #VersionAwareMarshaller(org.jboss.cache.RegionManager,boolean,boolean,String)})
112     *
113     * @param obj
114     * @return a byte stream representing the object passed in.
115     * @throws Exception
116     */

117    public byte[] objectToByteBuffer(Object JavaDoc obj) throws Exception JavaDoc
118    {
119       ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
120       ObjectOutputStream JavaDoc out;
121
122       // based on the default marshaller, construct an object output stream based on what's compatible.
123
out = ObjectSerializationFactory.createObjectOutputStream(bos);
124       out.writeShort(versionInt);
125
126       //now marshall the contents of the object
127
defaultMarshaller.objectToStream(obj, out);
128       out.close();
129
130       // and return bytes.
131
return bos.toByteArray();
132    }
133
134    /**
135     * Creates an Object from the byte buffer passed in, using the appropriate {@link Marshaller} based
136     * on the version headers in the byte stream.
137     *
138     * @param buf
139     * @return Object from byte buffer passed in.
140     * @throws Exception
141     */

142    public Object JavaDoc objectFromByteBuffer(byte[] buf) throws Exception JavaDoc
143    {
144       Marshaller marshaller;
145       int versionId;
146       ObjectInputStream JavaDoc in;
147       try
148       {
149          // just a peek - does not actually "remove" these bytes from the stream.
150
// create an input stream and read the first short
151
in = ObjectSerializationFactory.createObjectInputStream(buf);
152          versionId = in.readShort();
153       }
154       catch (Exception JavaDoc e)
155       {
156          log.error("Unable to read version id from first two bytes of stream, barfing.");
157          throw e;
158       }
159
160       marshaller = getMarshaller(versionId);
161
162       return marshaller.objectFromStream(in);
163    }
164
165    /**
166     * Lazily instantiates and loads the relevant marshaller for a given version.
167     *
168     * @param versionId
169     * @return appropriate marshaller for the version requested.
170     */

171    Marshaller getMarshaller(int versionId)
172    {
173       Marshaller marshaller;
174       switch (versionId)
175       {
176          case VERSION_200:
177          default:
178             marshaller = marshallers.get(VERSION_200);
179             if (marshaller == null)
180             {
181                marshaller = new CacheMarshaller200(manager, defaultInactive, useRegionBasedMarshalling);
182                marshallers.put(VERSION_200, marshaller);
183             }
184             break;
185       }
186       return marshaller;
187    }
188
189    /**
190     * Tests whether a particular Fqn passed in is inactive.
191     *
192     * @param fqn
193     * @return true if the fqn is inactive
194     */

195    public boolean isInactive(String JavaDoc fqn)
196    {
197       return defaultMarshaller.isInactive(fqn);
198    }
199
200    /**
201     * Returns the class loader associated with a particular Fqn.
202     *
203     * @param fqn
204     * @return the context class loader associated with the Fqn passed in.
205     */

206    public ClassLoader JavaDoc getClassLoader(String JavaDoc fqn)
207    {
208       return defaultMarshaller.getClassLoader(fqn);
209    }
210 }
211
Popular Tags