Source Code Cross Referenced for Extensions.java in  » XML » XPath-Saxon » net » sf » saxon » functions » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » XPath Saxon » net.sf.saxon.functions 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.saxon.functions;
002:
003:        import net.sf.saxon.Err;
004:        import net.sf.saxon.TransformerFactoryImpl;
005:        import net.sf.saxon.Controller;
006:        import net.sf.saxon.Configuration;
007:        import net.sf.saxon.style.StandardNames;
008:        import net.sf.saxon.tinytree.TinyBuilder;
009:        import net.sf.saxon.charcode.UnicodeCharacterSet;
010:        import net.sf.saxon.expr.*;
011:        import net.sf.saxon.om.*;
012:        import net.sf.saxon.sort.GlobalOrderComparer;
013:        import net.sf.saxon.sort.AtomicComparer;
014:        import net.sf.saxon.trace.Location;
015:        import net.sf.saxon.trans.DynamicError;
016:        import net.sf.saxon.trans.XPathException;
017:        import net.sf.saxon.type.SchemaType;
018:        import net.sf.saxon.type.Type;
019:        import net.sf.saxon.value.*;
020:
021:        import javax.xml.transform.Templates;
022:        import javax.xml.transform.TransformerConfigurationException;
023:        import javax.xml.transform.Transformer;
024:        import javax.xml.transform.TransformerException;
025:        import java.math.BigDecimal;
026:        import java.util.ArrayList;
027:        import java.util.List;
028:        import java.util.Collections;
029:        import java.io.*;
030:
031:        /**
032:         * This class implements functions that are supplied as standard with SAXON,
033:         * but which are not defined in the XSLT or XPath specifications. <p>
034:         *
035:         * To invoke these functions, use a function call of the form prefix:name() where
036:         * name is the method name, and prefix maps to a URI such as
037:         * http://saxon.sf.net/net.sf.saxon.functions.Extensions (only the part
038:         * of the URI after the last slash is important).
039:         */
040:
041:        public class Extensions {
042:
043:            // The class is never instantiated
044:            private Extensions() {
045:            }
046:
047:            /**
048:             * Switch tracing off. Only works if tracing is enabled.
049:             */
050:
051:            public static void pauseTracing(XPathContext c) {
052:                c.getController().pauseTracing(true);
053:            }
054:
055:            /**
056:             * Resume tracing. Only works if tracing was originally enabled
057:             * but is currently paused.
058:             */
059:
060:            public static void resumeTracing(XPathContext c) {
061:                c.getController().pauseTracing(false);
062:            }
063:
064:            /**
065:             * Return the system identifier of the context node
066:             */
067:
068:            public static String systemId(XPathContext c) throws XPathException {
069:                Item item = c.getContextItem();
070:                if (item == null) {
071:                    DynamicError e = new DynamicError(
072:                            "The context item for saxon:systemId() is not set");
073:                    e.setXPathContext(c);
074:                    throw e;
075:                }
076:                if (item instanceof  NodeInfo) {
077:                    return ((NodeInfo) item).getSystemId();
078:                } else {
079:                    return "";
080:                }
081:            }
082:
083:            /**
084:             * Return the line number of the context node.
085:             */
086:            public static int lineNumber(XPathContext c) {
087:                Item item = c.getCurrentIterator().current();
088:                if (item instanceof  NodeInfo) {
089:                    return ((NodeInfo) item).getLineNumber();
090:                } else {
091:                    return -1;
092:                }
093:            }
094:
095:            /**
096:             * Return the line number of the specified node.
097:             */
098:            public static int lineNumber(NodeInfo node) {
099:                if (node == null) {
100:                    return -1;
101:                }
102:                return node.getLineNumber();
103:            }
104:
105:            /**
106:             * Remove a document from the document pool. The effect is that the document becomes eligible for
107:             * garbage collection, allowing memory to be released when processing of the document has finished.
108:             * The downside is that a subsequent call on document() with the same URI causes the document to be
109:             * reloaded and reparsed, and the new nodes will have different node identity from the old.
110:             * @param context the evaluation context (supplied implicitly by the call mechanism)
111:             * @param doc the document to be released from the document pool
112:             * @return the document that was released. This allows a call such as
113:             * select="saxon:discard-document(document('a.xml'))"
114:             */
115:
116:            public static DocumentInfo discardDocument(XPathContext context,
117:                    DocumentInfo doc) {
118:                if (doc == null) {
119:                    return null;
120:                }
121:                return context.getController().getDocumentPool().discard(doc);
122:            }
123:
124:            /**
125:             * Determine whether two node-sets contain the same nodes
126:             * @param p1 The first node-set. The iterator must be correctly ordered.
127:             * @param p2 The second node-set. The iterator must be correctly ordered.
128:             * @return true if p1 and p2 contain the same set of nodes
129:             */
130:
131:            public static boolean hasSameNodes(SequenceIterator p1,
132:                    SequenceIterator p2) throws XPathException {
133:                SequenceIterator e1 = p1;
134:                SequenceIterator e2 = p2;
135:
136:                if (e1 == null) {
137:                    e1 = EmptyIterator.getInstance();
138:                }
139:
140:                if (e2 == null) {
141:                    e2 = EmptyIterator.getInstance();
142:                }
143:
144:                while (true) {
145:                    NodeInfo n1 = (NodeInfo) e1.next();
146:                    NodeInfo n2 = (NodeInfo) e2.next();
147:                    if (n1 == null || n2 == null) {
148:                        return n1 == n2;
149:                    }
150:                    if (!n1.isSameNodeInfo(n2)) {
151:                        return false;
152:                    }
153:                }
154:            }
155:
156:            /**
157:             * Total a stored expression over a set of nodes
158:             */
159:
160:            public static double sum(XPathContext context,
161:                    SequenceIterator nsv,
162:                    Evaluate.PreparedExpression pexpression)
163:                    throws XPathException {
164:
165:                if (nsv == null) {
166:                    nsv = EmptyIterator.getInstance();
167:                }
168:                if (pexpression == null) {
169:                    return Double.NaN;
170:                }
171:                double total = 0.0;
172:                XPathContext c = context.newMinorContext();
173:                c
174:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
175:                c.setCurrentIterator(nsv);
176:                while (true) {
177:                    Item next = nsv.next();
178:                    if (next == null)
179:                        break;
180:                    Item val = pexpression.expression.evaluateItem(c);
181:                    if (val instanceof  NumericValue) {
182:                        DoubleValue v = (DoubleValue) ((NumericValue) val)
183:                                .convert(Type.DOUBLE, context);
184:                        total += v.getDoubleValue();
185:                    } else {
186:                        DynamicError e = new DynamicError(
187:                                "expression in saxon:sum() must return numeric values");
188:                        e.setXPathContext(c);
189:                        throw e;
190:                    }
191:                }
192:                return total;
193:            }
194:
195:            /**
196:             * Get the maximum numeric value of a stored expression over a set of nodes
197:             */
198:
199:            public static double max(XPathContext context,
200:                    SequenceIterator nsv,
201:                    Evaluate.PreparedExpression pexpression)
202:                    throws XPathException {
203:
204:                if (nsv == null) {
205:                    nsv = EmptyIterator.getInstance();
206:                }
207:                if (pexpression == null) {
208:                    return Double.NaN;
209:                }
210:
211:                double max = Double.NEGATIVE_INFINITY;
212:                XPathContext c = context.newMinorContext();
213:                c
214:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
215:                c.setCurrentIterator(nsv);
216:                while (true) {
217:                    Item next = nsv.next();
218:                    if (next == null)
219:                        break;
220:                    Item val = pexpression.expression.evaluateItem(c);
221:                    if (val instanceof  NumericValue) {
222:                        DoubleValue v = (DoubleValue) ((NumericValue) val)
223:                                .convert(Type.DOUBLE, context);
224:                        if (v.getDoubleValue() > max)
225:                            max = v.getDoubleValue();
226:                    } else {
227:                        DynamicError e = new DynamicError(
228:                                "expression in saxon:max() must return numeric values");
229:                        e.setXPathContext(c);
230:                        throw e;
231:                    }
232:                }
233:                return max;
234:            }
235:
236:            /**
237:             * Get the minimum numeric value of a stored expression over a set of nodes
238:             */
239:
240:            public static double min(XPathContext context,
241:                    SequenceIterator nsv,
242:                    Evaluate.PreparedExpression pexpression)
243:                    throws XPathException {
244:
245:                if (nsv == null) {
246:                    nsv = EmptyIterator.getInstance();
247:                }
248:                if (pexpression == null) {
249:                    return Double.NaN;
250:                }
251:
252:                double min = Double.POSITIVE_INFINITY;
253:                XPathContext c = context.newMinorContext();
254:                c
255:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
256:                c.setCurrentIterator(nsv);
257:                while (true) {
258:                    Item next = nsv.next();
259:                    if (next == null)
260:                        break;
261:                    Item val = pexpression.expression.evaluateItem(c);
262:                    if (val instanceof  NumericValue) {
263:                        DoubleValue v = (DoubleValue) ((NumericValue) val)
264:                                .convert(Type.DOUBLE, context);
265:                        if (v.getDoubleValue() < min)
266:                            min = v.getDoubleValue();
267:                    } else {
268:                        DynamicError e = new DynamicError(
269:                                "expression in saxon:min() must return numeric values");
270:                        e.setXPathContext(context);
271:                        throw e;
272:                    }
273:                }
274:                return min;
275:            }
276:
277:            /**
278:             * Get the node with maximum numeric value of the string-value of each of a set of nodes
279:             */
280:
281:            public static Value highest(SequenceIterator nsv)
282:                    throws XPathException {
283:                return net.sf.saxon.exslt.Math.highest(nsv);
284:            }
285:
286:            /**
287:             * Get the maximum numeric value of a stored expression over a set of nodes
288:             */
289:
290:            public static SequenceIterator highest(XPathContext context,
291:                    SequenceIterator nsv,
292:                    Evaluate.PreparedExpression pexpression)
293:                    throws XPathException {
294:                if (nsv == null) {
295:                    return EmptyIterator.getInstance();
296:                }
297:                if (pexpression == null) {
298:                    return EmptyIterator.getInstance();
299:                }
300:
301:                double max = Double.NEGATIVE_INFINITY;
302:                XPathContext c = context.newMinorContext();
303:                c
304:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
305:                Item highest = null;
306:                c.setCurrentIterator(nsv);
307:                while (true) {
308:                    Item next = nsv.next();
309:                    if (next == null)
310:                        break;
311:                    Item val = pexpression.expression.evaluateItem(c);
312:                    if (val instanceof  NumericValue) {
313:                        DoubleValue v = (DoubleValue) ((NumericValue) val)
314:                                .convert(Type.DOUBLE, context);
315:                        if (v.getDoubleValue() > max) {
316:                            max = v.getDoubleValue();
317:                            highest = nsv.current();
318:                        }
319:                    } else {
320:                        DynamicError e = new DynamicError(
321:                                "expression in saxon:highest() must return numeric values");
322:                        e.setXPathContext(context);
323:                        throw e;
324:                    }
325:                }
326:                return SingletonIterator.makeIterator(highest);
327:            }
328:
329:            /**
330:             * Get the node with minimum numeric value of the string-value of each of a set of nodes
331:             */
332:
333:            public static Value lowest(SequenceIterator nsv)
334:                    throws XPathException {
335:                return net.sf.saxon.exslt.Math.lowest(nsv);
336:            }
337:
338:            /**
339:             * Get the node with minimum numeric value of a stored expression over a set of nodes
340:             */
341:
342:            public static SequenceIterator lowest(XPathContext context,
343:                    SequenceIterator nsv,
344:                    Evaluate.PreparedExpression pexpression)
345:                    throws XPathException {
346:                if (nsv == null) {
347:                    return EmptyIterator.getInstance();
348:                }
349:                if (pexpression == null) {
350:                    return EmptyIterator.getInstance();
351:                }
352:
353:                double min = Double.POSITIVE_INFINITY;
354:                XPathContext c = context.newMinorContext();
355:                c
356:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
357:                Item lowest = null;
358:                c.setCurrentIterator(nsv);
359:                while (true) {
360:                    Item next = nsv.next();
361:                    if (next == null)
362:                        break;
363:                    Item val = pexpression.expression.evaluateItem(c);
364:                    if (val instanceof  NumericValue) {
365:                        DoubleValue v = (DoubleValue) ((NumericValue) val)
366:                                .convert(Type.DOUBLE, context);
367:                        if (v.getDoubleValue() < min) {
368:                            min = v.getDoubleValue();
369:                            lowest = nsv.current();
370:                        }
371:                    } else {
372:                        DynamicError e = new DynamicError(
373:                                "expression in saxon:lowest() must return numeric values");
374:                        e.setXPathContext(context);
375:                        throw e;
376:                    }
377:                }
378:                return SingletonIterator.makeIterator(lowest);
379:            }
380:
381:            /**
382:             * Get the items that satisfy the given expression, up to and excluding the first one
383:             * (in sequence order) that doesn't
384:             */
385:
386:            public static SequenceIterator leading(XPathContext context,
387:                    SequenceIterator in, Evaluate.PreparedExpression pexp) {
388:                if (in == null) {
389:                    return EmptyIterator.getInstance();
390:                }
391:                if (pexp == null) {
392:                    return EmptyIterator.getInstance();
393:                }
394:
395:                XPathContext c2 = context.newMinorContext();
396:                c2
397:                        .setOriginatingConstructType(Location.SAXON_HIGHER_ORDER_EXTENSION_FUNCTION);
398:                return new FilterIterator.Leading(in, pexp.expression, c2);
399:            }
400:
401:            /**
402:             * Find all the nodes in ns1 that are after the first node in ns2.
403:             * Return ns1 if ns2 is empty,
404:             */
405:
406:            // This function is no longer documented as a user-visible extension function.
407:            // But exslt:trailing depends on it.
408:            public static SequenceIterator after(XPathContext context,
409:                    SequenceIterator ns1, SequenceIterator ns2)
410:                    throws XPathException {
411:
412:                NodeInfo first = null;
413:
414:                // Find the first node in ns2 (in document order)
415:
416:                GlobalOrderComparer comparer = GlobalOrderComparer
417:                        .getInstance();
418:                while (true) {
419:                    Item item = ns2.next();
420:                    if (item == null) {
421:                        if (first == null) {
422:                            return ns1;
423:                        } else {
424:                            break;
425:                        }
426:                    }
427:                    if (item instanceof  NodeInfo) {
428:                        NodeInfo node = (NodeInfo) item;
429:                        if (first == null) {
430:                            first = node;
431:                        } else {
432:                            if (comparer.compare(node, first) < 0) {
433:                                first = node;
434:                            }
435:                        }
436:                    } else {
437:                        DynamicError e = new DynamicError(
438:                                "Operand of after() contains an item that is not a node");
439:                        e.setXPathContext(context);
440:                        throw e;
441:                    }
442:                }
443:
444:                // Filter ns1 to select nodes that come after this one
445:
446:                Expression filter = new IdentityComparison(
447:                        new ContextItemExpression(), Token.FOLLOWS,
448:                        new SingletonNode(first));
449:
450:                return new FilterIterator(ns1, filter, context);
451:
452:            }
453:
454:            /**
455:             * Return a node-set by tokenizing a supplied string. Tokens are delimited by any sequence of
456:             * whitespace characters.
457:             */
458:
459:            // This extension is superseded by fn:tokenize(); it is no longer documented in Saxon 8.1
460:            public static SequenceIterator tokenize(String s) {
461:                if (s == null) {
462:                    // empty sequence supplied: treat as empty string
463:                    return EmptyIterator.getInstance();
464:                }
465:                return new StringTokenIterator(s);
466:            }
467:
468:            /**
469:             * Return a sequence by tokenizing a supplied string. The argument delim is a String, any character
470:             * in this string is considered to be a delimiter character, and any sequence of delimiter characters
471:             * acts as a separator between tokens.
472:             */
473:
474:            // This extension is superseded by fn:tokenize(); it is no longer documented in Saxon 8.1
475:            public static SequenceIterator tokenize(String s, String delim) {
476:                if (s == null) {
477:                    // empty sequence supplied: treat as empty string
478:                    return EmptyIterator.getInstance();
479:                }
480:                if (delim == null) {
481:                    return new StringTokenIterator(s);
482:                }
483:                return new StringTokenIterator(s, delim);
484:            }
485:
486:            /**
487:             * Return an XPath expression that identifies the current node
488:             */
489:
490:            public static String path(XPathContext c) throws XPathException {
491:                Item item = c.getContextItem();
492:                if (item == null) {
493:                    DynamicError e = new DynamicError(
494:                            "The context item for saxon:path() is not set");
495:                    e.setXPathContext(c);
496:                    throw e;
497:                }
498:                if (item instanceof  NodeInfo) {
499:                    return Navigator.getPath((NodeInfo) item);
500:                } else {
501:                    return "";
502:                }
503:            }
504:
505:            /**
506:             * Display the value of the type annotation of a node
507:             */
508:
509:            public static String typeAnnotation(XPathContext context,
510:                    NodeInfo node) {
511:                if (node == null) {
512:                    return null;
513:                }
514:                int code = node.getTypeAnnotation();
515:                if ((code & NodeInfo.IS_DTD_TYPE) != 0) {
516:                    code = StandardNames.XDT_UNTYPED_ATOMIC;
517:                }
518:                if (code == -1) {
519:                    int nodeKind = node.getNodeKind();
520:                    if (nodeKind == Type.ELEMENT || nodeKind == Type.DOCUMENT) {
521:                        return "untyped";
522:                    } else {
523:                        return "untypedAtomic";
524:                    }
525:                }
526:                SchemaType type = context.getConfiguration().getSchemaType(
527:                        code & 0xfffff);
528:                if (type == null) {
529:                    // Anonymous types are not accessible by the namecode
530:                    return context.getNamePool().getDisplayName(code);
531:                }
532:                return "type " + type.getDescription();
533:            }
534:
535:            /**
536:             * Return the XPathContext object
537:             */
538:
539:            public static XPathContext getContext(XPathContext c) {
540:                return c;
541:            }
542:
543:            /**
544:             * Return the Controller object
545:             */
546:
547:            public static Controller getController(XPathContext c) {
548:                return c.getController();
549:            }
550:
551:            /**
552:             * Return the Configuration object
553:             */
554:
555:            public static Configuration getConfiguration(XPathContext c) {
556:                return c.getConfiguration();
557:            }
558:
559:            /**
560:             * Get a pseudo-attribute of a processing instruction. Return an empty string
561:             * if the pseudo-attribute is not present.
562:             * Character references and built-in entity references are expanded
563:             */
564:
565:            public static String getPseudoAttribute(XPathContext c, String name)
566:                    throws XPathException {
567:                if (name == null) {
568:                    return null;
569:                }
570:                Item pi = c.getContextItem();
571:                if (pi == null) {
572:                    DynamicError e = new DynamicError(
573:                            "The context item for saxon:getPseudoAttribute() is not set");
574:                    e.setXPathContext(c);
575:                    throw e;
576:                }
577:                // we'll assume it's a PI, it doesn't matter if it isn't...
578:                String val = ProcInstParser.getPseudoAttribute(pi
579:                        .getStringValue(), name);
580:                if (val == null)
581:                    return "";
582:                return val;
583:            }
584:
585:            /**
586:             * Get a dayTimeDuration value corresponding to a given number of seconds
587:             */
588:            // no longer documented in Saxon 8.1
589:            public static SecondsDurationValue dayTimeDurationFromSeconds(
590:                    double arg) throws XPathException {
591:                return SecondsDurationValue.fromSeconds(new BigDecimal(arg));
592:            }
593:
594:            /**
595:             * Get a yearMonthDuration value corresponding to a given number of months
596:             */
597:            // no longer documented in Saxon 8.1
598:            public static MonthDurationValue yearMonthDurationFromMonths(
599:                    double arg) {
600:                return MonthDurationValue.fromMonths((int) arg);
601:            }
602:
603:            /**
604:             * Perform decimal division to a user-specified precision
605:             */
606:
607:            public static BigDecimal decimalDivide(BigDecimal arg1,
608:                    BigDecimal arg2, int scale) {
609:                if (arg1 == null || arg2 == null) {
610:                    return null;
611:                }
612:                return arg1.divide(arg2, scale, BigDecimal.ROUND_DOWN);
613:            }
614:
615:            /**
616:             * Get the UTF-8 encoding of a string
617:             * @param in the supplied string
618:             * @return a sequence of integers, each in the range 0-255, representing the octets of the UTF-8
619:             * encoding of the given string
620:             */
621:
622:            public static List stringToUtf8(String in) {
623:                if (in == null) {
624:                    return Collections.EMPTY_LIST;
625:                }
626:                ArrayList list = new ArrayList(in.length() * 2);
627:                byte[] octets = new byte[4];
628:                for (int i = 0; i < in.length(); i++) {
629:                    int used = UnicodeCharacterSet.getUTF8Encoding(
630:                            in.charAt(i), (i + 1 < in.length() ? in
631:                                    .charAt(i + 1) : (char) 0), octets);
632:                    for (int j = 0; j < used; j++) {
633:                        list.add(new Integer(255 & (int) octets[j]));
634:                    }
635:                }
636:                return list;
637:            }
638:
639:            /**
640:             * Convert a sequence of integers in the range 0-255, representing a sequence of octets,
641:             * to a base64Binary value
642:             */
643:
644:            public static Base64BinaryValue octetsToBase64Binary(byte[] in) {
645:                if (in == null) {
646:                    return null;
647:                }
648:                return new Base64BinaryValue(in);
649:            }
650:
651:            /**
652:             * Convert a sequence of integers in the range 0-255, representing a sequence of octets,
653:             * to a hexBinary value
654:             */
655:
656:            public static HexBinaryValue octetsToHexBinary(byte[] in) {
657:                if (in == null) {
658:                    return null;
659:                }
660:                return new HexBinaryValue(in);
661:            }
662:
663:            /**
664:             * Convert a base64Binary value to a sequence of integers representing the octets contained in the value
665:             */
666:
667:            public static byte[] base64BinaryToOctets(Base64BinaryValue in) {
668:                if (in == null) {
669:                    return null;
670:                }
671:                return in.getBinaryValue();
672:            }
673:
674:            /**
675:             * Convert a hexBinary value to a sequence of integers representing the octets contained in the value
676:             */
677:
678:            public static byte[] hexBinaryToOctets(HexBinaryValue in) {
679:                if (in == null) {
680:                    return null;
681:                }
682:                return in.getBinaryValue();
683:            }
684:
685:            /**
686:             * Convert a base64Binary value to a String, assuming a particular encoding
687:             */
688:
689:            public static String base64BinaryToString(XPathContext context,
690:                    Base64BinaryValue in, String encoding) throws Exception {
691:                if (in == null) {
692:                    return null;
693:                }
694:                if (encoding == null) {
695:                    encoding = "UTF-8";
696:                }
697:                byte[] bytes = in.getBinaryValue();
698:                ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
699:                InputStreamReader reader = new InputStreamReader(stream,
700:                        encoding);
701:                char[] array = new char[bytes.length];
702:                int used = reader.read(array, 0, array.length);
703:                checkBytes(array, 0, used, context.getConfiguration()
704:                        .getNameChecker());
705:                return new String(array, 0, used);
706:            }
707:
708:            /**
709:             * Convert a string to a base64Binary value in a given encoding
710:             */
711:
712:            public static Base64BinaryValue stringToBase64Binary(String in,
713:                    String encoding) throws UnsupportedEncodingException,
714:                    IOException {
715:                if (in == null) {
716:                    return null;
717:                }
718:                if (encoding == null) {
719:                    encoding = "UTF-8";
720:                }
721:                ByteArrayOutputStream stream = new ByteArrayOutputStream(in
722:                        .length());
723:                OutputStreamWriter writer = new OutputStreamWriter(stream,
724:                        encoding);
725:                writer.write(in);
726:                writer.close();
727:                byte[] bytes = stream.toByteArray();
728:                return octetsToBase64Binary(bytes);
729:            }
730:
731:            /**
732:             * Convert a hexBinary value to a String, assuming a particular encoding
733:             */
734:
735:            public static String hexBinaryToString(XPathContext context,
736:                    HexBinaryValue in, String encoding) throws Exception {
737:                if (in == null) {
738:                    return null;
739:                }
740:                if (encoding == null) {
741:                    encoding = "UTF-8";
742:                }
743:                byte[] bytes = in.getBinaryValue();
744:                ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
745:                InputStreamReader reader = new InputStreamReader(stream,
746:                        encoding);
747:                char[] array = new char[bytes.length];
748:                int used = reader.read(array, 0, array.length);
749:                checkBytes(array, 0, used, context.getConfiguration()
750:                        .getNameChecker());
751:                return new String(array, 0, used);
752:            }
753:
754:            /**
755:             * Check that bytes are valid XML characters (UTF-16 encoded)
756:             */
757:
758:            private static void checkBytes(char[] array, int start, int end,
759:                    NameChecker checker) throws XPathException {
760:                for (int c = start; c < end; c++) {
761:                    int ch32 = array[c];
762:                    if (XMLChar.isHighSurrogate(ch32)) {
763:                        char low = array[c++];
764:                        ch32 = XMLChar.supplemental((char) ch32, low);
765:                    }
766:                    if (!checker.isValidChar(ch32)) {
767:                        DynamicError err = new DynamicError(
768:                                "The byte sequence contains a character not allowed by XML (hex "
769:                                        + Integer.toHexString(ch32) + ')');
770:                        err.setErrorCode("XTDE1180");
771:                        throw err;
772:                    }
773:                }
774:            }
775:
776:            /**
777:             * Convert a string to a hexBinary value in a given encoding
778:             */
779:
780:            public static HexBinaryValue stringToHexBinary(String in,
781:                    String encoding) throws Exception {
782:                if (in == null) {
783:                    return null;
784:                }
785:                if (encoding == null) {
786:                    encoding = "UTF-8";
787:                }
788:                ByteArrayOutputStream stream = new ByteArrayOutputStream(in
789:                        .length());
790:                OutputStreamWriter writer = new OutputStreamWriter(stream,
791:                        encoding);
792:                writer.write(in);
793:                writer.close();
794:                byte[] bytes = stream.toByteArray();
795:                return octetsToHexBinary(bytes);
796:            }
797:
798:            /**
799:             * Test whether a given integer is the codepoint of a valid XML character
800:             */
801:
802:            public static boolean validCharacter(XPathContext c, int in) {
803:                return c.getConfiguration().getNameChecker().isValidChar(in);
804:            }
805:
806:            /**
807:             * Create a parentless namespace node. This function is useful in XQuery when namespaces need to be created
808:             * dynamically. The effect is the same as that of the xsl:namespace instruction in XSLT.
809:             */
810:
811:            public static NodeInfo namespaceNode(XPathContext context,
812:                    String prefix, String uri) throws XPathException {
813:                if (prefix == null) {
814:                    prefix = "";
815:                }
816:                if (!("".equals(prefix) || context.getConfiguration()
817:                        .getNameChecker().isValidNCName(prefix))) {
818:                    DynamicError err = new DynamicError("Namespace prefix "
819:                            + Err.wrap(prefix) + " is not a valid NCName");
820:                    throw err;
821:                }
822:                if (uri == null || "".equals(uri)) {
823:                    DynamicError err = new DynamicError(
824:                            "URI of namespace node must not be empty");
825:                    throw err;
826:                }
827:                final NamePool namePool = context.getNamePool();
828:                Orphan node = new Orphan(context.getConfiguration());
829:                node.setNodeKind(Type.NAMESPACE);
830:                node.setNameCode(namePool.allocate("", "", prefix));
831:                node.setStringValue(uri);
832:                return node;
833:            }
834:
835:            /**
836:             * Perform a parameterized deep-equals() test
837:             * @param context The evaluation context
838:             * @param arg1 The first sequence to be compared
839:             * @param arg2 The second sequence to be compared
840:             * @param collation The collation to be used (null if the default collation is to be used)
841:             * @param flags A string whose characters select options that cause the comparison to vary from the
842:             * standard fn:deep-equals() function. The flags are:
843:             * <ul>
844:             * <li>N - take namespace nodes into account</li>
845:             * <li>C - take comments into account</li>
846:             * <li>P - take processing instructions into account</li>
847:             * <li>w - don't take whitespace-only text nodes into account</li>
848:             * </ul>
849:             * @return true if the sequences are deep equal, otherwise false
850:             */
851:
852:            public static boolean deepEqual(XPathContext context,
853:                    SequenceIterator arg1, SequenceIterator arg2,
854:                    String collation, String flags) throws XPathException {
855:                AtomicComparer comparer;
856:                if (collation == null) {
857:                    comparer = new AtomicComparer(
858:                            context.getDefaultCollation(), context);
859:                } else {
860:                    comparer = new AtomicComparer(context
861:                            .getCollation(collation), context);
862:                }
863:                int flag = 0;
864:                if (flags.indexOf("N") >= 0) {
865:                    flag |= DeepEqual.INCLUDE_NAMESPACES;
866:                }
867:                if (flags.indexOf("C") >= 0) {
868:                    flag |= DeepEqual.INCLUDE_COMMENTS;
869:                }
870:                if (flags.indexOf("P") >= 0) {
871:                    flag |= DeepEqual.INCLUDE_PROCESSING_INSTRUCTIONS;
872:                }
873:                if (flags.indexOf("S") >= 0) {
874:                    flag |= DeepEqual.COMPARE_STRING_VALUES;
875:                }
876:                if (flags.indexOf("A") >= 0) {
877:                    flag |= DeepEqual.COMPARE_ANNOTATIONS;
878:                }
879:                if (flags.indexOf("w") >= 0) {
880:                    flag |= DeepEqual.EXCLUDE_WHITESPACE_TEXT_NODES;
881:                }
882:                if (flags.indexOf("?") >= 0) {
883:                    flag |= DeepEqual.WARNING_IF_FALSE;
884:                }
885:                return DeepEqual.deepEquals(arg1, arg2, comparer, context
886:                        .getConfiguration(), flag);
887:
888:            }
889:
890:            /**
891:             * Compile a document containing a stylesheet module into a stylesheet that can be used to perform
892:             * transformations
893:             */
894:
895:            public static Templates compileStylesheet(XPathContext context,
896:                    DocumentInfo doc) throws XPathException {
897:                if (doc == null) {
898:                    return null;
899:                }
900:                try {
901:                    TransformerFactoryImpl factory = new TransformerFactoryImpl(
902:                            context.getConfiguration());
903:                    return factory.newTemplates(doc);
904:                } catch (TransformerConfigurationException e) {
905:                    throw DynamicError.makeDynamicError(e);
906:                }
907:            }
908:
909:            /**
910:             * Run a transformation to convert an input tree to an output document
911:             * @param context The dynamic context
912:             * @param templates The compiled stylesheet
913:             * @param source The initial context node representing the document to be transformed
914:             */
915:
916:            public static DocumentInfo transform(XPathContext context,
917:                    Templates templates, NodeInfo source) throws XPathException {
918:                if (templates == null) {
919:                    return null;
920:                }
921:                if (source == null) {
922:                    return null;
923:                }
924:                try {
925:                    Transformer transformer = templates.newTransformer();
926:                    TinyBuilder builder = new TinyBuilder();
927:                    builder.setPipelineConfiguration(context.getController()
928:                            .makePipelineConfiguration());
929:                    transformer.transform(source, builder);
930:                    return (DocumentInfo) builder.getCurrentRoot();
931:                } catch (TransformerException e) {
932:                    throw DynamicError.makeDynamicError(e);
933:                }
934:            }
935:        }
936:
937:        //
938:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
939:        // you may not use this file except in compliance with the License. You may obtain a copy of the
940:        // License at http://www.mozilla.org/MPL/
941:        //
942:        // Software distributed under the License is distributed on an "AS IS" basis,
943:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
944:        // See the License for the specific language governing rights and limitations under the License.
945:        //
946:        // The Original Code is: all this file.
947:        //
948:        // The Initial Developer of the Original Code is Michael H. Kay.
949:        //
950:        // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
951:        //
952:        // Contributor(s): none.
953:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.