X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=jp%2Fbitmeister%2Fasn1%2Fpojo%2FPojoEncoder.java;fp=jp%2Fbitmeister%2Fasn1%2Fpojo%2FPojoEncoder.java;h=e28831224e2d30ce37483d57817d060c670d1655;hb=624b226143b8c23308c2ca108e16e02df46b178b;hp=0000000000000000000000000000000000000000;hpb=845441a67dbe1e8780b9f6704395d99c60a40cec;p=bm-asn1%2Fbm-asn1.git
diff --git a/jp/bitmeister/asn1/pojo/PojoEncoder.java b/jp/bitmeister/asn1/pojo/PojoEncoder.java
new file mode 100644
index 0000000..e288312
--- /dev/null
+++ b/jp/bitmeister/asn1/pojo/PojoEncoder.java
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2011-2012 BitMeister Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package jp.bitmeister.asn1.pojo;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.bitmeister.asn1.codec.ASN1Encoder;
+import jp.bitmeister.asn1.exception.ASN1DecodingException;
+import jp.bitmeister.asn1.exception.ASN1EncodingException;
+import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaList;
+import jp.bitmeister.asn1.pojo.annotation.ASN1JavaObject;
+import jp.bitmeister.asn1.processor.ASN1Visitor;
+import jp.bitmeister.asn1.processor.ASN1VisitorAdaptor;
+import jp.bitmeister.asn1.type.ASN1Type;
+import jp.bitmeister.asn1.type.CollectionType;
+import jp.bitmeister.asn1.type.ConstructiveType;
+import jp.bitmeister.asn1.type.ElementSpecification;
+import jp.bitmeister.asn1.type.SelectiveType;
+import jp.bitmeister.asn1.type.StringType;
+import jp.bitmeister.asn1.type.StructuredType;
+import jp.bitmeister.asn1.type.TimeType;
+import jp.bitmeister.asn1.type.UnknownType;
+import jp.bitmeister.asn1.type.builtin.ANY;
+import jp.bitmeister.asn1.type.builtin.BIT_STRING;
+import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
+import jp.bitmeister.asn1.type.builtin.CHOICE;
+import jp.bitmeister.asn1.type.builtin.ENUMERATED;
+import jp.bitmeister.asn1.type.builtin.INTEGER;
+import jp.bitmeister.asn1.type.builtin.NULL;
+import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
+import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
+import jp.bitmeister.asn1.type.builtin.REAL;
+import jp.bitmeister.asn1.type.builtin.RELATIVE_OID;
+import jp.bitmeister.asn1.type.builtin.SEQUENCE;
+import jp.bitmeister.asn1.type.builtin.SEQUENCE_OF;
+import jp.bitmeister.asn1.type.builtin.SET;
+import jp.bitmeister.asn1.type.builtin.SET_OF;
+import jp.bitmeister.asn1.value.BinString;
+
+/**
+ * ASN.1 to POJO data encoder.
+ *
+ *
+ * {@code PojoEncoder} is an implementation of {@code ASN1Encoder}. It
+ * translates an ASN.1 data to a POJO data. Correspondence of an ASN.1 class to
+ * a POJO class is indicated by {@code @ASN1JavaObject} annotation.
+ *
+ *
+ * @author WATANABE, Jun.
+ *
+ * @see ASN1Encoder
+ * @see PojoDecoder
+ * @see ASN1JavaObject
+ */
+public class PojoEncoder implements ASN1Encoder {
+
+ /**
+ * Destination of translation.
+ */
+ private Object object;
+
+ /**
+ * Instantiates {@code PojoEncoder} with a destination object.
+ *
+ * @param object
+ * The {@code @ASN1JavaObject} object.
+ */
+ public PojoEncoder(Object object) {
+ this.object = object;
+ }
+
+ /**
+ * Translates an ASN.1 data to corresponding POJO data.
+ *
+ * @param data
+ * The ASN.1 data to be translated.
+ * @return 0
+ * @throws ASN1EncodingException
+ * When an error occurred while the encoding process.
+ */
+ public int encode(ASN1Type data) throws ASN1EncodingException {
+ try {
+ if (data.accept(new StructureEncoder(object)) == null) {
+ ASN1EncodingException ex = new ASN1EncodingException();
+ ex.setMessage(
+ "Only structured classes (SEQUENCE, SET, CHOICE) can be translated to POJO.",
+ null, data.getClass(), null, data);
+ throw ex;
+ }
+ } catch (Exception e) {
+ ASN1EncodingException ex = new ASN1EncodingException();
+ ex.setMessage("Exception thrown while encoding process.", e,
+ data.getClass(), null, data);
+ throw ex;
+ }
+ return 0;
+ }
+
+ /**
+ * Internal processor class that processes {@code @ASN1JavaObject} class.
+ *
+ * @author WATANABE, Jun.
+ *
+ */
+ private class StructureEncoder extends
+ ASN1VisitorAdaptor {
+
+ /**
+ * Destination.
+ */
+ private Object object;
+
+ /**
+ * Instantiates {@code StructureEncoder} with a destination object.
+ *
+ * @param object
+ * The {@code @ASN1JavaObject} object.
+ */
+ StructureEncoder(Object object) {
+ this.object = object;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
+ * .asn1.type.builtin.CHOICE)
+ */
+ @Override
+ public Boolean visit(CHOICE data) throws Exception {
+ processSelective(data);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
+ * .asn1.type.builtin.SEQUENCE)
+ */
+ @Override
+ public Boolean visit(SEQUENCE data) throws Exception {
+ processConstructive(data);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1VisitorAdaptor#visit(jp.bitmeister
+ * .asn1.type.builtin.SET)
+ */
+ @Override
+ public Boolean visit(SET data) throws Exception {
+ processConstructive(data);
+ return true;
+ }
+
+ /**
+ * Processes constructive type (i.e. 'SEQUENCE' and 'SET') object.
+ *
+ * @param data
+ * The ASN.1 constructive type object.
+ * @throws Exception
+ * When an error occurred while translation process.
+ */
+ private void processConstructive(ConstructiveType data)
+ throws Exception {
+ PojoSpecification spec = PojoSpecification.getSpecification(object
+ .getClass());
+ if (!spec.checkTarget(data.getClass())) {
+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
+ ex.setMessage("Incompatible ASN.1 type data is specified.",
+ null, data.getClass(), null, null);
+ throw ex;
+ }
+ for (ElementSpecification e : data.getElementTypeList()) {
+ Field field = spec.getField(e);
+ if (field == null) {
+ continue;
+ }
+ ASN1Type component = data.getComponent(e);
+ if (component != null) {
+
+ field.set(object,
+ component.accept(new ElementEncoder(field)));
+ }
+ }
+ }
+
+ /**
+ * Processes selective type (i.e. 'CHOICE') object.
+ *
+ * @param data
+ * The ASN.1 selective type object.
+ * @throws Exception
+ * When an error occurred while translation process.
+ */
+ private void processSelective(SelectiveType data) throws Exception {
+ PojoSpecification spec = PojoSpecification.getSpecification(object
+ .getClass());
+ if (!spec.checkTarget(data.getClass())) {
+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
+ ex.setMessage("Incompatible ASN.1 type data is specified.",
+ null, data.getClass(), null, null);
+ throw ex;
+ }
+ String selection = data.selectedIdentifier();
+ Field field = spec.getField(data.getElement(selection));
+ if (field != null) {
+ field.set(object,
+ data.selectedValue().accept(new ElementEncoder(field)));
+ }
+ }
+
+ /**
+ * Internal processor class that processes {@code @ASN1JavaField} field.
+ *
+ * @author WATANABE, Jun.
+ *
+ */
+ private class ElementEncoder implements ASN1Visitor