Frames | No Frames |
1: /* transformer.java -- Content model transforms. 2: Copyright (C) 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.javax.swing.text.html.parser.models; 40: 41: import java.io.Serializable; 42: 43: import javax.swing.text.html.parser.ContentModel; 44: import javax.swing.text.html.parser.DTD; 45: 46: /** 47: * Transforms the standard ContentModel tree into the internal representation, 48: * used in this implementation. 49: * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 50: */ 51: public class transformer 52: implements Serializable 53: { 54: private static final long serialVersionUID = 1; 55: 56: /** 57: * All binary operators. 58: */ 59: protected static String binary = "&|,"; 60: 61: /** 62: * All unary operators. 63: */ 64: protected static String unary = "+*?"; 65: 66: /** 67: * Measure length of the linked list of the content models. 68: * @param c The heading element of the linked list. 69: * @return the length of the list (0 for null 1 if c!=null and c.next==null, 70: * etc. 71: */ 72: public static int measureChainLength(ContentModel c) 73: { 74: if (c == null) 75: return 0; 76: else 77: return measureChainLength(c.next) + 1; 78: } 79: 80: /** 81: * Transform into internal representation without usind dtd. 82: * This should be used only for testing. 83: */ 84: public static node transform(ContentModel c) 85: { 86: return transform(c, null); 87: } 88: 89: /** 90: * Transform into internal representation. 91: * @param c a model to transform 92: * @return a transformed model 93: * @throws Error if the model structure contains errors. 94: */ 95: public static node transform(ContentModel c, DTD dtd) 96: { 97: // Handle the special cases first. 98: if (c.content instanceof node) 99: return (node) c.content; 100: 101: // Do the typical transform. 102: node n; 103: 104: /* Case with the single token */ 105: if (c.next == null) 106: { 107: n = optionalTransform(c, dtd); 108: } 109: else /* Case with the chain of the multiple tokens. */ 110: { 111: node[] l = new node[ measureChainLength(c) ]; 112: ContentModel m = c; 113: for (int i = 0; i < l.length; i++) 114: { 115: if (m.content instanceof ContentModel) 116: { 117: ContentModel nested = (ContentModel) m.content; 118: if (nested.next == null && 119: !(nested.content instanceof ContentModel) 120: ) 121: { 122: l [ i ] = 123: new node((char) m.type, (char) nested.type, nested.content); 124: } 125: else 126: { 127: l [ i ] = transform(nested, dtd); 128: } 129: } 130: else 131: l [ i ] = new node((char) 0, (char) 0, m.content); 132: addtype(l [ i ], (char) m.type); 133: m = m.next; 134: } 135: 136: if (isBinary(c.type)) 137: for (int i = 0; i < l.length; i++) 138: { 139: l [ i ].binary = (char) c.type; 140: } 141: 142: n = new list(l); 143: } 144: 145: addtype(n, (char) c.type); 146: 147: return n; 148: } 149: 150: /** 151: * True for binary operator 152: * @param c a character to test 153: * @return true for [ ,&| ], false otherwise. 154: */ 155: private static boolean isBinary(int c) 156: { 157: return binary.indexOf((char) c) >= 0; 158: } 159: 160: /** 161: * True for unary operator. 162: * @param c a character to test 163: * @return true for [ +?* ], false otherwise. 164: */ 165: private static boolean isUnary(int c) 166: { 167: return unary.indexOf((char) c) >= 0; 168: } 169: 170: /** 171: * Assign an operation type for the given node. 172: * @param n A node to set the operation to. 173: * @param type Either binary or unary operation, is assigned to the 174: * corresponding field of the node. 175: * @throws error if the operation type is not 176: * representing a valid unary or binary operation. 177: */ 178: private static void addtype(node n, char type) 179: { 180: if (isBinary(type)) 181: n.binary = type; 182: 183: else if (isUnary(type)) 184: n.unary = type; 185: 186: else if (type != 0) 187: throw new Error("Invalid operation '" + (char) type + "'"); 188: } 189: 190: private static node optionalTransform(ContentModel c, DTD dtd) 191: { 192: node n; 193: if (c.content instanceof ContentModel) 194: n = transform((ContentModel) c.content, dtd); 195: else 196: 197: /* A single token with the specified operation */ 198: n = new node((char) 0, (char) 0, c.content); 199: return n; 200: } 201: }