OSDN Git Service

* Add ASN1Extendable annotation.
authorjwat <jwat@users.sourceforge.jp>
Wed, 8 Feb 2012 06:38:19 +0000 (15:38 +0900)
committerjwat <jwat@users.sourceforge.jp>
Wed, 8 Feb 2012 06:38:19 +0000 (15:38 +0900)
* Change return type of collection method of CollectionType from Collection<T> to List<T>.

15 files changed:
jp/bitmeister/asn1/annotation/ASN1Extendable.java [new file with mode: 0644]
jp/bitmeister/asn1/codec/ber/BerDecoder.java
jp/bitmeister/asn1/codec/ber/BerEncoder.java
jp/bitmeister/asn1/codec/xer/XerDecoder.java
jp/bitmeister/asn1/codec/xer/XerEncoder.java
jp/bitmeister/asn1/processor/ASN1StringBuilder.java
jp/bitmeister/asn1/sample/FrightStatusMain.java
jp/bitmeister/asn1/sample/FrightStatusTypes.java
jp/bitmeister/asn1/type/ASN1Module.java
jp/bitmeister/asn1/type/CollectionType.java
jp/bitmeister/asn1/type/ConstructiveType.java
jp/bitmeister/asn1/type/SelectiveType.java
jp/bitmeister/asn1/type/TypeSpecification.java
jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java
jp/bitmeister/asn1/type/builtin/SET_OF.java

diff --git a/jp/bitmeister/asn1/annotation/ASN1Extendable.java b/jp/bitmeister/asn1/annotation/ASN1Extendable.java
new file mode 100644 (file)
index 0000000..e6ab71c
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a type is extendable SET, SEQUENCE or CHOICE.
+ * 
+ * <p>
+ * If an {@code @ASN1Extendable} annotation is present on a SET, SEQUENCE or
+ * CHOICE type class, the class can be base class for other SET, SEQUENCE or
+ * CHOICE type class. This annotation will be used for defining common attribute
+ * or method to some of SET, SEQUENCE or CHOICE classes by using class
+ * inheritance. A type annotated as {@code @ASN1Extendable} can't define own
+ * elements.
+ * </p>
+ * <p>
+ * For example : <code><pre>
+ * &#064;ASN1Extendable
+ * public class IdentifiableSequence extends SEQUENCE {
+ * 
+ *     private ID id;
+ * 
+ *     public ID getID() {
+ *             return id;
+ *     }
+ *     
+ *     public void SetID(ID id) {
+ *             this.id = id;
+ *     }
+ * 
+ * }
+ * 
+ * public class User extends IdentifiableSequence {
+ * 
+ *     &#064;ASN1ElementType(0)
+ *     public INTEGER userNo;
+ * 
+ *     &#064;ASN1ElementType(value = 1, optional = true)
+ *     public PrintableString userName;
+ * 
+ * }
+ * 
+ * </pre></code>
+ * 
+ * </p>
+ * 
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ASN1Extendable {
+}
index 04ae61f..1d007f5 100644 (file)
@@ -555,7 +555,7 @@ public class BerDecoder implements ASN1Decoder,
         *             When an error occurred while the decoding process.
         */
        private <T extends ASN1Type> void processCollection(
-                       final CollectionType<T> data) throws ASN1DecodingException {
+                       final CollectionType<T, ?> data) throws ASN1DecodingException {
                if (data.size() > 0) {
                        data.clear();
                }
index 2c5202c..83be1d9 100644 (file)
@@ -274,7 +274,7 @@ public class BerEncoder implements ASN1Encoder,
         * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
         * .builtin.SEQUENCE_OF)
         */
-       public EncodedOctets visit(SEQUENCE_OF<? extends ASN1Type> data)
+       public EncodedOctets visit(SEQUENCE_OF<?> data)
                        throws ASN1EncodingException {
                return processCollection(data);
        }
@@ -297,7 +297,7 @@ public class BerEncoder implements ASN1Encoder,
         * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
         * .builtin.SET_OF)
         */
-       public ConstructedOctets visit(SET_OF<? extends ASN1Type> data)
+       public ConstructedOctets visit(SET_OF<?> data)
                        throws ASN1EncodingException {
                return processCollection(data);
        }
@@ -441,7 +441,7 @@ public class BerEncoder implements ASN1Encoder,
         * @throws ASN1EncodingException
         *             When an error occurred while the encoding process.
         */
