/*
 * $Header: /home/harald/repos/remotetea.sf.net/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParamInfo.java,v 1.2 2003/08/14 08:09:59 haraldalbrecht Exp $
 *
 * Copyright (c) 1999, 2000
 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen
 * D-52064 Aachen, Germany.
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program (see the file LICENSE.txt for more
 * details); if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 */

package org.acplt.oncrpc.apps.jrpcgen;

import java.io.IOException;

/**
 * The <code>JrpcgenParamInfo</code> class contains information about the
 * data type of a procedure's parameter, as well as the parameter's optional
 * name.
 *
 * @version $Revision: 1.2 $ $Date: 2003/08/14 08:09:59 $ $State: Exp $ $Locker:  $
 * @author Harald Albrecht
 */
class JrpcgenParamInfo implements JrpcgenItem {

	public static class Table extends JrpcgenItemTable<JrpcgenParamInfo> {}
	
    /**
     * Constructs a new <code>JrpcgenParamInfo</code> object containing
     * information about ...
     * 
     * @param parameterType The type of the parameter.
     * @param parameterName The name of the parameter.
     *
     */
    public JrpcgenParamInfo(JrpcgenTypeInfo typeInfo, String name) {
    	this.typeInfo = typeInfo;
        this.name = name;
    }
    
    @Override
    public String getIdentifier() {
    	return name;
    }
    
    public String getName() {
    	return name;
    }
    
    public String getType() {
    	return typeInfo.getDefinitionName();
    }
    
    public JrpcgenTypeInfo getTypeInfo() {
    	return typeInfo;
    }

    public void writeMethodParameter(JrpcgenJavaFile javaFile) {
    	javaFile.append(typeInfo.getJavaName()).space().append(name);
    }
    
    public void writeMethodParameter(JrpcgenJavaFile.MethodSignature methodSignature) {
    	methodSignature.parameter(typeInfo.getJavaName(), name);
    }
    
    public void writeFinalMethodParameter(JrpcgenJavaFile.MethodSignature methodSignature) {
    	methodSignature.parameterFinal(typeInfo.getJavaName(), name);
    }
    
    public String writeXdrCallArgument(JrpcgenJavaFile javaFile, JrpcgenContext context) {
    	String argumentName = name;
    	
    	/*
    	 * A new argument will be generated, if the XDR class of
    	 * the type is different from the Java name of the type.
    	 *  
    	 */
    	if (typeInfo.getJavaName().compareTo(typeInfo.getXdrClass()) != 0) {
    		argumentName = "args$";
    		javaFile.beginLine().append(typeInfo.getXdrClass()).space().append(argumentName).append(" = ");
    		typeInfo.writeJavaToXdr(javaFile, name);
    		javaFile.semicolon().newLine();
    	}
    	
    	return argumentName;
    }
    
    public void writeXdrEncodingCall(JrpcgenJavaFile javaFile, String xdrStream) {
    	/*
    	 * The type 'string' as parameter type within a procedure declaration is an extension
    	 * to the RPC lanuage specification, which usually does not accept vector types as arguments
    	 * to procedures. However, it has become common to use 'string' as parameter type and therefore
    	 * it is accepted within jrpcgen as well. However, as the type 'string' is used in a dynamic
    	 * vector context, the type mapping of type 'string' does provide the dynamic vector coding
    	 * methods, only. Therefore, if the parameter type is 'string', the dynmic vector coding method
    	 * will be called.   
    	 */
    	if (typeInfo.isStringType()) {
    		typeInfo.writeXdrDynamicVectorEncodingCall(javaFile.beginLine(), xdrStream, name);
    	} else {
        	typeInfo.writeXdrEncodingCall(javaFile.beginLine(), xdrStream, name);
    	}
    	javaFile.semicolon().newLine();
    }
    
    public void writeXdrDecodingCall(JrpcgenJavaFile javaFile, String xdrStream) {
    	javaFile.beginLine().append(name).append(" = ");
    	/*
    	 * The type 'string' as parameter type within a procedure declaration is an extension
    	 * to the RPC lanuage specification, which usually does not accept vector types as arguments
    	 * to procedures. However, it has become common to use 'string' as parameter type and therefore
    	 * it is accepted within jrpcgen as well. However, as the type 'string' is used in a dynamic
    	 * vector context, the type mapping of type 'string' does provide the dynamic vector coding
    	 * methods, only. Therefore, if the parameter type is 'string', the dynmic vector coding method
    	 * will be called.   
    	 */
    	if (typeInfo.isStringType()) {
    		typeInfo.writeXdrDynamicVectorDecodingCall(javaFile, xdrStream);	
    	} else {
    		typeInfo.writeXdrDecodingCall(javaFile, xdrStream);
    	}
    	
    	javaFile.semicolon().newLine();
    }
    
    public void appendAsDeclaration(JrpcgenJavaFile javaFile) {
    	javaFile.append(typeInfo.getJavaName()).space().append(name).println(';');
    }
    
    public <T extends Appendable> T dump(T appendable) {
    	try {
        	appendable.append(typeInfo.getDefinitionName());
        	
        	if (name != null)
        		appendable.append(' ').append(name);
    	} catch (IOException ioException) {
    		// Ignored at this place.
    	}
    	
    	return appendable;
    }

   private final JrpcgenTypeInfo typeInfo;
   private final String name;
   
}

// End of JrpcgenParamInfo.java