## Copyright 2007-2008 Cisco Systems Inc.
##
## Licensed 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.
// This file automatically generated by:
//   $version
//   $now
// This file is automatically created and should not be edited!
#set($i = $intf.name())

package $intf.parent().name();

import org.apache.etch.util.core.Who;
import org.apache.etch.bindings.java.msg.Message;
import org.apache.etch.bindings.java.support.DeliveryService;
import org.apache.etch.bindings.java.support.Pool;
import org.apache.etch.bindings.java.support.StubHelper;
import org.apache.etch.bindings.java.support._Etch_AuthException;
#if (!$hasBaseClass)
import org.apache.etch.bindings.java.support.StubBase;
#end
import org.apache.etch.bindings.java.support.Pool.PoolRunnable;
#foreach( $n in $intf.iterator() )
#if ($n.isExtern())
#if ($n.hasImport( $helper ))
import $n.getImport( $helper );
#end
#end
#end

#if ($hasBaseClass)
/**
 * Message to call translator for $i$suffix.
 */
@SuppressWarnings("unused")
public class Stub$i$suffix extends Stub$i<$i$suffix>
#set( $T = "$i$suffix" )
#else
/**
 * Message to call translator for $i$suffix.
 * @param <T> $i$suffix or a subclass thereof.
 */
@SuppressWarnings("unused")
public class Stub$i$suffix<T extends $i$suffix> extends StubBase<T>
#set( $T = "T" )
#end
{
	/**
	 * Stub for $i$suffix.
	 * @param svc the delivery service.
	 * @param obj the implementation of $i$suffix responsive to requests.
	 * @param queued thread pool used to run AsyncMode.QUEUED methods.
	 * @param free thread pool used to run AsyncMode.FREE methods.
	 */
	public Stub$i$suffix( DeliveryService svc, $T obj, Pool queued, Pool free )
	{
		super( svc, obj, queued, free );
	}
	
	static
	{
#foreach( $n in $intf.iterator() )
#if( $n.isMixin() )
#set( $m = $n.getModule() )
#set( $z = $m.iterator().next() )
		${m.name()}.Stub${z.name()}${suffix}.init();
#end
#end
	}

	/**
	 * Method used to force static initialization.
	 */
	public static void init()
	{
		// nothing to do.
	}
	
	static
	{
#foreach( $mthd in $intf.iterator() )
#if ($mthd.isMsgDir($mc))
#if (!$mthd.isHidden())
		ValueFactory$i.${mthd.vname( $helper )}.setStubHelper( new StubHelper<$i$suffix>()
		{
			public final void run( DeliveryService _svc, $i$suffix _obj, Who _sender, Message _msg ) throws Exception
			{
#if (!$mthd.isOneway())
				final Message _rmsg = _msg.reply();
#end
				try
				{
#if ($mthd.hasAuth())
#foreach ($param in $mthd.iterator())
					$helper.getTypeName( $param.type() ) $param.name() = ($helper.getTypeName( $param.type() )) _msg.get( ValueFactory$i.$param.vname( $helper ) );
#end
#end
#if ($mthd.hasAuth())
#set( $auth = $mthd.getAuth() )
#if ($auth.isMethodFalse())
					if (true)
#else
					if (!_obj.${auth.method()}(
#set( $sep = "" )
#foreach($arg in $auth.args())
#if ($arg.isLiteralConstant())
						($helper.getNativeTypeName( $arg.type() )) ${sep}$helper.getTypeValue( $arg.type(), $arg.value() )
#elseif ($arg.isParameter( $mthd ))
						${sep}$helper.qualifyParameterName( $arg.value() )
#elseif ($arg.isConstant( $intf ))
						${sep}$helper.qualifyConstantName( $intf, $arg.value() )
#elseif ($arg.isEnum( $intf ))
						${sep}$helper.qualifyEnumName( $intf, $arg.value() )
#else
						${sep}null
#end
#set( $sep = ", " )
#end
					))
#end
					throw new _Etch_AuthException( "stub could not authorize $mthd.name() using $auth.method()" );
#end
#if ($mthd.hasReturn())
					_rmsg.put( ValueFactory$i._mf_result,
#end
					_obj.$mthd.name()(
#set( $sep = "" )
#foreach ($param in $mthd.iterator())
#if ($mthd.hasAuth())
						${sep}$param.name()
#else
						${sep}($helper.getTypeName( $param.type() )) _msg.get( ValueFactory$i.$param.vname( $helper ) )
#end
#set( $sep = ", " )
#end
#if ($mthd.hasReturn())
					)
#end
					);
				}
				catch ( Exception e )
				{
					sessionNotify( _obj, e );
#if ($mthd.isOneway())
					Message _rmsg = _msg.reply( _msg.vf().get_mt__exception() );
#end
					_rmsg.put( ValueFactory$i._mf_result, e );
#if ($mthd.isOneway())
					_svc.transportMessage( _sender, _rmsg );
#end
				}
#if (!$mthd.isOneway())
				_svc.transportMessage( _sender, _rmsg );
#end
			}
		} );
#end
#end
#end
	}
}
