Source Code Cross Referenced for ExtensionFunctionCall.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.Configuration;
004:        import net.sf.saxon.expr.*;
005:        import net.sf.saxon.om.*;
006:        import net.sf.saxon.pattern.AnyNodeTest;
007:        import net.sf.saxon.trans.DynamicError;
008:        import net.sf.saxon.trans.XPathException;
009:        import net.sf.saxon.type.*;
010:        import net.sf.saxon.type.Type;
011:        import net.sf.saxon.value.*;
012:
013:        import javax.xml.transform.Source;
014:        import java.io.IOException;
015:        import java.io.ObjectInputStream;
016:        import java.io.ObjectOutputStream;
017:        import java.io.Serializable;
018:        import java.lang.reflect.*;
019:        import java.util.List;
020:        import java.math.BigDecimal;
021:
022:        /**
023:         * This class acts as a container for an extension function defined to call a method
024:         * in a user-defined class.
025:         *
026:         * <p>Note that the binding of an XPath function call to a Java method is done in
027:         * class {@link JavaExtensionLibrary}</p>
028:         */
029:
030:        public class ExtensionFunctionCall extends FunctionCall {
031:
032:            private transient AccessibleObject theMethod;
033:            // declared transient because AccessibleObject is not serializable
034:            private MethodRepresentation persistentMethod;
035:            // a serializable representation of the method, constructor, or field to be called
036:            private Class theClass;
037:            private Configuration config;
038:
039:            /**
040:             * Default constructor
041:             */
042:
043:            public ExtensionFunctionCall() {
044:            }
045:
046:            /**
047:             * Initialization: creates an ExtensionFunctionCall
048:             * @param nameCode the name code of the function, for display purposes
049:             * @param theClass the Java class containing the method to be called
050:             * @param object the method, field, or constructor of the Java class to be called
051:             */
052:
053:            public void init(int nameCode, Class theClass,
054:                    AccessibleObject object, Configuration config) {
055:                setFunctionNameCode(nameCode);
056:                this .theClass = theClass;
057:                this .theMethod = object;
058:                this .config = config;
059:            }
060:
061:            /**
062:             * preEvaluate: this method suppresses compile-time evaluation by doing nothing
063:             * (because the external function might have side-effects and might use the context)
064:             */
065:
066:            public Expression preEvaluate(StaticContext env) {
067:                return this ;
068:            }
069:
070:            /**
071:             * Method called by the expression parser when all arguments have been supplied
072:             */
073:
074:            public void checkArguments(StaticContext env) throws XPathException {
075:            }
076:
077:            /**
078:             * Determine which aspects of the context the expression depends on. The result is
079:             * a bitwise-or'ed value composed from constants such as XPathContext.VARIABLES and
080:             * XPathContext.CURRENT_NODE
081:             */
082:
083:            public int getIntrinsicDependencies() {
084:                if (theMethod instanceof  Method) {
085:                    Class[] theParameterTypes = ((Method) theMethod)
086:                            .getParameterTypes();
087:                    if (theParameterTypes.length > 0
088:                            && theParameterTypes[0] == XPathContext.class) {
089:                        return StaticProperty.DEPENDS_ON_CONTEXT_ITEM
090:                                | StaticProperty.DEPENDS_ON_POSITION
091:                                | StaticProperty.DEPENDS_ON_LAST;
092:                    }
093:                }
094:                return 0;
095:            }
096:
097:            /**
098:             * Evaluate the function. <br>
099:             * @param context The context in which the function is to be evaluated
100:             * @return a Value representing the result of the function.
101:             * @throws net.sf.saxon.trans.XPathException if the function cannot be evaluated.
102:             */
103:
104:            public SequenceIterator iterate(XPathContext context)
105:                    throws XPathException {
106:                ValueRepresentation[] argValues = new ValueRepresentation[argument.length];
107:                for (int i = 0; i < argValues.length; i++) {
108:                    argValues[i] = ExpressionTool.lazyEvaluate(argument[i],
109:                            context, 1);
110:                }
111:                try {
112:                    return call(argValues, context);
113:                } catch (XPathException err) {
114:                    String msg = err.getMessage();
115:                    msg = "Error in call to extension function {"
116:                            + theMethod.toString() + "}: " + msg;
117:                    DynamicError err2 = new DynamicError(msg, err
118:                            .getException());
119:                    err2.setXPathContext(context);
120:                    err2.setLocator(this );
121:                    err2.setErrorCode(err.getErrorCodeLocalPart());
122:                    throw err2;
123:                }
124:            }
125:
126:            /**
127:             * Get the class containing the method being called
128:             */
129:
130:            public Class getTargetClass() {
131:                return theClass;
132:            }
133:
134:            /**
135:             * Get the target method (or field, or constructor) being called
136:             */
137:
138:            public AccessibleObject getTargetMethod() {
139:                return theMethod;
140:            }
141:
142:            /**
143:             * Call an extension function previously identified using the bind() method. A subclass
144:             * can override this method.
145:             * @param argValues  The values of the arguments
146:             * @return  The value returned by the extension function
147:             */
148:
149:            private SequenceIterator call(ValueRepresentation[] argValues,
150:                    XPathContext context) throws XPathException {
151:
152:                Class[] theParameterTypes;
153:
154:                if (theMethod instanceof  Constructor) {
155:                    Constructor constructor = (Constructor) theMethod;
156:                    theParameterTypes = constructor.getParameterTypes();
157:                    Object[] params = new Object[theParameterTypes.length];
158:
159:                    setupParams(argValues, params, theParameterTypes, 0, 0,
160:                            context);
161:
162:                    try {
163:                        Object result = invokeConstructor(constructor, params);
164:                        return asIterator(result, context);
165:                    } catch (InstantiationException err0) {
166:                        DynamicError e = new DynamicError(
167:                                "Cannot instantiate class", err0);
168:                        throw e;
169:                    } catch (IllegalAccessException err1) {
170:                        DynamicError e = new DynamicError(
171:                                "Constructor access is illegal", err1);
172:                        throw e;
173:                    } catch (IllegalArgumentException err2) {
174:                        DynamicError e = new DynamicError(
175:                                "Argument is of wrong type", err2);
176:                        throw e;
177:                    } catch (NullPointerException err2) {
178:                        DynamicError e = new DynamicError("Object is null");
179:                        throw e;
180:                    } catch (InvocationTargetException err3) {
181:                        Throwable ex = err3.getTargetException();
182:                        if (ex instanceof  XPathException) {
183:                            throw (XPathException) ex;
184:                        } else {
185:                            if (context.getController().isTracing()
186:                                    || context.getConfiguration()
187:                                            .isTraceExternalFunctions()) {
188:                                err3.getTargetException().printStackTrace();
189:                            }
190:                            DynamicError e = new DynamicError(
191:                                    "Exception in extension function: "
192:                                            + err3.getTargetException()
193:                                                    .toString(), ex);
194:                            throw e;
195:                        }
196:                    }
197:                } else if (theMethod instanceof  Method) {
198:                    Method method = (Method) theMethod;
199:                    boolean isStatic = Modifier.isStatic(method.getModifiers());
200:                    Object theInstance;
201:                    theParameterTypes = method.getParameterTypes();
202:                    boolean usesContext = theParameterTypes.length > 0
203:                            && (theParameterTypes[0] == XPathContext.class);
204:                    if (isStatic) {
205:                        theInstance = null;
206:                    } else {
207:                        if (argValues.length == 0) {
208:                            DynamicError e = new DynamicError(
209:                                    "Must supply an argument for an instance-level extension function");
210:                            throw e;
211:                        }
212:                        Value arg0 = Value.asValue(argValues[0]);
213:                        theInstance = arg0.convertToJava(theClass, context);
214:                        // this fails if the first argument is not of a suitable class
215:                    }
216:
217:                    Object[] params = new Object[theParameterTypes.length];
218:
219:                    if (usesContext) {
220:                        params[0] = context;
221:                    }
222:
223:                    setupParams(argValues, params, theParameterTypes,
224:                            (usesContext ? 1 : 0), (isStatic ? 0 : 1), context);
225:
226:                    try {
227:                        Object result = invokeMethod(method, theInstance,
228:                                params);
229:                        //Object result = method.invoke(theInstance, params);
230:                        if (method.getReturnType().toString().equals("void")) {
231:                            // method returns void:
232:                            // tried (method.getReturnType()==Void.class) unsuccessfully
233:                            return EmptyIterator.getInstance();
234:                        }
235:                        return asIterator(result, context);
236:
237:                    } catch (IllegalAccessException err1) {
238:                        throw new DynamicError("Method access is illegal", err1);
239:                    } catch (IllegalArgumentException err2) {
240:                        throw new DynamicError("Argument is of wrong type",
241:                                err2);
242:                    } catch (NullPointerException err2) {
243:                        throw new DynamicError("Object is null", err2);
244:                    } catch (InvocationTargetException err3) {
245:                        Throwable ex = err3.getTargetException();
246:                        if (ex instanceof  XPathException) {
247:                            throw (XPathException) ex;
248:                        } else {
249:                            if (context.getController().isTracing()
250:                                    || context.getConfiguration()
251:                                            .isTraceExternalFunctions()) {
252:                                err3.getTargetException().printStackTrace();
253:                            }
254:                            throw new DynamicError(
255:                                    "Exception in extension function "
256:                                            + err3.getTargetException()
257:                                                    .toString(), ex);
258:                        }
259:                    }
260:                } else if (theMethod instanceof  Field) {
261:
262:                    // Start of code added by GS
263:
264:                    Field field = (Field) theMethod;
265:                    boolean isStatic = Modifier.isStatic(field.getModifiers());
266:                    Object theInstance;
267:                    if (isStatic) {
268:                        theInstance = null;
269:                    } else {
270:                        if (argValues.length == 0) {
271:                            DynamicError e = new DynamicError(
272:                                    "Must supply an argument for an instance-level extension function");
273:                            throw e;
274:                        }
275:                        Value arg0 = Value.asValue(argValues[0]);
276:                        theInstance = arg0.convertToJava(theClass, context);
277:                        // this fails if the first argument is not of a suitable class
278:                    }
279:
280:                    try {
281:                        Object result = getField(field, theInstance);
282:                        return asIterator(result, context);
283:
284:                    } catch (IllegalAccessException err1) {
285:                        DynamicError e = new DynamicError(
286:                                "Field access is illegal", err1);
287:                        throw e;
288:                    } catch (IllegalArgumentException err2) {
289:                        DynamicError e = new DynamicError(
290:                                "Argument is of wrong type", err2);
291:                        throw e;
292:                    }
293:                } else {
294:                    throw new AssertionError("property " + theMethod
295:                            + " is neither constructor, method, nor field");
296:                }
297:
298:            }
299:
300:            /**
301:             * Convert the extension function result to an XPath value (a sequence) and return a
302:             * SequenceIterator over that sequence
303:             * @param result the result returned by the Java extension function
304:             * @param context the dynamic context
305:             * @return an iterator over the items in the result
306:             * @throws net.sf.saxon.trans.XPathException
307:             */
308:
309:            private SequenceIterator asIterator(Object result,
310:                    XPathContext context) throws XPathException {
311:                if (result == null) {
312:                    return EmptyIterator.getInstance();
313:                }
314:                if (result instanceof  SequenceIterator) {
315:                    return (SequenceIterator) result;
316:                }
317:                if (result instanceof  Value) {
318:                    return ((Value) result).iterate(null);
319:                }
320:                if (result instanceof  NodeInfo) {
321:                    return SingletonIterator.makeIterator(((NodeInfo) result));
322:                }
323:                Value actual = Value.convertJavaObjectToXPath(result,
324:                        SequenceType.ANY_SEQUENCE, context.getConfiguration());
325:                return actual.iterate(context);
326:            }
327:
328:            /**
329:             * Set up parameters for the Java method call
330:             * @param argValues the supplied XPath argument values
331:             * @param params the result of converting the XPath argument values to Java objects
332:             * @param paramTypes the Java classes defining the types of the arguments in the method signature
333:             * @param firstParam normally 0, but 1 if the first parameter to the Java method is an XPathContext object
334:             * @param firstArg normally 0, but 1 if the first argument in the XPath call is the instance object whose method
335:             * is to be called
336:             * @param context The dynamic context, giving access to a NamePool and to schema information
337:             * @throws net.sf.saxon.trans.XPathException
338:             */
339:
340:            private void setupParams(ValueRepresentation[] argValues,
341:                    Object[] params, Class[] paramTypes, int firstParam,
342:                    int firstArg, XPathContext context) throws XPathException {
343:                int j = firstParam;
344:                for (int i = firstArg; i < argValues.length; i++) {
345:                    argValues[i] = Value.asValue(argValues[i]);
346:                    params[j] = ((Value) argValues[i]).convertToJava(
347:                            paramTypes[j], context);
348:                    j++;
349:                }
350:            }
351:
352:            /**
353:             * Determine the data type of the expression, if possible. All expressions return
354:             * sequences, in general; this method determines the type of the items within the
355:             * sequence, assuming that (a) this is known in advance, and (b) it is the same for
356:             * all items in the sequence.
357:             *
358:             * <p>This method will always return a result, though it may be the best approximation
359:             * that is available at the time.</p>
360:             *
361:             * @return the item type
362:             * @param th
363:             */
364:
365:            public ItemType getItemType(TypeHierarchy th) {
366:                return convertClassToType(getReturnClass());
367:            }
368:
369:            private ItemType convertClassToType(Class resultClass) {
370:                if (resultClass == null || resultClass == Value.class) {
371:                    return AnyItemType.getInstance();
372:                } else if (resultClass.toString().equals("void")) {
373:                    return AnyItemType.getInstance();
374:                } else if (resultClass == String.class
375:                        || resultClass == StringValue.class) {
376:                    return Type.STRING_TYPE;
377:                } else if (resultClass == Boolean.class
378:                        || resultClass == boolean.class
379:                        || resultClass == BooleanValue.class) {
380:                    return Type.BOOLEAN_TYPE;
381:                } else if (resultClass == Double.class
382:                        || resultClass == double.class
383:                        || resultClass == DoubleValue.class) {
384:                    return Type.DOUBLE_TYPE;
385:                } else if (resultClass == Float.class
386:                        || resultClass == float.class
387:                        || resultClass == FloatValue.class) {
388:                    return Type.FLOAT_TYPE;
389:                } else if (resultClass == Long.class
390:                        || resultClass == long.class
391:                        || resultClass == IntegerValue.class
392:                        || resultClass == BigIntegerValue.class
393:                        || resultClass == Integer.class
394:                        || resultClass == int.class
395:                        || resultClass == Short.class
396:                        || resultClass == short.class
397:                        || resultClass == Byte.class
398:                        || resultClass == byte.class) {
399:                    return Type.INTEGER_TYPE;
400:                } else if (resultClass == BigDecimal.class) {
401:                    return Type.DECIMAL_TYPE;
402:                } else if (Value.class.isAssignableFrom(resultClass)
403:                        || SequenceIterator.class.isAssignableFrom(resultClass)) {
404:                    return AnyItemType.getInstance();
405:
406:                } else {
407:                    // Offer the object to all the registered external object models
408:                    List externalObjectModels = config
409:                            .getExternalObjectModels();
410:                    for (int m = 0; m < externalObjectModels.size(); m++) {
411:                        ExternalObjectModel model = (ExternalObjectModel) externalObjectModels
412:                                .get(m);
413:                        if (model.isRecognizedNodeClass(resultClass)) {
414:                            return AnyNodeTest.getInstance();
415:                        }
416:                    }
417:                }
418:
419:                if (NodeInfo.class.isAssignableFrom(resultClass)
420:                        || Source.class.isAssignableFrom(resultClass)) {
421:                    return AnyNodeTest.getInstance();
422:                    // we could be more specific regarding the kind of node
423:                } else if (List.class.isAssignableFrom(resultClass)) {
424:                    return AnyItemType.getInstance();
425:                } else if (resultClass.isArray()) {
426:                    Class component = resultClass.getComponentType();
427:                    return convertClassToType(component);
428:                } else {
429:                    return new ExternalObjectType(resultClass);
430:                }
431:            }
432:
433:            public int computeCardinality() {
434:                Class resultClass = getReturnClass();
435:                if (resultClass == null) {
436:                    // we don't know yet
437:                    return StaticProperty.ALLOWS_ZERO_OR_MORE;
438:                }
439:                if (Value.class.isAssignableFrom(resultClass)
440:                        || SequenceIterator.class.isAssignableFrom(resultClass)
441:                        || List.class.isAssignableFrom(resultClass)
442:                        || Closure.class.isAssignableFrom(resultClass)
443:                        || Source.class.isAssignableFrom(resultClass)
444:                        || resultClass.isArray()) {
445:                    return StaticProperty.ALLOWS_ZERO_OR_MORE;
446:                }
447:                List models = config.getExternalObjectModels();
448:                for (int m = 0; m < models.size(); m++) {
449:                    ExternalObjectModel model = (ExternalObjectModel) models
450:                            .get(m);
451:                    if (model.isRecognizedNodeClass(resultClass)) {
452:                        return StaticProperty.ALLOWS_ZERO_OR_ONE;
453:                    } else if (model.isRecognizedNodeListClass(resultClass)) {
454:                        return StaticProperty.ALLOWS_ZERO_OR_MORE;
455:                    }
456:                }
457:                if (resultClass.isPrimitive()) {
458:                    if (resultClass.equals(Void.TYPE)) {
459:                        // this always returns an empty sequence, but we'll model it as
460:                        // zero or one
461:                        return StaticProperty.ALLOWS_ZERO_OR_ONE;
462:                    } else {
463:                        // return type = int, boolean, char etc
464:                        return StaticProperty.EXACTLY_ONE;
465:                    }
466:                } else {
467:                    return StaticProperty.ALLOWS_ZERO_OR_ONE;
468:                }
469:            }
470:
471:            /**
472:             * Get the Java class of the value returned by the method
473:             * @return the Java class of the value returned by the method
474:             */
475:
476:            private Class getReturnClass() {
477:                if (theMethod instanceof  Method) {
478:                    return ((Method) theMethod).getReturnType();
479:                } else if (theMethod instanceof  Field) {
480:                    return ((Field) theMethod).getType();
481:                } else if (theMethod instanceof  Constructor) {
482:                    return theClass;
483:                } else {
484:                    // cannot happen
485:                    return null;
486:                }
487:            }
488:
489:            /**
490:             * Determine whether this method uses the focus. True if the first argument is of type XPathContext.
491:             */
492:
493:            public boolean usesFocus() { // NOT CURRENTLY USED
494:                if (theMethod instanceof  Method) {
495:                    Class[] theParameterTypes = ((Method) theMethod)
496:                            .getParameterTypes();
497:                    return theParameterTypes.length > 0
498:                            && (theParameterTypes[0] == XPathContext.class);
499:                } else {
500:                    return false;
501:                }
502:            }
503:
504:            /**
505:             * Invoke a constructor. This method is provided separately so that it can be refined in a subclass.
506:             * For example, a subclass might perform tracing of calls, or might trap exceptions.
507:             * @param constructor The constructor to be invoked
508:             * @param params The parameters to be passed to the constructor
509:             * @return The object returned by the constructor
510:             * @throws InstantiationException if the invocation throws an InstantiationException
511:             * @throws IllegalAccessException if the invocation throws an IllegalAccessException
512:             * @throws InvocationTargetException if the invocation throws an InvocationTargetException (which happens
513:             * when the constructor itself throws an exception)
514:             */
515:
516:            protected Object invokeConstructor(Constructor constructor,
517:                    Object[] params) throws java.lang.InstantiationException,
518:                    java.lang.IllegalAccessException,
519:                    java.lang.reflect.InvocationTargetException {
520:                return constructor.newInstance(params);
521:            }
522:
523:            /**
524:             * Invoke a method. This method is provided separately so that it can be refined in a subclass.
525:             * For example, a subclass might perform tracing of calls, or might trap exceptions.
526:             * @param method The method to be invoked
527:             * @param instance The object on which the method is to be invoked. This is set to null if the
528:             * method is static.
529:             * @param params The parameters to be passed to the method
530:             * @return The object returned by the method
531:             * @throws IllegalAccessException if the invocation throws an IllegalAccessException
532:             * @throws InvocationTargetException if the invocation throws an InvocationTargetException (which happens
533:             * when the method itself throws an exception)
534:             */
535:
536:            protected Object invokeMethod(Method method, Object instance,
537:                    Object[] params) throws java.lang.IllegalAccessException,
538:                    java.lang.reflect.InvocationTargetException {
539:                return method.invoke(instance, params);
540:            }
541:
542:            /**
543:             * Access a field. This method is provided separately so that it can be refined in a subclass.
544:             * For example, a subclass might perform tracing of calls, or might trap exceptions.
545:             * @param field The field to be retrieved
546:             * @param instance The object whose field is to be retrieved. This is set to null if the
547:             * field is static.
548:             * @return The value of the field
549:             * @throws IllegalAccessException if the invocation throws an IllegalAccessException
550:             */
551:
552:            protected Object getField(Field field, Object instance)
553:                    throws java.lang.IllegalAccessException {
554:                return field.get(instance);
555:            }
556:
557:            /**
558:             * Code to handle serialization, used when compiling a stylesheet containing calls to extension functions
559:             */
560:
561:            private void writeObject(ObjectOutputStream s) throws IOException {
562:                persistentMethod = new MethodRepresentation(theClass, theMethod);
563:                s.defaultWriteObject();
564:            }
565:
566:            /**
567:             * Code to handle deserialization, used when reading in a compiled stylesheet
568:             */
569:
570:            private void readObject(ObjectInputStream s) throws IOException {
571:                try {
572:                    s.defaultReadObject();
573:                    theMethod = persistentMethod.recoverAccessibleObject();
574:                } catch (Exception e) {
575:                    throw new IOException(
576:                            "Failed to read compiled representation of extension function call to "
577:                                    + theClass.getClass());
578:                }
579:            }
580:
581:            /**
582:             * A Java AccessibleObject is not serializable. When compiling a stylesheet that contains extension
583:             * functions, we therefore need to create a serializable representation of the method (or constructor
584:             * or field) to be called. This is provided by the class MethodRepresentation.
585:             */
586:
587:            private static class MethodRepresentation implements  Serializable {
588:                private Class theClass;
589:                private byte category; // one of Method, Constructor, Field
590:                private String name; // the name of the method or field
591:                private Class[] params; // the types of the parameters to a method or constructor
592:
593:                public MethodRepresentation(Class theClass, AccessibleObject obj) {
594:                    this .theClass = theClass;
595:                    if (obj instanceof  Method) {
596:                        category = 0;
597:                        name = ((Method) obj).getName();
598:                        params = ((Method) obj).getParameterTypes();
599:                    } else if (obj instanceof  Constructor) {
600:                        category = 1;
601:                        params = ((Constructor) obj).getParameterTypes();
602:                    } else {
603:                        category = 2;
604:                        name = ((Field) obj).getName();
605:                    }
606:                }
607:
608:                public AccessibleObject recoverAccessibleObject()
609:                        throws NoSuchMethodException, NoSuchFieldException {
610:                    switch (category) {
611:                    case 0:
612:                        return theClass.getMethod(name, params);
613:                    case 1:
614:                        return theClass.getConstructor(params);
615:                    case 2:
616:                        return theClass.getField(name);
617:                    default:
618:                        return null;
619:                    }
620:                }
621:            }
622:
623:        }
624:
625:        //
626:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
627:        // you may not use this file except in compliance with the License. You may obtain a copy of the
628:        // License at http://www.mozilla.org/MPL/
629:        //
630:        // Software distributed under the License is distributed on an "AS IS" basis,
631:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
632:        // See the License for the specific language governing rights and limitations under the License.
633:        //
634:        // The Original Code is: all this file.
635:        //
636:        // The Initial Developer of the Original Code is Michael H. Kay.
637:        //
638:        // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
639:        //
640:        // Contributor(s): Gunther Schadow (changes to allow access to public fields; also wrapping
641:        // of extensions and mapping of null to empty sequence).
642:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.