From 560311568533485f5856cd92bf0c1a5f3f6fa5a5 Mon Sep 17 00:00:00 2001 From: jwat Date: Wed, 8 Feb 2012 15:38:19 +0900 Subject: [PATCH] * Add ASN1Extendable annotation. * Change return type of collection method of CollectionType from Collection to List. --- jp/bitmeister/asn1/annotation/ASN1Extendable.java | 70 ++++++++++++++++++++++ jp/bitmeister/asn1/codec/ber/BerDecoder.java | 2 +- jp/bitmeister/asn1/codec/ber/BerEncoder.java | 6 +- jp/bitmeister/asn1/codec/xer/XerDecoder.java | 2 +- jp/bitmeister/asn1/codec/xer/XerEncoder.java | 2 +- .../asn1/processor/ASN1StringBuilder.java | 10 ++-- jp/bitmeister/asn1/sample/FrightStatusMain.java | 2 +- jp/bitmeister/asn1/sample/FrightStatusTypes.java | 10 +++- jp/bitmeister/asn1/type/ASN1Module.java | 2 +- jp/bitmeister/asn1/type/CollectionType.java | 16 ++--- jp/bitmeister/asn1/type/ConstructiveType.java | 7 ++- jp/bitmeister/asn1/type/SelectiveType.java | 6 +- jp/bitmeister/asn1/type/TypeSpecification.java | 11 ++-- jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java | 6 +- jp/bitmeister/asn1/type/builtin/SET_OF.java | 6 +- 15 files changed, 121 insertions(+), 37 deletions(-) create mode 100644 jp/bitmeister/asn1/annotation/ASN1Extendable.java diff --git a/jp/bitmeister/asn1/annotation/ASN1Extendable.java b/jp/bitmeister/asn1/annotation/ASN1Extendable.java new file mode 100644 index 0000000..e6ab71c --- /dev/null +++ b/jp/bitmeister/asn1/annotation/ASN1Extendable.java @@ -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. + * + *

+ * 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. + *

+ *

+ * For example :

+ * @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 {
+ * 
+ * 	@ASN1ElementType(0)
+ * 	public INTEGER userNo;
+ * 
+ * 	@ASN1ElementType(value = 1, optional = true)
+ * 	public PrintableString userName;
+ * 
+ * }
+ * 
+ * 
+ * + *

