1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xalan.internal.xsltc.compiler; 22 23 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 24 import com.sun.org.apache.bcel.internal.generic.PUSH; 25 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 26 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 30 import java.util.List; 31 32 /** 33 * @author Jacek Ambroziak 34 * @author Santiago Pericas-Geertsen 35 * @LastModified: Oct 2017 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 }