KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > hessian > HessianHandleEncoder


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.hessian;
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 HessianHandleEncoder 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 HessianHandleEncoder(AbstractServer server, String JavaDoc serverId,
55                              Class JavaDoc primaryKeyClass)
56     throws ConfigException
57   {
58     super(serverId);
59     
60     _primaryKeyClass = primaryKeyClass;
61
62     if (_primaryKeyClass == null ||
63         _primaryKeyClass.isPrimitive() ||
64         _primaryKeyClass.getName().startsWith("java.lang."))
65       return;
66
67     _fields = _primaryKeyClass.getFields();
68     _fieldTypes = new int[_fields.length];
69
70     for (int i = 0; i < _fields.length; i++)
71       _fields[i].setAccessible(true);
72
73     setServer(server);
74   }
75   
76   /**
77    * Creates a home handle given the server id.
78    */

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

91   public AbstractHandle createHandle(String JavaDoc objectId)
92   {
93     HessianHandle handle = new HessianHandle(getURL(objectId), objectId);
94
95     return handle;
96   }
97
98   /**
99    * Creates a random string key which hashes to this server.
100    */

101   public String JavaDoc createRandomStringKey()
102   {
103     String JavaDoc originalKey = super.createRandomStringKey();
104
105     int srun = 0;
106     int tail = calculateHash(originalKey) * 65521;
107
108     CharBuffer cb = CharBuffer.allocate();
109     cb.append(originalKey);
110
111     int d1 = (64 + srun - tail) & 0x3f;
112     cb.append(_serverEncode64[d1]);
113
114     return cb.close();
115   }
116
117   /**
118    * Returns the hash of a string for load-balancing.
119    */

120   private int calculateHash(String JavaDoc key)
121   {
122     int hash = 137;
123     int len = key.length();
124     for (int i = 0; i < len; i++) {
125       char ch = key.charAt(i);
126       hash = 65521 * hash + _serverHash64[ch & 0xff];
127     }
128
129     return hash;
130   }
131
132   /**
133    * Converts a string object id to the correct key.
134    */

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

211   static {
212     _serverEncode64 = new char[64];
213     for (int i = 0; i < 26; i++) {
214       _serverEncode64[i] = (char) ('a' + i);
215       _serverEncode64[i + 26] = (char) ('A' + i);
216     }
217     for (int i = 0; i < 10; i++)
218       _serverEncode64[i + 52] = (char) ('0' + i);
219     _serverEncode64[62] = '-';
220     _serverEncode64[63] = '_';
221     
222     _serverHash64 = new int[256];
223     
224     for (int i = 0; i < 26; i++) {
225       _serverHash64['a' + i] = i;
226       _serverHash64['A' + i] = i + 26;
227     }
228     for (int i = 0; i < 10; i++)
229       _serverHash64['0' + i] = 52 + i;
230     _serverHash64['-'] = 62;
231     _serverHash64['_'] = 63;
232
233     int j = 64;
234     for (int i = 0; i < 256; i++) {
235       if (_serverHash64[i] == 0)
236         _serverHash64[i] = j++;
237     }
238     
239     _serverEncodeH2 = new char[64];
240     j = 0;
241     for (int i = 0; i < 64; i++) {
242       _serverEncodeH2[j] = _serverEncode64[i];
243       j = (j + 49) % 64;
244     }
245   }
246 }
247
Popular Tags