1 4 package gnu.kawa.xml; 5 import gnu.bytecode.*; 6 import gnu.lists.*; 7 import gnu.xml.*; 8 import gnu.expr.*; 9 import java.io.*; 10 import gnu.mapping.*; 11 12 public class ElementType extends NodeType 13 implements TypeValue, Externalizable, GroupPredicate 14 { 15 public static final String MATCH_ANY_LOCALNAME = ""; 16 public static final Symbol MATCH_ANY_QNAME 17 = new Symbol(null, MATCH_ANY_LOCALNAME); 18 19 Symbol qname; 20 21 public static final ElementType anyElement = make(null, null); 22 23 27 public static ElementType make (String namespaceURI, String localName) 28 { 29 Symbol qname; 30 if (namespaceURI != null) 31 qname = Symbol.make(namespaceURI, localName); 32 else if (localName == MATCH_ANY_LOCALNAME) 33 qname = MATCH_ANY_QNAME; 34 else 35 qname = new Symbol(null, localName); 36 return new ElementType(qname); 37 } 38 39 public static ElementType make (Symbol qname) 40 { 41 return new ElementType(qname); 42 } 43 44 public ElementType(Symbol qname) 45 { 46 this(null, qname); 47 } 48 49 public ElementType(String name, Symbol qname) 50 { 51 super(name != null && name.length() > 0 ? name 52 : "ELEMENT "+qname+" (*)"); 53 this.qname = qname; 54 } 55 56 public Type getImplementationType() 57 { 58 return ClassType.make("gnu.kawa.xml.KElement"); 59 } 60 61 public final String getNamespaceURI () { return qname.getNamespaceURI(); } 62 public final String getLocalName () { return qname.getLocalName(); } 63 64 public void emitCoerceFromObject (CodeAttr code) 65 { 66 code.emitPushString(qname.getNamespaceURI()); 67 code.emitPushString(qname.getLocalName()); 68 code.emitInvokeStatic(coerceMethod); 69 } 70 71 public Object coerceFromObject (Object obj) 72 { 73 return coerce(obj, qname.getNamespaceURI(), qname.getLocalName()); 74 } 75 76 public boolean isInstancePos (AbstractSequence seq, int ipos) 77 { 78 int kind = seq.getNextKind(ipos); 79 if (kind == Sequence.GROUP_VALUE) 80 return isInstance(seq, ipos, seq.getNextTypeObject(ipos)); 81 if (kind == Sequence.OBJECT_VALUE) 82 return isInstance(seq.getPosNext(ipos)); 83 return false; 84 } 85 86 public boolean isInstance(AbstractSequence seq, int ipos, Object groupType) 87 { 88 String namespaceURI = qname.getNamespaceURI(); 89 String localName = qname.getLocalName(); 90 String curNamespaceURI; 91 String curLocalName; 92 if (groupType instanceof Symbol) 93 { 94 Symbol qname = (Symbol) groupType; 95 curNamespaceURI = qname.getNamespaceURI(); 96 curLocalName = qname.getLocalName(); 97 } 98 99 107 else 108 { 109 curNamespaceURI = ""; 110 curLocalName = groupType.toString().intern(); } 112 if (localName != null && localName.length() == 0) 113 localName = null; 114 return ((localName == curLocalName || localName == null) 115 && (namespaceURI == curNamespaceURI || namespaceURI == null)); 116 } 117 118 public boolean isInstance (Object obj) 119 { 120 return coerceOrNull(obj, qname.getNamespaceURI(),qname.getLocalName()) 121 != null; 122 } 123 124 public static KElement coerceOrNull (Object obj, 125 String namespaceURI, String localName) 126 { 127 KElement pos = (KElement) NodeType.coerceOrNull(obj, GROUP_OK); 128 if (pos == null) 129 return null; 130 if (localName != null && localName.length() == 0) 131 localName = null; 132 Object curName = pos.getNextTypeObject(); 135 String curNamespaceURI; 136 String curLocalName; 137 if (curName instanceof Symbol) 138 { 139 Symbol qname = (Symbol) curName; 140 curNamespaceURI = qname.getNamespaceURI(); 141 curLocalName = qname.getLocalName(); 142 } 143 144 152 else 153 { 154 curNamespaceURI = ""; 155 curLocalName = curName.toString().intern(); } 157 if ((localName == curLocalName || localName == null) 158 && (namespaceURI == curNamespaceURI || namespaceURI == null)) 159 return pos; 160 return null; 161 } 162 163 public static KElement coerce (Object obj, 164 String namespaceURI, String localName) 165 { 166 KElement pos = coerceOrNull(obj, namespaceURI, localName); 167 if (pos == null) 168 throw new ClassCastException (); 169 return pos; 170 } 171 172 protected void emitCoerceOrNullMethod(Variable incoming, Compilation comp) 173 { 174 CodeAttr code = comp.getCode(); 175 if (incoming != null) 176 code.emitLoad(incoming); 177 code.emitPushString(qname.getNamespaceURI()); 178 code.emitPushString(qname.getLocalName()); 179 code.emitInvokeStatic(coerceOrNullMethod); 180 } 181 182 NamespaceBinding namespaceNodes; 183 public NamespaceBinding getNamespaceNodes () 184 { 185 return namespaceNodes; 186 } 187 188 public void setNamespaceNodes (NamespaceBinding bindings) 189 { 190 namespaceNodes = bindings; 191 } 192 193 public Procedure getConstructor () 194 { 195 gnu.kawa.xml.MakeElement element = new gnu.kawa.xml.MakeElement(); 196 element.tag = qname; 197 element.setHandlingKeywordParameters(true); 198 if (namespaceNodes != null) 199 element.setNamespaceNodes(namespaceNodes); 200 return element; 201 } 202 203 public static final ClassType typeElementType 204 = ClassType.make("gnu.kawa.xml.ElementType"); 205 static final Method coerceMethod 206 = typeElementType.getDeclaredMethod("coerce", 3); 207 static final Method coerceOrNullMethod 208 = typeElementType.getDeclaredMethod("coerceOrNull", 3); 209 210 public void writeExternal(ObjectOutput out) throws IOException 211 { 212 String name = getName(); 213 out.writeUTF(name == null ? "" : name); 214 out.writeObject(qname); 215 } 216 217 public void readExternal(ObjectInput in) 218 throws IOException, ClassNotFoundException 219 { 220 String name = in.readUTF(); 221 if (name.length() > 0) 222 setName(name); 223 qname = (Symbol) in.readObject(); 224 } 225 226 public String toString () 227 { 228 return "ElementType " + qname; 229 } 230 } 231 | Popular Tags |