001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package javax.swing.text.html.parser;
019:
020: import java.io.IOException;
021: import java.math.BigInteger;
022: import java.util.ArrayList;
023: import java.util.Enumeration;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Vector;
027:
028: import org.apache.harmony.security.asn1.ASN1Integer;
029: import org.apache.harmony.security.asn1.ASN1Sequence;
030: import org.apache.harmony.security.asn1.ASN1SetOf;
031: import org.apache.harmony.security.asn1.ASN1StringType;
032: import org.apache.harmony.security.asn1.ASN1Type;
033: import org.apache.harmony.security.asn1.BerInputStream;
034:
035: /**
036: * It implements ASN.1 codification tools for
037: * <code>javax.swing.text.html.parser.AttributeList</code>. Given an
038: * <code>AttributeList</code>, its values are codified in ASN.1 according to
039: * the following rule:
040: *
041: * <pre>
042: * HTMLElementAttributes ::= SEQUENCE {
043: * Name UTF8String,
044: * Type INTEGER,
045: * Modifier INTEGER,
046: * DefaultValue UTF8String OPTIONAL,
047: * PossibleValues SET OF UTF8String OPTIONAL
048: * }
049: * </pre>
050: *
051: * The class can be used to obtain a byte array representing the codification of
052: * an <code>AttributeList</code>, as well as an <code>AttributeList</code>
053: * from a byte array (previously obtained codifying an <code>AttributeList</code>).
054: * In fact, it serves as a wrapper for the codification and the
055: * <code>AttributeList</code> itself.
056: *
057: */
058: class Asn1Attributes {
059:
060: /**
061: * It stores the definition of an <code>AttributeList</code> as an ASN.1
062: * valid type according to the ASN.1 framework.
063: */
064: private static ASN1Type ASN1_ATTRIBUTES;
065:
066: /**
067: * The definition of the ASN1_ATTRIBUTES type according to the rule defined
068: * for an <code>AttributeList</code>. It also defines a custom
069: * encoder/decoder for this type.
070: */
071: static {
072: ASN1_ATTRIBUTES = new ASN1Sequence(new ASN1Type[] {
073: ASN1StringType.UTF8STRING, // 0 Name
074: ASN1Integer.getInstance(), // 1 Type
075: ASN1Integer.getInstance(), // 2 Modifier
076: ASN1StringType.UTF8STRING, // 3 DefaultValue
077: new ASN1SetOf(ASN1StringType.UTF8STRING) // 4 PosibleValues
078: }) {
079:
080: {
081: setOptional(3);
082: setOptional(4);
083: }
084:
085: /**
086: * Overrided method used to decodified the information that
087: * represents an <code>AttributeList</code>. It makes a completely
088: * new <code>AttributeList</code> with the information interpreted
089: * from the stream.
090: * <p>
091: * Note that the information related with the next
092: * <code>AttributeList</code> in the chain is managed in the
093: * <code>Asn1Element</code> class. For this reason, from this
094: * method, the <code>next</code> field is always set to null.
095: *
096: * @param in
097: * The <code>BerInputStream</code> where the
098: * codified information will be read from.
099: * @return An <code>AttributeList</code> filled with the
100: * information read from the stream.
101: */
102: public Object getDecodedObject(BerInputStream in) {
103: Object values[] = (Object[]) in.content;
104:
105: String name = (String) values[0]; // Name
106: int type = new BigInteger((byte[]) values[1])
107: .intValue(); // Type
108: int modifier = new BigInteger((byte[]) values[2])
109: .intValue(); // Modifier
110: String defValue = (String) values[3]; // DefValue
111: Vector vecValues = values[4] != null ? lst2vector((List) values[4])
112: : null;
113:
114: // XXX next value modified in Asn1Element...
115: return new AttributeList(name, type, modifier,
116: defValue, vecValues, null);
117: }
118:
119: /**
120: * Overrided method used to codify the information stored in an
121: * <code>AttributeList</code> into an array of bytes, according to
122: * its ASN.1 specification.
123: *
124: * @param object
125: * The object where the information to be codified is
126: * stored. It actually consists of an
127: * <code>Asn1Attributes</code> object which contains
128: * the <code>AttributeList</code> to be codified.
129: *
130: * @param values
131: * An array of objects where the attributes' name, type,
132: * modifier, default value and possibles allowed values
133: * information will be stored, ready for codification.
134: */
135: public void getValues(Object object, Object values[]) {
136: Asn1Attributes asn1 = (Asn1Attributes) object;
137:
138: try {
139: values[0] = asn1.getAttributeList().getName();
140: values[1] = BigInteger.valueOf(
141: asn1.getAttributeList().getType())
142: .toByteArray();
143: values[2] = BigInteger.valueOf(
144: asn1.getAttributeList().getModifier())
145: .toByteArray();
146: values[3] = asn1.getAttributeList().getValue();
147:
148: if (asn1.getAttributeList().values != null) {
149: ArrayList<String> lst = new ArrayList<String>();
150: for (Enumeration e = asn1.getAttributeList()
151: .getValues(); e.hasMoreElements();) {
152: lst.add((String) e.nextElement());
153: }
154: values[4] = lst;
155: }
156: } catch (IOException e) {
157: throw new AssertionError(e); // this should not happen
158: }
159: }
160: };
161: }
162:
163: /**
164: * It returns an <code>ASN1Type</code> value that contains the ASN.1
165: * codification rules for an <code>AttributeList</code> with its encoder
166: * and decoder.
167: * <p>
168: * Among other things, this method can be used to declare the types of new
169: * fields in other structures, as for example, in an
170: * <code>Asn1Element</code>.
171: *
172: * @return The value that defines an ASN.1 <code>AttributeList</code>
173: * representation with its encoder/decoder.
174: */
175: static ASN1Type getInstance() {
176: return ASN1_ATTRIBUTES;
177: }
178:
179: /**
180: * An internal copy of the <code>AttributeList</code> to be codified.
181: */
182: private AttributeList att;
183:
184: /**
185: * An internal copy of the byte array which contains the codification of an
186: * <code>AttributeList</code>. From this variable, the information used
187: * to decodify an <code>AttributeList</code> is read from.
188: */
189: private byte[] encoded;
190:
191: /**
192: * Constructs a new instance of an <code>Asn1Attributes</code> class from
193: * a byte array. The byte array received as argument can be later decodified
194: * into an <code>AttributeList</code>.
195: *
196: * @param encoded
197: * A byte array containing the codified information of an
198: * <code>AttributeList</code>.
199: */
200: public Asn1Attributes(byte[] encoded) {
201: byte[] copy = new byte[encoded.length];
202: System.arraycopy(encoded, 0, copy, 0, copy.length);
203: this .encoded = copy;
204: }
205:
206: /**
207: * Constructs a new instance of an <code>Asn1Attributes</code> class from
208: * an <code>AttributeList</code>. The <code>AttributeList</code>
209: * received as argument can be then codified into a byte array.
210: * <p>
211: * The value received as argument should not be null. If so, a
212: * <code>NullPointerException</code> is thrown.
213: *
214: * @param att
215: * The <code>AttributeList</code> to be codified.
216: */
217: public Asn1Attributes(AttributeList att) {
218: if (att == null) {
219: throw new NullPointerException();
220: }
221: this .att = att;
222: }
223:
224: /**
225: * Returns the representation of an <code>AttributeList</code> in ASN.1
226: * codification.
227: * <p>
228: * If the <code >Asn1Attributes</code> object was created with an
229: * <code>AttributeList</code>, then the <code>AttributeList</code> is
230: * codified and returned as a byte array. On the other hand, if the instance
231: * was created using a byte array, then no codification process is made.
232: *
233: * @return If at construction time an <code>AttributeList</code> was
234: * given, its representation in ASN.1 codification. If at
235: * construction time a byte array was given, a copy of the same
236: * array is returned.
237: */
238: public byte[] getEncoded() {
239: if (encoded == null) {
240: return ASN1_ATTRIBUTES.encode(att);
241: } else {
242: return encoded;
243: }
244: }
245:
246: /**
247: * Returns the <code>AttributeList</code> obtained from the decodification
248: * of an ASN.1 codified byte array.
249: * <p>
250: * If the <code>Asn1Attributes</code> was created giving an
251: * <code>AttributeList</code>, a reference to the same
252: * <code>AttributeList</code> is obtained. Otherwise, the byte array given
253: * at construction time is decodificated into a new
254: * <code>AttributeList</code> object.
255: *
256: * @return If at construction time an <code>AttributeList</code> was
257: * given, the same <code>AttributeList</code> is returned. If at
258: * construction time a byte array was given, an
259: * <code>AttributeList</code> constructed with the information
260: * stored in that byte array is returned.
261: * @throws IOException
262: * If the decodification process could not be carried out
263: * properly.
264: */
265: public AttributeList getAttributeList() throws IOException {
266: if (att == null) {
267: return (AttributeList) ASN1_ATTRIBUTES.decode(encoded);
268: } else {
269: return att;
270: }
271: }
272:
273: /**
274: * Converts a list of <code>String</code> into a vector of
275: * <code>String</code>.
276: *
277: * @param lst
278: * The list of <code>String</code> to be converted.
279: * @return A <code>Vector</code> containing the <code>String</code>s
280: * stored in the <code>List</code> received as argument.
281: */
282: private static Vector lst2vector(List lst) {
283: Vector<String> vecValues = new Vector<String>();
284: for (Iterator iter = lst.iterator(); iter.hasNext();) {
285: String element = (String) iter.next();
286: vecValues.addElement(element);
287: }
288: return vecValues;
289: }
290:
291: }
|