FileDocCategorySizeDatePackage
FunctionAvailableCall.javaAPI DocJava SE 5 API6126Fri Aug 26 14:55:34 BST 2005com.sun.org.apache.xalan.internal.xsltc.compiler

FunctionAvailableCall

public final class FunctionAvailableCall extends FunctionCall
author
G. Todd Miller
author
Santiago Pericas-Geertsen

Fields Summary
private Expression
_arg
private String
_nameOfFunct
private String
_namespaceOfFunct
private boolean
_isFunctionAvailable
Constructors Summary
public FunctionAvailableCall(QName fname, Vector arguments)
Constructs a FunctionAvailableCall FunctionCall. Takes the function name qname, for example, 'function-available', and a list of arguments where the arguments must be instances of LiteralExpression.

 

                                     
         
	super(fname, arguments);
	_arg = (Expression)arguments.elementAt(0);
	_type = null; 

        if (_arg instanceof LiteralExpr) {
	    LiteralExpr arg = (LiteralExpr) _arg;
            _namespaceOfFunct = arg.getNamespace();
            _nameOfFunct = arg.getValue();

            if (!isInternalNamespace()) {
              _isFunctionAvailable = hasMethods();
            }
        }
    
Methods Summary
public java.lang.ObjectevaluateAtCompileTime()
Returns an object representing the compile-time evaluation of an expression. We are only using this for function-available and element-available at this time.

	return getResult() ? Boolean.TRUE : Boolean.FALSE;
    
public booleangetResult()
Reports on whether the function specified in the argument to xslt function 'function-available' was found.

	if (_nameOfFunct == null) { 
	    return false;
	}

        if (isInternalNamespace()) {
            final Parser parser = getParser();
            _isFunctionAvailable = 
		parser.functionSupported(Util.getLocalName(_nameOfFunct));
        }
 	return _isFunctionAvailable;
    
private booleanhasMethods()
for external java functions only: reports on whether or not the specified method is found in the specifed class.

	LiteralExpr arg = (LiteralExpr)_arg;
	
	// Get the class name from the namespace uri
	String className = getClassNameFromUri(_namespaceOfFunct);
	
	// Get the method name from the argument to function-available
	String methodName = null;
	int colonIndex = _nameOfFunct.indexOf(":");
	if (colonIndex > 0) {
	  String functionName = _nameOfFunct.substring(colonIndex+1);
	  int lastDotIndex = functionName.lastIndexOf('.");
	  if (lastDotIndex > 0) {
	    methodName = functionName.substring(lastDotIndex+1);
	    if (className != null && !className.equals(""))
	      className = className + "." + functionName.substring(0, lastDotIndex);
	    else
	      className = functionName.substring(0, lastDotIndex);
	  }
	  else
	    methodName = functionName;
	}
	else
	  methodName = _nameOfFunct;
	  
	if (className == null || methodName == null) {
	    return false;
	}
	
	// Replace the '-' characters in the method name
	if (methodName.indexOf('-") > 0)
	  methodName = replaceDash(methodName);

	try {
            final Class clazz = ObjectFactory.findProviderClass(
                className, ObjectFactory.findClassLoader(), true);

	    if (clazz == null) {
	    	return false;
	    }

	    final Method[] methods = clazz.getMethods();

	    for (int i = 0; i < methods.length; i++) {
		final int mods = methods[i].getModifiers();

		if (Modifier.isPublic(mods) && Modifier.isStatic(mods)
			&& methods[i].getName().equals(methodName))
		{
		    return true;
		}
	    }
	}
	catch (ClassNotFoundException e) {
	  return false;
	}
        return false;   
    
private booleanisInternalNamespace()
Return true if the namespace uri is null or it is the XSLTC translet uri.

    	return (_namespaceOfFunct == null ||
            _namespaceOfFunct.equals(EMPTYSTRING) ||
	    _namespaceOfFunct.equals(TRANSLET_URI));
    
public voidtranslate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
Calls to 'function-available' are resolved at compile time since the namespaces declared in the stylsheet are not available at run time. Consequently, arguments to this function must be literals.

	final ConstantPoolGen cpg = classGen.getConstantPool();
	methodGen.getInstructionList().append(new PUSH(cpg, getResult()));
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypetypeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)
Argument of function-available call must be literal, typecheck returns the type of function-available to be boolean.

	if (_type != null) {
	   return _type;
	}
	if (_arg instanceof LiteralExpr) {
	    return _type = Type.Boolean;
	}
	ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
			"function-available", this);
	throw new TypeCheckError(err);