-       ConstructedOctets processCollection(CollectionType<?> data)
+       ConstructedOctets processCollection(CollectionType<? extends ASN1Type, ?> data)
                        throws ASN1EncodingException {
                ConstructedOctets octets = newConstructedOctets();
                for (ASN1Type e : data.collection()) {
index bc287ed..4b31a4f 100644 (file)
@@ -957,7 +957,7 @@ public class XerDecoder implements ASN1Decoder,
         * @return Handler for the data.
         */
        private <T extends ASN1Type> DataDecoder decoderForCollectionType(
-                       final CollectionType<T> data) {
+                       final CollectionType<T, ?> data) {
                return new ConstructedDataDecoder() {
 
                        private T component;
index 98f2420..70be035 100644 (file)
@@ -477,7 +477,7 @@ public class XerEncoder implements ASN1Encoder,
         * @throws ASN1EncodingException
         *             When an error occurred while the encoding process.
         */
-       private String processCollection(CollectionType<? extends ASN1Type> data)
+       private String processCollection(CollectionType<? extends ASN1Type, ?> data)
                        throws ASN1EncodingException {
                StringBuilder enclosure = builder;
                builder = new StringBuilder();
index 03ab4e7..1256024 100644 (file)
@@ -136,8 +136,8 @@ public class ASN1StringBuilder implements
                        if (specification.hasIdentifier()) {
                                builder.append(specification.identifier());
                                if (specification.reference() == null) {
-                                       if (data instanceof CollectionType<?>) {
-                                               CollectionType<?> collection = (CollectionType<?>) data;
+                                       if (data instanceof CollectionType<?, ?>) {
+                                               CollectionType<?, ?> collection = (CollectionType<?, ?>) data;
                                                if (!collection.componentType().equals(ANY.class)) {
                                                        builder.append(COLLECTION_OF).append(
                                                                        collection.componentSpecification()
@@ -298,7 +298,7 @@ public class ASN1StringBuilder implements
         * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
         * .builtin.SEQUENCE_OF)
         */
-       public Void visit(SEQUENCE_OF<? extends ASN1Type> data) {
+       public Void visit(SEQUENCE_OF<?> data) {
                writeCollection(data);
                return null;
        }
@@ -322,7 +322,7 @@ public class ASN1StringBuilder implements
         * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
         * .builtin.SET_OF)
         */
-       public Void visit(SET_OF<? extends ASN1Type> data) {
+       public Void visit(SET_OF<?> data) {
                writeCollection(data);
                return null;
        }
@@ -473,7 +473,7 @@ public class ASN1StringBuilder implements
         * @param data
         *            The collection data.
         */
-       private void writeCollection(CollectionType<? extends ASN1Type> data) {
+       private void writeCollection(CollectionType<? extends ASN1Type, ?> data) {
                Iterator<? extends ASN1Type> itr = data.collection().iterator();
                if (itr.hasNext()) {
                        while (true) {
index 6ec8a5f..f4190ea 100644 (file)
@@ -39,6 +39,7 @@ import jp.bitmeister.asn1.value.HexString;
 public class FrightStatusMain {
 
        public static void main(String[] args) {
+               
                AllFrights frights = new AllFrights(
                                new FrightStatus(
                                                new FrightNumber("JP041"),
@@ -71,7 +72,6 @@ public class FrightStatusMain {
 
                System.out.println("Source data:");
                System.out.println(frights);
-
                derEncAndDec(frights);
                xerEncAndDec(frights);
 
index 246f5e5..25c950e 100644 (file)
@@ -21,6 +21,7 @@ import jp.bitmeister.asn1.annotation.ASN1Alternative;
 import jp.bitmeister.asn1.annotation.ASN1DefinedTypes;
 import jp.bitmeister.asn1.annotation.ASN1Element;
 import jp.bitmeister.asn1.annotation.ASN1Enumeration;
+import jp.bitmeister.asn1.annotation.ASN1Extendable;
 import jp.bitmeister.asn1.annotation.ASN1ModuleTags;
 import jp.bitmeister.asn1.annotation.ASN1Tag;
 import jp.bitmeister.asn1.type.ASN1Module;
@@ -78,8 +79,15 @@ public class FrightStatusTypes extends ASN1Module {
                }
 
        }
+       
+       @ASN1Extendable
+       public static class AbstractSequence extends SEQUENCE {
+               
+               
+               
+       }
 
-       public static class Information extends SEQUENCE {
+       public static class Information extends AbstractSequence {
 
                @ASN1Element(value = 0)
                public Airport airport;
index 37fd422..6d89c2c 100644 (file)
@@ -127,5 +127,5 @@ public abstract class ASN1Module {
                        }
                }
        }
-
+       
 }
index 81d36dd..15ee6f0 100644 (file)
@@ -34,12 +34,12 @@ import jp.bitmeister.asn1.type.builtin.SET_OF;
  * @see SET_OF
  * @author WATANABE, Jun. <jwat at bitmeister.jp>
  */
-public abstract class CollectionType<T extends ASN1Type> extends ASN1Type
+public abstract class CollectionType<T extends ASN1Type, C extends Collection<T>> extends ASN1Type
                implements SizeCountable {
 
        private Class<T> componentType;
 
-       private Collection<T> collection;
+       private C collection;
 
        /**
         * Instantiate a {@code CollectionType} instance whose component is the
@@ -74,10 +74,10 @@ public abstract class CollectionType<T extends ASN1Type> extends ASN1Type
         * 
         * @return The collection.
         */
-       public Collection<T> collection() {
+       public C collection() {
                return collection;
        }
-
+       
        /**
         * Returns the type of component of this data.
         * 
@@ -102,7 +102,7 @@ public abstract class CollectionType<T extends ASN1Type> extends ASN1Type
         * 
         * @return A new collection.
         */
-       protected abstract Collection<T> newCollection();
+       protected abstract C newCollection();
 
        /*
         * (non-Javadoc)
@@ -140,8 +140,8 @@ public abstract class CollectionType<T extends ASN1Type> extends ASN1Type
         */
        @Override
        public boolean valueEquals(Object other) {
-               if (other instanceof CollectionType<?>) {
-                       return collection.equals(((CollectionType<?>) other).collection);
+               if (other instanceof CollectionType<?, ?>) {
+                       return collection.equals(((CollectionType<?, ?>) other).collection);
                }
                return false;
        }
@@ -164,7 +164,7 @@ public abstract class CollectionType<T extends ASN1Type> extends ASN1Type
        @Override
        @SuppressWarnings("unchecked")
        public Object clone() {
-               CollectionType<T> clone = ASN1Type.instantiate(getClass());
+               CollectionType<T, C> clone = ASN1Type.instantiate(getClass());
                clone.collection.addAll(collection);
                return clone;
        }
index 03d8916..7614dd2 100644 (file)
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 
 import jp.bitmeister.asn1.annotation.ASN1Element;
+import jp.bitmeister.asn1.annotation.ASN1Extendable;
 import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
 import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
 import jp.bitmeister.asn1.exception.ASN1InvalidDataValue;
@@ -71,7 +72,8 @@ public abstract class ConstructiveType extends StructuredType {
                Class<? extends ConstructiveType> parent = (Class<? extends ConstructiveType>) type
                                .getSuperclass();
                ElementSpecification[] array;
-               if (parent == SET.class || parent == SEQUENCE.class) {
+               if (parent == SET.class || parent == SEQUENCE.class
+                               || parent.isAnnotationPresent(ASN1Extendable.class)) {
                        Collections.sort(elements);
                        array = elements.toArray(new ElementSpecification[0]);
                        if (TypeSpecification.getSpecification(type).tagDefault() == ASN1TagDefault.AUTOMATIC_TAGS) {
@@ -86,7 +88,8 @@ public abstract class ConstructiveType extends StructuredType {
                        if (!elements.isEmpty()) {
                                ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
                                ex.setMessage(
-                                               "If a class does not extend SET or SEQUENCE directly, it can not define own elements.",
+                                               "If a class does not extend SET, SEQUENCE or a type annotated as ASN1Extendable" +
+                                               " directly, it can not define own elements.",
                                                null, type, null, null);
                                throw ex;
                        }
index 5715d3f..a2e1bfe 100644 (file)
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.Map;
 
 import jp.bitmeister.asn1.annotation.ASN1Alternative;
+import jp.bitmeister.asn1.annotation.ASN1Extendable;
 import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
 import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
 import jp.bitmeister.asn1.type.builtin.CHOICE;
@@ -67,7 +68,7 @@ public abstract class SelectiveType extends StructuredType {
                Class<? extends SelectiveType> parent = (Class<? extends SelectiveType>) type
                                .getSuperclass();
                NamedTypeSpecification[] array;
-               if (parent == CHOICE.class) {
+               if (parent == CHOICE.class || parent.isAnnotationPresent(ASN1Extendable.class)) {
                        if (alternatives.isEmpty()) {
                                ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
                                ex.setMessage(
@@ -84,7 +85,8 @@ public abstract class SelectiveType extends StructuredType {
                        if (!alternatives.isEmpty()) {
                                ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
                                ex.setMessage(
-                                               "If a class does not extend CHOICE directly, it can not define own alternatives.",
+                                               "If a class does not extend CHOICE or a type annotated as ASN1Extendable directly," +
+                                               "it can not define own alternatives.",
                                                null, type, null, null);
                                throw ex;
                        }
index 5b7085b..28d96b7 100644 (file)
@@ -20,6 +20,7 @@ import java.util.Map;
 
 import jp.bitmeister.asn1.annotation.ASN1Anonymous;
 import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
+import jp.bitmeister.asn1.annotation.ASN1Extendable;
 import jp.bitmeister.asn1.annotation.ASN1Identifier;
 import jp.bitmeister.asn1.annotation.ASN1ModuleRef;
 import jp.bitmeister.asn1.annotation.ASN1Tag;
@@ -46,6 +47,7 @@ public class TypeSpecification {
         *            The {@code Class} object of an ASN.1 type.
         * @return The {@code TypeSpecification} of the type.
         */
+       @SuppressWarnings("unchecked")
        static TypeSpecification getSpecification(Class<? extends ASN1Type> type) {
                if (TYPE_SPECIFICATIONS.containsKey(type)) {
                        return TYPE_SPECIFICATIONS.get(type);
@@ -61,12 +63,10 @@ public class TypeSpecification {
                } else if (type.isMemberClass()) {
                        Class<?> enclosure = type.getDeclaringClass();
                        if (ASN1Module.class.isAssignableFrom(enclosure)) {
-                               @SuppressWarnings("unchecked")
                                Class<? extends ASN1Module> module = (Class<? extends ASN1Module>) enclosure;
                                specification.module = module;
                        }
                        if (ASN1Type.class.isAssignableFrom(enclosure)) {
-                               @SuppressWarnings("unchecked")
                                Class<? extends ASN1Type> enclosingType = (Class<? extends ASN1Type>) enclosure;
                                specification.module = getSpecification(enclosingType).module;
                        }
@@ -81,9 +81,10 @@ public class TypeSpecification {
                // set reference type specification.
                if (!type.isAnnotationPresent(ASN1BuiltIn.class)) {
                        try {
-                               @SuppressWarnings("unchecked")
-                               Class<? extends ASN1Type> referenceType = (Class<? extends ASN1Type>) type
-                                               .getSuperclass();
+                               Class<? extends ASN1Type> referenceType = type;
+                               do {
+                                       referenceType = (Class<? extends ASN1Type>) referenceType.getSuperclass();
+                               } while (referenceType.isAnnotationPresent(ASN1Extendable.class));
                                specification.reference = getSpecification(referenceType);
                        } catch (ClassCastException e) {
                                ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
index 4c44bef..abab6c5 100644 (file)
@@ -16,7 +16,7 @@
 package jp.bitmeister.asn1.type.builtin;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.List;
 
 import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
 import jp.bitmeister.asn1.annotation.ASN1Identifier;
@@ -45,7 +45,7 @@ import jp.bitmeister.asn1.type.CollectionType;
 @ASN1Identifier("SEQUENCE")
 @ASN1XmlTypeName("SEQUENCE_OF")
 @ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 16, tagMode = ASN1TagMode.IMPLICIT)
-public abstract class SEQUENCE_OF<T extends ASN1Type> extends CollectionType<T> {
+public abstract class SEQUENCE_OF<T extends ASN1Type> extends CollectionType<T, List<T>> {
 
        /**
         * Instantiate an empty {@code SEQUENCE_OF}.
@@ -75,7 +75,7 @@ public abstract class SEQUENCE_OF<T extends ASN1Type> extends CollectionType<T>
         * @see jp.bitmeister.asn1.type.CollectionType#newCollection()
         */
        @Override
-       protected Collection<T> newCollection() {
+       protected List<T> newCollection() {
                return new ArrayList<T>();
        }
 
index 33b36f6..1fbe07e 100644 (file)
@@ -16,7 +16,7 @@
 package jp.bitmeister.asn1.type.builtin;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.List;
 
 import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
 import jp.bitmeister.asn1.annotation.ASN1Identifier;
@@ -44,7 +44,7 @@ import jp.bitmeister.asn1.type.CollectionType;
 @ASN1Identifier("SET")
 @ASN1XmlTypeName("SET_OF")
 @ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 17, tagMode = ASN1TagMode.IMPLICIT)
-public abstract class SET_OF<T extends ASN1Type> extends CollectionType<T> {
+public abstract class SET_OF<T extends ASN1Type> extends CollectionType<T, List<T>> {
 
        /**
         * Instantiate an empty {@code SET_OF}.
@@ -75,7 +75,7 @@ public abstract class SET_OF<T extends ASN1Type> extends CollectionType<T> {
         */
        @Override
        @SuppressWarnings("serial")
-       protected Collection<T> newCollection() {
+       protected List<T> newCollection() {
                return new ArrayList<T>() {
 
                        @Override