* @see ASN1Type
*/
public class ASN1StringBuilder implements
- ASN1Processor<String, ASN1RuntimeException>,
- ASN1Visitor<Void, ASN1RuntimeException> {
+ ASN1Processor<String, ASN1RuntimeException> {
private static final String NEW_LINE = System.getProperty("line.separator");
private static final String SPACE = " ";
}
};
- private StringBuilder builder;
-
- private int indent;
-
/**
* Instantiates an {@code ASN1StringBuilder}.
*/
* @return A string representation of the ASN.1 data.
*/
public String process(ASN1Type data) {
- indent = 0;
- builder = new StringBuilder();
- write(data);
- return builder.toString();
+ return new InternalProcessor().process(data);
}
-
- /**
- * Writes descriptions of the data to the 'builder'.
- *
- * @param data
- * The ASN.1 data.
- */
- private void write(ASN1Type data) {
- TypeSpecification specification = data.specification();
- while (true) {
- if (specification.hasIdentifier()) {
- builder.append(specification.identifier());
- if (specification.reference() == null) {
- if (data instanceof CollectionType<?, ?>) {
- CollectionType<?, ?> collection = (CollectionType<?, ?>) data;
- if (!collection.componentType().equals(ANY.class)) {
- builder.append(COLLECTION_OF).append(
- collection.componentSpecification()
- .identifier());
+
+ private class InternalProcessor implements ASN1Visitor<Void, ASN1RuntimeException> {
+
+ private StringBuilder builder;
+
+ private int indent;
+
+ /**
+ * Returns a string representation of the ASN.1 data.
+ *
+ * @param data
+ * The ASN.1 data.
+ * @return A string representation of the ASN.1 data.
+ */
+ private String process(ASN1Type data) {
+ indent = 0;
+ builder = new StringBuilder();
+ write(data);
+ return builder.toString();
+ }
+
+ /**
+ * Writes descriptions of the data to the 'builder'.
+ *
+ * @param data
+ * The ASN.1 data.
+ */
+ private void write(ASN1Type data) {
+ TypeSpecification specification = data.specification();
+ while (true) {
+ if (specification.hasIdentifier()) {
+ builder.append(specification.identifier());
+ if (specification.reference() == null) {
+ if (data instanceof CollectionType<?, ?>) {
+ CollectionType<?, ?> collection = (CollectionType<?, ?>) data;
+ if (!collection.componentType().equals(ANY.class)) {
+ builder.append(COLLECTION_OF).append(
+ collection.componentSpecification()
+ .identifier());
+ }
+ }
+ break;
+ } else {
+ builder.append(ASSIGN);
+ if (specification.tag() != null) {
+ writeTag(specification.tag());
+ builder.append(SPACE);
}
- }
- break;
- } else {
- builder.append(ASSIGN);
- if (specification.tag() != null) {
- writeTag(specification.tag());
- builder.append(SPACE);
}
}
+ specification = specification.reference();
}
- specification = specification.reference();
- }
- if (data instanceof PrimitiveType<?>) {
- builder.append(VALUE_OPEN);
- if (data.hasValue()) {
- data.accept(this);
+ if (data instanceof PrimitiveType<?>) {
+ builder.append(VALUE_OPEN);
+ if (data.hasValue()) {
+ data.accept(this);
+ } else {
+ builder.append(NOT_SET);
+ }
+ builder.append(VALUE_CLOSE);
} else {
- builder.append(NOT_SET);
+ builder.append(CONSTRUCTIVE_OPEN);
+ indent++;
+ data.accept(this);
+ indent--;
+ builder.append(CONSTRUCTIVE_CLOSE);
}
- builder.append(VALUE_CLOSE);
- } else {
- builder.append(CONSTRUCTIVE_OPEN);
- indent++;
- data.accept(this);
- indent--;
- builder.append(CONSTRUCTIVE_CLOSE);
}
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.BOOLEAN)
- */
- public Void visit(BOOLEAN data) {
- builder.append(data.value() ? "TRUE" : "FALSE");
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BOOLEAN)
+ */
+ public Void visit(BOOLEAN data) {
+ builder.append(data.value() ? "TRUE" : "FALSE");
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.INTEGER)
- */
- public Void visit(INTEGER data) {
- String numberId = data.identifier();
- if (numberId != null) {
- builder.append(numberId);
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.INTEGER)
+ */
+ public Void visit(INTEGER data) {
+ String numberId = data.identifier();
+ if (numberId != null) {
+ builder.append(numberId);
+ }
+ builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
+ return null;
}
- builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
- return null;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.ENUMERATED)
- */
- public Void visit(ENUMERATED data) {
- visit((INTEGER) data);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.ENUMERATED)
+ */
+ public Void visit(ENUMERATED data) {
+ visit((INTEGER) data);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.REAL)
- */
- public Void visit(REAL data) {
- builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.REAL)
+ */
+ public Void visit(REAL data) {
+ builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.BIT_STRING)
- */
- public Void visit(BIT_STRING data) {
- if (data.hasNamedBits()) {
- builder.append(NAMED_BITS_OPEN);
- boolean trailing = false;
- for (int i = 0; i < data.size(); i++) {
- if (data.bit(i)) {
- String identifier = data.nameOfBit(i);
- if (identifier != null) {
- if (trailing) {
- builder.append(NAMED_BITS_SEPARATOR).append(SPACE);
- } else {
- builder.append(SPACE);
- trailing = true;
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BIT_STRING)
+ */
+ public Void visit(BIT_STRING data) {
+ if (data.hasNamedBits()) {
+ builder.append(NAMED_BITS_OPEN);
+ boolean trailing = false;
+ for (int i = 0; i < data.size(); i++) {
+ if (data.bit(i)) {
+ String identifier = data.nameOfBit(i);
+ if (identifier != null) {
+ if (trailing) {
+ builder.append(NAMED_BITS_SEPARATOR).append(SPACE);
+ } else {
+ builder.append(SPACE);
+ trailing = true;
+ }
+ builder.append(identifier);
}
- builder.append(identifier);
}
}
+ builder.append(SPACE).append(NAMED_BITS_CLOSE).append(SEPARATOR);
}
- builder.append(SPACE).append(NAMED_BITS_CLOSE).append(SEPARATOR);
+ builder.append(new BinString(data.value()).toString());
+ return null;
}
- builder.append(new BinString(data.value()).toString());
- return null;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.OCTET_STRING)
- */
- public Void visit(OCTET_STRING data) {
- builder.append(new HexString(data.value()).toString());
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.OCTET_STRING)
+ */
+ public Void visit(OCTET_STRING data) {
+ builder.append(new HexString(data.value()).toString());
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.NULL)
- */
- public Void visit(NULL data) {
- builder.append(NULL);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.NULL)
+ */
+ public Void visit(NULL data) {
+ builder.append(NULL);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.SEQUENCE)
- */
- public Void visit(SEQUENCE data) {
- writeConstructive(data);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.SEQUENCE)
+ */
+ public Void visit(SEQUENCE data) {
+ writeConstructive(data);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.SEQUENCE_OF)
- */
- public Void visit(SEQUENCE_OF<?> data) {
- writeCollection(data);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.SEQUENCE_OF)
+ */
+ public Void visit(SEQUENCE_OF<?> data) {
+ writeCollection(data);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.SET)
- */
- public Void visit(SET data) {
- writeConstructive(data);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.SET)
+ */
+ public Void visit(SET data) {
+ writeConstructive(data);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.SET_OF)
- */
- public Void visit(SET_OF<?> data) {
- writeCollection(data);
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.SET_OF)
+ */
+ public Void visit(SET_OF<?> data) {
+ writeCollection(data);
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.CHOICE)
- */
- public Void visit(CHOICE data) {
- indent();
- if (!data.hasValue()) {
- builder.append(NOT_SET);
- } else {
- builder.append(data.selectedIdentifier());
- if (data.selectedTag() != null) {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.CHOICE)
+ */
+ public Void visit(CHOICE data) {
+ indent();
+ if (!data.hasValue()) {
+ builder.append(NOT_SET);
+ } else {
+ builder.append(data.selectedIdentifier());
+ if (data.selectedTag() != null) {
+ builder.append(SEPARATOR);
+ writeTag(data.selectedTag());
+ }
builder.append(SEPARATOR);
- writeTag(data.selectedTag());
+ write(data.selectedValue());
}
- builder.append(SEPARATOR);
- write(data.selectedValue());
+ return null;
}
- return null;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.OBJECT_IDENTIFIER)
- */
- public Void visit(OBJECT_IDENTIFIER data) {
- builder.append(OID_OPEN);
- if (data.value().size() > 0) {
- builder.append(SPACE).append(data.value().get(0));
- for (int i = 1; i < data.value().size(); i++) {
- builder.append('.').append(data.value().get(i));
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.OBJECT_IDENTIFIER)
+ */
+ public Void visit(OBJECT_IDENTIFIER data) {
+ builder.append(OID_OPEN);
+ if (data.value().size() > 0) {
+ builder.append(SPACE).append(data.value().get(0));
+ for (int i = 1; i < data.value().size(); i++) {
+ builder.append('.').append(data.value().get(i));
+ }
+ builder.append(SPACE);
}
- builder.append(SPACE);
+ builder.append(OID_CLOSE);
+ return null;
}
- builder.append(OID_CLOSE);
- return null;
- }
-
- /* (non-Javadoc)
- * @see jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type.builtin.RELATIVE_OID)
- */
- public Void visit(RELATIVE_OID data) {
- return visit((OBJECT_IDENTIFIER)data);
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .StringType)
- */
- public Void visit(StringType data) {
- try {
- String value = data.stringValue();
- builder.append(STRING_OPEN).append(value).append(STRING_CLOSE);
- } catch (Exception e) {
- builder.append(new HexString(data.value()).toString());
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type.builtin.RELATIVE_OID)
+ */
+ public Void visit(RELATIVE_OID data) {
+ return visit((OBJECT_IDENTIFIER)data);
}
- return null;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .TimeType)
- */
- public Void visit(TimeType data) {
- visit((StringType)data);
- builder.append(SPACE).append(DATE_FORMAT.get().format(data.date()));
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .StringType)
+ */
+ public Void visit(StringType data) {
+ try {
+ String value = data.stringValue();
+ builder.append(STRING_OPEN).append(value).append(STRING_CLOSE);
+ } catch (Exception e) {
+ builder.append(new HexString(data.value()).toString());
+ }
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.ANY)
- */
- public Void visit(ANY data) {
- write(data.value());
- return null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .TimeType)
+ */
+ public Void visit(TimeType data) {
+ visit((StringType)data);
+ builder.append(SPACE).append(DATE_FORMAT.get().format(data.date()));
+ return null;
+ }
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .UnknownType)
- */
- public Void visit(UnknownType data) {
- for (int i = 0; i < data.value().length; i++) {
- if (i % 16 == 0) {
- indent();
- }
- builder.append(String.format("%02X", data.value()[i]));
- builder.append(i % 16 == 15 ? NEW_LINE : SPACE);
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.ANY)
+ */
+ public Void visit(ANY data) {
+ write(data.value());
+ return null;
}
- return null;
- }
- /**
- * Writes descriptions of each element of {@code ConstructiveType}.
- *
- * @param data
- * The constructive data.
- */
- private void writeConstructive(ConstructiveType data) {
- ElementSpecification[] elements = data.getElementTypeList();
- for (int i = 0; i < elements.length; i++) {
- if (i != 0) {
- builder.append(CONSTRUCTIVE_SEPARATOR);
- }
- indent();
- builder.append(elements[i].identifier()).append(SEPARATOR);
- if (elements[i].tag() != null) {
- writeTag(elements[i].tag());
- builder.append(SEPARATOR);
- }
- ASN1Type element = data.getComponent(elements[i]);
- if (element == null) {
- builder.append(NOT_SET);
- } else {
- write(element);
- }
- if (elements[i].optional()) {
- builder.append(OPTIONAL);
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .UnknownType)
+ */
+ public Void visit(UnknownType data) {
+ for (int i = 0; i < data.value().length; i++) {
+ if (i % 16 == 0) {
+ indent();
+ }
+ builder.append(String.format("%02X", data.value()[i]));
+ builder.append(i % 16 == 15 ? NEW_LINE : SPACE);
}
+ return null;
}
- }
- /**
- * Writes descriptions of each member of {@code CollectionType}.
- *
- * @param data
- * The collection data.
- */
- private void writeCollection(CollectionType<? extends ASN1Type, ?> data) {
- Iterator<? extends ASN1Type> itr = data.collection().iterator();
- if (itr.hasNext()) {
- while (true) {
+ /**
+ * Writes descriptions of each element of {@code ConstructiveType}.
+ *
+ * @param data
+ * The constructive data.
+ */
+ private void writeConstructive(ConstructiveType data) {
+ ElementSpecification[] elements = data.getElementTypeList();
+ for (int i = 0; i < elements.length; i++) {
+ if (i != 0) {
+ builder.append(CONSTRUCTIVE_SEPARATOR);
+ }
indent();
- write(itr.next());
- if (!itr.hasNext()) {
- return;
+ builder.append(elements[i].identifier()).append(SEPARATOR);
+ if (elements[i].tag() != null) {
+ writeTag(elements[i].tag());
+ builder.append(SEPARATOR);
+ }
+ ASN1Type element = data.getComponent(elements[i]);
+ if (element == null) {
+ builder.append(NOT_SET);
+ } else {
+ write(element);
+ }
+ if (elements[i].optional()) {
+ builder.append(OPTIONAL);
}
- builder.append(CONSTRUCTIVE_SEPARATOR);
}
}
- indent();
- builder.append(NOT_SET);
- }
- /**
- * Writes tag description.
- *
- * @param tag
- * The tag.
- */
- private void writeTag(ASN1TagValue tag) {
- builder.append(TAG_OPEN);
- if (tag.tagClass() != ASN1TagClass.CONTEXT_SPECIFIC) {
- builder.append(tag.tagClass()).append(SPACE);
+ /**
+ * Writes descriptions of each member of {@code CollectionType}.
+ *
+ * @param data
+ * The collection data.
+ */
+ private void writeCollection(CollectionType<? extends ASN1Type, ?> data) {
+ Iterator<? extends ASN1Type> itr = data.collection().iterator();
+ if (itr.hasNext()) {
+ while (true) {
+ indent();
+ write(itr.next());
+ if (!itr.hasNext()) {
+ return;
+ }
+ builder.append(CONSTRUCTIVE_SEPARATOR);
+ }
+ }
+ indent();
+ builder.append(NOT_SET);
}
- builder.append(tag.tagNumber()).append(TAG_CLOSE);
- if (tag.tagMode() == ASN1TagMode.IMPLICIT) {
- builder.append(IMPLICIT);
+
+ /**
+ * Writes tag description.
+ *
+ * @param tag
+ * The tag.
+ */
+ private void writeTag(ASN1TagValue tag) {
+ builder.append(TAG_OPEN);
+ if (tag.tagClass() != ASN1TagClass.CONTEXT_SPECIFIC) {
+ builder.append(tag.tagClass()).append(SPACE);
+ }
+ builder.append(tag.tagNumber()).append(TAG_CLOSE);
+ if (tag.tagMode() == ASN1TagMode.IMPLICIT) {
+ builder.append(IMPLICIT);
+ }
}
- }
- /**
- * Writes indents.
- */
- private void indent() {
- for (int i = 0; i < indent; i++) {
- builder.append(INDENT);
+ /**
+ * Writes indents.
+ */
+ private void indent() {
+ for (int i = 0; i < indent; i++) {
+ builder.append(INDENT);
+ }
}
+
}
-
+
}