+ * + * @author WATANABE, Jun. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ASN1Extendable { +} diff --git a/jp/bitmeister/asn1/codec/ber/BerDecoder.java b/jp/bitmeister/asn1/codec/ber/BerDecoder.java index 04ae61f..1d007f5 100644 --- a/jp/bitmeister/asn1/codec/ber/BerDecoder.java +++ b/jp/bitmeister/asn1/codec/ber/BerDecoder.java @@ -555,7 +555,7 @@ public class BerDecoder implements ASN1Decoder, * When an error occurred while the decoding process. */ private void processCollection( - final CollectionType data) throws ASN1DecodingException { + final CollectionType data) throws ASN1DecodingException { if (data.size() > 0) { data.clear(); } diff --git a/jp/bitmeister/asn1/codec/ber/BerEncoder.java b/jp/bitmeister/asn1/codec/ber/BerEncoder.java index 2c5202c..83be1d9 100644 --- a/jp/bitmeister/asn1/codec/ber/BerEncoder.java +++ b/jp/bitmeister/asn1/codec/ber/BerEncoder.java @@ -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 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 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 data) throws ASN1EncodingException { ConstructedOctets octets = newConstructedOctets(); for (ASN1Type e : data.collection()) { diff --git a/jp/bitmeister/asn1/codec/xer/XerDecoder.java b/jp/bitmeister/asn1/codec/xer/XerDecoder.java index bc287ed..4b31a4f 100644 --- a/jp/bitmeister/asn1/codec/xer/XerDecoder.java +++ b/jp/bitmeister/asn1/codec/xer/XerDecoder.java @@ -957,7 +957,7 @@ public class XerDecoder implements ASN1Decoder, * @return Handler for the data. */ private DataDecoder decoderForCollectionType( - final CollectionType data) { + final CollectionType data) { return new ConstructedDataDecoder() { private T component; diff --git a/jp/bitmeister/asn1/codec/xer/XerEncoder.java b/jp/bitmeister/asn1/codec/xer/XerEncoder.java index 98f2420..70be035 100644 --- a/jp/bitmeister/asn1/codec/xer/XerEncoder.java +++ b/jp/bitmeister/asn1/codec/xer/XerEncoder.java @@ -477,7 +477,7 @@ public class XerEncoder implements ASN1Encoder, * @throws ASN1EncodingException * When an error occurred while the encoding process. */ - private String processCollection(CollectionType data) + private String processCollection(CollectionType data) throws ASN1EncodingException { StringBuilder enclosure = builder; builder = new StringBuilder(); diff --git a/jp/bitmeister/asn1/processor/ASN1StringBuilder.java b/jp/bitmeister/asn1/processor/ASN1StringBuilder.java index 03ab4e7..1256024 100644 --- a/jp/bitmeister/asn1/processor/ASN1StringBuilder.java +++ b/jp/bitmeister/asn1/processor/ASN1StringBuilder.java @@ -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 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 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 data) { + private void writeCollection(CollectionType data) { Iterator itr = data.collection().iterator(); if (itr.hasNext()) { while (true) { diff --git a/jp/bitmeister/asn1/sample/FrightStatusMain.java b/jp/bitmeister/asn1/sample/FrightStatusMain.java index 6ec8a5f..f4190ea 100644 --- a/jp/bitmeister/asn1/sample/FrightStatusMain.java +++ b/jp/bitmeister/asn1/sample/FrightStatusMain.java @@ -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); diff --git a/jp/bitmeister/asn1/sample/FrightStatusTypes.java b/jp/bitmeister/asn1/sample/FrightStatusTypes.java index 246f5e5..25c950e 100644 --- a/jp/bitmeister/asn1/sample/FrightStatusTypes.java +++ b/jp/bitmeister/asn1/sample/FrightStatusTypes.java @@ -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; diff --git a/jp/bitmeister/asn1/type/ASN1Module.java b/jp/bitmeister/asn1/type/ASN1Module.java index 37fd422..6d89c2c 100644 --- a/jp/bitmeister/asn1/type/ASN1Module.java +++ b/jp/bitmeister/asn1/type/ASN1Module.java @@ -127,5 +127,5 @@ public abstract class ASN1Module { } } } - + } diff --git a/jp/bitmeister/asn1/type/CollectionType.java b/jp/bitmeister/asn1/type/CollectionType.java index 81d36dd..15ee6f0 100644 --- a/jp/bitmeister/asn1/type/CollectionType.java +++ b/jp/bitmeister/asn1/type/CollectionType.java @@ -34,12 +34,12 @@ import jp.bitmeister.asn1.type.builtin.SET_OF; * @see SET_OF * @author WATANABE, Jun. */ -public abstract class CollectionType extends ASN1Type +public abstract class CollectionType> extends ASN1Type implements SizeCountable { private Class componentType; - private Collection collection; + private C collection; /** * Instantiate a {@code CollectionType} instance whose component is the @@ -74,10 +74,10 @@ public abstract class CollectionType extends ASN1Type * * @return The collection. */ - public Collection collection() { + public C collection() { return collection; } - + /** * Returns the type of component of this data. * @@ -102,7 +102,7 @@ public abstract class CollectionType extends ASN1Type * * @return A new collection. */ - protected abstract Collection newCollection(); + protected abstract C newCollection(); /* * (non-Javadoc) @@ -140,8 +140,8 @@ public abstract class CollectionType 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 extends ASN1Type @Override @SuppressWarnings("unchecked") public Object clone() { - CollectionType clone = ASN1Type.instantiate(getClass()); + CollectionType clone = ASN1Type.instantiate(getClass()); clone.collection.addAll(collection); return clone; } diff --git a/jp/bitmeister/asn1/type/ConstructiveType.java b/jp/bitmeister/asn1/type/ConstructiveType.java index 03d8916..7614dd2 100644 --- a/jp/bitmeister/asn1/type/ConstructiveType.java +++ b/jp/bitmeister/asn1/type/ConstructiveType.java @@ -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 parent = (Class) 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; } diff --git a/jp/bitmeister/asn1/type/SelectiveType.java b/jp/bitmeister/asn1/type/SelectiveType.java index 5715d3f..a2e1bfe 100644 --- a/jp/bitmeister/asn1/type/SelectiveType.java +++ b/jp/bitmeister/asn1/type/SelectiveType.java @@ -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 parent = (Class) 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; } diff --git a/jp/bitmeister/asn1/type/TypeSpecification.java b/jp/bitmeister/asn1/type/TypeSpecification.java index 5b7085b..28d96b7 100644 --- a/jp/bitmeister/asn1/type/TypeSpecification.java +++ b/jp/bitmeister/asn1/type/TypeSpecification.java @@ -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 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 module = (Class) enclosure; specification.module = module; } if (ASN1Type.class.isAssignableFrom(enclosure)) { - @SuppressWarnings("unchecked") Class enclosingType = (Class) 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 referenceType = (Class) type - .getSuperclass(); + Class referenceType = type; + do { + referenceType = (Class) referenceType.getSuperclass(); + } while (referenceType.isAnnotationPresent(ASN1Extendable.class)); specification.reference = getSpecification(referenceType); } catch (ClassCastException e) { ASN1IllegalDefinition ex = new ASN1IllegalDefinition(); diff --git a/jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java b/jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java index 4c44bef..abab6c5 100644 --- a/jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java +++ b/jp/bitmeister/asn1/type/builtin/SEQUENCE_OF.java @@ -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 extends CollectionType { +public abstract class SEQUENCE_OF extends CollectionType> { /** * Instantiate an empty {@code SEQUENCE_OF}. @@ -75,7 +75,7 @@ public abstract class SEQUENCE_OF extends CollectionType * @see jp.bitmeister.asn1.type.CollectionType#newCollection() */ @Override - protected Collection newCollection() { + protected List newCollection() { return new ArrayList(); } diff --git a/jp/bitmeister/asn1/type/builtin/SET_OF.java b/jp/bitmeister/asn1/type/builtin/SET_OF.java index 33b36f6..1fbe07e 100644 --- a/jp/bitmeister/asn1/type/builtin/SET_OF.java +++ b/jp/bitmeister/asn1/type/builtin/SET_OF.java @@ -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 extends CollectionType { +public abstract class SET_OF extends CollectionType> { /** * Instantiate an empty {@code SET_OF}. @@ -75,7 +75,7 @@ public abstract class SET_OF extends CollectionType { */ @Override @SuppressWarnings("serial") - protected Collection newCollection() { + protected List newCollection() { return new ArrayList() { @Override -- 2.11.0