/*
 * 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.
 */
/*
 * $Id$
 */

package org.apache.xalan.xsltc.compiler;

import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.INVOKESTATIC;
import org.apache.bcel.generic.INVOKEVIRTUAL;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.PUSH;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
import org.apache.xalan.xsltc.compiler.util.StringType;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
import org.apache.xalan.xsltc.compiler.util.Util;

/**
 * @author Morten Jorgensen
 */
final class TransletOutput extends Instruction {

    private Expression _filename;
    private boolean _append;

    /**
     * Displays the contents of this <xsltc:output> element.
     */
    public void display(int indent) {
	indent(indent);
	Util.println("TransletOutput: " + _filename);
    }
		
    /**
     * Parse the contents of this <xsltc:output> element. The only attribute
     * we recognise is the 'file' attribute that contains teh output filename.
     */
    public void parseContents(Parser parser) {
	// Get the output filename from the 'file' attribute
	String filename = getAttribute("file");
        
        // If the 'append' attribute is set to "yes" or "true",
        // the output is appended to the file.
        String append   = getAttribute("append");

	// Verify that the filename is in fact set
	if ((filename == null) || (filename.equals(EMPTYSTRING))) {
	    reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "file");
	}

	// Save filename as an attribute value template
	_filename = AttributeValue.create(this, filename, parser);
        
        if (append != null && (append.toLowerCase().equals("yes") ||
            append.toLowerCase().equals("true"))) {
          _append = true;     
        }
        else
          _append = false;
          
	parseChildren(parser);
    }
    
    /**
     * Type checks the 'file' attribute (must be able to convert it to a str).
     */
    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
	final Type type = _filename.typeCheck(stable);
	if (type instanceof StringType == false) {
	    _filename = new CastExpr(_filename, Type.String);
	}
	typeCheckContents(stable);
	return Type.Void;
    }
    
    /**
     * Compile code that opens the give file for output, dumps the contents of
     * the element to the file, then closes the file.
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
	final ConstantPoolGen cpg = classGen.getConstantPool();
	final InstructionList il = methodGen.getInstructionList();
	final boolean isSecureProcessing = classGen.getParser().getXSLTC()
	                                   .isSecureProcessing();

	if (isSecureProcessing) {
	    int index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
				         "unallowed_extension_elementF",
				         "(Ljava/lang/String;)V");
	    il.append(new PUSH(cpg, "redirect"));
	    il.append(new INVOKESTATIC(index));
	    return; 	
	}

	// Save the current output handler on the stack
	il.append(methodGen.loadHandler());
	
	final int open =  cpg.addMethodref(TRANSLET_CLASS,
					   "openOutputHandler",
                                           "(" + STRING_SIG + "Z)" +
					   TRANSLET_OUTPUT_SIG);

	final int close =  cpg.addMethodref(TRANSLET_CLASS,
					    "closeOutputHandler",
					    "("+TRANSLET_OUTPUT_SIG+")V");

	// Create the new output handler (leave it on stack)
	il.append(classGen.loadTranslet());
	_filename.translate(classGen, methodGen);
        il.append(new PUSH(cpg, _append));
	il.append(new INVOKEVIRTUAL(open));

	// Overwrite current handler
	il.append(methodGen.storeHandler());
	
	// Translate contents with substituted handler
	translateContents(classGen, methodGen);

	// Close the output handler (close file)
	il.append(classGen.loadTranslet());
	il.append(methodGen.loadHandler());
	il.append(new INVOKEVIRTUAL(close));

	// Restore old output handler from stack
	il.append(methodGen.storeHandler());
    }
}

