001: // Copyright (c) 2001, 2002, 2003, 2006 Per M.A. Bothner and Brainfood Inc.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.kawa.xml;
005:
006: import gnu.bytecode.*;
007: import gnu.lists.*;
008: import gnu.xml.*;
009: import gnu.expr.*;
010: import java.io.*;
011: import gnu.mapping.Symbol;
012:
013: public class ProcessingInstructionType extends NodeType implements
014: TypeValue, Externalizable {
015: String target;
016:
017: public static final ProcessingInstructionType piNodeTest = new ProcessingInstructionType(
018: null);
019:
020: public ProcessingInstructionType(String target) {
021: super (target == null ? "processing-instruction()"
022: : "processing-instruction(" + target + ")");
023: this .target = target;
024: }
025:
026: public static ProcessingInstructionType getInstance(String target) {
027: return target == null ? piNodeTest
028: : new ProcessingInstructionType(target);
029: }
030:
031: public Type getImplementationType() {
032: return ClassType.make("gnu.kawa.xml.KProcessingInstruction");
033:
034: }
035:
036: public void emitCoerceFromObject(CodeAttr code) {
037: code.emitPushString(target);
038: code.emitInvokeStatic(coerceMethod);
039: }
040:
041: public Object coerceFromObject(Object obj) {
042: return coerce(obj, target);
043: }
044:
045: public boolean isInstancePos(AbstractSequence seq, int ipos) {
046: int kind = seq.getNextKind(ipos);
047: if (kind == Sequence.PROCESSING_INSTRUCTION_VALUE)
048: return target == null
049: || target.equals(seq.getNextTypeObject(ipos));
050: if (kind == Sequence.OBJECT_VALUE)
051: return isInstance(seq.getPosNext(ipos));
052: return false;
053: }
054:
055: public boolean isInstance(Object obj) {
056: return coerceOrNull(obj, target) != null;
057: }
058:
059: public static KProcessingInstruction coerceOrNull(Object obj,
060: String target) {
061: KProcessingInstruction pos = (KProcessingInstruction) NodeType
062: .coerceOrNull(obj, PI_OK);
063: return pos != null
064: && (target == null || target.equals(pos.getTarget())) ? pos
065: : null;
066: }
067:
068: public static KProcessingInstruction coerce(Object obj,
069: String target) {
070: KProcessingInstruction pos = coerceOrNull(obj, target);
071: if (pos == null)
072: throw new ClassCastException();
073: return pos;
074: }
075:
076: protected void emitCoerceOrNullMethod(Variable incoming,
077: Compilation comp) {
078: CodeAttr code = comp.getCode();
079: if (incoming != null)
080: code.emitLoad(incoming);
081: code.emitPushString(target);
082: code.emitInvokeStatic(coerceOrNullMethod);
083: }
084:
085: public static final ClassType typeProcessingInstructionType = ClassType
086: .make("gnu.kawa.xml.ProcessingInstructionType");
087: static final Method coerceMethod = typeProcessingInstructionType
088: .getDeclaredMethod("coerce", 2);
089: static final Method coerceOrNullMethod = typeProcessingInstructionType
090: .getDeclaredMethod("coerceOrNull", 2);
091:
092: public void writeExternal(ObjectOutput out) throws IOException {
093: out.writeObject(target);
094: }
095:
096: public void readExternal(ObjectInput in) throws IOException,
097: ClassNotFoundException {
098: target = (String) in.readObject();
099: }
100:
101: public String toString() {
102: return "ProcessingInstructionType "
103: + (target == null ? "*" : target);
104: }
105: }
|