| 
 | 
 | 
 | 
 | 
 */  | 
 | 
/*  | 
 | 
 * Licensed to the Apache Software Foundation (ASF) under one or more  | 
 | 
 * contributor license agreements.  See the NOTICE file distributed with  | 
 | 
 * this work for additional information regarding copyright ownership.  | 
 | 
 * The ASF licenses this file to You under the Apache License, Version 2.0  | 
 | 
 * (the "License"); you may not use this file except in compliance with  | 
 | 
 * the License.  You may obtain a copy of the License at  | 
 | 
 *  | 
 | 
 *      http://www.apache.org/licenses/LICENSE-2.0  | 
 | 
 *  | 
 | 
 * Unless required by applicable law or agreed to in writing, software  | 
 | 
 * distributed under the License is distributed on an "AS IS" BASIS,  | 
 | 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  | 
 | 
 * See the License for the specific language governing permissions and  | 
 | 
 * limitations under the License.  | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.org.apache.xalan.internal.xsltc.compiler;  | 
 | 
 | 
 | 
import com.sun.org.apache.bcel.internal.generic.ALOAD;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.ASTORE;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.CHECKCAST;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.InstructionList;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;  | 
 | 
import com.sun.org.apache.bcel.internal.generic.PUSH;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;  | 
 | 
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;  | 
 | 
import com.sun.org.apache.xml.internal.utils.XML11Char;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
final class WithParam extends Instruction { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private QName _name;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    protected String _escapedName;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private Expression _select;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private LocalVariableGen _domAdapter;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private boolean _doParameterOptimization = false;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public void display(int indent) { | 
 | 
        indent(indent);  | 
 | 
        Util.println("with-param " + _name); | 
 | 
        if (_select != null) { | 
 | 
            indent(indent + IndentIncrement);  | 
 | 
            Util.println("select " + _select.toString()); | 
 | 
        }  | 
 | 
        displayContents(indent + IndentIncrement);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public String getEscapedName() { | 
 | 
        return _escapedName;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public QName getName() { | 
 | 
        return _name;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public void setName(QName name) { | 
 | 
        _name = name;  | 
 | 
        _escapedName = Util.escape(name.getStringRep());  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public void setDoParameterOptimization(boolean flag) { | 
 | 
        _doParameterOptimization = flag;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void parseContents(Parser parser) { | 
 | 
        final String name = getAttribute("name"); | 
 | 
        if (name.length() > 0) { | 
 | 
            if (!XML11Char.isXML11ValidQName(name)) { | 
 | 
                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name,  | 
 | 
                                            this);  | 
 | 
                parser.reportError(Constants.ERROR, err);  | 
 | 
            }  | 
 | 
            setName(parser.getQNameIgnoreDefaultNs(name));  | 
 | 
        } else { | 
 | 
            reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");  | 
 | 
        }  | 
 | 
 | 
 | 
        final String select = getAttribute("select"); | 
 | 
        if (select.length() > 0) { | 
 | 
            _select = parser.parseExpression(this, "select", null);  | 
 | 
        }  | 
 | 
 | 
 | 
        parseChildren(parser);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public Type typeCheck(SymbolTable stable) throws TypeCheckError { | 
 | 
        if (_select != null) { | 
 | 
            final Type tselect = _select.typeCheck(stable);  | 
 | 
            if (tselect instanceof ReferenceType == false) { | 
 | 
                _select = new CastExpr(_select, Type.Reference);  | 
 | 
            }  | 
 | 
        } else { | 
 | 
            typeCheckContents(stable);  | 
 | 
        }  | 
 | 
        return Type.Void;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void translateValue(ClassGenerator classGen,  | 
 | 
                               MethodGenerator methodGen)  | 
 | 
    { | 
 | 
          | 
 | 
        if (_select != null) { | 
 | 
            _select.translate(classGen, methodGen);  | 
 | 
            _select.startIterator(classGen, methodGen);  | 
 | 
        // If not, compile result tree from parameter body if present.  | 
 | 
        // Store result tree into local variable for releasing it later  | 
 | 
        } else if (hasContents()) { | 
 | 
            final InstructionList il = methodGen.getInstructionList();  | 
 | 
            compileResultTree(classGen, methodGen);  | 
 | 
            _domAdapter = methodGen.addLocalVariable2("@" + _escapedName, | 
 | 
                                                      Type.ResultTree.toJCType(),  | 
 | 
                                                      il.getEnd());  | 
 | 
            il.append(DUP);  | 
 | 
            il.append(new ASTORE(_domAdapter.getIndex()));  | 
 | 
        // If neither are present then store empty string in parameter slot  | 
 | 
        } else { | 
 | 
            final ConstantPoolGen cpg = classGen.getConstantPool();  | 
 | 
            final InstructionList il = methodGen.getInstructionList();  | 
 | 
            il.append(new PUSH(cpg, Constants.EMPTYSTRING));  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) { | 
 | 
        final ConstantPoolGen cpg = classGen.getConstantPool();  | 
 | 
        final InstructionList il = methodGen.getInstructionList();  | 
 | 
 | 
 | 
          | 
 | 
        if (_doParameterOptimization) { | 
 | 
            translateValue(classGen, methodGen);  | 
 | 
            return;  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        String name = Util.escape(getEscapedName());  | 
 | 
 | 
 | 
          | 
 | 
        il.append(classGen.loadTranslet());  | 
 | 
 | 
 | 
        // Load the name of the parameter  | 
 | 
        il.append(new PUSH(cpg, name));   | 
 | 
          | 
 | 
        translateValue(classGen, methodGen);  | 
 | 
          | 
 | 
        il.append(new PUSH(cpg, false));  | 
 | 
          | 
 | 
        il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,  | 
 | 
                                                     ADD_PARAMETER,  | 
 | 
                                                     ADD_PARAMETER_SIG)));  | 
 | 
        il.append(POP);   | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public void releaseResultTree(ClassGenerator classGen,  | 
 | 
                                  MethodGenerator methodGen)  | 
 | 
    { | 
 | 
        if (_domAdapter != null) { | 
 | 
            final ConstantPoolGen cpg = classGen.getConstantPool();  | 
 | 
            final InstructionList il = methodGen.getInstructionList();  | 
 | 
            if (classGen.getStylesheet().callsNodeset() &&  | 
 | 
                classGen.getDOMClass().equals(MULTI_DOM_CLASS))  | 
 | 
            { | 
 | 
                final int removeDA =  | 
 | 
                    cpg.addMethodref(MULTI_DOM_CLASS, "removeDOMAdapter",  | 
 | 
                                     "(" + DOM_ADAPTER_SIG + ")V"); | 
 | 
                il.append(methodGen.loadDOM());  | 
 | 
                il.append(new CHECKCAST(cpg.addClass(MULTI_DOM_CLASS)));  | 
 | 
                il.append(new ALOAD(_domAdapter.getIndex()));  | 
 | 
                il.append(new CHECKCAST(cpg.addClass(DOM_ADAPTER_CLASS)));  | 
 | 
                il.append(new INVOKEVIRTUAL(removeDA));  | 
 | 
            }  | 
 | 
            final int release =  | 
 | 
                cpg.addInterfaceMethodref(DOM_IMPL_CLASS, "release", "()V");  | 
 | 
            il.append(new ALOAD(_domAdapter.getIndex()));  | 
 | 
            il.append(new INVOKEINTERFACE(release, 1));  | 
 | 
            _domAdapter.setEnd(il.getEnd());  | 
 | 
            methodGen.removeLocalVariable(_domAdapter);  | 
 | 
            _domAdapter = null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |