* Change return type of collection method of CollectionType from Collection<T> to List<T>.
--- /dev/null
+/*
+ * 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>
+ * @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;
+ *
+ * }
+ *
+ * </pre></code>
+ *
+ * </p>
+ *
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ASN1Extendable {
+}
* 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();
}
* 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);
}
* 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);
}
* @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()) {
* @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;
* @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();
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()
* 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;
}
* 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;
}
* @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) {
public class FrightStatusMain {
public static void main(String[] args) {
+
AllFrights frights = new AllFrights(
new FrightStatus(
new FrightNumber("JP041"),
System.out.println("Source data:");
System.out.println(frights);
-
derEncAndDec(frights);
xerEncAndDec(frights);
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;
}
}
+
+ @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;
* @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
*
* @return The collection.
*/
- public Collection<T> collection() {
+ public C collection() {
return collection;
}
-
+
/**
* Returns the type of component of this data.
*
*
* @return A new collection.
*/
- protected abstract Collection<T> newCollection();
+ protected abstract C newCollection();
/*
* (non-Javadoc)
*/
@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;
}
@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;
}
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;
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) {
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;
}
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;
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(
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;
}
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;
* 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);
} 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;
}
// 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();
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;
@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}.
* @see jp.bitmeister.asn1.type.CollectionType#newCollection()
*/
@Override
- protected Collection<T> newCollection() {
+ protected List<T> newCollection() {
return new ArrayList<T>();
}
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;
@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}.
*/
@Override
@SuppressWarnings("serial")
- protected Collection<T> newCollection() {
+ protected List<T> newCollection() {
return new ArrayList<T>() {
@Override