1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xalan.internal.xsltc.compiler;
23
24import java.util.Vector;
25
26import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
27import com.sun.org.apache.bcel.internal.generic.PUSH;
28import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
29import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
30import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
31import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
32import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
33
34/**
35 * @author Jacek Ambroziak
36 * @author Santiago Pericas-Geertsen
37 */
38final class ElementAvailableCall extends FunctionCall {
39
40    public ElementAvailableCall(QName fname, Vector arguments) {
41        super(fname, arguments);
42    }
43
44    /**
45     * Force the argument to this function to be a literal string.
46     */
47    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
48        if (argument() instanceof LiteralExpr) {
49            return _type = Type.Boolean;
50        }
51        ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
52                                    "element-available", this);
53        throw new TypeCheckError(err);
54    }
55
56    /**
57     * Returns an object representing the compile-time evaluation
58     * of an expression. We are only using this for function-available
59     * and element-available at this time.
60     */
61    public Object evaluateAtCompileTime() {
62        return getResult() ? Boolean.TRUE : Boolean.FALSE;
63    }
64
65    /**
66     * Returns the result that this function will return
67     */
68    public boolean getResult() {
69        try {
70            final LiteralExpr arg = (LiteralExpr) argument();
71            final String qname = arg.getValue();
72            final int index = qname.indexOf(':');
73            final String localName = (index > 0) ?
74                qname.substring(index + 1) : qname;
75            return getParser().elementSupported(arg.getNamespace(),
76                                                localName);
77        }
78        catch (ClassCastException e) {
79            return false;
80        }
81    }
82
83    /**
84     * Calls to 'element-available' are resolved at compile time since
85     * the namespaces declared in the stylsheet are not available at run
86     * time. Consequently, arguments to this function must be literals.
87     */
88    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
89        final ConstantPoolGen cpg = classGen.getConstantPool();
90        final boolean result = getResult();
91        methodGen.getInstructionList().append(new PUSH(cpg, result));
92    }
93}
94