1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package org.openrdf.elmo.sesame.converters.impl;
30
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.InputStream;
34 import java.io.ObjectInputStream;
35 import java.io.ObjectOutputStream;
36
37 import org.openrdf.elmo.exceptions.ElmoConversionException;
38 import org.openrdf.elmo.sesame.converters.Marshall;
39 import org.openrdf.model.Literal;
40 import org.openrdf.model.URI;
41 import org.openrdf.model.ValueFactory;
42
43 public class ObjectSerializationMarshall<T> implements Marshall<T> {
44 private static final String pseudo[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
45 "9", "A", "B", "C", "D", "E", "F" };
46 private ValueFactory vf;
47
48 private Class<T> type;
49
50 private URI datatype;
51
52 public ObjectSerializationMarshall(ValueFactory vf, Class<T> type) {
53 super();
54 this.vf = vf;
55 this.type = type;
56 this.datatype = vf.createURI("java:", type.getName());
57 }
58
59 public Class<T> getJavaClass() {
60 return type;
61 }
62
63 public URI getDatatype() {
64 return datatype;
65 }
66
67 public void setDatatype(URI datatype) {
68 this.datatype = datatype;
69 }
70
71 public T deserialize(Literal literal) {
72 try {
73 byte[] decoded = decode(literal.getLabel());
74 InputStream is = new ByteArrayInputStream(decoded);
75 ObjectInputStream ois = new ObjectInputStream(is);
76 Object result = ois.readObject();
77 ois.close();
78 return type.cast(result);
79 } catch (ElmoConversionException e) {
80 throw e;
81 } catch (Exception e) {
82 throw new ElmoConversionException(e);
83 }
84 }
85
86 public Literal serialize(T object) {
87 try {
88 ByteArrayOutputStream bos = new ByteArrayOutputStream();
89 ObjectOutputStream oos = new ObjectOutputStream(bos);
90 oos.writeObject(object);
91 oos.close();
92 byte[] byteArray = bos.toByteArray();
93 String label = encode(byteArray);
94 return vf.createLiteral(label, datatype);
95 } catch (ElmoConversionException e) {
96 throw e;
97 } catch (Exception e) {
98 throw new ElmoConversionException(e);
99 }
100 }
101
102 private String encode(byte[] in) {
103 StringBuilder out = new StringBuilder(in.length * 2);
104 for (int i = 0; i < in.length; i++) {
105 byte ch = (byte) (in[i] & 0xF0);
106 ch = (byte) (ch >>> 4);
107 ch = (byte) (ch & 0x0F);
108 out.append(pseudo[ch]);
109 ch = (byte) (in[i] & 0x0F);
110 out.append(pseudo[ch]);
111 }
112 return out.toString();
113 }
114
115 private byte[] decode(String str) {
116 char[] in = str.toCharArray();
117 byte[] out = new byte[in.length / 2];
118 if (in.length % 2 == 1)
119 throw new ElmoConversionException("Hex String must be an odd number of characters");
120 int j = 0;
121 for (int i = 0; i < out.length; i++) {
122 int most = Character.digit(in[j++], 16);
123 int least = Character.digit(in[j++], 16);
124 int value = most << 4 | least;
125 out[i] = (byte) (value & 0xFF);
126 }
127 return out;
128 }
129 }