KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > burlap > BurlapHandleEncoder


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.ejb.burlap;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.ejb.AbstractServer;
33 import com.caucho.ejb.EJBExceptionWrapper;
34 import com.caucho.ejb.protocol.AbstractHandle;
35 import com.caucho.ejb.protocol.AbstractHomeHandle;
36 import com.caucho.ejb.protocol.HandleEncoder;
37 import com.caucho.util.CharBuffer;
38
39 import javax.ejb.EJBException JavaDoc;
40 import java.lang.reflect.Field JavaDoc;
41
42 /**
43  * Encodes and decodes handles.
44  */

45 public class BurlapHandleEncoder extends HandleEncoder {
46   private static char []serverEncode64;
47   private static int []serverHash64;
48   private static char []serverEncodeH2;
49
50   private Class JavaDoc _primaryKeyClass;
51   private Field JavaDoc []_fields;
52   private int []fieldTypes;
53
54   public BurlapHandleEncoder(String JavaDoc serverId, Class JavaDoc primaryKeyClass)
55     throws ConfigException
56   {
57     super(serverId);
58
59     _primaryKeyClass = primaryKeyClass;
60
61     if (_primaryKeyClass == null ||
62         _primaryKeyClass.isPrimitive() ||
63         _primaryKeyClass.getName().startsWith("java.lang."))
64       return;
65
66     _fields = _primaryKeyClass.getFields();
67     fieldTypes = new int[_fields.length];
68   }
69
70   public BurlapHandleEncoder(AbstractServer server, String JavaDoc serverId,
71                              Class JavaDoc primaryKeyClass)
72     throws ConfigException
73   {
74     this(serverId, primaryKeyClass);
75
76     setServer(server);
77   }
78
79   /**
80    * Creates a home handle given the server id.
81    */

82   public AbstractHomeHandle createHomeHandle()
83   {
84     try {
85       return new BurlapHomeHandle(getServer().getEJBHome(), getServerId());
86     } catch (Throwable JavaDoc e) {
87       return new BurlapHomeHandle(getServerId());
88     }
89   }
90
91   /**
92    * Creates a handle given the server id and the object id.
93    */

94   public AbstractHandle createHandle(String JavaDoc objectId)
95   {
96     String JavaDoc url = getURL(objectId);
97
98     try {
99       return new BurlapHandle(url, getServer().getEJBObject(objectId));
100     } catch (Throwable JavaDoc e) {
101       return new BurlapHandle(url);
102     }
103   }
104   
105   /**
106    * Creates a random string key which hashes to this server.
107    */

108   public String JavaDoc createRandomStringKey()
109   {
110     String JavaDoc originalKey = super.createRandomStringKey();
111
112     int srun = 0;
113     int tail = calculateHash(originalKey) * 65521;
114
115     CharBuffer cb = CharBuffer.allocate();
116     cb.append(originalKey);
117
118     int d1 = (64 + srun - tail) & 0x3f;
119     cb.append(serverEncode64[d1]);
120
121     return cb.close();
122   }
123
124   /**
125    * Returns the hash of a string for load-balancing.
126    */

127   private int calculateHash(String JavaDoc key)
128   {
129     int hash = 137;
130     int len = key.length();
131     for (int i = 0; i < len; i++) {
132       char ch = key.charAt(i);
133       hash = 65521 * hash + serverHash64[ch & 0xff];
134     }
135
136     return hash;
137   }
138
139   /**
140    * Converts a string object id to the correct key.
141    */

142   public Object JavaDoc objectIdToKey(Object JavaDoc objectKey)
143   {
144     String JavaDoc objectId = (String JavaDoc) objectKey;
145
146     if (_primaryKeyClass == null)
147       return objectId;
148     else if (_primaryKeyClass.equals(String JavaDoc.class))
149       return objectId;
150     else if (_primaryKeyClass.equals(Integer JavaDoc.class) ||
151              _primaryKeyClass.equals(int.class))
152       return new Integer JavaDoc(objectId);
153     else if (_primaryKeyClass.equals(Long JavaDoc.class) ||
154              _primaryKeyClass.equals(long.class))
155       return new Long JavaDoc(objectId);
156     else if (_primaryKeyClass.equals(Float JavaDoc.class) ||
157              _primaryKeyClass.equals(float.class))
158       return new Float JavaDoc(objectId);
159     else if (_primaryKeyClass.equals(Double JavaDoc.class) ||
160              _primaryKeyClass.equals(double.class))
161       return new Double JavaDoc(objectId);
162     else if (Character JavaDoc.class.equals(_primaryKeyClass) ||
163              char.class.equals(_primaryKeyClass))
164       return objectId;
165     else if (_fields != null) {
166       Object JavaDoc obj;
167
168       try {
169         obj = _primaryKeyClass.newInstance();
170
171         int length = objectId.length();
172         int j = 0;
173         
174         CharBuffer cb = new CharBuffer();
175         for (int i = 0; i < _fields.length; i++) {
176           cb.clear();
177           for (; j < length && objectId.charAt(j) != ','; j++)
178             cb.append(objectId.charAt(j));
179
180           j++;
181
182           String JavaDoc field = cb.toString();
183           Class JavaDoc fieldClass = _fields[i].getType();
184         
185           if (fieldClass.equals(String JavaDoc.class))
186             _fields[i].set(obj, field);
187           else if (fieldClass.equals(int.class))
188             _fields[i].setInt(obj, Integer.parseInt(field));
189           else if (fieldClass.equals(Integer JavaDoc.class))
190             _fields[i].set(obj, new Integer JavaDoc(field));
191           else if (fieldClass.equals(long.class))
192             _fields[i].setLong(obj, Long.parseLong(field));
193           else if (fieldClass.equals(Long JavaDoc.class))
194             _fields[i].set(obj, new Long JavaDoc(field));
195           else if (fieldClass.equals(float.class))
196             _fields[i].setFloat(obj, (float) Double.parseDouble(field));
197           else if (fieldClass.equals(Float JavaDoc.class))
198             _fields[i].set(obj, new Float JavaDoc(field));
199           else if (fieldClass.equals(double.class))
200             _fields[i].setDouble(obj, Double.parseDouble(field));
201           else if (fieldClass.equals(Double JavaDoc.class))
202             _fields[i].set(obj, new Double JavaDoc(field));
203           else if (char.class.equals(fieldClass))
204             _fields[i].setChar(obj, field.charAt(0));
205           else if (Character JavaDoc.class.equals(fieldClass))
206             _fields[i].set(obj, new Character JavaDoc(field.charAt(0)));
207           else
208             throw new RuntimeException JavaDoc();
209         }
210
211         j++;
212       } catch (Exception JavaDoc e) {
213         throw EJBExceptionWrapper.create(e);
214       }
215       
216       return obj;
217     }
218     else
219       throw new EJBException JavaDoc("bad primary key class");
220   }
221
222   /**
223    * Initialize the server encoding hash.
224    */

225   static {
226     serverEncode64 = new char[64];
227     for (int i = 0; i < 26; i++) {
228       serverEncode64[i] = (char) ('a' + i);
229       serverEncode64[i + 26] = (char) ('A' + i);
230     }
231     for (int i = 0; i < 10; i++)
232       serverEncode64[i + 52] = (char) ('0' + i);
233     serverEncode64[62] = '-';
234     serverEncode64[63] = '_';
235     
236     serverHash64 = new int[256];
237     
238     for (int i = 0; i < 26; i++) {
239       serverHash64['a' + i] = i;
240       serverHash64['A' + i] = i + 26;
241     }
242     for (int i = 0; i < 10; i++)
243       serverHash64['0' + i] = 52 + i;
244     serverHash64['-'] = 62;
245     serverHash64['_'] = 63;
246
247     int j = 64;
248     for (int i = 0; i < 256; i++) {
249       if (serverHash64[i] == 0)
250         serverHash64[i] = j++;
251     }
252     
253     serverEncodeH2 = new char[64];
254     j = 0;
255     for (int i = 0; i < 64; i++) {
256       serverEncodeH2[j] = serverEncode64[i];
257       j = (j + 49) % 64;
258     }
259   }
260 }
261
Popular Tags