ECF日記(その3)

サンプルをかく!って昨日言っていたので、早速かいてみよう!
と思ったのですが、とりあえず動かすためのとっつきはどこから手をつけたらよいのやら。

ECFの林をうろうろしていたところ、Eclipseのlauncheに

  • ECF Client Application
  • ECF Server Application

というのがあるのを発見!早速動かしてみる。

…Clientがうごかん。

原因はClientの方はEquinoxさんが動いていないとPluginが活性化していないので動かないというもの。
しょうがない。じゃ、コピッてEclipseApplication化してみるか。
と思って新しくプラグイン作って依存関係に必要そうなのを突っ込んでみる。

/META-INF/MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Lerning Plug-in
Bundle-SymbolicName: kompiro.ecf.lerning;singleton:=true
Bundle-Version: 0.0.1
Bundle-Activator: kompiro.ecf.lerning.Activator
Require-Bundle: org.eclipse.core.runtime,
 org.eclipse.ecf,
 org.eclipse.ecf.datashare,
 org.eclipse.ecf.sharedobject,
 org.eclipse.ecf.provider

どれどれ。動かしてみっか。と思ってClinentApplicationにorg.eclipse.core.runtime.IPlatformRunnerbleをimplementsに追加した。

なんとIPlatformRunnerbleはDeprecatedですと?
Eclipseを落としてきたときにstartup.jarがeclipseのルートフォルダから消えていたのはその関係かな?Eclipse上で複数EclipseApplicationを動かすようにするための布石か?

とか思いながら修正してみる。動かしてみると今度はContaner用のファクトリクラスのクラスロードがうまくいかない模様。その他channelを試してみるためのコードを追加したものが今の手元にあるやつなので貼っつけてみる。LicenseはEPLだったはずなのできっと大丈夫。

package kompiro.ecf.lerning;


import java.util.HashMap;

import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.ecf.core.ContainerTypeDescription;
import org.eclipse.ecf.core.ContainerFactory;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.sharedobject.ISharedObject;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContainer;
import org.eclipse.ecf.core.sharedobject.SharedObjectContainerFactory;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.datashare.IChannel;
import org.eclipse.ecf.datashare.IChannelContainerAdapter;
import org.eclipse.ecf.datashare.IChannelListener;
import org.eclipse.ecf.datashare.events.IChannelEvent;
import org.eclipse.ecf.datashare.events.IChannelMessageEvent;
import org.eclipse.ecf.provider.generic.GenericContainerInstantiator;
import org.eclipse.ecf.provider.generic.TCPServerSOContainer;

/**
 * An ECF client container implementation that runs as an application.
 * <p>
 * Usage: java org.eclipse.ecf.provider.app.ClientApplication &lt;serverid&gt
 * <p>
 * If &lt;serverid&gt; is omitted or "-" is specified,
 * ecftcp://localhost:3282/server" is used.  
 *  
 */
public class ClientApplication implements IPlatformRunnable{

	public static final int DEFAULT_WAITTIME = 60000;
	public static final int DEFAULT_TIMEOUT = TCPServerSOContainer.DEFAULT_KEEPALIVE;
	public static final String CONTAINER_FACTORY_NAME = GenericContainerInstantiator.class.getName();
	public static final String COMPOSENT_CONTAINER_NAME = GenericContainerInstantiator.class.getName();

	// Number of clients to create
	private static final int clientCount = 3;
	// Array of client instances
	private ISharedObjectContainer [] clients = new ISharedObjectContainer[clientCount];
	// ServerApplication name to connect to
	private String serverName = null;
	// Class names of any sharedObjects to be created.  If null, no sharedObjects created.
	private String [] sharedObjectClassNames = null;
	// IDs of sharedObjects created
	private ID [] sharedObjects = null;
	private IChannel[] channels;
	
	private ContainerTypeDescription contd = null;
	public ClientApplication() {
		super();
	}
	
	public void init(String [] args) throws Exception {
		serverName = TCPServerSOContainer.getDefaultServerURL();
		if (args.length > 0) {
			if (!args[0].equals("-")) serverName = args[0]; //$NON-NLS-1$
		}
		if (args.length > 1) {
			sharedObjectClassNames = new String[args.length - 1];
			for (int i = 0; i < args.length - 1; i++) {
				sharedObjectClassNames[i] = args[i + 1];
			}
		}
		// Setup factory descriptions since Eclipse does not do this for us
		contd = new ContainerTypeDescription(CONTAINER_FACTORY_NAME,new GenericContainerInstantiator(),null);
		ContainerFactory.getDefault().addDescription(contd);
		for(int i=0; i < clientCount; i++) {
			clients[i] = createClient();
		}
	}
	
