1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Oct 2017 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 22 package com.sun.org.apache.xalan.internal.xsltc.compiler; 23 24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 25 import com.sun.org.apache.bcel.internal.generic.PUSH; 26 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 31 import java.util.List; 32 33 /** 34 * @author Jacek Ambroziak 35 * @author Santiago Pericas-Geertsen 36 */ 37 final class ElementAvailableCall extends FunctionCall { 38 39 public ElementAvailableCall(QName fname, List<Expression> arguments) { 40 super(fname, arguments); 41 } 42 43 /** 44 * Force the argument to this function to be a literal string. 45 */ 46 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 47 if (argument() instanceof LiteralExpr) { 48 return _type = Type.Boolean; 49 } 50 ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR, 51 "element-available", this); 52 throw new TypeCheckError(err); 53 } 54 55 /** 56 * Returns an object representing the compile-time evaluation 57 * of an expression. We are only using this for function-available 58 * and element-available at this time. 59 */ 60 public Object evaluateAtCompileTime() { 61 return getResult() ? Boolean.TRUE : Boolean.FALSE; 62 } 63 64 /** 65 * Returns the result that this function will return 66 */ 67 public boolean getResult() { 68 try { 69 final LiteralExpr arg = (LiteralExpr) argument(); 70 final String qname = arg.getValue(); 71 final int index = qname.indexOf(':'); 72 final String localName = (index > 0) ? 73 qname.substring(index + 1) : qname; 74 return getParser().elementSupported(arg.getNamespace(), 75 localName); 76 } 77 catch (ClassCastException e) { 78 return false; 79 } 80 } 81 82 /** 83 * Calls to 'element-available' are resolved at compile time since 84 * the namespaces declared in the stylsheet are not available at run 85 * time. Consequently, arguments to this function must be literals. 86 */ 87 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 88 final ConstantPoolGen cpg = classGen.getConstantPool(); 89 final boolean result = getResult(); 90 methodGen.getInstructionList().append(new PUSH(cpg, result)); 91 } 92 }