## 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 for your convenience and will not be
// overwritten once it exists! Please edit this file as necessary to implement
// your service logic.
#set($i = $intf.name())
#set($intfname = "$i$suffix")
#set($baseclname = "Base$intfname")
#set($clname = "Impl$intfname")
#if ($helper.isServer($mc))
#set($peer = "client")
#set($peerclass = "Remote${i}Client")
#else
#set($peer = "server")
#set($peerclass = "Remote${i}Server")
#end

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

#if ($helper.isServer($mc))
import org.apache.etch.bindings.java.support.ServerFactory;
import org.apache.etch.util.core.io.Transport;

/**
 * Main program for ${i}Server. This program makes a listener to accept
 * connections from Main${i}Client.
 */
public class Main${i}Listener implements ${i}Helper.${i}ServerFactory
{
	/**
	 * Main program for ${i}Server.
	 * 
	 * @param args command line arguments.
	 * @throws Exception
	 */
	public static void main( String[] args ) throws Exception
	{
		// TODO Change to correct URI
		String uri = "tcp://0.0.0.0:4001";
		
		ServerFactory listener = ${i}Helper.newListener( uri, null,
			new Main${i}Listener() );

		// Start the Listener
		listener.transportControl( Transport.START_AND_WAIT_UP, 4000 );
	}

	public ${i}Server new${i}Server( Remote${i}Client client )
	{
		return new Impl${i}Server( client );
	}
}
#else
/**
 * Main program for ${i}Client. This program makes a connection to the
 * listener created by Main${i}Listener.
 */
public class Main${i}Client implements ${i}Helper.${i}ClientFactory
{
	/**
	 * Main program for ${i}Client.
	 * 
	 * @param args command line arguments.
	 * @throws Exception
	 */
	public static void main( String[] args ) throws Exception
	{
		// TODO Change to correct URI
		String uri = "tcp://localhost:4001";
		
		Remote${i}Server server = ${i}Helper.newServer( uri, null,
			new Main${i}Client() );

		// Connect to the service
		server._startAndWaitUp( 4000 );

		// TODO Insert Your Code Here

		// Disconnect from the service
		server._stopAndWaitDown( 4000 );
	}

	public ${i}Client new${i}Client( Remote${i}Server server )
		throws Exception
	{
		return new Impl${i}Client( server );
	}
}
#end