	protected ISharedObjectContainer createClient() throws Exception {
		// Make identity instance for the new container
		ID newContainerID = IDFactory.getDefault().createGUID();
		ISharedObjectContainer result =  SharedObjectContainerFactory.getDefault().createSharedObjectContainer(contd,new Object[] { newContainerID, new Integer(DEFAULT_TIMEOUT)});
		return result;
	}
	
	public void connect(ID server) throws Exception {
		for(int i = 0; i < clientCount; i++) {
			System.out.print("ClientApplication "+clients[i].getID().getName()+" joining "+server.getName()+"..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			clients[i].connect(server,null);
			System.out.println("completed."); //$NON-NLS-1$
		}
	}

	public void disconnect() {
		for(int i = 0; i < clientCount; i++) {
			System.out.print("ClientApplication "+clients[i].getID().getName()+" leaving..."); //$NON-NLS-1$ //$NON-NLS-2$
			clients[i].disconnect();
			System.out.println("completed."); //$NON-NLS-1$
		}
	}
	
	public void createSharedObjects() throws Exception {
		if (sharedObjectClassNames != null) {
			for(int j=0; j < clientCount; j++) {
				ISharedObjectContainer scg = clients[j];
				sharedObjects = new ID[sharedObjectClassNames.length];
				for(int i=0; i < sharedObjectClassNames.length; i++) {
					System.out.println("Creating sharedObject: "+sharedObjectClassNames[i]+" for client "+scg.getID().getName()); //$NON-NLS-1$ //$NON-NLS-2$
					ISharedObject so = (ISharedObject) Class.forName(sharedObjectClassNames[i]).newInstance();
					sharedObjects[i] = IDFactory.getDefault().createStringID(sharedObjectClassNames[i] + "_" +  i); //$NON-NLS-1$
					scg.getSharedObjectManager().addSharedObject(sharedObjects[i], so, new HashMap());
					System.out.println("Created sharedObject for client "+scg.getID().getName()); //$NON-NLS-1$
				}
			}
		}

	}
	public void removeSharedObjects() throws Exception {
		if (sharedObjects == null) return;
		for(int j=0; j < clientCount; j++) {
			for(int i=0; i < sharedObjects.length; i++) {
				System.out.println("Removing sharedObject: "+sharedObjects[i].getName()+" for client "+clients[j].getID().getName()); //$NON-NLS-1$ //$NON-NLS-2$
				clients[j].getSharedObjectManager().removeSharedObject(sharedObjects[i]);
			}
		}
	}
	public void createChannel(){
		System.out.println("start create Channels.");
		channels = new IChannel[clientCount];
		for(int i=0; i < clientCount; i++){
			IChannelContainerAdapter channelAdapter = (IChannelContainerAdapter) clients[i].getAdapter(IChannelContainerAdapter.class);
			ID channelID;
			try {
				channelID = IDFactory.getDefault().createID(channelAdapter.getChannelNamespace(),"test");
				IChannelListener listener = new IChannelListener(){
					public void handleChannelEvent(IChannelEvent event) {
						if(event instanceof IChannelMessageEvent){
							IChannelMessageEvent messageEvent = (IChannelMessageEvent)event;
							String message = new String(messageEvent.getData());
							System.out.println(event.getChannelID() + " : " + message);
						}
					}
				};
				channels[i] = channelAdapter.createChannel(channelID, listener , new HashMap<Object, Object>());
			} catch (IDCreateException e) {
				e.printStackTrace();
			} catch (ECFException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * An ECF client container implementation that runs as an application.
	 * <p>
	 * Usage: java org.eclipse.ecf.provider.app.ClientApplication &lt;serverid&gt
	 * <p>
	 * If &lt;serverid&gt; is omitted or "-" is specified,
	 * ecftcp://localhost:3282/server" is used.  
	 *  
	 */
	public static void main(String[] args) throws Exception {
		ClientApplication st = new ClientApplication();
		st.init(args);
		// Get server id to join
		ID serverID = IDFactory.getDefault().createStringID(st.serverName);
		st.connect(serverID);
		st.createSharedObjects();
		st.createChannel();
		st.getChannels()[0].sendMessage("Hello message!".getBytes());
		System.out.println("Waiting "+DEFAULT_WAITTIME+" ms..."); //$NON-NLS-1$ //$NON-NLS-2$
		Thread.sleep(DEFAULT_WAITTIME);
		st.removeSharedObjects();
		st.disconnect();
		System.out.println("Exiting."); //$NON-NLS-1$
	}

	private IChannel[] getChannels() {
		return channels;
	}

	public Object run(Object args) throws Exception {
		ClientApplication.main(new String[]{});
		return IPlatformRunnable.EXIT_OK;
	}

}

英語でもあんまり情報のないものをおっかけるのはたのすぃね。