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.Collection;
024:
025: import org.apache.harmony.security.asn1.ASN1Integer;
026: import org.apache.harmony.security.asn1.ASN1Sequence;
027: import org.apache.harmony.security.asn1.ASN1SequenceOf;
028: import org.apache.harmony.security.asn1.ASN1Type;
029: import org.apache.harmony.security.asn1.BerInputStream;
030:
031: /**
032: * It implements ASN.1 codification tools for
033: * <code>javax.swing.text.html.parser.ContentModel</code>. Given a
034: * <code>ContentModel</code>, its values are codified in ASN.1 according to
035: * the following rule:
036: *
037: * <pre>
038: * HTMLContentModel ::= SEQUENCE OF SEQUENCE {
039: * Type INTEGER,
040: * Index INTEGER
041: * }
042: * </pre>
043: *
044: * The structure used to store the <code>ContentModel</code> is a sort of
045: * binary tree that imitate the internal structure of a
046: * <code>ContentModel</code>.
047: * <p>
048: * As you may know, a <code>ContentModel</code> can be represented by a binary
049: * tree where each node denotes one of the following possible values:
050: * <ul>
051: * <li> A binary relation between its children.
052: * <li> A unary relation applied only to its left child.
053: * <li> An element.
054: * <li> A null value.
055: * </ul>
056: * <p>
057: * So, depending on each of those possible values, a different node is created
058: * to summarize that information. We will denote each node as a pair of (type,
059: * index). Therefore, according to the representation of a ContentModel,we have
060: * the following conversions:
061: * <p>
062: *
063: * <b>CASE 1: A binary relation between its children</b>
064: *
065: * <pre>
066: * B
067: * / => [B,-1]
068: * C1
069: * \
070: * C2
071: * \
072: * ...
073: * \
074: * Cn
075: *
076: *
077: * </pre>
078: *
079: *
080: * <b>CASE 2: A unary relation applied inly to its left child</b>
081: *
082: * <pre>
083: * U
084: * / => [U,-1]
085: * C1
086: * </pre>
087: *
088: *
089: * <b>CASE 3: An element</b>
090: *
091: * <pre>
092: * ELEM => [-2, ELEM.getIndex()]
093: * </pre>
094: *
095: *
096: * <b>CASE 4: A null value</b>
097: *
098: * <pre>
099: * NULL => [-1,-1]
100: * </pre>
101: *
102: *
103: *
104: * For example, lets take the <code>ContentModel</code>'s tree for the HEAD
105: * <code>Element<code>. The <code>ContentModel</code> is defined as:
106: *
107: * <pre>
108: * TITLE & ISINDEX? & BASE?
109: * </pre>
110: *
111: * And the <code>ContentModel</code> tree for this case is then:
112: *
113: * <pre>
114: * &
115: * |
116: * +-----------------+-----------------+
117: * | |
118: * 0 NULL
119: * +---------+---------+
120: * | |
121: * TITLE ?
122: * +---------+---------+
123: * | |
124: * 0 ?
125: * +----+----+ +----+----+
126: * | | | |
127: * ISINDEX NULL 0 NULL
128: * +-----+-----+
129: * | |
130: * BASE NULL
131: *
132: * </pre>
133: *
134: * Then, this representation translated into our tree representation looks like:
135: *
136: *
137: * <pre>
138: * ['&',-1]
139: * |
140: * +-----------------+-----------------+
141: * | |
142: * [0,-1] [-1,-1]
143: * +---------+---------+
144: * | |
145: * [-2,TITLE] ['?',-1]
146: * +---------+---------+
147: * | |
148: * [0,-1] ['?',-1]
149: * +----+----+ +----+----+
150: * | | | |
151: * [-2,ISINDEX][-1,-1] [0,-1] [-1,-1]
152: * +-----+-----+
153: * | |
154: * [-2,BASE] [-1,-1]
155: * </pre>
156: *
157: * So then, this simpler tree can be stored as a sequence of pairs (type,index),
158: * and reconstructing it again is straightforward if both, the storage and
159: * recovery of information, are made is BSF mode.
160: * <p>
161: * Then, this tree will be represented by the sequence:
162: * <p>
163: * ['&',-1] , [0,-1], [-1,-1], [-2,TITLE], ['?',-1], [0,-1], ['?',-1],
164: * [-2,ISINDEX], [-1,-1], [0,-1], [-1,-1], [-2,BASE], [-1,-1]
165: * <p>
166: * And the relation among nodes can be restored if we consider that if the
167: * sequence is numerated from 0, we maintain the number of processed
168: * <tt>relation nodes (rn)</tt> and we read the stored nodes in order, for any
169: * relational node, its sons are stored ad positions 2*rn+1 and 2*rn+2.
170: *
171: * The class can be used to obtain a byte array representing the codification of
172: * a <code>ContentModel</code>, as well as a <code>ContentModel</code> from
173: * a byte array (previously obtained codifying a <code>ContentModel</code>).
174: * In fact, it serves as a wrapper for the codification and the
175: * <code>ContentModel</code> itself.
176: *
177: */
178: class Asn1ContentModel {
179:
180: /**
181: * It stores the definition of a <code>ContentModel</code> as an ASN.1
182: * valid type according to the ASN.1 framework.
183: */
184: private static ASN1Type ASN1_CONTENT_MODEL;
185:
186: /**
187: * The definition of the ASN1_CONTENT_MODEL type according to the rule
188: * defined for a <code>ContentModel</code>. It also defines a custom
189: * encoder/decoder for this type.
190: */
191: static {
192: ASN1_CONTENT_MODEL = new ASN1SequenceOf(Asn1ModelElement
193: .getInstance()) {
194:
195: /**
196: * Overrided method used to decodified the information that
197: * represents a <code>ContentModel</code>. It makes a completely
198: * new <code>ContentModel</code> with the information interpreted
199: * from the stream.
200: * <p>
201: * As at this point no information about other <code>Element</code>s
202: * is available, a partial empty <code>Element</code> is used to
203: * denote the presence of other elements in the
204: * <code>ContentModel</code>.
205: *
206: * @param in
207: * The <code>BerInputStream</code> where the
208: * codificated information will be read from.
209: * @return A <code>ContentModel</code> filled with the information
210: * read from the stream.
211: */
212: public Object getDecodedObject(BerInputStream in) {
213: Object values = in.content;
214:
215: int pos = 0;
216: ArrayList mLst = (ArrayList) values;
217: ArrayList<Object> queue = new ArrayList<Object>();
218: ContentModel rootModel = (ContentModel) ModelElement
219: .makeContent((ModelElement) mLst.get(0));
220: ContentModel actualModel = null;
221: if (rootModel != null) {
222: queue.add(rootModel);
223: }
224:
225: while (!queue.isEmpty()) {
226: actualModel = (ContentModel) queue.remove(0);
227: actualModel.content = ModelElement
228: .makeContent((ModelElement) mLst
229: .get(pos * 2 + 1));
230: actualModel.next = (ContentModel) ModelElement
231: .makeContent((ModelElement) mLst
232: .get(pos * 2 + 2));
233: if (actualModel.content instanceof ContentModel) {
234: queue.add(actualModel.content);
235: }
236: if (actualModel.next != null) {
237: queue.add(actualModel.next);
238: }
239: pos++;
240: }
241:
242: return rootModel;
243: }
244:
245: /**
246: * Overrided method used to codify the information stored in an
247: * <code>ContentModel</code> into an array of bytes, according to
248: * its ASN.1 specification.
249: *
250: * @param object
251: * The object where the information to be codified is
252: * stored. It actually consists of an
253: * <code>Asn1ContentModel</code> object which contains
254: * the <code>ContentModel</code> to be codified.
255: *
256: * @return A collection with the information of the nodes that
257: * compose the <code>ContentModel</code>, ready to be
258: * codified.
259: */
260: public Collection getValues(Object object) {
261: ArrayList<Object> queue = new ArrayList<Object>();
262: ArrayList<ModelElement> mLst = new ArrayList<ModelElement>();
263: Asn1ContentModel asn1 = (Asn1ContentModel) object;
264: ContentModel model = asn1.getWrappedContentModel();
265:
266: mLst.add(new ModelElement(model));
267: if (model != null) {
268: queue.add(model);
269: }
270: while (!queue.isEmpty()) {
271: model = (ContentModel) queue.remove(0);
272: mLst.add(new ModelElement((model.content)));
273: mLst.add(new ModelElement(model.next));
274: if ((model.content) instanceof ContentModel) {
275: queue.add(model.content);
276: }
277: if (model.next != null) {
278: queue.add(model.next);
279: }
280: }
281:
282: return mLst;
283: }
284: };
285: }
286:
287: /**
288: * It returns an <code>ASN1Type</code> value that contains the ASN.1
289: * codification rules for a <code>ContentModel</code> with its encoder and
290: * decoder.
291: * <p>
292: * Among other things, this method can be used to declare the types of new
293: * fields in other structures, as for example, in an
294: * <code>Asn1Element</code>.
295: *
296: * @return The value that defines an ASN.1 <code>ContentModel</code>
297: * representation with its encoder/decoder.
298: */
299: static ASN1Type getInstance() {
300: return ASN1_CONTENT_MODEL;
301: }
302:
303: /**
304: * An internal copy of the <code>ContentModel</code> to be codified.
305: */
306: private ContentModel contentModel;
307:
308: /**
309: * An internal copy of the byte array which contains the codification of an
310: * <code>ContentModel</code>. From this variable, the information used to
311: * decodify a <code>ContentModel</code> is read from.
312: */
313: private byte[] encoded;
314:
315: /**
316: * Constructs a new instance of an <code>Asn1ContentModel</code> class
317: * from a byte array. The byte array received as argument can be later
318: * decodified into a <code>ContentModel</code>.
319: *
320: * @param encoded
321: * A byte array containing the codified information of a
322: * <code>ContentModel</code>.
323: */
324: public Asn1ContentModel(byte[] encoded) {
325: byte[] copy = new byte[encoded.length];
326: System.arraycopy(encoded, 0, copy, 0, copy.length);
327: this .encoded = copy;
328: }
329:
330: /**
331: * Constructs a new instance of an <code>Asn1ContentModel</code> class
332: * from a <code>ContentModel</code>. The <code>ContentModel</code>
333: * received as argument can be then codified into a byte array.
334: *
335: * @param contentModel
336: * The <code>ContentModel</code> to be codified.
337: */
338: public Asn1ContentModel(ContentModel contentModel) {
339: this .contentModel = contentModel;
340: }
341:
342: /**
343: * Returns the representation of a <code>ContentModel</code> in ASN.1
344: * codification.
345: * <p>
346: * If the <code >Asn1ContentModel</code> object was created with a
347: * <code>ContentModel</code>, then the <code>ContentModel</code> is
348: * codified and returned as a byte array. On the other hand, if the instance
349: * was created using a byte array, then no codification process is made.
350: *
351: * @return If at construction time a <code>ContentModel</code> was given,
352: * its representation in ASN.1 codification. If at construction time
353: * a byte array was given, a copy of the same array is returned.
354: */
355: public byte[] getEncoded() {
356: if (encoded == null) {
357: return ASN1_CONTENT_MODEL.encode(contentModel);
358: } else {
359: byte[] copy = new byte[encoded.length];
360: System.arraycopy(encoded, 0, copy, 0, copy.length);
361: return copy;
362: }
363: }
364:
365: /**
366: * Returns the <code>ContentModel</code> obtained from the decodification
367: * of an ASN.1 codified byte array.
368: * <p>
369: * If the <code>Asn1ContentModel</code> was created giving an
370: * <code>ContentModel</code>, a reference to the same
371: * <code>ContentModel</code> is obtained. Otherwise, the byte array given
372: * at construction time is decodificated into a new
373: * <code>ContentModel</code> object.
374: *
375: * @return If at construction time a <code>ContentModel</code> was given,
376: * the same <code>ContentModel</code> is returned. If at
377: * construction time a byte array was given, a
378: * <code>ContentModel</code> constructed with the information
379: * stored in that byte array is returned.
380: * @throws IOException
381: * If the decodification process could not be carried out
382: * properly.
383: */
384: public ContentModel getContentModel() throws IOException {
385: if (contentModel == null) {
386: return (ContentModel) ASN1_CONTENT_MODEL.decode(encoded);
387: } else {
388: return contentModel;
389: }
390: }
391:
392: /**
393: * Returns the <code>ContentModel</code> wrapped into the
394: * <code>Asn1ContentModel</code> object.
395: *
396: * @return The wrapped <code>ContentModel</code>, if one was used at
397: * construction time, or null if the object was created using a byte
398: * array.
399: */
400: public ContentModel getWrappedContentModel() {
401: return contentModel;
402: }
403: }
404:
405: /**
406: * It implements the elements that compose the sequence that defines a
407: * <code>ContentModel</code>.
408: * <p>
409: * When the ASN.1 representation for the <code>ContentModel</code> was given,
410: * it was defined as a "SEQUENCE OF" some structures, thus the purpose of this
411: * class is to define the "SEQUENCE" that implements that structures. Such
412: * structures will be denoted by the name <code>ModelElement</code>.
413: * <p>
414: * When defined the codification of a <code>ContentModel</code>, its tree
415: * structure was established. This class just defines the node's structure of
416: * such tree.
417: */
418: class ModelElement {
419:
420: /**
421: * It stores the type of the node.
422: */
423: private int type;
424:
425: /**
426: * It stores the index of the <code>Element</code> that codify the node.
427: */
428: private int index;
429:
430: /**
431: * Sets the values of the node.
432: *
433: * @param type
434: * The type set to the node
435: * @param index
436: * The index of the <code>Element</code> that the node is
437: * codifying.
438: */
439: private void setValues(int type, int index) {
440: this .type = type;
441: this .index = index;
442: }
443:
444: /**
445: * Returns the type of the node.
446: *
447: * @return The integer representation of the symbol that denote the unary
448: * ('*', '+', '?') or binary ('|', '&', ',') relation that relates
449: * the two children of this node. 0 if the node represents an
450: * <code>Element</code> or -1 if the node represents a null value.
451: */
452: public int getType() {
453: return type;
454: }
455:
456: /**
457: * Returns the index of the <code>Element</code> that the node is
458: * codifying.
459: *
460: * @return The index of the codified <code>Element</code> or -1 if no
461: * <code>Element</code> is codified.
462: */
463: public int getIndex() {
464: return index;
465: }
466:
467: /**
468: * Constructs a new <code>ModelElement</code> given a type and index
469: * value.
470: *
471: * @param type
472: * The node type. Any <code>int</code> value is possible.
473: * @param index
474: * The node index. Any <code>int</code> value is possible.
475: */
476: public ModelElement(final int type, final int index) {
477: setValues(type, index);
478: }
479:
480: /**
481: * Constructs a new <code>ModelElement</code> given a
482: * <code>ContentModel</code>. The information used to define the
483: * <code>ModelElement</code> is retrieved from the
484: * <code>ContentModel</code>.
485: *
486: * @param obj
487: * The <code>ContentModel</code> from where the information
488: * used to define the <code>ModelElement</code> is retrieved.
489: */
490: public ModelElement(Object obj) {
491: if (obj == null) {
492: setValues(-1, -1);
493: } else {
494: if (obj instanceof Element) {
495: setValues(-2, ((Element) obj).index);
496: } else {
497: setValues(((ContentModel) obj).type, -1);
498: }
499: }
500: }
501:
502: /**
503: * Constructs a <code>ContentModel</code> using the information stored
504: * into a <code>ModelElement</code>. If the <code>ModelElement</code>
505: * denoted an <code>Element</code>, an <code>Element</code> with only
506: * its index and a suitable name will be returned.
507: *
508: * @param me
509: * The <code>ModelElement</code> from where the information to
510: * construct the <code>ContentModel</code> is retrieved.
511: * @return A <code>ContentModel</code> or <code>Element</code>
512: * initialized with the information
513: * stored in the <code>ModelElement<code> given as argument.
514: */
515: public static Object makeContent(ModelElement me) {
516: Object obj;
517: switch (me.getType()) {
518: case -1:
519: obj = null;
520: break;
521: case -2:
522: obj = new Element(me.getIndex(),
523: "ELEMENT " + me.getIndex(), false, false, null,
524: null, 1, null, null, null);
525: break;
526: default:
527: obj = new ContentModel();
528: ((ContentModel) obj).type = me.getType();
529: break;
530: }
531: return obj;
532: }
533: }
534:
535: /**
536: * It implements ASN.1 codification tools for the nodes that conforms the
537: * <code>ContentModel</code> tree representation.
538: * <p>
539: * The class can be used to obtain a byte array representing the codification of
540: * a <code>ModelElement</code>, as well as a <code>ModelElement</code> from
541: * a byte array (previously obtained codifying a <code>ModelElement</code>).
542: */
543: class Asn1ModelElement {
544:
545: /**
546: * It stores the definition of a <code>ModelElement</code> as an ASN.1
547: * valid type according to the ASN.1 framework.
548: */
549: private static ASN1Type ASN1_MODEL_ELEMENT;
550:
551: /**
552: * It returns an <code>ASN1Type</code> value that contains the ASN.1
553: * codification rules for a <code>ModelElement</code> with its encoder and
554: * decoder.
555: * <p>
556: * Among other things, this method can be used to declare the types of new
557: * fields in other structures, as for example, in an
558: * <code>Asn1ContentModel</code>.
559: *
560: * @return The value that defines an ASN.1 <code>ModelElement</code>
561: * representation with its encoder/decoder.
562: */
563: static ASN1Type getInstance() {
564: return ASN1_MODEL_ELEMENT;
565: }
566:
567: /**
568: * The definition of the ASN1_MODEL_ELEMENT type according to the rule
569: * defined for a <code>ModelElement</code>. It also defines a custom
570: * encoder/decoder for this type.
571: */
572: static {
573: ASN1_MODEL_ELEMENT = new ASN1Sequence(new ASN1Type[] {
574: ASN1Integer.getInstance(), // Type
575: ASN1Integer.getInstance() // Index
576: }) {
577:
578: /**
579: * Overrided method used to decodified the information that
580: * represents a <code>ModelElement</code>. It makes a completely
581: * new <code>ModelElement</code> with the information interpreted
582: * from the stream.
583: *
584: * @param in
585: * The <code>BerInputStream</code> where the
586: * codificated information will be read from.
587: * @return A <code>ModelElement</code> filled with the information
588: * read from the stream.
589: */
590: public Object getDecodedObject(BerInputStream in) {
591: Object values[] = (Object[]) in.content;
592:
593: int type = new BigInteger((byte[]) values[0])
594: .intValue();
595: int index = new BigInteger((byte[]) values[1])
596: .intValue();
597:
598: return new ModelElement(type, index);
599: }
600:
601: /**
602: * Overrided method used to codify the information stored in an
603: * <code>ModelElement</code> into an array of bytes, according to
604: * its ASN.1 specification.
605: *
606: * @param object
607: * The object where the information to be codified is
608: * stored. It actually consists of a
609: * <code>ModelElement</code>.
610: *
611: * @param values
612: * An array of objects where the model node's type and
613: * index information will be stored, ready for
614: * codification.
615: */
616: public void getValues(Object object, Object values[]) {
617: ModelElement me = (ModelElement) object;
618:
619: values[0] = BigInteger.valueOf(me.getType())
620: .toByteArray();
621: values[1] = BigInteger.valueOf(me.getIndex())
622: .toByteArray();
623: }
624: };
625: }
626: }
|