From 00be72e06bb34278cb2784515d9b9e09a3b5dfa9 Mon Sep 17 00:00:00 2001 From: Adrian Cumiskey Date: Thu, 22 Oct 2009 13:20:53 +0000 Subject: [PATCH] Fixes https://issues.apache.org/bugzilla/show_bug.cgi?id=47941 Created Triplet interface. Created new AttributeValueTriplet and AttributeQualifierTriplet. Promoted truncate() from GraphicsCharacterString to AbstractAFPObject so it can be reused for AttributeValueTriplet. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@828678 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/afp/goca/GraphicsCharacterString.java | 18 +-- .../fop/afp/modca/AbstractAFPObject.java | 17 ++- .../AbstractTripletStructuredObject.java | 9 +- .../fop/afp/modca/TagLogicalElement.java | 111 ++++++------------ .../afp/modca/triplets/AbstractTriplet.java | 62 +--------- .../triplets/AttributeQualifierTriplet.java | 48 ++++++++ .../modca/triplets/AttributeValueTriplet.java | 53 +++++++++ .../fop/afp/modca/triplets/Triplet.java | 66 +++++++++++ 8 files changed, 232 insertions(+), 152 deletions(-) create mode 100644 src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java create mode 100644 src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java create mode 100644 src/java/org/apache/fop/afp/modca/triplets/Triplet.java diff --git a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java index 4094314a2..6d6e44c97 100644 --- a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java +++ b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java @@ -45,7 +45,7 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord { */ public GraphicsCharacterString(String str, int x, int y) { super(x, y); - this.str = truncate(str); + this.str = truncate(str, MAX_STR_LEN); } /** @@ -57,7 +57,7 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord { */ public GraphicsCharacterString(String str) { super(null); - this.str = truncate(str); + this.str = truncate(str, MAX_STR_LEN); } /** {@inheritDoc} */ @@ -82,20 +82,6 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord { os.write(data); } - /** - * Truncates the string as necessary - * - * @param str a character string - * @return a possibly truncated string - */ - private String truncate(String str) { - if (str.length() > MAX_STR_LEN) { - str = str.substring(0, MAX_STR_LEN); - log.warn("truncated character string, longer than " + MAX_STR_LEN + " chars"); - } - return str; - } - /** * Returns the text string as an encoded byte array * diff --git a/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java b/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java index ae1c83377..45239a6cf 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java +++ b/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java @@ -43,7 +43,7 @@ public abstract class AbstractAFPObject implements Streamable { /** the structured field class id */ protected static final byte SF_CLASS = (byte)0xD3; - private static final byte[] SF_HEADER = new byte[] { + protected static final byte[] SF_HEADER = new byte[] { 0x5A, // Structured field identifier 0x00, // Length byte 1 0x10, // Length byte 2 @@ -177,6 +177,21 @@ public abstract class AbstractAFPObject implements Streamable { } } + /** + * Truncates the string as necessary + * + * @param str a character string + * @param maxLength the maximum length allowed for the string + * @return a possibly truncated string + */ + protected String truncate(String str, int maxLength) { + if (str.length() > maxLength) { + str = str.substring(0, maxLength); + log.warn("truncated character string '" + str + "', longer than " + maxLength + " chars"); + } + return str; + } + /** structured field type codes */ public interface Type { diff --git a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java index a14af2967..efc38f3b8 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java +++ b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java @@ -27,9 +27,12 @@ import java.util.List; import org.apache.fop.afp.modca.Registry.ObjectType; import org.apache.fop.afp.modca.triplets.AbstractTriplet; +import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet; +import org.apache.fop.afp.modca.triplets.AttributeValueTriplet; import org.apache.fop.afp.modca.triplets.CommentTriplet; import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet; import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet; +import org.apache.fop.afp.modca.triplets.Triplet; /** * A MODCA structured object base class providing support for Triplets @@ -37,7 +40,7 @@ import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet; public class AbstractTripletStructuredObject extends AbstractStructuredObject { /** list of object triplets */ - protected List/**/ triplets = new java.util.ArrayList/**/(); + protected List/**/ triplets = new java.util.ArrayList/**/(); /** * Returns the triplet data length @@ -109,7 +112,7 @@ public class AbstractTripletStructuredObject extends AbstractStructuredObject { * * @param triplet the triplet to add */ - protected void addTriplet(AbstractTriplet triplet) { + protected void addTriplet(Triplet triplet) { triplets.add(triplet); } @@ -130,7 +133,7 @@ public class AbstractTripletStructuredObject extends AbstractStructuredObject { } /** - * Sets the fully qualified name of this resource + * Sets the fully qualified name of this structured field * * @param fqnType the fully qualified name type of this resource * @param fqnFormat the fully qualified name format of this resource diff --git a/src/java/org/apache/fop/afp/modca/TagLogicalElement.java b/src/java/org/apache/fop/afp/modca/TagLogicalElement.java index 5c1f7bbbb..cb7a67d28 100644 --- a/src/java/org/apache/fop/afp/modca/TagLogicalElement.java +++ b/src/java/org/apache/fop/afp/modca/TagLogicalElement.java @@ -21,9 +21,10 @@ package org.apache.fop.afp.modca; import java.io.IOException; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet; +import org.apache.fop.afp.modca.triplets.AttributeValueTriplet; +import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet; import org.apache.fop.afp.util.BinaryUtils; /** @@ -45,7 +46,7 @@ import org.apache.fop.afp.util.BinaryUtils; * effect on the appearance of a document when it is presented. *

