View Javadoc

1   /*
2    * Copyright (c) 2011.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.hbql.io;
22  
23  import org.apache.hadoop.hbase.hbql.client.HBqlException;
24  import org.apache.hadoop.hbase.hbql.mapping.FieldType;
25  import org.apache.hadoop.hbase.util.Bytes;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.ByteArrayOutputStream;
29  import java.io.IOException;
30  import java.io.ObjectInputStream;
31  import java.io.ObjectOutputStream;
32  import java.io.Serializable;
33  import java.lang.reflect.Array;
34  
35  public class HadoopSerialization extends Serialization {
36  
37      private static final int arraysize = Bytes.SIZEOF_INT;
38  
39      public Object getScalarFromBytes(final FieldType fieldType, final byte[] b) throws HBqlException {
40  
41          if (b == null || b.length == 0)
42              return null;
43  
44          try {
45              switch (fieldType) {
46  
47                  case BooleanType:
48                      return Bytes.toBoolean(b);
49  
50                  case ByteType:
51                      return b[0];
52  
53                  case CharType: {
54                      final String s = Bytes.toString(b);
55                      return s.charAt(0);
56                  }
57  
58                  case ShortType:
59                      return Bytes.toShort(b);
60  
61                  case IntegerType:
62                      return Bytes.toInt(b);
63  
64                  case LongType:
65                      return Bytes.toLong(b);
66  
67                  case FloatType:
68                      return Bytes.toFloat(b);
69  
70                  case DoubleType:
71                      return Bytes.toDouble(b);
72  
73                  case KeyType:
74                  case StringType:
75                      return Bytes.toString(b);
76  
77                  case DateType:
78                  case ObjectType: {
79                      final ByteArrayInputStream bais = new ByteArrayInputStream(b);
80                      final ObjectInputStream ois = new ObjectInputStream(bais);
81                      try {
82                          return ois.readObject();
83                      }
84                      finally {
85                          ois.close();
86                      }
87                  }
88  
89                  default:
90                      throw new HBqlException("Unknown type in getScalarFromBytes() - " + fieldType);
91              }
92          }
93          catch (IOException e) {
94              // e.printStackTrace();
95              throw new HBqlException(getExceptionMessage("getScalarFromBytes()", e));
96          }
97          catch (ClassNotFoundException e) {
98              throw new HBqlException(getExceptionMessage("getScalarFromBytes()", e));
99          }
100     }
101 
102     public byte[] getScalarAsBytes(final FieldType fieldType, final Object obj) throws HBqlException {
103 
104         if (obj == null)
105             return null;
106 
107         try {
108             switch (fieldType) {
109 
110                 case BooleanType:
111                     return Bytes.toBytes((Boolean)obj);
112 
113                 case ByteType: {
114                     final byte[] retval = {((Byte)obj).byteValue()};
115                     return retval;
116                 }
117 
118                 case CharType: {
119                     final String s = String.valueOf(obj);
120                     return Bytes.toBytes(s);
121                 }
122 
123                 case ShortType:
124                     return Bytes.toBytes((Short)obj);
125 
126                 case IntegerType:
127                     return Bytes.toBytes((Integer)obj);
128 
129                 case LongType:
130                     return Bytes.toBytes((Long)obj);
131 
132                 case FloatType:
133                     return Bytes.toBytes((Float)obj);
134 
135                 case DoubleType:
136                     return Bytes.toBytes((Double)obj);
137 
138                 case KeyType:
139                 case StringType:
140                     return Bytes.toBytes((String)obj);
141 
142                 case DateType:
143                 case ObjectType:
144                     final ByteArrayOutputStream baos = new ByteArrayOutputStream();
145                     final ObjectOutputStream oos = new ObjectOutputStream(baos);
146                     oos.writeObject((Serializable)obj);
147                     oos.flush();
148                     try {
149                         return baos.toByteArray();
150                     }
151                     finally {
152                         oos.close();
153                     }
154 
155                 default:
156                     throw new HBqlException("Unknown type in getScalarAsBytes() - " + fieldType);
157             }
158         }
159         catch (IOException e) {
160             // e.printStackTrace();
161             throw new HBqlException(getExceptionMessage("getScalarAsBytes()", e));
162         }
163     }
164 
165     public Object getArrayFromBytes(final FieldType fieldType, final Class clazz, final byte[] b) throws HBqlException {
166 
167         if (b == null || b.length == 0)
168             return null;
169 
170         try {
171             switch (fieldType) {
172 
173                 case BooleanType: {
174                     final ByteArrayInputStream bais = new ByteArrayInputStream(b);
175                     final ObjectInputStream ois = new ObjectInputStream(bais);
176                     final int length = ois.readInt();
177                     final Object array = Array.newInstance(clazz, length);
178                     for (int i = 0; i < length; i++) {
179                         Array.set(array, i, ois.readBoolean());
180                     }
181                     return array;
182                 }
183 
184                 case ByteType: {
185                     final int length = this.readLength(b);
186                     int offset = arraysize;
187                     final Object array = Array.newInstance(clazz, length);
188                     for (int i = 0; i < length; i++) {
189                         Array.set(array, i, b[offset]);
190                         offset += fieldType.getSize();
191                     }
192                     return array;
193                 }
194 
195                 case CharType: {
196                     final String s = new String(b);
197                     return s.toCharArray();
198                 }
199 
200                 case ShortType: {
201                     final int length = this.readLength(b);
202                     int offset = arraysize;
203                     final Object array = Array.newInstance(clazz, length);
204                     for (int i = 0; i < length; i++) {
205                         Array.set(array, i, Bytes.toShort(b, offset));
206                         offset += fieldType.getSize();
207                     }
208                     return array;
209                 }
210 
211                 case IntegerType: {
212                     final int length = this.readLength(b);
213                     int offset = arraysize;
214                     final Object array = Array.newInstance(clazz, length);
215                     for (int i = 0; i < length; i++) {
216                         Array.set(array, i, Bytes.toInt(b, offset));
217                         offset += fieldType.getSize();
218                     }
219                     return array;
220                 }
221 
222                 case LongType: {
223                     final int length = this.readLength(b);
224                     int offset = arraysize;
225                     final Object array = Array.newInstance(clazz, length);
226                     for (int i = 0; i < length; i++) {
227                         Array.set(array, i, Bytes.toLong(b, offset));
228                         offset += fieldType.getSize();
229                     }
230                     return array;
231                 }
232 
233                 case FloatType: {
234                     final int length = this.readLength(b);
235                     int offset = arraysize;
236                     final Object array = Array.newInstance(clazz, length);
237                     for (int i = 0; i < length; i++) {
238                         final float val = Bytes.toFloat(b, offset);
239                         Array.set(array, i, val);
240                         offset += fieldType.getSize();
241                     }
242                     return array;
243                 }
244 
245                 case DoubleType: {
246                     final int length = this.readLength(b);
247                     int offset = arraysize;
248                     final Object array = Array.newInstance(clazz, length);
249                     for (int i = 0; i < length; i++) {
250                         final double val = Bytes.toDouble(b, offset);
251                         Array.set(array, i, val);
252                         offset += fieldType.getSize();
253                     }
254                     return array;
255                 }
256 
257                 case StringType: {
258                     final ByteArrayInputStream bais = new ByteArrayInputStream(b);
259                     final ObjectInputStream ois = new ObjectInputStream(bais);
260                     final int length = ois.readInt();
261                     final Object array = Array.newInstance(clazz, length);
262                     for (int i = 0; i < length; i++) {
263                         Array.set(array, i, ois.readUTF());
264                     }
265                     return array;
266                 }
267 
268                 case DateType:
269                 case ObjectType: {
270                     final ByteArrayInputStream bais = new ByteArrayInputStream(b);
271                     final ObjectInputStream ois = new ObjectInputStream(bais);
272                     try {
273                         final int length = ois.readInt();
274                         final Object array = Array.newInstance(clazz, length);
275                         for (int i = 0; i < length; i++) {
276                             Array.set(array, i, ois.readObject());
277                         }
278                         return array;
279                     }
280                     finally {
281                         ois.close();
282                     }
283                 }
284 
285                 default:
286                     throw new HBqlException("Unknown type in getArrayFromBytes() - " + fieldType);
287             }
288         }
289         catch (IOException e) {
290             throw new HBqlException(getExceptionMessage("getArrayFromBytes()", e));
291         }
292         catch (ClassNotFoundException e) {
293             throw new HBqlException(getExceptionMessage("getArrayFromBytes()", e));
294         }
295     }
296 
297     public byte[] getArrayAsBytes(final FieldType fieldType, final Object obj) throws HBqlException {
298 
299         if (obj == null)
300             return null;
301 
302         try {
303             switch (fieldType) {
304 
305                 case BooleanType: {
306                     final ByteArrayOutputStream baos = new ByteArrayOutputStream();
307                     final ObjectOutputStream oos = new ObjectOutputStream(baos);
308                     oos.writeInt(((boolean[])obj).length);
309                     for (final boolean val : (boolean[])obj) {
310                         oos.writeBoolean(val);
311                     }
312                     oos.flush();
313                     return baos.toByteArray();
314                 }
315 
316                 case ByteType: {
317                     final int length = ((byte[])obj).length;
318                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
319                     this.writeLength(b, length);
320                     int offset = arraysize;
321                     for (final byte val : (byte[])obj) {
322                         Bytes.putByte(b, offset, val);
323                         offset += fieldType.getSize();
324                     }
325                     return b;
326                 }
327 
328                 case CharType: {
329                     final String s = new String((char[])obj);
330                     return Bytes.toBytes(s);
331                 }
332 
333                 case ShortType: {
334                     final int length = ((short[])obj).length;
335                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
336                     this.writeLength(b, length);
337                     int offset = arraysize;
338                     for (final short val : (short[])obj) {
339                         Bytes.putShort(b, offset, val);
340                         offset += fieldType.getSize();
341                     }
342                     return b;
343                 }
344 
345                 case IntegerType: {
346                     final int length = ((int[])obj).length;
347                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
348                     this.writeLength(b, length);
349                     int offset = arraysize;
350                     for (final int val : (int[])obj) {
351                         Bytes.putInt(b, offset, val);
352                         offset += fieldType.getSize();
353                     }
354                     return b;
355                 }
356 
357                 case LongType: {
358                     final int length = ((long[])obj).length;
359                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
360                     this.writeLength(b, length);
361                     int offset = arraysize;
362                     for (final long val : (long[])obj) {
363                         Bytes.putLong(b, offset, val);
364                         offset += fieldType.getSize();
365                     }
366                     return b;
367                 }
368 
369                 case FloatType: {
370                     final int length = ((float[])obj).length;
371                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
372                     this.writeLength(b, length);
373                     int offset = arraysize;
374                     for (final float val : (float[])obj) {
375                         Bytes.putFloat(b, offset, val);
376                         offset += fieldType.getSize();
377                     }
378                     return b;
379                 }
380 
381                 case DoubleType: {
382                     final int length = ((double[])obj).length;
383                     final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
384                     this.writeLength(b, length);
385                     int offset = arraysize;
386                     for (final double val : (double[])obj) {
387                         Bytes.putDouble(b, offset, val);
388                         offset += fieldType.getSize();
389                     }
390                     return b;
391                 }
392 
393                 case StringType: {
394                     final ByteArrayOutputStream baos = new ByteArrayOutputStream();
395                     final ObjectOutputStream oos = new ObjectOutputStream(baos);
396                     oos.writeInt(((Object[])obj).length);
397                     for (final String val : (String[])obj) {
398                         oos.writeUTF(val);
399                     }
400                     oos.flush();
401                     return baos.toByteArray();
402                 }
403 
404                 case DateType:
405                 case ObjectType: {
406                     final ByteArrayOutputStream baos = new ByteArrayOutputStream();
407                     final ObjectOutputStream oos = new ObjectOutputStream(baos);
408                     oos.writeInt(((Object[])obj).length);
409                     for (final Object val : (Object[])obj) {
410                         oos.writeObject((Serializable)val);
411                     }
412                     oos.flush();
413                     return baos.toByteArray();
414                 }
415 
416                 default:
417                     throw new HBqlException("Unknown type in getArrayAsBytes() - " + fieldType);
418             }
419         }
420         catch (IOException e) {
421             throw new HBqlException(getExceptionMessage("getArrayAsBytes()", e));
422         }
423     }
424 
425     private int readLength(final byte[] b) {
426         return Bytes.toInt(b);
427     }
428 
429     private void writeLength(final byte[] b, final int length) {
430         Bytes.putInt(b, 0, length);
431     }
432 }