KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > FunctionAvailableCall


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: FunctionAvailableCall.java,v 1.19 2004/02/23 10:29:35 aruny Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.Vector JavaDoc;
25
26 import org.apache.bcel.generic.ConstantPoolGen;
27 import org.apache.bcel.generic.PUSH;
28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
29 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
30 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
31 import org.apache.xalan.xsltc.compiler.util.Type;
32 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
33 import org.apache.xalan.xsltc.compiler.util.Util;
34
35 /**
36  * @author G. Todd Miller
37  * @author Santiago Pericas-Geertsen
38  */

39 final class FunctionAvailableCall extends FunctionCall {
40
41     private Expression _arg;
42     private String JavaDoc _nameOfFunct = null;
43     private String JavaDoc _namespaceOfFunct = null;
44     private boolean _isFunctionAvailable = false;
45
46     /**
47      * Constructs a FunctionAvailableCall FunctionCall. Takes the
48      * function name qname, for example, 'function-available', and
49      * a list of arguments where the arguments must be instances of
50      * LiteralExpression.
51      */

52     public FunctionAvailableCall(QName fname, Vector JavaDoc arguments) {
53     super(fname, arguments);
54     _arg = (Expression)arguments.elementAt(0);
55     _type = null;
56
57         if (_arg instanceof LiteralExpr) {
58         LiteralExpr arg = (LiteralExpr) _arg;
59             _namespaceOfFunct = arg.getNamespace();
60             _nameOfFunct = arg.getValue();
61
62             if (!isInternalNamespace()) {
63               _isFunctionAvailable = hasMethods();
64             }
65         }
66     }
67
68     /**
69      * Argument of function-available call must be literal, typecheck
70      * returns the type of function-available to be boolean.
71      */

72     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
73     if (_type != null) {
74        return _type;
75     }
76     if (_arg instanceof LiteralExpr) {
77         return _type = Type.Boolean;
78     }
79     ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
80             "function-available", this);
81     throw new TypeCheckError(err);
82     }
83
84     /**
85      * Returns an object representing the compile-time evaluation
86      * of an expression. We are only using this for function-available
87      * and element-available at this time.
88      */

89     public Object JavaDoc evaluateAtCompileTime() {
90     return getResult() ? Boolean.TRUE : Boolean.FALSE;
91     }
92
93     /**
94      * for external java functions only: reports on whether or not
95      * the specified method is found in the specifed class.
96      */

97     private boolean hasMethods() {
98     LiteralExpr arg = (LiteralExpr)_arg;
99     
100     // Get the class name from the namespace uri
101
String JavaDoc className = getClassNameFromUri(_namespaceOfFunct);
102     
103     // Get the method name from the argument to function-available
104
String JavaDoc methodName = null;
105     int colonIndex = _nameOfFunct.indexOf(":");
106     if (colonIndex > 0) {
107       String JavaDoc functionName = _nameOfFunct.substring(colonIndex+1);
108       int lastDotIndex = functionName.lastIndexOf('.');
109       if (lastDotIndex > 0) {
110         methodName = functionName.substring(lastDotIndex+1);
111         if (className != null && !className.equals(""))
112           className = className + "." + functionName.substring(0, lastDotIndex);
113         else
114           className = functionName.substring(0, lastDotIndex);
115       }
116       else
117         methodName = functionName;
118     }
119     else
120       methodName = _nameOfFunct;
121       
122     if (className == null || methodName == null) {
123         return false;
124     }
125     
126     // Replace the '-' characters in the method name
127
if (methodName.indexOf('-') > 0)
128       methodName = replaceDash(methodName);
129
130     try {
131             final Class JavaDoc clazz = ObjectFactory.findProviderClass(
132                 className, ObjectFactory.findClassLoader(), true);
133
134         if (clazz == null) {
135             return false;
136         }
137
138         final Method JavaDoc[] methods = clazz.getMethods();
139
140         for (int i = 0; i < methods.length; i++) {
141         final int mods = methods[i].getModifiers();
142
143         if (Modifier.isPublic(mods) && Modifier.isStatic(mods)
144             && methods[i].getName().equals(methodName))
145         {
146             return true;
147         }
148         }
149     }
150     catch (ClassNotFoundException JavaDoc e) {
151       return false;
152     }
153         return false;
154     }
155
156     /**
157      * Reports on whether the function specified in the argument to
158      * xslt function 'function-available' was found.
159      */

160     public boolean getResult() {
161     if (_nameOfFunct == null) {
162         return false;
163     }
164
165         if (isInternalNamespace()) {
166             final Parser parser = getParser();
167             _isFunctionAvailable =
168         parser.functionSupported(Util.getLocalName(_nameOfFunct));
169         }
170     return _isFunctionAvailable;
171     }
172     
173     /**
174      * Return true if the namespace uri is null or it is the XSLTC translet uri.
175      */

176     private boolean isInternalNamespace() {
177         return (_namespaceOfFunct == null ||
178             _namespaceOfFunct.equals(EMPTYSTRING) ||
179         _namespaceOfFunct.equals(TRANSLET_URI));
180     }
181
182     /**
183      * Calls to 'function-available' are resolved at compile time since
184      * the namespaces declared in the stylsheet are not available at run
185      * time. Consequently, arguments to this function must be literals.
186      */

187     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
188     final ConstantPoolGen cpg = classGen.getConstantPool();
189     methodGen.getInstructionList().append(new PUSH(cpg, getResult()));
190     }
191
192 }
193
Popular Tags