Commit MetaInfo

Revision624b226143b8c23308c2ca108e16e02df46b178b (tree)
Time2012-10-22 16:27:04
Authorjwat <jwat@user...>
Commiterjwat

Log Message

* The 1st release of ASN.1 / POJO translation feature.
* Add set(int) method to INTEGER class.

Change Summary

Incremental Difference

--- a/jp/bitmeister/asn1/codec/ber/BerEncoder.java
+++ b/jp/bitmeister/asn1/codec/ber/BerEncoder.java
@@ -89,7 +89,7 @@ public class BerEncoder implements ASN1Encoder,
8989 * Encodes an ASN.1 data.
9090 *
9191 * @param data
92- * The ASN.1 data to be encoded
92+ * The ASN.1 data to be encoded.
9393 * @return The size of encoded octets.
9494 * @throws ASN1EncodingException
9595 * When an error occurred while the encoding process.
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/PojoDecoder.java
@@ -0,0 +1,565 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo;
17+
18+import java.lang.reflect.Field;
19+import java.math.BigInteger;
20+import java.util.Date;
21+import java.util.List;
22+import java.util.Map.Entry;
23+
24+import jp.bitmeister.asn1.codec.ASN1Decoder;
25+import jp.bitmeister.asn1.exception.ASN1DecodingException;
26+import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
27+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaObject;
28+import jp.bitmeister.asn1.processor.ASN1Visitor;
29+import jp.bitmeister.asn1.processor.ASN1VisitorAdaptor;
30+import jp.bitmeister.asn1.type.ASN1Type;
31+import jp.bitmeister.asn1.type.CollectionType;
32+import jp.bitmeister.asn1.type.ConstructiveType;
33+import jp.bitmeister.asn1.type.ElementSpecification;
34+import jp.bitmeister.asn1.type.NamedTypeSpecification;
35+import jp.bitmeister.asn1.type.SelectiveType;
36+import jp.bitmeister.asn1.type.StringType;
37+import jp.bitmeister.asn1.type.StructuredType;
38+import jp.bitmeister.asn1.type.TimeType;
39+import jp.bitmeister.asn1.type.UnknownType;
40+import jp.bitmeister.asn1.type.builtin.ANY;
41+import jp.bitmeister.asn1.type.builtin.BIT_STRING;
42+import jp.bitmeister.asn1.type.builtin.BOOLEAN;
43+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
44+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
45+import jp.bitmeister.asn1.type.builtin.CHOICE;
46+import jp.bitmeister.asn1.type.builtin.ENUMERATED;
47+import jp.bitmeister.asn1.type.builtin.INTEGER;
48+import jp.bitmeister.asn1.type.builtin.NULL;
49+import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
50+import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
51+import jp.bitmeister.asn1.type.builtin.REAL;
52+import jp.bitmeister.asn1.type.builtin.RELATIVE_OID;
53+import jp.bitmeister.asn1.type.builtin.SEQUENCE;
54+import jp.bitmeister.asn1.type.builtin.SEQUENCE_OF;
55+import jp.bitmeister.asn1.type.builtin.SET;
56+import jp.bitmeister.asn1.type.builtin.SET_OF;
57+import jp.bitmeister.asn1.value.HexString;
58+
59+/**
60+ * POJO to ASN.1 data decoder.
61+ *
62+ * <p>
63+ * {@code PojoDecoder} is an implementation of {@code ASN1Decoder}. It
64+ * translates a POJO data to an ASN.1 data. Correspondence of a POJO class to an
65+ * ASN.1 class is indicated by {@code @ASN1JavaObject} annotation.
66+ * </p>
67+ *
68+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
69+ *
70+ * @see ASN1Decoder
71+ * @see PojoEncoder
72+ * @see ASN1JavaObject
73+ */
74+public class PojoDecoder implements ASN1Decoder {
75+
76+ /**
77+ * Source of translation.
78+ */
79+ private Object object;
80+
81+ /**
82+ * Instantiates a {@code PojoDecoder} with a source object.
83+ *
84+ * @param object
85+ * The POJO data to be translated.
86+ */
87+ public PojoDecoder(Object object) {
88+ this.object = object;
89+ }
90+
91+ /**
92+ * Translates a POJO data to corresponding ASN.1 data.
93+ *
94+ * @return The ASN.1 data
95+ * @throws ASN1DecodingException
96+ * When an error occurred while the decoding process.
97+ */
98+ public ASN1Type decode() throws ASN1DecodingException {
99+ ASN1JavaObject javaObj = object.getClass().getAnnotation(
100+ ASN1JavaObject.class);
101+ if (javaObj == null) {
102+ ASN1DecodingException ex = new ASN1DecodingException();
103+ ex.setMessage(
104+ "@ASN1JavaObject annotation is not present on the POJO class.",
105+ null, null, null, null);
106+ throw ex;
107+ }
108+ return decode(javaObj.value());
109+ }
110+
111+ /**
112+ * Translates a POJO data to corresponding ASN.1 data.
113+ *
114+ * @param type
115+ * The class object of destination ASN.1 type.
116+ * @return The ASN.1 data
117+ * @throws ASN1DecodingException
118+ * When an error occurred while the decoding process.
119+ */
120+ public <T extends ASN1Type> T decode(Class<T> type)
121+ throws ASN1DecodingException {
122+ T data = ASN1Type.instantiate(type);
123+ try {
124+ if (data.accept(new StructureDecoder(object)) == null) {
125+ ASN1DecodingException ex = new ASN1DecodingException();
126+ ex.setMessage(
127+ "Only structured classes (SEQUENCE, SET, CHOICE) can be destination of POJO transration.",
128+ null, type, null, null);
129+ throw ex;
130+ }
131+ } catch (Exception e) {
132+ ASN1DecodingException ex = new ASN1DecodingException();
133+ ex.setMessage("Failed to decode POJO object to ASN.1 data.", e,
134+ type, null, null);
135+ throw ex;
136+ }
137+ return data;
138+ }
139+
140+ /**
141+ * Internal processor class that processes {@code @ASN1JavaObject} class.
142+ *
143+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
144+ *
145+ */
146+ private class StructureDecoder extends
147+ ASN1VisitorAdaptor<Boolean, Exception> {
148+
149+ /**
150+ * Source.
151+ */
152+ private Object object;
153+
154+ /**
155+ * Instantiates {@code StructureDecoder} with a source object.
156+ *
157+ * @param object
158+ * The {@code @ASN1JavaObject} object.
159+ */
160+ StructureDecoder(Object object) {
161+ this.object = object;
162+ }
163+
164+ /*
165+ * (non-Javadoc)
166+ *
167+ * @see
168+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
169+ * .asn1.type.builtin.CHOICE)
170+ */
171+ @Override
172+ public Boolean visit(CHOICE data) throws Exception {
173+ processSelective(data);
174+ return true;
175+ }
176+
177+ /*
178+ * (non-Javadoc)
179+ *
180+ * @see
181+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
182+ * .asn1.type.builtin.SEQUENCE)
183+ */
184+ @Override
185+ public Boolean visit(SEQUENCE data) throws Exception {
186+ processConstructive(data);
187+ return true;
188+ }
189+
190+ /*
191+ * (non-Javadoc)
192+ *
193+ * @see
194+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
195+ * .asn1.type.builtin.SET)
196+ */
197+ @Override
198+ public Boolean visit(SET data) throws Exception {
199+ processConstructive(data);
200+ return true;
201+ }
202+
203+ /**
204+ * Processes constructive type (i.e. 'SEQUENCE' and 'SET') object.
205+ *
206+ * @param data
207+ * The ASN.1 constructive type object.
208+ * @throws Exception
209+ * When an error occurred while translation process.
210+ */
211+ private void processConstructive(ConstructiveType data)
212+ throws Exception {
213+ PojoSpecification spec = PojoSpecification.getSpecification(object
214+ .getClass());
215+ if (!spec.checkTarget(data.getClass())) {
216+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
217+ ex.setMessage("Incompatible ASN.1 type is specified.", null,
218+ data.getClass(), null, null);
219+ throw ex;
220+ }
221+ for (ElementSpecification e : data.getElementTypeList()) {
222+ Object value = spec.getField(e).get(object);
223+ if (value != null) {
224+ ASN1Type element = e.instantiate();
225+ element.accept(new ElementProcessor(value));
226+ data.set(e, element);
227+ }
228+ }
229+ }
230+
231+ /**
232+ * Processes selective type (i.e. 'CHOICE') object.
233+ *
234+ * @param data
235+ * The ASN.1 selective type object.
236+ * @throws Exception
237+ * When an error occurred while translation process.
238+ */
239+ private void processSelective(SelectiveType data) throws Exception {
240+ PojoSpecification spec = PojoSpecification.getSpecification(object
241+ .getClass());
242+ if (!spec.checkTarget(data.getClass())) {
243+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
244+ ex.setMessage("Incompatible ASN.1 type is specified.", null,
245+ data.getClass(), null, null);
246+ throw ex;
247+ }
248+ for (Entry<String, Field> e : spec.getFields()) {
249+ Object value = e.getValue().get(object);
250+ if (value != null) {
251+ NamedTypeSpecification namedType = data.getElement(e
252+ .getKey());
253+ ASN1Type element = namedType.instantiate();
254+ element.accept(new ElementProcessor(value));
255+ data.set(namedType, element);
256+ }
257+ }
258+ }
259+
260+ /**
261+ * Internal processor class that processes {@code @ASN1JavaField} field.
262+ *
263+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
264+ *
265+ */
266+ private class ElementProcessor implements ASN1Visitor<Void, Exception> {
267+
268+ /**
269+ * Value of source field.
270+ */
271+ private Object element;
272+
273+ /**
274+ * Instantiates {@code ElementProcessor} with value of source field.
275+ *
276+ * @param field
277+ * The value of source field.
278+ */
279+ ElementProcessor(Object element) {
280+ this.element = element;
281+ }
282+
283+ /*
284+ * (non-Javadoc)
285+ *
286+ * @see
287+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
288+ * asn1.type.builtin.BOOLEAN)
289+ */
290+ public Void visit(BOOLEAN data) throws IllegalAccessException {
291+ data.set((Boolean) element);
292+ return null;
293+ }
294+
295+ /*
296+ * (non-Javadoc)
297+ *
298+ * @see
299+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
300+ * asn1.type.builtin.INTEGER)
301+ */
302+ public Void visit(INTEGER data) throws IllegalAccessException {
303+ data.set((Long) element);
304+ return null;
305+ }
306+
307+ /*
308+ * (non-Javadoc)
309+ *
310+ * @see
311+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
312+ * asn1.type.builtin.BigINTEGER)
313+ */
314+ public Void visit(BigINTEGER data) throws IllegalAccessException {
315+ data.set((BigInteger) element);
316+ return null;
317+ }
318+
319+ /*
320+ * (non-Javadoc)
321+ *
322+ * @see
323+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
324+ * asn1.type.builtin.BIT_STRING)
325+ */
326+ public Void visit(BIT_STRING data) throws IllegalAccessException {
327+ data.set(new HexString((byte[]) element));
328+ return null;
329+ }
330+
331+ /*
332+ * (non-Javadoc)
333+ *
334+ * @see
335+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
336+ * asn1.type.builtin.OCTET_STRING)
337+ */
338+ public Void visit(OCTET_STRING data) throws IllegalAccessException {
339+ data.set((byte[]) element);
340+ return null;
341+ }
342+
343+ /*
344+ * (non-Javadoc)
345+ *
346+ * @see
347+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
348+ * asn1.type.builtin.NULL)
349+ */
350+ public Void visit(NULL data) throws IllegalAccessException {
351+ return null;
352+ }
353+
354+ /*
355+ * (non-Javadoc)
356+ *
357+ * @see
358+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
359+ * asn1.type.builtin.OBJECT_IDENTIFIER)
360+ */
361+ public Void visit(OBJECT_IDENTIFIER data)
362+ throws IllegalAccessException {
363+ data.set((int[]) element);
364+ return null;
365+ }
366+
367+ /*
368+ * (non-Javadoc)
369+ *
370+ * @see
371+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
372+ * asn1.type.builtin.REAL)
373+ */
374+ public Void visit(REAL data) throws IllegalAccessException {
375+ data.set((Double) element);
376+ return null;
377+ }
378+
379+ /*
380+ * (non-Javadoc)
381+ *
382+ * @see
383+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
384+ * asn1.type.builtin.ENUMERATED)
385+ */
386+ public Void visit(ENUMERATED data) throws IllegalAccessException {
387+ data.set((Long) element);
388+ return null;
389+ }
390+
391+ /*
392+ * (non-Javadoc)
393+ *
394+ * @see
395+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
396+ * asn1.type.builtin.BigENUMERATED)
397+ */
398+ public Void visit(BigENUMERATED data) throws IllegalAccessException {
399+ data.set((BigInteger) element);
400+ return null;
401+ }
402+
403+ /*
404+ * (non-Javadoc)
405+ *
406+ * @see
407+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
408+ * asn1.type.builtin.RELATIVE_OID)
409+ */
410+ public Void visit(RELATIVE_OID data) throws IllegalAccessException {
411+ data.set((int[]) element);
412+ return null;
413+ }
414+
415+ /*
416+ * (non-Javadoc)
417+ *
418+ * @see
419+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
420+ * asn1.type.StringType)
421+ */
422+ public Void visit(StringType data) throws IllegalAccessException {
423+ data.set((String) element);
424+ return null;
425+ }
426+
427+ /*
428+ * (non-Javadoc)
429+ *
430+ * @see
431+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
432+ * asn1.type.TimeType)
433+ */
434+ public Void visit(TimeType data) throws IllegalAccessException {
435+ data.set((Date) element);
436+ return null;
437+ }
438+
439+ /*
440+ * (non-Javadoc)
441+ *
442+ * @see
443+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
444+ * asn1.type.builtin.ANY)
445+ */
446+ public Void visit(ANY data) throws Exception {
447+ ASN1DecodingException ex = new ASN1DecodingException();
448+ ex.setMessage("ANY type is not supported.", null, ANY.class,
449+ null, data);
450+ throw ex;
451+ }
452+
453+ /*
454+ * (non-Javadoc)
455+ *
456+ * @see
457+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
458+ * asn1.type.builtin.CHOICE)
459+ */
460+ public Void visit(CHOICE data) throws Exception {
461+ processStructured(data);
462+ return null;
463+ }
464+
465+ /*
466+ * (non-Javadoc)
467+ *
468+ * @see
469+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
470+ * asn1.type.builtin.SEQUENCE)
471+ */
472+ public Void visit(SEQUENCE data) throws Exception {
473+ processStructured(data);
474+ return null;
475+ }
476+
477+ /*
478+ * (non-Javadoc)
479+ *
480+ * @see
481+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
482+ * asn1.type.builtin.SEQUENCE_OF)
483+ */
484+ public Void visit(SEQUENCE_OF<? extends ASN1Type> data)
485+ throws Exception {
486+ processCollection(data);
487+ return null;
488+ }
489+
490+ /*
491+ * (non-Javadoc)
492+ *
493+ * @see
494+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
495+ * asn1.type.builtin.SET)
496+ */
497+ public Void visit(SET data) throws Exception {
498+ processStructured(data);
499+ return null;
500+ }
501+
502+ /*
503+ * (non-Javadoc)
504+ *
505+ * @see
506+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
507+ * asn1.type.builtin.SET_OF)
508+ */
509+ public Void visit(SET_OF<? extends ASN1Type> data) throws Exception {
510+ processCollection(data);
511+ return null;
512+ }
513+
514+ /*
515+ * (non-Javadoc)
516+ *
517+ * @see
518+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
519+ * asn1.type.UnknownType)
520+ */
521+ public Void visit(UnknownType data) throws Exception {
522+ ASN1DecodingException ex = new ASN1DecodingException();
523+ ex.setMessage("UnkonwnType is not supported.", null,
524+ UnknownType.class, null, data);
525+ throw ex;
526+ }
527+
528+ /**
529+ * Processes structured type (i.e. 'SEQUENCE', 'SET' and 'CHOICE')
530+ * object.
531+ *
532+ * @param data
533+ * The ASN.1 structured type object.
534+ * @throws Exception
535+ * When an error occurred while translation process.
536+ */
537+ private void processStructured(StructuredType data)
538+ throws Exception {
539+ data.accept(new StructureDecoder(element));
540+ }
541+
542+ /**
543+ * Processes collection type (i.e. 'SEQUENCE OF' and 'SET OF')
544+ * object.
545+ *
546+ * @param data
547+ * The ASN.1 collection type object.
548+ * @throws Exception
549+ * When an error occurred while translation process.
550+ */
551+ private <C extends ASN1Type> void processCollection(
552+ CollectionType<C, ?> data) throws Exception {
553+ List<?> list = (List<?>) element;
554+ for (Object e : list) {
555+ C component = ASN1Type.instantiate(data.componentType());
556+ component.accept(new ElementProcessor(e));
557+ data.collection().add(component);
558+ }
559+ }
560+
561+ }
562+
563+ }
564+
565+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/PojoEncoder.java
@@ -0,0 +1,541 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo;
17+
18+import java.lang.reflect.Field;
19+import java.util.ArrayList;
20+import java.util.List;
21+
22+import jp.bitmeister.asn1.codec.ASN1Encoder;
23+import jp.bitmeister.asn1.exception.ASN1DecodingException;
24+import jp.bitmeister.asn1.exception.ASN1EncodingException;
25+import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
26+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaList;
27+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaObject;
28+import jp.bitmeister.asn1.processor.ASN1Visitor;
29+import jp.bitmeister.asn1.processor.ASN1VisitorAdaptor;
30+import jp.bitmeister.asn1.type.ASN1Type;
31+import jp.bitmeister.asn1.type.CollectionType;
32+import jp.bitmeister.asn1.type.ConstructiveType;
33+import jp.bitmeister.asn1.type.ElementSpecification;
34+import jp.bitmeister.asn1.type.SelectiveType;
35+import jp.bitmeister.asn1.type.StringType;
36+import jp.bitmeister.asn1.type.StructuredType;
37+import jp.bitmeister.asn1.type.TimeType;
38+import jp.bitmeister.asn1.type.UnknownType;
39+import jp.bitmeister.asn1.type.builtin.ANY;
40+import jp.bitmeister.asn1.type.builtin.BIT_STRING;
41+import jp.bitmeister.asn1.type.builtin.BOOLEAN;
42+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
43+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
44+import jp.bitmeister.asn1.type.builtin.CHOICE;
45+import jp.bitmeister.asn1.type.builtin.ENUMERATED;
46+import jp.bitmeister.asn1.type.builtin.INTEGER;
47+import jp.bitmeister.asn1.type.builtin.NULL;
48+import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
49+import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
50+import jp.bitmeister.asn1.type.builtin.REAL;
51+import jp.bitmeister.asn1.type.builtin.RELATIVE_OID;
52+import jp.bitmeister.asn1.type.builtin.SEQUENCE;
53+import jp.bitmeister.asn1.type.builtin.SEQUENCE_OF;
54+import jp.bitmeister.asn1.type.builtin.SET;
55+import jp.bitmeister.asn1.type.builtin.SET_OF;
56+import jp.bitmeister.asn1.value.BinString;
57+
58+/**
59+ * ASN.1 to POJO data encoder.
60+ *
61+ * <p>
62+ * {@code PojoEncoder} is an implementation of {@code ASN1Encoder}. It
63+ * translates an ASN.1 data to a POJO data. Correspondence of an ASN.1 class to
64+ * a POJO class is indicated by {@code @ASN1JavaObject} annotation.
65+ * </p>
66+ *
67+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
68+ *
69+ * @see ASN1Encoder
70+ * @see PojoDecoder
71+ * @see ASN1JavaObject
72+ */
73+public class PojoEncoder implements ASN1Encoder {
74+
75+ /**
76+ * Destination of translation.
77+ */
78+ private Object object;
79+
80+ /**
81+ * Instantiates {@code PojoEncoder} with a destination object.
82+ *
83+ * @param object
84+ * The {@code @ASN1JavaObject} object.
85+ */
86+ public PojoEncoder(Object object) {
87+ this.object = object;
88+ }
89+
90+ /**
91+ * Translates an ASN.1 data to corresponding POJO data.
92+ *
93+ * @param data
94+ * The ASN.1 data to be translated.
95+ * @return 0
96+ * @throws ASN1EncodingException
97+ * When an error occurred while the encoding process.
98+ */
99+ public int encode(ASN1Type data) throws ASN1EncodingException {
100+ try {
101+ if (data.accept(new StructureEncoder(object)) == null) {
102+ ASN1EncodingException ex = new ASN1EncodingException();
103+ ex.setMessage(
104+ "Only structured classes (SEQUENCE, SET, CHOICE) can be translated to POJO.",
105+ null, data.getClass(), null, data);
106+ throw ex;
107+ }
108+ } catch (Exception e) {
109+ ASN1EncodingException ex = new ASN1EncodingException();
110+ ex.setMessage("Exception thrown while encoding process.", e,
111+ data.getClass(), null, data);
112+ throw ex;
113+ }
114+ return 0;
115+ }
116+
117+ /**
118+ * Internal processor class that processes {@code @ASN1JavaObject} class.
119+ *
120+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
121+ *
122+ */
123+ private class StructureEncoder extends
124+ ASN1VisitorAdaptor<Boolean, Exception> {
125+
126+ /**
127+ * Destination.
128+ */
129+ private Object object;
130+
131+ /**
132+ * Instantiates {@code StructureEncoder} with a destination object.
133+ *
134+ * @param object
135+ * The {@code @ASN1JavaObject} object.
136+ */
137+ StructureEncoder(Object object) {
138+ this.object = object;
139+ }
140+
141+ /*
142+ * (non-Javadoc)
143+ *
144+ * @see
145+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
146+ * .asn1.type.builtin.CHOICE)
147+ */
148+ @Override
149+ public Boolean visit(CHOICE data) throws Exception {
150+ processSelective(data);
151+ return true;
152+ }
153+
154+ /*
155+ * (non-Javadoc)
156+ *
157+ * @see
158+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
159+ * .asn1.type.builtin.SEQUENCE)
160+ */
161+ @Override
162+ public Boolean visit(SEQUENCE data) throws Exception {
163+ processConstructive(data);
164+ return true;
165+ }
166+
167+ /*
168+ * (non-Javadoc)
169+ *
170+ * @see
171+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
172+ * .asn1.type.builtin.SET)
173+ */
174+ @Override
175+ public Boolean visit(SET data) throws Exception {
176+ processConstructive(data);
177+ return true;
178+ }
179+
180+ /**
181+ * Processes constructive type (i.e. 'SEQUENCE' and 'SET') object.
182+ *
183+ * @param data
184+ * The ASN.1 constructive type object.
185+ * @throws Exception
186+ * When an error occurred while translation process.
187+ */
188+ private void processConstructive(ConstructiveType data)
189+ throws Exception {
190+ PojoSpecification spec = PojoSpecification.getSpecification(object
191+ .getClass());
192+ if (!spec.checkTarget(data.getClass())) {
193+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
194+ ex.setMessage("Incompatible ASN.1 type data is specified.",
195+ null, data.getClass(), null, null);
196+ throw ex;
197+ }
198+ for (ElementSpecification e : data.getElementTypeList()) {
199+ Field field = spec.getField(e);
200+ if (field == null) {
201+ continue;
202+ }
203+ ASN1Type component = data.getComponent(e);
204+ if (component != null) {
205+
206+ field.set(object,
207+ component.accept(new ElementEncoder(field)));
208+ }
209+ }
210+ }
211+
212+ /**
213+ * Processes selective type (i.e. 'CHOICE') object.
214+ *
215+ * @param data
216+ * The ASN.1 selective type object.
217+ * @throws Exception
218+ * When an error occurred while translation process.
219+ */
220+ private void processSelective(SelectiveType data) throws Exception {
221+ PojoSpecification spec = PojoSpecification.getSpecification(object
222+ .getClass());
223+ if (!spec.checkTarget(data.getClass())) {
224+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
225+ ex.setMessage("Incompatible ASN.1 type data is specified.",
226+ null, data.getClass(), null, null);
227+ throw ex;
228+ }
229+ String selection = data.selectedIdentifier();
230+ Field field = spec.getField(data.getElement(selection));
231+ if (field != null) {
232+ field.set(object,
233+ data.selectedValue().accept(new ElementEncoder(field)));
234+ }
235+ }
236+
237+ /**
238+ * Internal processor class that processes {@code @ASN1JavaField} field.
239+ *
240+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
241+ *
242+ */
243+ private class ElementEncoder implements ASN1Visitor<Object, Exception> {
244+
245+ /**
246+ * Destination field.
247+ */
248+ Field field;
249+
250+ /**
251+ * Instantiates {@code ElementEncoder} with a destination field.
252+ *
253+ * @param field
254+ * The destination field.
255+ */
256+ ElementEncoder(Field field) {
257+ this.field = field;
258+ }
259+
260+ /*
261+ * (non-Javadoc)
262+ *
263+ * @see
264+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
265+ * asn1.type.builtin.BOOLEAN)
266+ */
267+ public Object visit(BOOLEAN data) throws Exception {
268+ return data.value();
269+ }
270+
271+ /*
272+ * (non-Javadoc)
273+ *
274+ * @see
275+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
276+ * asn1.type.builtin.INTEGER)
277+ */
278+ public Object visit(INTEGER data) throws Exception {
279+ return data.value();
280+ }
281+
282+ /*
283+ * (non-Javadoc)
284+ *
285+ * @see
286+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
287+ * asn1.type.builtin.BigINTEGER)
288+ */
289+ public Object visit(BigINTEGER data) throws Exception {
290+ return data.longValue();
291+ }
292+
293+ /*
294+ * (non-Javadoc)
295+ *
296+ * @see
297+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
298+ * asn1.type.builtin.BIT_STRING)
299+ */
300+ public Object visit(BIT_STRING data) throws Exception {
301+ return new BinString(data.value()).toByteArray();
302+ }
303+
304+ /*
305+ * (non-Javadoc)
306+ *
307+ * @see
308+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
309+ * asn1.type.builtin.OCTET_STRING)
310+ */
311+ public Object visit(OCTET_STRING data) throws Exception {
312+ byte[] value = new byte[data.size()];
313+ System.arraycopy(data.value(), 0, value, 0, value.length);
314+ return value;
315+ }
316+
317+ /*
318+ * (non-Javadoc)
319+ *
320+ * @see
321+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
322+ * asn1.type.builtin.NULL)
323+ */
324+ public Object visit(NULL data) throws Exception {
325+ return new Object();
326+ }
327+
328+ /*
329+ * (non-Javadoc)
330+ *
331+ * @see
332+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
333+ * asn1.type.builtin.OBJECT_IDENTIFIER)
334+ */
335+ public Object visit(OBJECT_IDENTIFIER data) throws Exception {
336+ int[] value = new int[data.value().size()];
337+ for (int i = 0; i < value.length; i++) {
338+ value[i] = data.value().get(i);
339+ }
340+ return value;
341+ }
342+
343+ /*
344+ * (non-Javadoc)
345+ *
346+ * @see
347+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
348+ * asn1.type.builtin.REAL)
349+ */
350+ public Object visit(REAL data) throws Exception {
351+ return data.value();
352+ }
353+
354+ /*
355+ * (non-Javadoc)
356+ *
357+ * @see
358+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
359+ * asn1.type.builtin.ENUMERATED)
360+ */
361+ public Object visit(ENUMERATED data) throws Exception {
362+ return data.value();
363+ }
364+
365+ /*
366+ * (non-Javadoc)
367+ *
368+ * @see
369+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
370+ * asn1.type.builtin.BigENUMERATED)
371+ */
372+ public Object visit(BigENUMERATED data) throws Exception {
373+ return data.longValue();
374+ }
375+
376+ /*
377+ * (non-Javadoc)
378+ *
379+ * @see
380+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
381+ * asn1.type.builtin.RELATIVE_OID)
382+ */
383+ public Object visit(RELATIVE_OID data) throws Exception {
384+ int[] value = new int[data.value().size()];
385+ for (int i = 0; i < value.length; i++) {
386+ value[i] = data.value().get(i);
387+ }
388+ return value;
389+ }
390+
391+ /*
392+ * (non-Javadoc)
393+ *
394+ * @see
395+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
396+ * asn1.type.builtin.ANY)
397+ */
398+ public Object visit(ANY data) throws Exception {
399+ return data.value().accept(new ElementEncoder(field));
400+ }
401+
402+ /*
403+ * (non-Javadoc)
404+ *
405+ * @see
406+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
407+ * asn1.type.builtin.CHOICE)
408+ */
409+ public Object visit(CHOICE data) throws Exception {
410+ return processStructured(data);
411+ }
412+
413+ /*
414+ * (non-Javadoc)
415+ *
416+ * @see
417+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
418+ * asn1.type.builtin.SEQUENCE_OF)
419+ */
420+ public Object visit(SEQUENCE_OF<? extends ASN1Type> data)
421+ throws Exception {
422+ return processCollection(data);
423+ }
424+
425+ /*
426+ * (non-Javadoc)
427+ *
428+ * @see
429+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
430+ * asn1.type.builtin.SEQUENCE)
431+ */
432+ public Object visit(SEQUENCE data) throws Exception {
433+ return processStructured(data);
434+ }
435+
436+ /*
437+ * (non-Javadoc)
438+ *
439+ * @see
440+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
441+ * asn1.type.builtin.SET_OF)
442+ */
443+ public Object visit(SET_OF<? extends ASN1Type> data)
444+ throws Exception {
445+ return processCollection(data);
446+ }
447+
448+ /*
449+ * (non-Javadoc)
450+ *
451+ * @see
452+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
453+ * asn1.type.builtin.SET)
454+ */
455+ public Object visit(SET data) throws Exception {
456+ return processStructured(data);
457+ }
458+
459+ /*
460+ * (non-Javadoc)
461+ *
462+ * @see
463+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
464+ * asn1.type.StringType)
465+ */
466+ public Object visit(StringType data) throws Exception {
467+ return data.stringValue();
468+ }
469+
470+ /*
471+ * (non-Javadoc)
472+ *
473+ * @see
474+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
475+ * asn1.type.TimeType)
476+ */
477+ public Object visit(TimeType data) throws Exception {
478+ return data.date();
479+ }
480+
481+ /*
482+ * (non-Javadoc)
483+ *
484+ * @see
485+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.
486+ * asn1.type.UnknownType)
487+ */
488+ public Object visit(UnknownType data) throws Exception {
489+ ASN1DecodingException ex = new ASN1DecodingException();
490+ ex.setMessage("UnkonwnType is not supported.", null,
491+ UnknownType.class, null, data);
492+ throw ex;
493+ }
494+
495+ /**
496+ * Processes structured type (i.e. 'SEQUENCE', 'SET' and 'CHOICE')
497+ * object.
498+ *
499+ * @param data
500+ * The ASN.1 structured type object.
501+ * @return Translated POJO instance.
502+ * @throws Exception
503+ * When an error occurred while translation process.
504+ */
505+ private Object processStructured(StructuredType data)
506+ throws Exception {
507+ ASN1JavaList javaList = field.getAnnotation(ASN1JavaList.class);
508+ Object component;
509+ if (javaList != null) {
510+ component = javaList.value().newInstance();
511+ } else {
512+ component = field.getType().newInstance();
513+ }
514+ data.accept(new StructureEncoder(component));
515+ return component;
516+ }
517+
518+ /**
519+ * Processes collection type (i.e. 'SEQUENCE OF' and 'SET OF')
520+ * object.
521+ *
522+ * @param data
523+ * The ASN.1 collection type object.
524+ * @return Translated POJO instance.
525+ * @throws Exception
526+ * When an error occurred while translation process.
527+ */
528+ private Object processCollection(CollectionType<?, ?> data)
529+ throws Exception {
530+ List<Object> list = new ArrayList<Object>();
531+ for (ASN1Type component : data.collection()) {
532+ list.add(component.accept(new ElementEncoder(field)));
533+ }
534+ return list;
535+ }
536+
537+ }
538+
539+ }
540+
541+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/PojoSpecification.java
@@ -0,0 +1,137 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo;
17+
18+import java.lang.reflect.Field;
19+import java.util.HashMap;
20+import java.util.Map;
21+import java.util.Map.Entry;
22+import java.util.Set;
23+
24+import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
25+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaField;
26+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaObject;
27+import jp.bitmeister.asn1.type.NamedTypeSpecification;
28+import jp.bitmeister.asn1.type.StructuredType;
29+
30+/**
31+ * Specifications of POJO classes that can be translated to ASN.1 types.
32+ *
33+ * <p>
34+ * An instance of this class contains static information of a POJO class that
35+ * can be translated to an ASN.1 class. These POJO classes are annotated as
36+ * {@code @ASN1JavaObject} and have some fields annotated as {@code @ASN1JavaField
37+ * }.
38+ * </p>
39+ *
40+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
41+ *
42+ * @see ASN1JavaObject
43+ * @see ASN1JavaField
44+ */
45+class PojoSpecification {
46+
47+ /**
48+ * Contains {@code PojoSpecifications} of {@code @ASN1JavaObject} classes.
49+ */
50+ private static Map<Class<?>, PojoSpecification> SPECIFICATIONS = new HashMap<Class<?>, PojoSpecification>();
51+
52+ /**
53+ * Returns the PojoSpecification related to the {@code ASN1JavaObject}
54+ * class.
55+ *
56+ * @param clazz
57+ * The {@code @ASN1JavaObject} class.
58+ * @return The PojoSpecification.
59+ */
60+ static PojoSpecification getSpecification(Class<?> clazz) {
61+ PojoSpecification pojoSpec = SPECIFICATIONS.get(clazz);
62+ if (pojoSpec == null) {
63+ ASN1JavaObject javaObj = clazz.getAnnotation(ASN1JavaObject.class);
64+ if (javaObj == null) {
65+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
66+ ex.setMessage(
67+ "ASN.1 type that corresponds to the POJO must be specified.",
68+ null, null, null, null);
69+ throw ex;
70+ }
71+ pojoSpec = new PojoSpecification();
72+ pojoSpec.targetType = javaObj.value();
73+ for (Field field : clazz.getFields()) {
74+ ASN1JavaField javaField = field
75+ .getAnnotation(ASN1JavaField.class);
76+ if (javaField != null) {
77+ String fieldName = javaField.value();
78+ if (fieldName.length() == 0) {
79+ fieldName = field.getName();
80+ }
81+ pojoSpec.fields.put(fieldName, field);
82+ }
83+ }
84+ SPECIFICATIONS.put(clazz, pojoSpec);
85+ }
86+ return pojoSpec;
87+ }
88+
89+ /**
90+ * The ASN.1 structured type related to this {@code @ASN1JavaObject} class.
91+ */
92+ private Class<? extends StructuredType> targetType;
93+
94+ /**
95+ * Map from ASN.1 identifier of element to {@code @ASN1JavaField} field.
96+ */
97+ private Map<String, Field> fields = new HashMap<String, Field>();
98+
99+ /**
100+ * Instantiates a {@code PojoSpecification}.
101+ */
102+ private PojoSpecification() {
103+ }
104+
105+ /**
106+ * Tests if the class is same as target class of this
107+ * {@code @ASN1JavaObject} .
108+ *
109+ * @param type
110+ * The class object to be checked.
111+ * @return {@code true} if the class is the target class.
112+ */
113+ boolean checkTarget(Class<? extends StructuredType> type) {
114+ return type.equals(targetType);
115+ }
116+
117+ /**
118+ * Returns the entry set of map of fields.
119+ *
120+ * @return The entry set.
121+ */
122+ Set<Entry<String, Field>> getFields() {
123+ return fields.entrySet();
124+ }
125+
126+ /**
127+ * Returns a field corresponds to the {@code NamedTypeSpecification}.
128+ *
129+ * @param namedType
130+ * The specification of the ASN.1 element.
131+ * @return The field corresponds to the ASN.1 element.
132+ */
133+ Field getField(NamedTypeSpecification namedType) {
134+ return fields.get(namedType.identifier());
135+ }
136+
137+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/annotation/ASN1JavaField.java
@@ -0,0 +1,152 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo.annotation;
17+
18+import java.lang.annotation.ElementType;
19+import java.lang.annotation.Retention;
20+import java.lang.annotation.RetentionPolicy;
21+import java.lang.annotation.Target;
22+
23+/**
24+ * Indicates identifier of an element of ASN.1 structured type that the field to
25+ * be translated.
26+ *
27+ * <p>
28+ * A field that annotated as {@code @ASN1JavaField} will be translated to a
29+ * particular element of corresponding ASN.1 type indicated by value parameter.
30+ * {@code @ASN1JavaField} field must be contained in a class that annotated as
31+ * {@code @ASN1JavaObject}. An {@code @ASN1JavaField} field must be a public,
32+ * non-static and non-final field.
33+ * </p>
34+ *
35+ * <p>
36+ * Every {@code @ASN1JavaField} fields must be declared as particular type that
37+ * corresponds with ASN.1 type to be translated. Following table shows
38+ * correspondence of ASN.1 types to POJO types.
39+ * </p>
40+ *
41+ * <p>
42+ * <table border=1>
43+ * <th>ASN.1 type</th>
44+ * <th>POJO type</th>
45+ * <tr>
46+ * <td>BOOLEAN</td>
47+ * <td>Boolean</td>
48+ * </tr>
49+ * <tr>
50+ * <td>INTEGER</td>
51+ * <td>Long</td>
52+ * </tr>
53+ * <tr>
54+ * <td>BigINTEGER</td>
55+ * <td>BigInteger</td>
56+ * </tr>
57+ * <tr>
58+ * <td>BIT_STRING</td>
59+ * <td>byte[]</td>
60+ * </tr>
61+ * <tr>
62+ * <td>OCTET_STRING</td>
63+ * <td>byte[]</td>
64+ * </tr>
65+ * <tr>
66+ * <td>NULL</td>
67+ * <td>Object</td>
68+ * </tr>
69+ * <tr>
70+ * <td>OBJECT_IDENTIFIER</td>
71+ * <td>int[]</td>
72+ * </tr>
73+ * <tr>
74+ * <td>ObjectDescriptor</td>
75+ * <td>String</td>
76+ * </tr>
77+ * <tr>
78+ * <td>REAL</td>
79+ * <td>Double</td>
80+ * </tr>
81+ * <tr>
82+ * <td>ENUMERATED</td>
83+ * <td>Long</td>
84+ * </tr>
85+ * <tr>
86+ * <td>BigENUMERATED</td>
87+ * <td>BigInteger</td>
88+ * </tr>
89+ * <tr>
90+ * <td>RELATIVE_OID</td>
91+ * <td>int[]</td>
92+ * </tr>
93+ * <tr>
94+ * <td>SEQUENCE</td>
95+ * <td>@ASN1JavaObject class</td>
96+ * </tr>
97+ * <tr>
98+ * <td>SEQUENCE_OF&lt;ASN.1 type&gt;</td>
99+ * <td>List&lt;POJO type&gt;</td>
100+ * </tr>
101+ * <td>SET</td>
102+ * <td>@ASN1JavaObject class</td>
103+ * </tr>
104+ * <tr>
105+ * <td>SET_OF&lt;ASN.1 type&gt;</td>
106+ * <td>List&lt;POJO type&gt;</td>
107+ * </tr>
108+ * <tr>
109+ * <td>CHOICE</td>
110+ * <td>@ASN1JavaObject class</td>
111+ * </tr>
112+ * <tr>
113+ * <td>String types</td>
114+ * <td>String</td>
115+ * </tr>
116+ * <tr>
117+ * <td>Time types</td>
118+ * <td>Date</td>
119+ * </tr>
120+ * </table>
121+ * </p>
122+ *
123+ * <p>
124+ * If the component of a {@code SEQUENCE_OF} or {@code SET_OF type} is a
125+ * structured ASN.1 type, the field must have an {@code @ASN1JavaList}
126+ * annotation also to indicate corresponding POJO class of the component.
127+ * </p>
128+ *
129+ * <p>
130+ * If field name of an {@code @ASN1JavaField} field that is returned by
131+ * {@code Field.getName()} method and the ASN.1 identifier of corresponding
132+ * ASN.1 element are same, value parameter of {@code @ASN1JavaField} annotation
133+ * can be omitted.
134+ * </p>
135+ *
136+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
137+ *
138+ * @see ASN1JavaObject
139+ * @see ASN1JavaList
140+ */
141+@Target(ElementType.FIELD)
142+@Retention(RetentionPolicy.RUNTIME)
143+public @interface ASN1JavaField {
144+
145+ /**
146+ * Indicates the identifier of an element of corresponding ASN.1 type.
147+ *
148+ * @return The identifier of corresponding element.
149+ */
150+ public String value() default "";
151+
152+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/annotation/ASN1JavaList.java
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo.annotation;
17+
18+import java.lang.annotation.ElementType;
19+import java.lang.annotation.Retention;
20+import java.lang.annotation.RetentionPolicy;
21+import java.lang.annotation.Target;
22+import java.util.List;
23+
24+/**
25+ * Indicates POJO class of component of {@code List} field.
26+ *
27+ * <p>
28+ * This annotation is used for indicating POJO class of component of
29+ * {@code List} field that corresponds to {@code SEQUENCE_OF} or {@code SET_OF}
30+ * ASN.1 type field. If the component of a {@code SEQUENCE_OF} or
31+ * {@code SET_OF type} is a structured ASN.1 type, an {@code @ASN1JavaList}
32+ * annotation must indicate corresponding POJO class of the component.
33+ * </p>
34+ *
35+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
36+ *
37+ * @see List
38+ * @see ASN1JavaObject
39+ * @see ASN1JavaField
40+ */
41+@Target(ElementType.FIELD)
42+@Retention(RetentionPolicy.RUNTIME)
43+public @interface ASN1JavaList {
44+
45+ /**
46+ * Indicates POJO class of component of {@code List} field.
47+ *
48+ * @return The class instance of POJO type.
49+ */
50+ public Class<?> value();
51+
52+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/annotation/ASN1JavaObject.java
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+package jp.bitmeister.asn1.pojo.annotation;
17+
18+import java.lang.annotation.ElementType;
19+import java.lang.annotation.Retention;
20+import java.lang.annotation.RetentionPolicy;
21+import java.lang.annotation.Target;
22+
23+import jp.bitmeister.asn1.pojo.PojoDecoder;
24+import jp.bitmeister.asn1.pojo.PojoEncoder;
25+import jp.bitmeister.asn1.type.StructuredType;
26+
27+/**
28+ * Indicates an ASN.1 structured type that the POJO class to be translated.
29+ *
30+ * <p>
31+ * A POJO class that annotated as {@code @ASN1JavaObject} can be translated to a
32+ * particular ASN.1 structured (i.e. 'SEQUENCE', 'SET' or 'CHOICE') type
33+ * indicated by {@code value} parameter. Each field of the POJO class
34+ * corresponding to elements of ASN.1 type must be annotated as
35+ * {@code @ASN1JavaField}.
36+ * </p>
37+ * <p>
38+ * Every {@code @ASN1JavaObject} class must have public default constructor
39+ * (i.e. the constructor that has no parameters).
40+ * </p>
41+ *
42+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
43+ *
44+ * @see ASN1JavaField
45+ * @see ASN1JavaList
46+ * @see PojoEncoder
47+ * @see PojoDecoder
48+ */
49+@Target(ElementType.TYPE)
50+@Retention(RetentionPolicy.RUNTIME)
51+public @interface ASN1JavaObject {
52+
53+ /**
54+ * Indicates corresponding ASN.1 type of this POJO class.
55+ *
56+ * @return The class instance of corresponding ASN.1 type.
57+ */
58+ public Class<? extends StructuredType> value();
59+
60+}
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/annotation/package-info.java
@@ -0,0 +1,19 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+/**
17+ * Contains the annotations used for defining correspondence between ASN.1 and POJO class.
18+ */
19+package jp.bitmeister.asn1.pojo.annotation;
\ No newline at end of file
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/package-info.java
@@ -0,0 +1,19 @@
1+/*
2+ * Copyright 2011-2012 BitMeister Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+/**
17+ * Contains the translator classes used for ASN.1 to POJO translation.
18+ */
19+package jp.bitmeister.asn1.pojo;
\ No newline at end of file
--- a/jp/bitmeister/asn1/type/builtin/INTEGER.java
+++ b/jp/bitmeister/asn1/type/builtin/INTEGER.java
@@ -78,6 +78,16 @@ public class INTEGER extends AbstractInteger<Long> {
7878 public INTEGER(long value) {
7979 set(value);
8080 }
81+
82+ /**
83+ * Sets the int value to this data.
84+ *
85+ * @param value
86+ * The value to be assigned.
87+ */
88+ public void set(int value) {
89+ super.set((long)value);
90+ }
8191
8292 /* (non-Javadoc)
8393 * @see jp.bitmeister.asn1.type.AbstractInteger#getNamedNumberMap()
Show on old repository browser