Source Code Cross Referenced for Value.java in  » XML » saxonb » net » sf » saxon » value » 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 » saxonb » net.sf.saxon.value 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package net.sf.saxon.value;
0002:
0003:        import net.sf.saxon.Configuration;
0004:        import net.sf.saxon.Controller;
0005:        import net.sf.saxon.event.Builder;
0006:        import net.sf.saxon.event.PipelineConfiguration;
0007:        import net.sf.saxon.event.Sender;
0008:        import net.sf.saxon.event.SequenceReceiver;
0009:        import net.sf.saxon.expr.*;
0010:        import net.sf.saxon.functions.Aggregate;
0011:        import net.sf.saxon.om.*;
0012:        import net.sf.saxon.style.StandardNames;
0013:        import net.sf.saxon.tinytree.TinyBuilder;
0014:        import net.sf.saxon.trans.DynamicError;
0015:        import net.sf.saxon.trans.XPathException;
0016:        import net.sf.saxon.type.*;
0017:
0018:        import javax.xml.transform.Source;
0019:        import javax.xml.transform.dom.DOMSource;
0020:        import java.io.PrintStream;
0021:        import java.io.Serializable;
0022:        import java.lang.reflect.Array;
0023:        import java.lang.reflect.InvocationTargetException;
0024:        import java.lang.reflect.Method;
0025:        import java.math.BigDecimal;
0026:        import java.math.BigInteger;
0027:        import java.net.URI;
0028:        import java.net.URL;
0029:        import java.util.*;
0030:
0031:        /**
0032:         * A value is the result of an expression but it is also an expression in its own right.
0033:         * Note that every value can be regarded as a sequence - in many cases, a sequence of
0034:         * length one.
0035:         */
0036:
0037:        public abstract class Value implements  Expression, Serializable,
0038:                ValueRepresentation {
0039:
0040:            /**
0041:             * Static method to make a Value from a given Item (which may be either an AtomicValue
0042:             * or a NodeInfo
0043:             * @param val       The supplied value, or null, indicating the empty sequence.
0044:             * @return          The supplied value, if it is a value, or a SingletonNode that
0045:             *                  wraps the item, if it is a node. If the supplied value was null,
0046:             *                  return an EmptySequence
0047:             */
0048:
0049:            public static Value asValue(ValueRepresentation val) {
0050:                if (val instanceof  Value) {
0051:                    return (Value) val;
0052:                } else if (val == null) {
0053:                    return EmptySequence.getInstance();
0054:                } else {
0055:                    return new SingletonNode((NodeInfo) val);
0056:                }
0057:            }
0058:
0059:            /**
0060:             * Static method to make an Item from a Value
0061:             * @param value the value to be converted
0062:             * @param context the context. It is probably safe to set this to null.
0063:             * @return null if the value is an empty sequence; or the only item in the value
0064:             * if it is a singleton sequence
0065:             * @throws XPathException if the Value contains multiple items
0066:             */
0067:
0068:            public static Item asItem(ValueRepresentation value,
0069:                    XPathContext context) throws XPathException {
0070:                if (value instanceof  Item) {
0071:                    return (Item) value;
0072:                } else if (value instanceof  EmptySequence) {
0073:                    return null;
0074:                } else if (value instanceof  SingletonNode) {
0075:                    return ((SingletonNode) value).getNode();
0076:                } else if (value instanceof  AtomicValue) {
0077:                    return (AtomicValue) value;
0078:                } else if (value instanceof  Closure) {
0079:                    return ((Closure) value).evaluateItem(context);
0080:                } else {
0081:                    SequenceIterator iter = Value.getIterator(value);
0082:                    Item item = iter.next();
0083:                    if (item == null) {
0084:                        return null;
0085:                    } else if (iter.next() != null) {
0086:                        throw new AssertionError(
0087:                                "Attempting to access a sequence as an item");
0088:                    } else {
0089:                        return item;
0090:                    }
0091:                }
0092:            }
0093:
0094:            /**
0095:             * Static method to get an Iterator over any ValueRepresentation (which may be either a Value
0096:             * or a NodeInfo
0097:             * @param val       The supplied value, or null, indicating the empty sequence.
0098:             * @param context   The evaluation context. This may be null. It should always be possible to
0099:             *                  iterate over a value without supplying a context, but sometimes the context
0100:             *                  can provide access to better error information
0101:             * @return          The supplied value, if it is a value, or a SingletonNode that
0102:             *                  wraps the item, if it is a node. If the supplied value was null,
0103:             *                  return an EmptySequence
0104:             */
0105:
0106:            public static SequenceIterator asIterator(ValueRepresentation val,
0107:                    XPathContext context) throws XPathException {
0108:                if (val instanceof  Value) {
0109:                    return ((Value) val).iterate(context);
0110:                } else if (val == null) {
0111:                    return EmptyIterator.getInstance();
0112:                } else {
0113:                    return SingletonIterator.makeIterator((NodeInfo) val);
0114:                }
0115:            }
0116:
0117:            /**
0118:             * Static method to convert strings to numbers. Might as well go here as anywhere else.
0119:             * @param s the String to be converted
0120:             * @return a double representing the value of the String
0121:             * @throws NumberFormatException if the value cannot be converted
0122:             */
0123:
0124:            public static double stringToNumber(CharSequence s)
0125:                    throws NumberFormatException {
0126:                String n = trimWhitespace(s).toString();
0127:                if ("INF".equals(n)) {
0128:                    return Double.POSITIVE_INFINITY;
0129:                } else if ("-INF".equals(n)) {
0130:                    return Double.NEGATIVE_INFINITY;
0131:                } else if ("NaN".equals(n)) {
0132:                    return Double.NaN;
0133:                } else {
0134:                    return Double.parseDouble(n);
0135:                }
0136:            }
0137:
0138:            /**
0139:             * Normalize whitespace as defined in XML Schema
0140:             */
0141:
0142:            public static CharSequence normalizeWhitespace(CharSequence in) {
0143:                FastStringBuffer sb = new FastStringBuffer(in.length());
0144:                for (int i = 0; i < in.length(); i++) {
0145:                    char c = in.charAt(i);
0146:                    switch (c) {
0147:                    case '\n':
0148:                    case '\r':
0149:                    case '\t':
0150:                        sb.append(' ');
0151:                        break;
0152:                    default:
0153:                        sb.append(c);
0154:                        break;
0155:                    }
0156:                }
0157:                return sb;
0158:            }
0159:
0160:            /**
0161:             * Collapse whitespace as defined in XML Schema
0162:             */
0163:
0164:            public static CharSequence collapseWhitespace(CharSequence in) {
0165:                if (in.length() == 0) {
0166:                    return in;
0167:                }
0168:
0169:                FastStringBuffer sb = new FastStringBuffer(in.length());
0170:                boolean inWhitespace = true;
0171:                int i = 0;
0172:                for (; i < in.length(); i++) {
0173:                    char c = in.charAt(i);
0174:                    switch (c) {
0175:                    case '\n':
0176:                    case '\r':
0177:                    case '\t':
0178:                    case ' ':
0179:                        if (inWhitespace) {
0180:                            // remove the whitespace
0181:                        } else {
0182:                            sb.append(' ');
0183:                            inWhitespace = true;
0184:                        }
0185:                        break;
0186:                    default:
0187:                        sb.append(c);
0188:                        inWhitespace = false;
0189:                        break;
0190:                    }
0191:                }
0192:                if (sb.charAt(sb.length() - 1) == ' ') {
0193:                    sb.setLength(sb.length() - 1);
0194:                }
0195:                return sb;
0196:            }
0197:
0198:            /**
0199:             * Remove leading and trailing whitespace. This has the same effect as collapseWhitespace,
0200:             * but is cheaper, for use by data types that do not allow internal whitespace.
0201:             * @param in the input string whose whitespace is to be removed
0202:             * @return the result of removing excess whitespace
0203:             */
0204:            public static CharSequence trimWhitespace(CharSequence in) {
0205:                if (in.length() == 0) {
0206:                    return in;
0207:                }
0208:                int first = 0;
0209:                int last = in.length() - 1;
0210:                while (in.charAt(first) <= 0x20) {
0211:                    if (first++ >= last) {
0212:                        return "";
0213:                    }
0214:                }
0215:                while (in.charAt(last) <= 0x20) {
0216:                    last--;
0217:                }
0218:                return in.subSequence(first, last + 1);
0219:            }
0220:
0221:            /**
0222:             * Get a SequenceIterator over a ValueRepresentation
0223:             */
0224:
0225:            public static SequenceIterator getIterator(ValueRepresentation val)
0226:                    throws XPathException {
0227:                if (val instanceof  Value) {
0228:                    return ((Value) val).iterate(null);
0229:                } else if (val instanceof  NodeInfo) {
0230:                    return SingletonIterator.makeIterator((NodeInfo) val);
0231:                } else if (val == null) {
0232:                    throw new AssertionError(
0233:                            "Value of variable is undefined (null)");
0234:                } else {
0235:                    throw new AssertionError("Unknown value representation "
0236:                            + val.getClass());
0237:                }
0238:            }
0239:
0240:            /**
0241:             * Simplify an expression
0242:             * @return for a Value, this always returns the value unchanged
0243:             */
0244:
0245:            public final Expression simplify(StaticContext env) {
0246:                return this ;
0247:            }
0248:
0249:            /**
0250:             * TypeCheck an expression
0251:             * @return for a Value, this always returns the value unchanged
0252:             */
0253:
0254:            public final Expression typeCheck(StaticContext env,
0255:                    ItemType contextItemType) {
0256:                return this ;
0257:            }
0258:
0259:            /**
0260:             * Optimize an expression
0261:             * @return for a Value, this always returns the value unchanged
0262:             */
0263:
0264:            public final Expression optimize(Optimizer opt, StaticContext env,
0265:                    ItemType contextItemType) {
0266:                return this ;
0267:            }
0268:
0269:            /**
0270:             * Determine the data type of the items in the expression, if possible
0271:             * @return for the default implementation: AnyItemType (not known)
0272:             * @param th The TypeHierarchy. Can be null if the target is an AtomicValue.
0273:             */
0274:
0275:            public ItemType getItemType(TypeHierarchy th) {
0276:                return AnyItemType.getInstance();
0277:            }
0278:
0279:            /**
0280:             * Determine the cardinality
0281:             */
0282:
0283:            public int getCardinality() {
0284:                try {
0285:                    SequenceIterator iter = iterate(null);
0286:                    Item next = iter.next();
0287:                    if (next == null) {
0288:                        return StaticProperty.EMPTY;
0289:                    } else {
0290:                        if (iter.next() != null) {
0291:                            return StaticProperty.ALLOWS_ONE_OR_MORE;
0292:                        } else {
0293:                            return StaticProperty.EXACTLY_ONE;
0294:                        }
0295:                    }
0296:                } catch (XPathException err) {
0297:                    // can't actually happen
0298:                    return StaticProperty.ALLOWS_ZERO_OR_MORE;
0299:                }
0300:            }
0301:
0302:            /**
0303:             * Get the sub-expressions of this expression.
0304:             * @return for a Value, this always returns an empty array
0305:             */
0306:
0307:            public final Iterator iterateSubExpressions() {
0308:                return Collections.EMPTY_LIST.iterator();
0309:            }
0310:
0311:            /**
0312:             * Get the expression that immediately contains this expression. This method
0313:             * returns null for an outermost expression; it also return null in the case
0314:             * of literal values. For an XPath expression occurring within an XSLT stylesheet,
0315:             * this method returns the XSLT instruction containing the XPath expression.
0316:             * @return the expression that contains this expression, if known; return null
0317:             * if there is no containing expression or if the containing expression is unknown.
0318:             */
0319:
0320:            public final Container getParentExpression() {
0321:                return null;
0322:            }
0323:
0324:            /**
0325:             * Get the static properties of this expression (other than its type). For a
0326:             * Value, the only special property is {@link StaticProperty#NON_CREATIVE}.
0327:             * @return {@link StaticProperty#NON_CREATIVE}
0328:             */
0329:
0330:            public int getSpecialProperties() {
0331:                return StaticProperty.NON_CREATIVE;
0332:            }
0333:
0334:            /**
0335:             * Offer promotion for this subexpression. Values (constant expressions)
0336:             * are never promoted
0337:             * @param offer details of the offer, for example the offer to move
0338:             *     expressions that don't depend on the context to an outer level in
0339:             *     the containing expression
0340:             * @return For a Value, this always returns the value unchanged
0341:             */
0342:
0343:            public final Expression promote(PromotionOffer offer) {
0344:                return this ;
0345:            }
0346:
0347:            /**
0348:             * Determine which aspects of the context the expression depends on. The result is
0349:             * a bitwise-or'ed value composed from constants such as StaticProperty.VARIABLES and
0350:             * StaticProperty.CURRENT_NODE
0351:             * @return for a Value, this always returns zero.
0352:             */
0353:
0354:            public final int getDependencies() {
0355:                return 0;
0356:            }
0357:
0358:            /**
0359:             * Get the n'th item in the sequence (starting from 0). This is defined for all
0360:             * Values, but its real benefits come for a sequence Value stored extensionally
0361:             * (or for a MemoClosure, once all the values have been read)
0362:             */
0363:
0364:            public Item itemAt(int n) throws XPathException {
0365:                if ((getImplementationMethod() & EVALUATE_METHOD) != 0) {
0366:                    if (n == 0) {
0367:                        Item item = evaluateItem(null);
0368:                        return (item == null ? null : item);
0369:                    } else {
0370:                        return null;
0371:                    }
0372:                }
0373:                if (n < 0) {
0374:                    return null;
0375:                }
0376:                int i = 0; // indexing is zero-based
0377:                SequenceIterator iter = iterate(null);
0378:                while (true) {
0379:                    Item item = iter.next();
0380:                    if (item == null) {
0381:                        return null;
0382:                    }
0383:                    if (i++ == n) {
0384:                        return item;
0385:                    }
0386:                }
0387:            }
0388:
0389:            /**
0390:             * Get the length of the sequence
0391:             */
0392:
0393:            public int getLength() throws XPathException {
0394:                return Aggregate.count(iterate(null));
0395:            }
0396:
0397:            /**
0398:             * Evaluate as a singleton item (or empty sequence). Note: this implementation returns
0399:             * the first item in the sequence. The method should not be used unless appropriate type-checking
0400:             * has been done to ensure that the value will be a singleton.
0401:             */
0402:
0403:            public Item evaluateItem(XPathContext context)
0404:                    throws XPathException {
0405:                return iterate(context).next();
0406:            }
0407:
0408:            /**
0409:             * Process the value as an instruction, without returning any tail calls
0410:             * @param context The dynamic context, giving access to the current node,
0411:             * the current variables, etc.
0412:             */
0413:
0414:            public void process(XPathContext context) throws XPathException {
0415:                SequenceIterator iter = iterate(context);
0416:                SequenceReceiver out = context.getReceiver();
0417:                while (true) {
0418:                    Item it = iter.next();
0419:                    if (it == null)
0420:                        break;
0421:                    out.append(it, 0, NodeInfo.ALL_NAMESPACES);
0422:                }
0423:            }
0424:
0425:            /**
0426:             * Convert the value to a string, using the serialization rules.
0427:             * For atomic values this is the same as a cast; for sequence values
0428:             * it gives a space-separated list.
0429:             * @throws XPathException The method can fail if evaluation of the value
0430:             * has been deferred, and if a failure occurs during the deferred evaluation.
0431:             * No failure is possible in the case of an AtomicValue.
0432:             */
0433:
0434:            public String getStringValue() throws XPathException {
0435:                FastStringBuffer sb = new FastStringBuffer(1024);
0436:                SequenceIterator iter = iterate(null);
0437:                Item item = iter.next();
0438:                if (item != null) {
0439:                    while (true) {
0440:                        sb.append(item.getStringValueCS());
0441:                        item = iter.next();
0442:                        if (item == null) {
0443:                            break;
0444:                        }
0445:                        sb.append(' ');
0446:                    }
0447:                }
0448:                return sb.toString();
0449:            }
0450:
0451:            /**
0452:             * Evaluate an expression as a String. This function must only be called in contexts
0453:             * where it is known that the expression will return a single string (or where an empty sequence
0454:             * is to be treated as a zero-length string). Implementations should not attempt to convert
0455:             * the result to a string, other than converting () to "". This method is used mainly to
0456:             * evaluate expressions produced by compiling an attribute value template.
0457:             *
0458:             * @exception XPathException if any dynamic error occurs evaluating the
0459:             *     expression
0460:             * @exception ClassCastException if the result type of the
0461:             *     expression is not xs:string?
0462:             * @param context The context in which the expression is to be evaluated
0463:             * @return the value of the expression, evaluated in the current context.
0464:             *     The expression must return a string or (); if the value of the
0465:             *     expression is (), this method returns "".
0466:             */
0467:
0468:            public String evaluateAsString(XPathContext context)
0469:                    throws XPathException {
0470:                AtomicValue value = (AtomicValue) evaluateItem(context);
0471:                if (value == null)
0472:                    return "";
0473:                return value.getStringValue();
0474:            }
0475:
0476:            /**
0477:             * Get the effective boolean value of the expression. This returns false if the value
0478:             * is the empty sequence, a zero-length string, a number equal to zero, or the boolean
0479:             * false. Otherwise it returns true.
0480:             *
0481:             * @param context The context in which the expression is to be evaluated
0482:             * @exception XPathException if any dynamic error occurs evaluating the
0483:             *     expression
0484:             * @return the effective boolean value
0485:             */
0486:
0487:            public boolean effectiveBooleanValue(XPathContext context)
0488:                    throws XPathException {
0489:                return ExpressionTool.effectiveBooleanValue(iterate(context));
0490:            }
0491:
0492:            /**
0493:             * Compare two (sequence) values for equality. This supports identity constraints in XML Schema,
0494:             * which allow list-valued elements and attributes to participate in key and uniqueness constraints.
0495:             * This method returns false if any error occurs during the comparison, or if any of the items
0496:             * in either sequence is a node rather than an atomic value.
0497:             */
0498:
0499:            public boolean equals(Object obj) {
0500:                try {
0501:                    if (obj instanceof  Value) {
0502:                        SequenceIterator iter1 = iterate(null);
0503:                        SequenceIterator iter2 = ((Value) obj).iterate(null);
0504:                        while (true) {
0505:                            Item item1 = iter1.next();
0506:                            Item item2 = iter2.next();
0507:                            if (item1 == null && item2 == null) {
0508:                                return true;
0509:                            }
0510:                            if (item1 == null || item2 == null) {
0511:                                return false;
0512:                            }
0513:                            if (item1 instanceof  NodeInfo
0514:                                    || item2 instanceof  NodeInfo) {
0515:                                return false;
0516:                            }
0517:                            if (!item1.equals(item2)) {
0518:                                return false;
0519:                            }
0520:                        }
0521:                    } else {
0522:                        return false;
0523:                    }
0524:                } catch (XPathException e) {
0525:                    return false;
0526:                }
0527:            }
0528:
0529:            /**
0530:             * Compare two (sequence) values for equality. This supports identity constraints in XML Schema,
0531:             * which allow list-valued elements and attributes to participate in key and uniqueness constraints.
0532:             * This method returns false if any error occurs during the comparison, or if any of the items
0533:             * in either sequence is a node rather than an atomic value.
0534:             */
0535:
0536:            public boolean schemaEquals(Value obj) {
0537:                try {
0538:                    SequenceIterator iter1 = iterate(null);
0539:                    SequenceIterator iter2 = obj.iterate(null);
0540:                    while (true) {
0541:                        Item item1 = iter1.next();
0542:                        Item item2 = iter2.next();
0543:                        if (item1 == null && item2 == null) {
0544:                            return true;
0545:                        }
0546:                        if (item1 == null || item2 == null) {
0547:                            return false;
0548:                        }
0549:                        if (item1 instanceof  NodeInfo
0550:                                || item2 instanceof  NodeInfo) {
0551:                            return false;
0552:                        }
0553:                        if (!((AtomicValue) item1)
0554:                                .schemaEquals((AtomicValue) item2)) {
0555:                            return false;
0556:                        }
0557:                    }
0558:                } catch (XPathException e) {
0559:                    return false;
0560:                }
0561:            }
0562:
0563:            /**
0564:             * Return a hash code to support the equals() function
0565:             */
0566:
0567:            public int hashCode() {
0568:                try {
0569:                    int hash = 0x06639662; // arbitrary seed
0570:                    SequenceIterator iter = iterate(null);
0571:                    while (true) {
0572:                        Item item = iter.next();
0573:                        if (item == null) {
0574:                            return hash;
0575:                        }
0576:                        hash ^= item.hashCode();
0577:                    }
0578:                } catch (XPathException e) {
0579:                    return 0;
0580:                }
0581:            }
0582:
0583:            /**
0584:             * Check statically that the results of the expression are capable of constructing the content
0585:             * of a given schema type.
0586:             * @param parentType The schema type
0587:             * @param env the static context
0588:             * @param whole
0589:             * @throws XPathException if the expression doesn't match the required content type
0590:             */
0591:
0592:            public void checkPermittedContents(SchemaType parentType,
0593:                    StaticContext env, boolean whole) throws XPathException {
0594:                return;
0595:            }
0596:
0597:            /**
0598:             * Reduce a value to its simplest form. If the value is a closure or some other form of deferred value
0599:             * such as a FunctionCallPackage, then it is reduced to a SequenceExtent. If it is a SequenceExtent containing
0600:             * a single item, then it is reduced to that item. One consequence that is exploited by class FilterExpression
0601:             * is that if the value is a singleton numeric value, then the result will be an instance of NumericValue
0602:             */
0603:
0604:            public Value reduce() throws XPathException {
0605:                return this ;
0606:            }
0607:
0608:            /**
0609:             * Convert to Java object (for passing to external functions)
0610:             */
0611:
0612:            public Object convertToJava(Class target, XPathContext context)
0613:                    throws XPathException {
0614:
0615:                if (target == Object.class) {
0616:                    List list = new ArrayList(20);
0617:                    return convertToJavaList(list, context);
0618:                }
0619:
0620:                // See if the extension function is written to accept native Saxon objects
0621:
0622:                if (target.isAssignableFrom(this .getClass())) {
0623:                    return this ;
0624:                } else if (target.isAssignableFrom(SequenceIterator.class)) {
0625:                    return iterate(context);
0626:                }
0627:
0628:                // Offer the object to registered external object models
0629:
0630:                if ((this  instanceof  ObjectValue || !(this  instanceof  AtomicValue))
0631:                        && !(this  instanceof  EmptySequence)) {
0632:                    List externalObjectModels = context.getConfiguration()
0633:                            .getExternalObjectModels();
0634:                    for (int m = 0; m < externalObjectModels.size(); m++) {
0635:                        ExternalObjectModel model = (ExternalObjectModel) externalObjectModels
0636:                                .get(m);
0637:                        Object object = model.convertXPathValueToObject(this ,
0638:                                target, context);
0639:                        if (object != null) {
0640:                            return object;
0641:                        }
0642:                    }
0643:                }
0644:
0645:                if (Collection.class.isAssignableFrom(target)) {
0646:                    Collection list;
0647:                    if (target.isAssignableFrom(ArrayList.class)) {
0648:                        list = new ArrayList(100);
0649:                    } else {
0650:                        try {
0651:                            list = (Collection) target.newInstance();
0652:                        } catch (InstantiationException e) {
0653:                            DynamicError de = new DynamicError(
0654:                                    "Cannot instantiate collection class "
0655:                                            + target);
0656:                            de.setXPathContext(context);
0657:                            throw de;
0658:                        } catch (IllegalAccessException e) {
0659:                            DynamicError de = new DynamicError(
0660:                                    "Cannot access collection class " + target);
0661:                            de.setXPathContext(context);
0662:                            throw de;
0663:                        }
0664:                    }
0665:                    return convertToJavaList(list, context);
0666:                } else if (target.isArray()) {
0667:                    Class component = target.getComponentType();
0668:                    if (component.isAssignableFrom(Item.class)
0669:                            || component.isAssignableFrom(NodeInfo.class)
0670:                            || component.isAssignableFrom(DocumentInfo.class)) {
0671:                        Value extent = this ;
0672:                        if (extent instanceof  Closure) {
0673:                            extent = SequenceExtent.makeSequenceExtent(extent
0674:                                    .iterate(null));
0675:                        }
0676:                        int length = extent.getLength();
0677:                        Object array = Array.newInstance(component, length);
0678:                        SequenceIterator iter = extent.iterate(null);
0679:                        for (int i = 0; i < length; i++) {
0680:                            Item item = iter.next();
0681:                            try {
0682:                                Array.set(array, i, item);
0683:                            } catch (IllegalArgumentException err) {
0684:                                DynamicError d = new DynamicError(
0685:                                        "Item "
0686:                                                + i
0687:                                                + " in supplied sequence cannot be converted "
0688:                                                + "to the component type of the Java array ("
0689:                                                + component + ')', err);
0690:                                d.setXPathContext(context);
0691:                                throw d;
0692:                            }
0693:                        }
0694:                        return array;
0695:                    } else /* if (!(this instanceof AtomicValue)) */{
0696:                        // try atomizing the sequence, unless this is a single atomic value, in which case we've already
0697:                        // tried that.
0698:                        SequenceIterator it = Atomizer.AtomizingFunction
0699:                                .getAtomizingIterator(iterate(context));
0700:                        int length;
0701:                        if ((it.getProperties() & SequenceIterator.LAST_POSITION_FINDER) == 0) {
0702:                            SequenceExtent extent = new SequenceExtent(it);
0703:                            length = extent.getLength();
0704:                            it = extent.iterate(context);
0705:                        } else {
0706:                            length = ((LastPositionFinder) it)
0707:                                    .getLastPosition();
0708:                        }
0709:                        Object array = Array.newInstance(component, length);
0710:                        for (int i = 0; i < length; i++) {
0711:                            try {
0712:                                AtomicValue val = (AtomicValue) it.next();
0713:                                Object jval = val.convertToJava(component,
0714:                                        context);
0715:                                Array.set(array, i, jval);
0716:                            } catch (XPathException err) {
0717:                                DynamicError d = new DynamicError(
0718:                                        "Cannot convert item in atomized sequence to the component type of the Java array",
0719:                                        err);
0720:                                d.setXPathContext(context);
0721:                                throw d;
0722:                            }
0723:                        }
0724:                        return array;
0725:                        //            } else {
0726:                        //                DynamicError d = new DynamicError(
0727:                        //                     "Cannot convert supplied argument value to the required type");
0728:                        //                d.setXPathContext(context);
0729:                        //                throw d;
0730:                    }
0731:
0732:                } else if (target.isAssignableFrom(Item.class)
0733:                        || target.isAssignableFrom(NodeInfo.class)
0734:                        || target.isAssignableFrom(DocumentInfo.class)) {
0735:
0736:                    // try passing the first item in the sequence provided it is the only one
0737:                    SequenceIterator iter = iterate(null);
0738:                    Item first = null;
0739:                    while (true) {
0740:                        Item next = iter.next();
0741:                        if (next == null) {
0742:                            break;
0743:                        }
0744:                        if (first != null) {
0745:                            DynamicError err = new DynamicError(
0746:                                    "Sequence contains more than one value; Java method expects only one");
0747:                            err.setXPathContext(context);
0748:                            throw err;
0749:                        }
0750:                        first = next;
0751:                    }
0752:                    if (first == null) {
0753:                        // sequence is empty; pass a Java null
0754:                        return null;
0755:                    }
0756:                    if (target.isAssignableFrom(first.getClass())) {
0757:                        // covers Item and NodeInfo
0758:                        return first;
0759:                    }
0760:
0761:                    Object n = first;
0762:                    while (n instanceof  VirtualNode) {
0763:                        // If we've got a wrapper around a DOM or JDOM node, and the user wants a DOM
0764:                        // or JDOM node, we unwrap it
0765:                        Object vn = ((VirtualNode) n).getUnderlyingNode();
0766:                        if (target.isAssignableFrom(vn.getClass())) {
0767:                            return vn;
0768:                        } else {
0769:                            n = vn;
0770:                        }
0771:                    }
0772:
0773:                    throw new DynamicError(
0774:                            "Cannot convert supplied XPath value to the required type for the extension function");
0775:                } else if (!(this  instanceof  AtomicValue)) {
0776:                    // try atomizing the value, unless this is an atomic value, in which case we've already tried that
0777:                    SequenceIterator it = Atomizer.AtomizingFunction
0778:                            .getAtomizingIterator(iterate(context));
0779:                    Item first = null;
0780:                    while (true) {
0781:                        Item next = it.next();
0782:                        if (next == null) {
0783:                            break;
0784:                        }
0785:                        if (first != null) {
0786:                            DynamicError err = new DynamicError(
0787:                                    "Sequence contains more than one value; Java method expects only one");
0788:                            err.setXPathContext(context);
0789:                            throw err;
0790:                        }
0791:                        first = next;
0792:                    }
0793:                    if (first == null) {
0794:                        // sequence is empty; pass a Java null
0795:                        return null;
0796:                    }
0797:                    if (target.isAssignableFrom(first.getClass())) {
0798:                        return first;
0799:                    } else {
0800:                        return ((AtomicValue) first).convertToJava(target,
0801:                                context);
0802:                    }
0803:                } else {
0804:                    throw new DynamicError(
0805:                            "Cannot convert supplied XPath value to the required type for the extension function");
0806:                }
0807:            }
0808:
0809:            private Collection convertToJavaList(Collection list,
0810:                    XPathContext context) throws XPathException {
0811:                // TODO: with JDK 1.5, check to see if the item type of the list is constrained
0812:                SequenceIterator iter = iterate(null);
0813:                while (true) {
0814:                    Item it = iter.next();
0815:                    if (it == null) {
0816:                        //                if (list.size() == 0) {
0817:                        //                    // map empty sequence to null
0818:                        //                    return null;
0819:                        //                } else {
0820:                        return list;
0821:                        //                }
0822:                    }
0823:                    if (it instanceof  AtomicValue) {
0824:                        list.add(((AtomicValue) it).convertToJava(Object.class,
0825:                                context));
0826:                    } else if (it instanceof  VirtualNode) {
0827:                        list.add(((VirtualNode) it).getUnderlyingNode());
0828:                    } else {
0829:                        list.add(it);
0830:                    }
0831:                }
0832:            }
0833:
0834:            /**
0835:             * Diagnostic display of the expression
0836:             */
0837:
0838:            public void display(int level, NamePool pool, PrintStream out) {
0839:                final TypeHierarchy th = pool.getTypeHierarchy();
0840:                try {
0841:                    out.println(ExpressionTool.indent(level) + "sequence of "
0842:                            + getItemType(th).toString() + " (");
0843:                    SequenceIterator iter = iterate(null);
0844:                    while (true) {
0845:                        Item it = iter.next();
0846:                        if (it == null) {
0847:                            break;
0848:                        }
0849:                        if (it instanceof  NodeInfo) {
0850:                            out.println(ExpressionTool.indent(level + 1)
0851:                                    + "node "
0852:                                    + Navigator.getPath(((NodeInfo) it)));
0853:                        } else {
0854:                            out.println(ExpressionTool.indent(level + 1)
0855:                                    + it.toString());
0856:                        }
0857:                    }
0858:                    out.println(ExpressionTool.indent(level) + ')');
0859:                } catch (XPathException err) {
0860:                    out.println(ExpressionTool.indent(level) + "(*error*)");
0861:                }
0862:            }
0863:
0864:            /**
0865:             * Convert a Java object to an XPath value. This method is called to handle the result
0866:             * of an external function call (but only if the required type is not known),
0867:             * and also to process global parameters passed to the stylesheet or query.
0868:             * @param object The Java object to be converted
0869:             * @param requiredType The required type of the result (if known)
0870:             * @param config The Configuration: may be null, in which case certain kinds of object
0871:             * (eg. DOM nodes) cannot be handled
0872:             * @return the result of converting the value. If the value is null, returns null.
0873:             */
0874:
0875:            public static Value convertJavaObjectToXPath(Object object,
0876:                    SequenceType requiredType, Configuration config)
0877:                    throws XPathException {
0878:
0879:                ItemType requiredItemType = requiredType.getPrimaryType();
0880:
0881:                if (object == null) {
0882:                    return EmptySequence.getInstance();
0883:                }
0884:
0885:                // Offer the object to all the registered external object models
0886:
0887:                List externalObjectModels = config.getExternalObjectModels();
0888:                for (int m = 0; m < externalObjectModels.size(); m++) {
0889:                    ExternalObjectModel model = (ExternalObjectModel) externalObjectModels
0890:                            .get(m);
0891:                    Value val = model.convertObjectToXPathValue(object, config);
0892:                    if (val != null
0893:                            && TypeChecker.testConformance(val, requiredType,
0894:                                    config) == null) {
0895:                        return val;
0896:                    }
0897:                }
0898:
0899:                if (requiredItemType instanceof  ExternalObjectType) {
0900:                    Class theClass = ((ExternalObjectType) requiredItemType)
0901:                            .getJavaClass();
0902:                    if (theClass.isAssignableFrom(object.getClass())) {
0903:                        return new ObjectValue(object);
0904:                    } else {
0905:                        throw new DynamicError(
0906:                                "Supplied parameter value is not of class "
0907:                                        + theClass.getName());
0908:                    }
0909:                }
0910:
0911:                Value value = convertToBestFit(object, config);
0912:                return value;
0913:
0914:            }
0915:
0916:            private static Value convertToBestFit(Object object,
0917:                    Configuration config) throws XPathException {
0918:                if (object instanceof  String) {
0919:                    return StringValue.makeStringValue((String) object);
0920:
0921:                } else if (object instanceof  Character) {
0922:                    return new StringValue(object.toString());
0923:
0924:                } else if (object instanceof  Boolean) {
0925:                    return BooleanValue.get(((Boolean) object).booleanValue());
0926:
0927:                } else if (object instanceof  Double) {
0928:                    return new DoubleValue(((Double) object).doubleValue());
0929:
0930:                } else if (object instanceof  Float) {
0931:                    return new FloatValue(((Float) object).floatValue());
0932:
0933:                } else if (object instanceof  Short) {
0934:                    return new IntegerValue(((Short) object).shortValue(),
0935:                            (AtomicType) BuiltInSchemaFactory
0936:                                    .getSchemaType(StandardNames.XS_SHORT));
0937:                } else if (object instanceof  Integer) {
0938:                    return new IntegerValue(((Integer) object).intValue(),
0939:                            (AtomicType) BuiltInSchemaFactory
0940:                                    .getSchemaType(StandardNames.XS_INT));
0941:                } else if (object instanceof  Long) {
0942:                    return new IntegerValue(((Long) object).longValue(),
0943:                            (AtomicType) BuiltInSchemaFactory
0944:                                    .getSchemaType(StandardNames.XS_LONG));
0945:                } else if (object instanceof  Byte) {
0946:                    return new IntegerValue(((Byte) object).byteValue(),
0947:                            (AtomicType) BuiltInSchemaFactory
0948:                                    .getSchemaType(StandardNames.XS_BYTE));
0949:
0950:                } else if (object instanceof  BigInteger) {
0951:                    return BigIntegerValue.makeValue(((BigInteger) object));
0952:
0953:                } else if (object instanceof  BigDecimal) {
0954:                    return new DecimalValue(((BigDecimal) object));
0955:
0956:                    //        } else if (object instanceof QName) {
0957:                    //            return new QNameValue((QName)object);
0958:                    // TODO: reinstate above lines in JDK 1.5
0959:                } else if (object.getClass().getName().equals(
0960:                        "javax.xml.namespace.QName")) {
0961:                    return makeQNameValue(object, config);
0962:
0963:                } else if (object instanceof  URI) {
0964:                    return new AnyURIValue(object.toString());
0965:
0966:                } else if (object instanceof  URL) {
0967:                    return new AnyURIValue(object.toString());
0968:
0969:                } else if (object instanceof  Closure) {
0970:                    // Force eager evaluation, because of problems with side-effects.
0971:                    // (The value might depend on data that is mutable.)
0972:                    return ExpressionTool.eagerEvaluate((Closure) object,
0973:                            config.getConversionContext());
0974:
0975:                } else if (object instanceof  Value) {
0976:                    return (Value) object;
0977:
0978:                } else if (object instanceof  NodeInfo) {
0979:                    if (((NodeInfo) object).getNamePool() != config
0980:                            .getNamePool()) {
0981:                        throw new DynamicError(
0982:                                "Externally-supplied node belongs to wrong NamePool");
0983:                    }
0984:                    return new SingletonNode((NodeInfo) object);
0985:
0986:                } else if (object instanceof  SequenceIterator) {
0987:                    //return new SequenceIntent((SequenceIterator)object);
0988:                    return Closure
0989:                            .makeIteratorClosure((SequenceIterator) object);
0990:
0991:                } else if (object instanceof  List) {
0992:                    Item[] array = new Item[((List) object).size()];
0993:                    int a = 0;
0994:                    for (Iterator i = ((List) object).iterator(); i.hasNext();) {
0995:                        Object obj = i.next();
0996:                        if (obj instanceof  NodeInfo) {
0997:                            array[a++] = (NodeInfo) obj;
0998:                        } else {
0999:                            Value v = convertToBestFit(obj, config);
1000:                            if (v != null) {
1001:                                if (v instanceof  Item) {
1002:                                    array[a++] = (Item) v;
1003:                                } else if (v instanceof  EmptySequence) {
1004:                                    // no action
1005:                                } else if (v instanceof  SingletonNode) {
1006:                                    NodeInfo node = ((SingletonNode) v)
1007:                                            .getNode();
1008:                                    if (node != null) {
1009:                                        array[a++] = node;
1010:                                    }
1011:                                } else {
1012:                                    throw new DynamicError(
1013:                                            "Returned List contains an object that cannot be converted to an Item ("
1014:                                                    + obj.getClass() + ')');
1015:                                }
1016:                            }
1017:                        }
1018:                    }
1019:
1020:                    return new SequenceExtent(array);
1021:
1022:                } else if (object instanceof  Object[]) {
1023:                    Item[] array = new Item[((Object[]) object).length];
1024:                    int a = 0;
1025:                    for (int i = 0; i < ((Object[]) object).length; i++) {
1026:                        Object obj = ((Object[]) object)[i];
1027:                        if (obj instanceof  NodeInfo) {
1028:                            array[a++] = (NodeInfo) obj;
1029:                        } else if (obj != null) {
1030:                            Value v = convertToBestFit(obj, config);
1031:                            if (v != null) {
1032:                                if (v instanceof  Item) {
1033:                                    array[a++] = (Item) v;
1034:                                } else {
1035:                                    throw new DynamicError(
1036:                                            "Returned array contains an object that cannot be converted to an Item ("
1037:                                                    + obj.getClass() + ')');
1038:                                }
1039:                            }
1040:                        }
1041:                    }
1042:                    return new SequenceExtent(array, 0, a);
1043:
1044:                } else if (object instanceof  long[]) {
1045:                    Item[] array = new Item[((long[]) object).length];
1046:                    for (int i = 0; i < ((long[]) object).length; i++) {
1047:                        array[i] = new IntegerValue(((long[]) object)[i]);
1048:                    }
1049:                    return new SequenceExtent(array);
1050:
1051:                } else if (object instanceof  int[]) {
1052:                    Item[] array = new Item[((int[]) object).length];
1053:                    for (int i = 0; i < ((int[]) object).length; i++) {
1054:                        array[i] = new IntegerValue(((int[]) object)[i]);
1055:                    }
1056:                    return new SequenceExtent(array);
1057:
1058:                } else if (object instanceof  short[]) {
1059:                    Item[] array = new Item[((short[]) object).length];
1060:                    for (int i = 0; i < ((short[]) object).length; i++) {
1061:                        array[i] = new IntegerValue(((short[]) object)[i]);
1062:                    }
1063:                    return new SequenceExtent(array);
1064:
1065:                } else if (object instanceof  byte[]) { // interpret this as unsigned bytes
1066:                    Item[] array = new Item[((byte[]) object).length];
1067:                    for (int i = 0; i < ((byte[]) object).length; i++) {
1068:                        array[i] = new IntegerValue(
1069:                                255 & (int) ((byte[]) object)[i]);
1070:                    }
1071:                    return new SequenceExtent(array);
1072:
1073:                } else if (object instanceof  char[]) {
1074:                    return StringValue.makeStringValue(new String(
1075:                            (char[]) object));
1076:
1077:                } else if (object instanceof  boolean[]) {
1078:                    Item[] array = new Item[((boolean[]) object).length];
1079:                    for (int i = 0; i < ((boolean[]) object).length; i++) {
1080:                        array[i] = BooleanValue.get(((boolean[]) object)[i]);
1081:                    }
1082:                    return new SequenceExtent(array);
1083:
1084:                } else if (object instanceof  Source && config != null) {
1085:                    if (object instanceof  DOMSource) {
1086:                        return new SingletonNode(Controller.unravel(
1087:                                (Source) object, config));
1088:                    }
1089:                    try {
1090:                        Builder b = new TinyBuilder();
1091:                        PipelineConfiguration pipe = config
1092:                                .makePipelineConfiguration();
1093:                        b.setPipelineConfiguration(pipe);
1094:                        new Sender(pipe).send((Source) object, b);
1095:                        return new SingletonNode(b.getCurrentRoot());
1096:                    } catch (XPathException err) {
1097:                        throw new DynamicError(err);
1098:                    }
1099:                } else {
1100:                    // See whether this is an object representing a Node in some recognized object model
1101:                    ExternalObjectModel model = config
1102:                            .findExternalObjectModel(object);
1103:                    if (model != null) {
1104:                        DocumentInfo doc = model.wrapDocument(object, "",
1105:                                config);
1106:                        NodeInfo node = model.wrapNode(doc, object);
1107:                        return Value.asValue(node);
1108:                    }
1109:                }
1110:                return new ObjectValue(object);
1111:            }
1112:
1113:            /**
1114:             * Temporary method to make a QNameValue from a JAXP 1.3 QName, without creating a compile-time link
1115:             * to the JDK 1.5 QName class
1116:             * @param object an instance of javax.xml.namespace.QName
1117:             * @return a corresponding Saxon QNameValue, or null if any error occurs performing the conversion
1118:             */
1119:
1120:            public static QNameValue makeQNameValue(Object object,
1121:                    Configuration config) {
1122:                try {
1123:                    Class qnameClass = config.getClass(
1124:                            "javax.xml.namespace.QName", false, null);
1125:                    Class[] args = EMPTY_CLASS_ARRAY;
1126:                    Method getPrefix = qnameClass.getMethod("getPrefix", args);
1127:                    Method getLocalPart = qnameClass.getMethod("getLocalPart",
1128:                            args);
1129:                    Method getNamespaceURI = qnameClass.getMethod(
1130:                            "getNamespaceURI", args);
1131:                    String prefix = (String) getPrefix.invoke(object, args);
1132:                    String localPart = (String) getLocalPart.invoke(object,
1133:                            args);
1134:                    String uri = (String) getNamespaceURI.invoke(object, args);
1135:                    return new QNameValue(prefix, uri, localPart, config
1136:                            .getNameChecker());
1137:                } catch (XPathException e) {
1138:                    return null;
1139:                } catch (NoSuchMethodException e) {
1140:                    return null;
1141:                } catch (IllegalAccessException e) {
1142:                    return null;
1143:                } catch (InvocationTargetException e) {
1144:                    return null;
1145:                }
1146:            }
1147:
1148:            public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
1149:
1150:            /**
1151:             * Convert to a string for diagnostic output
1152:             */
1153:
1154:            public String toString() {
1155:                try {
1156:                    return getStringValue();
1157:                } catch (XPathException err) {
1158:                    return super .toString();
1159:                }
1160:            }
1161:
1162:            /**
1163:             * Internal method to convert an XPath value to a Java object.
1164:             * An atomic value is returned as an instance
1165:             * of the best available Java class. If the item is a node, the node is "unwrapped",
1166:             * to return the underlying node in the original model (which might be, for example,
1167:             * a DOM or JDOM node).
1168:             */
1169:
1170:            public static Object convert(Item item) throws XPathException {
1171:                if (item instanceof  NodeInfo) {
1172:                    Object node = item;
1173:                    while (node instanceof  VirtualNode) {
1174:                        // strip off any layers of wrapping
1175:                        node = ((VirtualNode) node).getUnderlyingNode();
1176:                    }
1177:                    return node;
1178:                } else {
1179:                    switch (((AtomicValue) item).getItemType(null)
1180:                            .getPrimitiveType()) {
1181:                    case Type.STRING:
1182:                    case Type.UNTYPED_ATOMIC:
1183:                    case Type.ANY_URI:
1184:                    case Type.DURATION:
1185:                        return item.getStringValue();
1186:                    case Type.BOOLEAN:
1187:                        return (((BooleanValue) item).getBooleanValue() ? Boolean.TRUE
1188:                                : Boolean.FALSE);
1189:                    case Type.DECIMAL:
1190:                        return ((DecimalValue) item).getValue();
1191:                    case Type.INTEGER:
1192:                        return new Long(((NumericValue) item).longValue());
1193:                    case Type.DOUBLE:
1194:                        return new Double(((DoubleValue) item).getDoubleValue());
1195:                    case Type.FLOAT:
1196:                        return new Float(((FloatValue) item).getValue());
1197:                    case Type.DATE_TIME:
1198:                        return ((DateTimeValue) item).getCalendar().getTime();
1199:                    case Type.DATE:
1200:                        return ((DateValue) item).getCalendar().getTime();
1201:                    case Type.TIME:
1202:                        return item.getStringValue();
1203:                    case Type.BASE64_BINARY:
1204:                        return ((Base64BinaryValue) item).getBinaryValue();
1205:                    case Type.HEX_BINARY:
1206:                        return ((HexBinaryValue) item).getBinaryValue();
1207:                    default:
1208:                        return item;
1209:                    }
1210:                }
1211:            }
1212:        }
1213:
1214:        //
1215:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
1216:        // you may not use this file except in compliance with the License. You may obtain a copy of the
1217:        // License at http://www.mozilla.org/MPL/
1218:        //
1219:        // Software distributed under the License is distributed on an "AS IS" basis,
1220:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
1221:        // See the License for the specific language governing rights and limitations under the License.
1222:        //
1223:        // The Original Code is: all this file.
1224:        //
1225:        // The Initial Developer of the Original Code is Michael H. Kay.
1226:        //
1227:        // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
1228:        //
1229:        // Contributor(s): none.
1230:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.