*/ -public class TagLogicalElement extends AbstractAFPObject { +public class TagLogicalElement extends AbstractTripletStructuredObject { /** * Name of the key, used within the TLE @@ -75,77 +76,43 @@ public class TagLogicalElement extends AbstractAFPObject { this.tleID = tleID; } - /** {@inheritDoc} */ - public void writeToStream(OutputStream os) throws IOException { - - // convert name and value to ebcdic - byte[] tleByteName = null; - byte[] tleByteValue = null; - try { - tleByteName = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - tleByteValue = value.getBytes(AFPConstants.EBCIDIC_ENCODING); - } catch (UnsupportedEncodingException usee) { - tleByteName = name.getBytes(); - tleByteValue = value.getBytes(); - log.warn( - "Constructor:: UnsupportedEncodingException translating the name " - + name); - } - - byte[] data = new byte[27 + tleByteName.length + tleByteValue.length]; - - data[0] = 0x5A; - // Set the total record length - byte[] rl1 - = BinaryUtils.convert(26 + tleByteName.length + tleByteValue.length, 2); - //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a TLE - data[3] = (byte) 0xD3; - data[4] = (byte) Type.ATTRIBUTE; - data[5] = (byte) Category.PROCESS_ELEMENT; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - //Use 2 triplets, attribute name and value (the key for indexing) - - byte[] rl2 = BinaryUtils.convert(tleByteName.length + 4, 1); - data[9] = rl2[0]; // length of the triplet, including this field - data[10] = 0x02; //Identifies it as a FQN triplet - data[11] = 0x0B; // GID format - data[12] = 0x00; - - // write out TLE name - int pos = 13; - for (int i = 0; i < tleByteName.length; i++) { - data[pos++] = tleByteName[i]; - } - - byte[] rl3 = BinaryUtils.convert(tleByteValue.length + 4, 1); - data[pos++] = rl3[0]; // length of the triplet, including this field - data[pos++] = 0x36; //Identifies the triplet, attribute value - data[pos++] = 0x00; // Reserved - data[pos++] = 0x00; // Reserved + /** + * Sets the attribute value of this structured field + * + * @param value the attribute value + */ + public void setAttributeValue(String value) { + addTriplet(new AttributeValueTriplet(value)); + } - for (int i = 0; i < tleByteValue.length; i++) { - data[pos++] = tleByteValue[i]; - } - // attribute qualifier - data[pos++] = 0x0A; - data[pos++] = (byte)0x80; - byte[] id = BinaryUtils.convert(tleID, 4); - for (int i = 0; i < id.length; i++) { - data[pos++] = id[i]; - } - byte[] level = BinaryUtils.convert(1, 4); - for (int i = 0; i < level.length; i++) { - data[pos++] = level[i]; - } + /** + * Sets the attribute qualifier of this structured field + * + * @param seqNumber the attribute sequence number + * @param levNumber the attribute level number + */ + public void setAttributeQualifier(int seqNumber, int levNumber) { + addTriplet(new AttributeQualifierTriplet(seqNumber, levNumber)); + } + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + setFullyQualifiedName( + FullyQualifiedNameTriplet.TYPE_ATTRIBUTE_GID, + FullyQualifiedNameTriplet.FORMAT_CHARSTR, + name); + setAttributeQualifier(tleID, 1); + setAttributeValue(value); + + byte[] data = new byte[SF_HEADER.length]; + copySF(data, Type.ATTRIBUTE, Category.PROCESS_ELEMENT); + + int tripletDataLength = getTripletDataLength(); + byte[] l = BinaryUtils.convert(data.length + tripletDataLength - 1, 2); + data[1] = l[0]; + data[2] = l[1]; os.write(data); + + writeTriplets(os); } } diff --git a/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java index 598df1b98..5cd136ab2 100644 --- a/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java +++ b/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java @@ -19,70 +19,12 @@ package org.apache.fop.afp.modca.triplets; -import org.apache.fop.afp.Streamable; -import org.apache.fop.afp.StructuredData; +import org.apache.fop.afp.modca.AbstractAFPObject; /** * A simple implementation of a MOD:CA triplet */ -public abstract class AbstractTriplet implements Streamable, StructuredData { - public static final byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01; - - /** Triplet identifiers */ - public static final byte FULLY_QUALIFIED_NAME = 0x02; - public static final byte MAPPING_OPTION = 0x04; - public static final byte OBJECT_CLASSIFICATION = 0x10; - public static final byte MODCA_INTERCHANGE_SET = 0x18; - public static final byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F; - public static final byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21; - public static final byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22; - public static final byte RESOURCE_LOCAL_IDENTIFIER = 0x24; - public static final byte RESOURCE_SECTION_NUMBER = 0x25; - public static final byte CHARACTER_ROTATION = 0x26; - public static final byte OBJECT_BYTE_OFFSET = 0x2D; - public static final byte ATTRIBUTE_VALUE = 0x36; - public static final byte DESCRIPTOR_POSITION = 0x43; - public static final byte MEDIA_EJECT_CONTROL = 0x45; - public static final byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46; - public static final byte RESOURCE_USAGE_ATTRIBUTE = 0x47; - public static final byte MEASUREMENT_UNITS = 0x4B; - public static final byte OBJECT_AREA_SIZE = 0x4C; - public static final byte AREA_DEFINITION = 0x4D; - public static final byte COLOR_SPECIFICATION = 0x4E; - public static final byte ENCODING_SCHEME_ID = 0x50; - public static final byte MEDIUM_MAP_PAGE_NUMBER = 0x56; - public static final byte OBJECT_BYTE_EXTENT = 0x57; - public static final byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58; - public static final byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59; - public static final byte OBJECT_OFFSET = 0x5A; - public static final byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D; - public static final byte OBJECT_COUNT = 0x5E; - public static final byte OBJECT_DATE_AND_TIMESTAMP = 0x62; - public static final byte COMMENT = 0x65; - public static final byte MEDIUM_ORIENTATION = 0x68; - public static final byte RESOURCE_OBJECT_INCLUDE = 0x6C; - public static final byte PRESENTATION_SPACE_RESET_MIXING = 0x70; - public static final byte PRESENTATION_SPACE_MIXING_RULE = 0x71; - public static final byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72; - public static final byte TONER_SAVER = 0x74; - public static final byte COLOR_FIDELITY = 0x75; - public static final byte FONT_FIDELITY = 0x78; - public static final byte ATTRIBUTE_QUALIFIER = (byte)0x80; - public static final byte PAGE_POSITION_INFORMATION = (byte)0x81; - public static final byte PARAMETER_VALUE = (byte)0x82; - public static final byte PRESENTATION_CONTROL = (byte)0x83; - public static final byte FONT_RESOLUTION_AND_METRIC_TECHNOLOGY = (byte)0x84; - public static final byte FINISHING_OPERATION = (byte)0x85; - public static final byte TEXT_FIDELITY = (byte)0x86; - public static final byte MEDIA_FIDELITY = (byte)0x87; - public static final byte FINISHING_FIDELITY = (byte)0x88; - public static final byte DATA_OBJECT_FONT_DESCRIPTOR = (byte)0x8B; - public static final byte LOCALE_SELECTOR = (byte)0x8C; - public static final byte UP3I_FINISHING_OPERATION = (byte)0x8E; - public static final byte COLOR_MANAGEMENT_RESOURCE_DESCRIPTOR = (byte)0x91; - public static final byte RENDERING_INTENT = (byte)0x95; - public static final byte CMR_TAG_FIDELITY = (byte)0x96; - public static final byte DEVICE_APPEARANCE = (byte)0x97; +public abstract class AbstractTriplet extends AbstractAFPObject implements Triplet { /** the triplet identifier */ protected final byte id; diff --git a/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java new file mode 100644 index 000000000..e07ac0adb --- /dev/null +++ b/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java @@ -0,0 +1,48 @@ +package org.apache.fop.afp.modca.triplets; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.fop.afp.util.BinaryUtils; + +/** + * The attribute qualifier triplet is used to specify a qualifier for a document + * attribute. + */ +public class AttributeQualifierTriplet extends AbstractTriplet { + + private int seqNumber; + private int levNumber; + + /** + * Main constructor + * + * @param seqNumber the attribute qualifier sequence number + * @param levNumber the attribute qualifier level number + */ + public AttributeQualifierTriplet(int seqNumber, int levNumber) { + super(ATTRIBUTE_QUALIFIER); + this.seqNumber = seqNumber; + this.levNumber = levNumber; + } + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + byte[] data = getData(); + byte[] id = BinaryUtils.convert(seqNumber, 4); + System.arraycopy(id, 0, data, 2, id.length); + byte[] level = BinaryUtils.convert(levNumber, 4); + System.arraycopy(level, 0, data, 6, level.length); + os.write(data); + } + + /** {@inheritDoc} */ + public int getDataLength() { + return 10; + } + + /** {@inheritDoc} */ + public String toString() { + return "seqNumber=" + seqNumber + ", levNumber=" + levNumber; + } +} diff --git a/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java new file mode 100644 index 000000000..1924b05f2 --- /dev/null +++ b/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java @@ -0,0 +1,53 @@ +package org.apache.fop.afp.modca.triplets; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.fop.afp.AFPConstants; + +/** + * The attribute value triplet is used to specify a value for a document + * attribute. + */ +public class AttributeValueTriplet extends AbstractTriplet { + private String attVal; + + /** + * Main constructor + * + * @param attVal an attribute value + */ + public AttributeValueTriplet(String attVal) { + super(ATTRIBUTE_VALUE); + this.attVal = truncate(attVal, MAX_LENGTH - 4); + } + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + byte[] data = super.getData(); + data[2] = 0x00; // Reserved + data[3] = 0x00; // Reserved + + // convert name and value to ebcdic + byte[] tleByteValue = null; + try { + tleByteValue = attVal.getBytes(AFPConstants.EBCIDIC_ENCODING); + } catch (UnsupportedEncodingException usee) { + tleByteValue = attVal.getBytes(); + throw new IllegalArgumentException(attVal + " encoding failed"); + } + System.arraycopy(tleByteValue, 0, data, 4, tleByteValue.length); + os.write(data); + } + + /** {@inheritDoc} */ + public int getDataLength() { + return 4 + attVal.length(); + } + + /** {@inheritDoc} */ + public String toString() { + return attVal; + } +} diff --git a/src/java/org/apache/fop/afp/modca/triplets/Triplet.java b/src/java/org/apache/fop/afp/modca/triplets/Triplet.java new file mode 100644 index 000000000..4b061aeb0 --- /dev/null +++ b/src/java/org/apache/fop/afp/modca/triplets/Triplet.java @@ -0,0 +1,66 @@ +package org.apache.fop.afp.modca.triplets; + +import org.apache.fop.afp.Streamable; +import org.apache.fop.afp.StructuredData; + +public interface Triplet extends Streamable, StructuredData { + int MAX_LENGTH = 254; + + byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01; + + /** Triplet identifiers */ + byte FULLY_QUALIFIED_NAME = 0x02; + byte MAPPING_OPTION = 0x04; + byte OBJECT_CLASSIFICATION = 0x10; + byte MODCA_INTERCHANGE_SET = 0x18; + byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F; + byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21; + byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22; + byte RESOURCE_LOCAL_IDENTIFIER = 0x24; + byte RESOURCE_SECTION_NUMBER = 0x25; + byte CHARACTER_ROTATION = 0x26; + byte OBJECT_BYTE_OFFSET = 0x2D; + byte ATTRIBUTE_VALUE = 0x36; + byte DESCRIPTOR_POSITION = 0x43; + byte MEDIA_EJECT_CONTROL = 0x45; + byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46; + byte RESOURCE_USAGE_ATTRIBUTE = 0x47; + byte MEASUREMENT_UNITS = 0x4B; + byte OBJECT_AREA_SIZE = 0x4C; + byte AREA_DEFINITION = 0x4D; + byte COLOR_SPECIFICATION = 0x4E; + byte ENCODING_SCHEME_ID = 0x50; + byte MEDIUM_MAP_PAGE_NUMBER = 0x56; + byte OBJECT_BYTE_EXTENT = 0x57; + byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58; + byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59; + byte OBJECT_OFFSET = 0x5A; + byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D; + byte OBJECT_COUNT = 0x5E; + byte OBJECT_DATE_AND_TIMESTAMP = 0x62; + byte COMMENT = 0x65; + byte MEDIUM_ORIENTATION = 0x68; + byte RESOURCE_OBJECT_INCLUDE = 0x6C; + byte PRESENTATION_SPACE_RESET_MIXING = 0x70; + byte PRESENTATION_SPACE_MIXING_RULE = 0x71; + byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72; + byte TONER_SAVER = 0x74; + byte COLOR_FIDELITY = 0x75; + byte FONT_FIDELITY = 0x78; + byte ATTRIBUTE_QUALIFIER = (byte)0x80; + byte PAGE_POSITION_INFORMATION = (byte)0x81; + byte PARAMETER_VALUE = (byte)0x82; + byte PRESENTATION_CONTROL = (byte)0x83; + byte FONT_RESOLUTION_AND_METRIC_TECHNOLOGY = (byte)0x84; + byte FINISHING_OPERATION = (byte)0x85; + byte TEXT_FIDELITY = (byte)0x86; + byte MEDIA_FIDELITY = (byte)0x87; + byte FINISHING_FIDELITY = (byte)0x88; + byte DATA_OBJECT_FONT_DESCRIPTOR = (byte)0x8B; + byte LOCALE_SELECTOR = (byte)0x8C; + byte UP3I_FINISHING_OPERATION = (byte)0x8E; + byte COLOR_MANAGEMENT_RESOURCE_DESCRIPTOR = (byte)0x91; + byte RENDERING_INTENT = (byte)0x95; + byte CMR_TAG_FIDELITY = (byte)0x96; + byte DEVICE_APPEARANCE = (byte)0x97; +} -- 2.39.5