1 4 package gnu.xquery.lang; 5 import gnu.mapping.*; 6 import gnu.lists.*; 7 import gnu.expr.*; 8 import gnu.text.Char; 9 import kawa.standard.Scheme; 10 import gnu.bytecode.*; 11 import gnu.kawa.lispexpr.LangPrimType; 12 import gnu.xquery.util.*; 13 import gnu.xml.*; 14 import gnu.text.Lexer; 15 import gnu.text.SourceMessages; 16 import java.io.Reader ; 17 import java.util.Vector ; 18 import gnu.kawa.functions.ConstantFunction0; 19 import gnu.kawa.reflect.ClassMethods; 20 import gnu.math.IntNum; 21 import gnu.kawa.xml.*; 22 23 24 25 public class XQuery extends Language 26 { 27 public static final String XQUERY_FUNCTION_NAMESPACE 28 = "http://www.w3.org/2005/xpath-functions"; 29 public static final String KAWA_FUNCTION_NAMESPACE 30 = "http://kawa.gnu.org/"; 31 public static final String QEXO_FUNCTION_NAMESPACE 32 = "http://qexo.gnu.org/"; 33 public static final String LOCAL_NAMESPACE 34 = "http://www.w3.org/2005/xquery-local-functions"; 35 public static final String SCHEMA_NAMESPACE 36 = "http://www.w3.org/2001/XMLSchema"; 37 public static final String SCHEMA_INSTANCE_NAMESPACE 38 = "http://www.w3.org/2001/XMLSchema-instance"; 39 public static final String XHTML_NAMESPACE 40 = "http://www.w3.org/1999/xhtml"; 41 public static final Namespace xqueryFunctionNamespace 42 = Namespace.getInstance(XQUERY_FUNCTION_NAMESPACE); 43 public static final Namespace kawaFunctionNamespace 44 = Namespace.getInstance(KAWA_FUNCTION_NAMESPACE); 45 public static final Namespace qexoFunctionNamespace 46 = Namespace.getInstance(QEXO_FUNCTION_NAMESPACE); 47 public static final Namespace[] defaultFunctionNamespacePath 48 = { qexoFunctionNamespace, 49 xqueryFunctionNamespace, 50 Namespace.EmptyNamespace, 51 kawaFunctionNamespace }; 52 static boolean charIsInt = false; 53 54 55 public static final String DEFAULT_ELEMENT_PREFIX = null; 56 57 public static final String DEFAULT_FUNCTION_PREFIX = "(functions)"; 58 59 Namespace defaultNamespace; 60 61 public boolean hasSeparateFunctionNamespace() 62 { 63 return true; 64 } 65 66 public static gnu.math.Numeric asNumber(Object arg) 67 { 68 if (arg instanceof Char) 69 return gnu.math.IntNum.make(((Char) arg).intValue()); 70 return (gnu.math.Numeric) arg; 71 } 72 73 public static char asChar(Object x) 74 { 75 if (x instanceof Char) 76 return ((Char) x).charValue(); 77 int i; 78 if (x instanceof gnu.math.Numeric) 79 i = ((gnu.math.Numeric) x).intValue(); 80 else 81 i = -1; 82 if (i < 0 || i > 0xffff) 83 throw new ClassCastException ("not a character value"); 84 return (char) i; 85 } 86 87 public boolean isTrue(Object value) 88 { 89 return gnu.xquery.util.BooleanValue.booleanValue(value); 90 } 91 92 public gnu.text.Lexer getLexer(InPort inp, SourceMessages messages) 93 { 94 return new XQParser(inp, messages, this); 95 } 96 97 public Compilation getCompilation (Lexer lexer, SourceMessages messages) 98 { 99 return new Compilation(this, messages, ((XQParser) lexer).lexical); 100 } 101 102 103 public static final int PARSE_WITH_FOCUS = 0x10000; 104 105 public boolean parse (Compilation tr, int options) 106 throws java.io.IOException , gnu.text.SyntaxException 107 { 108 ModuleExp mexp = tr.mainLambda; 109 Compilation.defaultCallConvention = Compilation.CALL_WITH_CONSUMER; 110 tr.mustCompileHere(); 111 XQParser parser = (XQParser) tr.lexer; 112 if (parser.isInteractive()) 113 { 114 Expression sexp = parser.parse(tr); 115 if (sexp == null) 116 return false; 117 mexp.body = sexp; 118 } 119 else if ((options & PARSE_WITH_FOCUS) != 0) 120 { 121 LambdaExp lexp = new LambdaExp(3); 122 Declaration dotDecl = lexp.addDeclaration(XQParser.DOT_VARNAME); 123 dotDecl.setFlag(Declaration.IS_SINGLE_VALUE); 124 dotDecl.noteValue (null); lexp.addDeclaration(XQParser.POSITION_VARNAME, Type.int_type); 126 lexp.addDeclaration(XQParser.LAST_VARNAME, Type.int_type); 127 tr.push(lexp); 128 lexp.body = parser.parse(tr); 129 tr.pop(lexp); 130 mexp.body = lexp; 131 } 132 else 133 { 134 Vector exps = new Vector (10); 135 Expression sexp = mexp.body; 136 if (sexp instanceof BeginExp) 137 { 138 BeginExp bexp = (BeginExp) sexp; 139 int blen = bexp.getExpressionCount(); 140 Expression[] bexps = bexp.getExpressions(); 141 for (int i = 0; i < blen; i++) 142 exps.addElement(bexps[i]); 143 } 144 else if (sexp != null && sexp != QuoteExp.voidExp) 145 { 146 exps.addElement(sexp); 147 } 148 for (;;) 149 { 150 sexp = parser.parse(tr); 151 if (sexp == null) 152 { 153 if (parser.parseCount == 0 && !parser.isInteractive()) 154 { 155 parser.error('e', "empty module", "XPST0003"); 156 return false; 157 } 158 break; 159 } 160 exps.addElement(sexp); 161 } 162 int nexps = exps.size(); 163 if (nexps == 0) 164 mexp.body = QuoteExp.voidExp; 165 else if (nexps == 1) 166 mexp.body = (Expression) exps.elementAt(0); 167 else 168 { 169 Expression[] arr = new Expression[nexps]; 170 exps.copyInto(arr); 171 mexp.body = new BeginExp(arr); 172 } 173 } 174 tr.pop(mexp); 178 179 if (false) 180 { 181 OutPort dout = OutPort.outDefault(); 182 dout.println ("[Before name-resolving \""+mexp.getName()+"\":"); 183 mexp.print(dout); 184 dout.println(']'); 185 dout.flush(); 186 } 187 188 XQResolveNames resolver = new XQResolveNames(tr); 189 resolver.functionNamespacePath = parser.functionNamespacePath; 190 resolver.parser = parser; 191 resolver.resolveModule(mexp); tr.setState(Compilation.BODY_PARSED); 193 return true; 194 } 195 196 public void resolve (Compilation comp) 197 { 198 } 199 200 public static int namespaceForFunctions (int argCount) 201 { 202 return (argCount << 2) | FUNCTION_NAMESPACE; 203 } 204 205 public static final int VARIADIC_FUNCTION_NAMESPACE = 206 (-1 << 2) | FUNCTION_NAMESPACE; 207 208 public int getNamespaceOf(Declaration decl) 209 { 210 if (decl.isProcedureDecl()) 211 { 212 if (decl.getCode() < 0) 213 return VARIADIC_FUNCTION_NAMESPACE; 214 Expression value = decl.getValue(); 215 if (value instanceof LambdaExp) 216 { 217 LambdaExp lexp = (LambdaExp) value; 218 if (lexp.min_args == lexp.max_args) 219 return namespaceForFunctions(lexp.min_args); 220 } 221 else if (value instanceof QuoteExp) 222 { 223 Object val = ((QuoteExp) value).getValue(); 224 if (val instanceof Procedure) 225 { 226 Procedure proc = (Procedure) val; 227 int min = proc.minArgs(); 228 int max = proc.maxArgs(); 229 if (min == max) 230 return namespaceForFunctions(min); 231 } 232 } 233 else if (value instanceof ReferenceExp) 234 return getNamespaceOf(((ReferenceExp) value).getBinding()); 235 return VARIADIC_FUNCTION_NAMESPACE; 237 } 238 return VALUE_NAMESPACE; 239 } 240 241 public boolean hasNamespace (Declaration decl, int namespace) 242 { 243 int dnspace = getNamespaceOf(decl); 244 return (dnspace == namespace 245 || (dnspace == VARIADIC_FUNCTION_NAMESPACE 246 && (namespace & FUNCTION_NAMESPACE) != 0) 247 || (namespace == VARIADIC_FUNCTION_NAMESPACE 248 && (dnspace & FUNCTION_NAMESPACE) != 0)); 249 } 250 251 public Symbol getSymbol (String name) 252 { 253 return Symbol.make(defaultNamespace, name); 254 } 255 256 public void define(String name, Object value) 257 { 258 Symbol sym = Symbol.make(defaultNamespace, name); 259 Object prop = value instanceof Procedure ? EnvironmentKey.FUNCTION : null; 260 environ.define(sym, prop, value); 261 } 262 263 protected void define_method(String name, String cname, String mname) 264 { 265 Symbol sym = Symbol.make(defaultNamespace, name); 266 ClassType ctype = ClassType.make(cname); 269 Procedure proc = ClassMethods.apply(ctype, mname, '\0', this); 270 proc.setSymbol(sym); 271 environ.define(sym, EnvironmentKey.FUNCTION, proc); 272 } 273 274 public String getName() 275 { 276 return "XQuery"; 277 } 278 279 static int envCounter = 0; 280 281 282 public static Environment extensionsEnvEnv 283 = Environment.getInstance(KAWA_FUNCTION_NAMESPACE); 284 285 293 public void applyWithFocus (Procedure proc, 294 Object item, int position, int size, 295 Consumer out) 296 throws Throwable 297 { 298 CallContext ctx = CallContext.getInstance(); 299 proc.check3(item, IntNum.make(position),IntNum.make(size), ctx); 300 Consumer save = ctx.consumer; 301 try 302 { 303 ctx.consumer = out; 304 ctx.runUntilDone(); 305 } 306 finally 307 { 308 ctx.consumer = save; 309 } 310 } 311 312 320 public Object applyWithFocus (Procedure proc, 321 Object item, int position, int size) 322 throws Throwable 323 { 324 CallContext ctx = CallContext.getInstance(); 325 int oldIndex = ctx.startFromContext(); 326 try 327 { 328 proc.check3(item, IntNum.make(position),IntNum.make(size), ctx); 329 return ctx.getFromContext(oldIndex); 330 } 331 catch (Throwable ex) 332 { 333 ctx.cleanupFromContext(oldIndex); 334 throw ex; 335 } 336 } 337 338 346 public void applyWithFocus (Procedure proc, Object values, Consumer out) 347 throws Throwable 348 { 349 CallContext ctx = CallContext.getInstance(); 350 Consumer save = ctx.consumer; 351 try 352 { 353 ctx.consumer = out; 354 applyWithFocus$X(proc, values, ctx); 355 } 356 finally 357 { 358 ctx.consumer = save; 359 } 360 } 361 362 370 public Object applyWithFocus (Procedure proc, Object values) 371 throws Throwable 372 { 373 CallContext ctx = CallContext.getInstance(); 374 int oldIndex = ctx.startFromContext(); 375 try 376 { 377 applyWithFocus$X(proc, values, ctx); 378 return ctx.getFromContext(oldIndex); 379 } 380 catch (Throwable ex) 381 { 382 ctx.cleanupFromContext(oldIndex); 383 throw ex; 384 } 385 } 386 387 397 public void applyWithFocus$X (Procedure proc, Object values, CallContext ctx) 398 throws Throwable 399 { 400 if (values instanceof Values) 401 { 402 Values v = (Values) values; 403 int count = v.size(); 404 if (count == 0) 405 return; 406 int ipos = 0; 407 IntNum size = IntNum.make(count); 408 for (int i = 1; ; i++) 409 { 410 proc.check3(v.getPosNext(ipos), IntNum.make(i), size, ctx); 411 ctx.runUntilDone(); 412 if (i == count) 413 break; 414 ipos = v.nextPos(ipos); 415 } 416 } 417 else 418 { 419 IntNum one = IntNum.one(); 420 proc.check3(values, one, one, ctx); 421 ctx.runUntilDone(); 422 } 423 } 424 425 431 public Procedure evalToFocusProc (String expr) 432 throws Throwable 433 { 434 SourceMessages messages = new SourceMessages(); 435 Procedure proc = evalToFocusProc(new CharArrayInPort(expr), messages); 436 if (messages.seenErrors()) 437 throw new RuntimeException ("invalid syntax in eval form:\n" 438 + messages.toString(20)); 439 return proc; 440 } 441 442 449 public Procedure evalToFocusProc (Reader in, SourceMessages messages) 450 throws Throwable 451 { 452 InPort port = in instanceof InPort ? (InPort) in : new InPort(in); 453 Compilation comp = parse(port, messages, PARSE_WITH_FOCUS|PARSE_IMMEDIATE); 454 CallContext ctx = CallContext.getInstance(); 455 int oldIndex = ctx.startFromContext(); 456 try 457 { 458 ModuleExp.evalModule(Environment.getCurrent(), ctx, comp, null, null); 459 return (Procedure) ctx.getFromContext(oldIndex); 460 } 461 catch (Throwable ex) 462 { 463 ctx.cleanupFromContext(oldIndex); 464 throw ex; 465 } 466 } 467 468 475 public void evalWithFocus (Reader in, SourceMessages messages, 476 Object values, Consumer out) 477 throws Throwable 478 { 479 applyWithFocus(evalToFocusProc(in, messages), values, out); 480 } 481 482 488 public Object evalWithFocus (String expr, Object values) 489 throws Throwable 490 { 491 return applyWithFocus(evalToFocusProc(expr), values); 492 } 493 494 501 public Object evalWithFocus (String expr, 502 Object item, int position, int size) 503 throws Throwable 504 { 505 return applyWithFocus(evalToFocusProc(expr), item, position, size); 506 } 507 508 516 public void evalWithFocus (Reader in, SourceMessages messages, 517 Object item, int position, int size, 518 Consumer out) 519 throws Throwable 520 { 521 applyWithFocus(evalToFocusProc(in, messages), item, position, size, out); 522 } 523 524 530 public void eval_with_focus$X (String expr, 531 Object values, 532 CallContext ctx) 533 throws Throwable 534 { 535 applyWithFocus$X(evalToFocusProc(expr), values, ctx); 536 } 537 538 544 public void eval_with_focus$X (String expr, 545 Object item, int position, int size, 546 CallContext ctx) 547 throws Throwable 548 { 549 Procedure proc = evalToFocusProc(expr); 550 proc.check3(item, IntNum.make(position), IntNum.make(size), ctx); 551 } 552 553 public static final Environment xqEnvironment 554 = Environment.make(XQUERY_FUNCTION_NAMESPACE); 555 556 public static final XQuery instance = new XQuery(); 559 static { instance.initXQuery(); } 560 561 public XQuery() 562 { 563 environ = xqEnvironment; 564 defaultNamespace = xqueryFunctionNamespace; 565 } 566 567 private void initXQuery () 568 { 569 ModuleBody.setMainPrintValues(true); 570 571 604 605 defProcStFld("unescaped-data", "gnu.kawa.xml.MakeUnescapedData", "unescapedData"); 606 defProcStFld("item-at", "gnu.xquery.util.ItemAt", "itemAt"); 607 defProcStFld("count", "gnu.kawa.functions.CountValues", "countValues"); 608 define_method("sum", "gnu.xquery.util.Reduce", "sum"); defProcStFld("avg", "gnu.xquery.util.Average", "avg"); 610 defProcStFld("sublist", "gnu.xquery.util.SubList", "subList"); defProcStFld("subsequence", "gnu.xquery.util.SubList", "subList"); 612 define_method("empty", "gnu.xquery.util.SequenceUtils", 613 "isEmptySequence"); 614 define_method("exists", "gnu.xquery.util.SequenceUtils", 615 "exists"); 616 define_method("insert-before", "gnu.xquery.util.SequenceUtils", 617 "insertBefore$X"); 618 define_method("remove", "gnu.xquery.util.SequenceUtils", 619 "remove$X"); 620 define_method("reverse", "gnu.xquery.util.SequenceUtils", 621 "reverse$X"); 622 defProcStFld("false", "gnu.xquery.lang.XQuery", "falseFunction"); 623 defProcStFld("true", "gnu.xquery.lang.XQuery", "trueFunction"); 624 defProcStFld("boolean", "gnu.xquery.util.BooleanValue", "booleanValue"); 625 626 define_method("trace", "gnu.xquery.util.Debug", "trace"); 627 define_method("error", "gnu.xquery.util.XQException", 628 "error"); defProcStFld("write-to", "gnu.kawa.xml.WriteTo", "writeTo"); 630 defProcStFld("write-to-if-changed", "gnu.kawa.xml.WriteTo", 631 "writeToIfChanged"); 632 defProcStFld("iterator-items", 633 "gnu.kawa.xml.IteratorItems", "iteratorItems"); 634 defProcStFld("list-items", "gnu.kawa.xml.ListItems", "listItems"); 635 define_method("node-name", "gnu.kawa.xml.NodeName", "nodeName"); 636 define_method("nilled", "gnu.xquery.util.NodeUtils", "nilled"); 637 define_method("data", "gnu.xquery.util.NodeUtils", "data$X"); 638 define_method("lower-case", "gnu.xquery.util.StringUtils", "lowerCase"); 639 define_method("upper-case", "gnu.xquery.util.StringUtils", "upperCase"); 640 define_method("substring", "gnu.xquery.util.StringUtils", "substring"); 641 define_method("string-length", 642 "gnu.xquery.util.StringUtils", "stringLength"); 643 define_method("substring-before", 644 "gnu.xquery.util.StringUtils", "substringBefore"); 645 define_method("substring-after", 646 "gnu.xquery.util.StringUtils", "substringAfter"); 647 define_method("translate", "gnu.xquery.util.StringUtils", "translate"); 648 define_method("encode-for-uri", "gnu.xquery.util.StringUtils", 649 "encodeForUri"); 650 define_method("iri-to-uri", "gnu.xquery.util.StringUtils", "iriToUri"); 651 define_method("escape-html-uri", "gnu.xquery.util.StringUtils", 652 "escapeHtmlUri"); 653 define_method("contains", "gnu.xquery.util.StringUtils", "contains"); 656 define_method("starts-with", "gnu.xquery.util.StringUtils", "startsWith"); 657 define_method("ends-with","gnu.xquery.util.StringUtils", "endsWith"); 658 define_method("codepoint-equal", "gnu.xquery.util.StringUtils", 659 "codepointEqual"); 660 define_method("normalize-unicode", "gnu.xquery.util.StringUtils", 661 "normalizeUnicode"); 662 define_method("string-join", "gnu.xquery.util.StringUtils", "stringJoin"); 663 define_method("concat", "gnu.xquery.util.StringUtils", "concat$V"); 664 define_method("matches", "gnu.xquery.util.StringUtils", "matches"); 665 define_method("replace", "gnu.xquery.util.StringUtils", "replace"); 666 define_method("tokenize", "gnu.xquery.util.StringUtils", "tokenize$X"); 667 define_method("string-to-codepoints", "gnu.xquery.util.StringUtils", 668 "stringToCodepoints$X"); 669 define_method("codepoints-to-string", "gnu.xquery.util.StringUtils", 670 "codepointsToString"); 671 672 define_method("abs", "gnu.xquery.util.NumberValue", "abs"); 673 define_method("floor", "gnu.xquery.util.NumberValue", "floor"); 674 define_method("ceiling", "gnu.xquery.util.NumberValue", "ceiling"); 675 define_method("round", "gnu.xquery.util.NumberValue", "round"); 676 define_method("round-half-to-even", "gnu.xquery.util.NumberValue", 677 "roundHalfToEven"); 678 679 define_method("QName", "gnu.xquery.util.QNameUtils", "makeQName"); 680 define_method("resolve-QName", "gnu.xquery.util.QNameUtils", 681 "resolveQNameUsingElement"); 682 define_method("prefix-from-QName", "gnu.xquery.util.QNameUtils", 683 "prefixFromQName"); 684 define_method("local-name-from-QName", "gnu.xquery.util.QNameUtils", 685 "localNameFromQName"); 686 define_method("namespace-uri-from-QName", "gnu.xquery.util.QNameUtils", 687 "namespaceURIFromQName"); 688 define_method("namespace-uri-for-prefix", "gnu.xquery.util.QNameUtils", 689 "namespaceURIForPrefix"); 690 define_method("in-scope-prefixes", "gnu.xquery.util.NodeUtils", 691 "inScopePrefixes$X"); 692 define_method("document-uri", "gnu.xquery.util.NodeUtils", "documentUri"); 693 694 define_method("years-from-duration", "gnu.xquery.util.TimeUtils", 695 "yearsFromDuration"); 696 define_method("months-from-duration", "gnu.xquery.util.TimeUtils", 697 "monthsFromDuration"); 698 define_method("days-from-duration", "gnu.xquery.util.TimeUtils", 699 "daysFromDuration"); 700 define_method("hours-from-duration", "gnu.xquery.util.TimeUtils", 701 "hoursFromDuration"); 702 define_method("minutes-from-duration", "gnu.xquery.util.TimeUtils", 703 "minutesFromDuration"); 704 define_method("seconds-from-duration", "gnu.xquery.util.TimeUtils", 705 "secondsFromDuration"); 706 define_method("year-from-dateTime", "gnu.xquery.util.TimeUtils", 707 "yearFromDateTime"); 708 define_method("month-from-dateTime", "gnu.xquery.util.TimeUtils", 709 "monthFromDateTime"); 710 define_method("day-from-dateTime", "gnu.xquery.util.TimeUtils", 711 "dayFromDateTime"); 712 define_method("hours-from-dateTime", "gnu.xquery.util.TimeUtils", 713 "hoursFromDateTime"); 714 define_method("minutes-from-dateTime", "gnu.xquery.util.TimeUtils", 715 "minutesFromDateTime"); 716 define_method("seconds-from-dateTime", "gnu.xquery.util.TimeUtils", 717 "secondsFromDateTime"); 718 define_method("timezone-from-dateTime", "gnu.xquery.util.TimeUtils", 719 "timezoneFromDateTime"); 720 define_method("year-from-date", "gnu.xquery.util.TimeUtils", 721 "yearFromDate"); 722 define_method("month-from-date", "gnu.xquery.util.TimeUtils", 723 "monthFromDate"); 724 define_method("day-from-date", "gnu.xquery.util.TimeUtils", 725 "dayFromDate"); 726 define_method("timezone-from-date", "gnu.xquery.util.TimeUtils", 727 "timezoneFromDate"); 728 define_method("hours-from-time", "gnu.xquery.util.TimeUtils", 729 "hoursFromTime"); 730 define_method("minutes-from-time", "gnu.xquery.util.TimeUtils", 731 "minutesFromTime"); 732 define_method("seconds-from-time", "gnu.xquery.util.TimeUtils", 733 "secondsFromTime"); 734 define_method("timezone-from-time", "gnu.xquery.util.TimeUtils", 735 "timezoneFromTime"); 736 define_method("adjust-dateTime-to-timezone", "gnu.xquery.util.TimeUtils", 737 "adjustDateTimeToTimezone"); define_method("adjust-date-to-timezone", "gnu.xquery.util.TimeUtils", 739 "adjustDateToTimezone"); define_method("adjust-time-to-timezone", "gnu.xquery.util.TimeUtils", 741 "adjustTimeToTimezone"); define_method("dateTime", "gnu.xquery.util.TimeUtils", "dateTime"); 743 744 define_method("zero-or-one", "gnu.xquery.util.SequenceUtils", "zeroOrOne"); 745 define_method("one-or-more", "gnu.xquery.util.SequenceUtils", "oneOrMore"); 746 define_method("exactly-one", "gnu.xquery.util.SequenceUtils", "exactlyOne"); 747 748 defProcStFld("distinct-nodes", "gnu.kawa.xml.SortNodes", "sortNodes"); 749 750 defProcStFld("children", "gnu.kawa.xml.Children", "children"); 752 define_method("not", "gnu.xquery.util.BooleanValue", "not"); 753 754 defaultNamespace = qexoFunctionNamespace; 755 defProcStFld("response-header", "gnu.kawa.servlet.HTTP"); 756 defProcStFld("response-content-type", "gnu.kawa.servlet.HTTP"); 757 defProcStFld("response-status", "gnu.kawa.servlet.HTTP"); 758 defProcStFld("error-response", "gnu.kawa.servlet.HTTP"); 759 defProcStFld("current-servlet", "gnu.kawa.servlet.HTTP"); 760 defProcStFld("current-servlet-context", "gnu.kawa.servlet.HTTP"); 761 defProcStFld("current-servlet-config", "gnu.kawa.servlet.HTTP"); 762 defProcStFld("servlet-context-realpath", "gnu.kawa.servlet.HTTP"); 763 defProcStFld("get-response", "gnu.kawa.servlet.HTTP"); 764 defProcStFld("get-request", "gnu.kawa.servlet.HTTP"); 765 defProcStFld("request-method", "gnu.kawa.servlet.HTTP"); 766 defProcStFld("request-uri", "gnu.kawa.servlet.HTTP"); 767 defProcStFld("request-url", "gnu.kawa.servlet.HTTP"); 768 defProcStFld("request-path-info", "gnu.kawa.servlet.HTTP"); 769 defProcStFld("request-path-translated", "gnu.kawa.servlet.HTTP"); 770 defProcStFld("request-servlet-path", "gnu.kawa.servlet.HTTP"); 771 defProcStFld("request-query-string", "gnu.kawa.servlet.HTTP"); 772 defProcStFld("request-parameter", "gnu.kawa.servlet.HTTP"); 773 defProcStFld("request-parameters", "gnu.kawa.servlet.HTTP"); 774 defaultNamespace = xqueryFunctionNamespace; 775 } 776 777 public static XQuery getInstance() 778 { 779 return instance; 780 } 781 782 783 public static void registerEnvironment() 784 { 785 Language.setDefaults(new XQuery()); 786 } 787 788 static public QuoteExp falseExp = 789 new QuoteExp(Boolean.FALSE, XDataType.booleanType); 790 static public QuoteExp trueExp = 791 new QuoteExp(Boolean.TRUE, XDataType.booleanType); 792 793 public static final ConstantFunction0 falseFunction 794 = new ConstantFunction0("false", falseExp); 795 public static final ConstantFunction0 trueFunction 796 = new ConstantFunction0("true", trueExp); 797 798 public Consumer getOutputConsumer(java.io.Writer out) 799 { 800 return new XMLPrinter(out, false); 801 } 802 803 static Object [] typeMap = 804 { "string", XDataType.stringType, 805 "untypedAtomic", XDataType.untypedAtomicType, 806 "boolean", XDataType.booleanType, 807 "integer", XIntegerType.integerType, 808 "long", XIntegerType.longType, 809 "int", XIntegerType.intType, 810 "short", XIntegerType.shortType, 811 "byte", XIntegerType.byteType, 812 "unsignedLong", XIntegerType.unsignedLongType, 813 "unsignedInt", XIntegerType.unsignedIntType, 814 "unsignedShort", XIntegerType.unsignedShortType, 815 "unsignedByte", XIntegerType.unsignedByteType, 816 "positiveInteger", XIntegerType.positiveIntegerType, 817 "nonPositiveInteger", XIntegerType.nonPositiveIntegerType, 818 "negativeInteger", XIntegerType.negativeIntegerType, 819 "nonNegativeInteger", XIntegerType.nonNegativeIntegerType, 820 "date", XTimeType.dateType, 821 "dateTime", XTimeType.dateTimeType, 822 "time", XTimeType.timeType, 823 "duration", XTimeType.durationType, 824 "yearMonthDuration", XTimeType.yearMonthDurationType, 825 "dayTimeDuration", XTimeType.dayTimeDurationType, 826 "gYearMonth", XTimeType.gYearMonthType, 827 "gYear", XTimeType.gYearType, 828 "gMonthDay", XTimeType.gMonthDayType, 829 "gDay", XTimeType.gDayType, 830 "gMonth", XTimeType.gMonthType, 831 "decimal", XDataType.decimalType, 832 "float", XDataType.floatType, 833 "double", XDataType.doubleType, 834 "anyURI", XDataType.anyURIType, 835 "hexBinary", XDataType.hexBinaryType, 836 "base64Binary", XDataType.base64BinaryType, 837 "NOTATION", XDataType.NotationType, 838 "QName", "gnu.mapping.Symbol", 839 "anyAtomicType", Type.pointer_type 840 }; 841 842 public static Type getStandardType (String name) 843 { 844 for (int i = typeMap.length; (i -= 2) >= 0; ) 845 { 846 if (typeMap[i].equals(name)) 847 { 848 Object t = typeMap[i+1]; 849 if (t instanceof String ) 850 return Scheme.string2Type((String ) t); 851 else 852 return (Type) t; 853 } 854 } 855 return null; 856 } 857 858 public Type getTypeFor(String name) 859 { 860 String core = name.startsWith("xs:") ? name.substring(3) 861 : name.startsWith("xdt:") ? name.substring(4) 862 : name; 863 Type t = getStandardType(core); 864 return t != null ? t : Scheme.string2Type(name); 865 } 866 867 public Type getTypeFor (Class clas) 868 { 869 if (clas.isPrimitive()) 870 { 871 String name = clas.getName(); 872 if (name.equals("boolean")) 873 return XDataType.booleanType; 874 return Scheme.getNamedType(name); 875 } 876 else if (! clas.isArray()) 877 { 878 String name = clas.getName(); 879 if (name.equals("java.lang.String")) 880 return XDataType.stringType; 881 if (name.equals("gnu.kawa.xml.UntypedAtomic")) 882 return XDataType.untypedAtomicType; 883 if (name.equals("java.lang.Boolean")) 884 return XDataType.booleanType; 885 if (name.equals("java.lang.Float")) 886 return XDataType.floatType; 887 if (name.equals("java.lang.Double")) 888 return XDataType.doubleType; 889 if (name.equals("java.math.BigDecimal")) 890 return XDataType.decimalType; 891 if (name.equals("gnu.math.Duration")) 892 return XDataType.durationType; 893 894 if (name.equals("java.net.URI")) 895 return XDataType.anyURIType; 896 897 } 898 return Type.make(clas); 899 } 900 901 public Procedure getPrompter() 902 { 903 return new Prompter(); 904 } 905 906 925 926 927 static void mangle (String name, int start, int length, 928 StringBuffer sbuf, char mode) 929 { 930 char prev = 'P'; 933 int outStart = sbuf.length(); 934 for (int i = 0; i < length; ) 935 { 936 boolean wordStart; 937 char ch = name.charAt(start + i); 938 i++; 939 if (Character.isUpperCase(ch)) 940 { 941 wordStart = prev != 'U' 942 || (i < length 943 && Character.isLowerCase(name.charAt(start+i))); 944 prev = 'U'; 945 } 946 else if (Character.isLowerCase(ch)) 947 { 948 wordStart = prev != 'L' || prev != 'U'; 949 prev = 'L'; 950 } 951 else if (Character.isLetter(ch)) 952 { wordStart = prev != 'O'; 954 prev = 'O'; 955 } 956 else if (Character.isDigit(ch)) 957 { 958 wordStart = prev != 'D'; 959 prev = 'D'; 960 } 961 else if (Character.isJavaIdentifierPart(ch)) 962 { 963 wordStart = prev != 'D' && prev != 'M'; 964 prev = 'M'; 965 } 966 else { 968 prev = 'P'; 969 continue; 970 } 971 if (wordStart || mode == '_') 972 { 973 if (wordStart && mode == '_' && sbuf.length() > outStart) 974 sbuf.append('_'); 975 ch = Character.toUpperCase(ch); 976 } 977 sbuf.append(ch); 978 } 979 } 980 public static String mangle (String name) 981 { 982 StringBuffer sbuf = new StringBuffer (); 983 mangle(name, 0, name.length(), sbuf, 'U'); 984 return sbuf.toString(); 985 } 986 987 public static String makeClassName (String source) 988 { 989 source = source.replace(java.io.File.separatorChar, '/'); 990 int sl = source.lastIndexOf('/'); 991 if (sl >= 0) 992 source = source.substring(sl+1); 993 int dot = source.lastIndexOf('.'); 994 if (dot >= 0) 995 source = source.substring(0, dot); 996 return Compilation.mangleNameIfNeeded(source); 997 } 998 999 public static Object getExternal (Symbol name, Object type) 1000 { 1001 Environment env = Environment.getCurrent(); 1002 Object value = env.get(name, null, null); 1003 if (value == null) 1004 value = env.get(Symbol.makeWithUnknownNamespace(name.getLocalName(), 1005 name.getPrefix()), 1006 null, null); 1007 if (value == null) 1008 throw new RuntimeException ("unbound external "+name); 1009 if (type == null) 1010 return value; 1011 if (type instanceof XDataType) 1012 return ((XDataType) type).cast(value); 1013 if (type instanceof ClassType) 1014 { 1015 String cname = ((ClassType) type).getName(); 1016 if ("gnu.math.IntNum".equals(cname)) 1018 return IntNum.valueOf(value.toString()); 1019 if ("gnu.math.RealNum".equals(cname)) 1020 return gnu.math.DFloNum.make(Double.parseDouble(value.toString())); 1021 } 1022 try 1023 { 1024 value = ((Type) type).coerceFromObject(value); 1025 } 1026 catch (ClassCastException ex) 1027 { 1028 throw new WrongType(name.toString(), 1029 WrongType.ARG_VARNAME, 1030 value, 1031 type.toString()); 1032 } 1033 return value; 1034 } 1035} 1036 1037class Prompter extends Procedure1 1038{ 1039 public Object apply1 (Object arg) 1040 { 1041 InPort port = (InPort) arg; 1042 int line = port.getLineNumber() + 1; 1043 char state = port.readState; 1044 if (state == '\n') 1045 state = ' '; 1046 if (state == '<') 1047 return "<!--" + line + "-->"; 1048 else if (state == ':') 1049 return "-(:" + line + "c:) "; 1050 else 1051 return "(: " + line + state + ":) "; 1052 } 1053} 1054 | Popular Tags |