diff --git a/rse/plugins/org.eclipse.dstore.core/.classpath b/rse/plugins/org.eclipse.dstore.core/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/.classpath
@@ -0,0 +1,7 @@
+
+
February 24, 2005
+The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.
+ +If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content.
+ + + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/build.properties b/rse/plugins/org.eclipse.dstore.core/build.properties new file mode 100644 index 00000000000..548cdcde880 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/build.properties @@ -0,0 +1,10 @@ +bin.includes = plugin.properties,\ + about.html,\ + META-INF/, \ + serverscripts/ +source.dstore_core.jar = src/ +output.dstore_core.jar = bin/ +src.includes = about.html,\ + plugin.properties,\ + META-INF/,\ + serverscripts/ diff --git a/rse/plugins/org.eclipse.dstore.core/plugin.properties b/rse/plugins/org.eclipse.dstore.core/plugin.properties new file mode 100644 index 00000000000..c8c9c63a2cc --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/plugin.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2000, 2006 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +plugin.name = RSE Dstore Core diff --git a/rse/plugins/org.eclipse.dstore.core/serverscripts/auth.pl b/rse/plugins/org.eclipse.dstore.core/serverscripts/auth.pl new file mode 100644 index 00000000000..6b4f4da569e --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/serverscripts/auth.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w + +use Shell; + +if (!defined($ARGV[0]) || !defined($ARGV[1]) || !defined($ARGV[2]) || !defined($ARGV[3]) || !defined($ARGV[4])) +{ + print("command usage:\n"); + print("auth.pl USER, PATH, PORT, TIMEOUT, TICKET\n"); +} +else +{ + $userIN = $ARGV[0]; + $pathIN = $ARGV[1]; + $portIN = $ARGV[2]; + $timeoutIN = $ARGV[3]; + $ticketIN = $ARGV[4]; + + $pwdIN =+ * The ClassByteStreamHandler class is used to abstract classfile read and write operations + * across the network. By default this is used for sending and receiving class files + * on the client and the server. The class can be extended if the default byte stream + * implementations are not sufficient for a particular platform or use. + *
+ *
+ * If ClassByteStreamHandler is extended, you need to tell the DataStore to use the
+ * extended implementation. To do that, call DataStore.setClassByteStreamHandler(ClassByteStreamHandler)
.
+ *
+ * The IClassByteStreamHandler interface is used to abstract file read and write operations
+ * across the network.
+ *
+ */
+public interface IClassByteStreamHandler
+{
+
+ /**
+ * Returns the unique ID for this bytestream handler
+ * @return the unique id
+ */
+ public String getIdentifier();
+
+ /**
+ * Receive a class and load it. This method is called by the
+ * DataStore when the communication layer receives a class file transfer
+ * This method kicks off a new thread so that the receiver thread can be free
+ * to receive other data.
+ *
+ * @param className the name of the class to receive
+ * @param buffer the bytes that comprise the class
+ * @param size the number of bytes in the class
+ */
+ public void receiveBytes(String className, byte[] buffer, int size);
+
+ /**
+ * Save a class instance in the specified location. Invokes the operation in a new thread. This method is called by the
+ * DataStore when the communication layer receives a class file transfer
+ *
+ * @param buffer the bytes to insert in the class instance
+ * @param size the number of bytes to insert
+ */
+ public void receiveInstanceBytes(byte[] buffer, int size);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IRemoteClassInstance.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IRemoteClassInstance.java
new file mode 100644
index 00000000000..faeb5e355e4
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IRemoteClassInstance.java
@@ -0,0 +1,25 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.java;
+
+import java.io.Serializable;
+
+public interface IRemoteClassInstance extends Serializable
+{
+ public void arrivedOnServer();
+ public void updatedOnClient();
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/LocalObjectInputStream.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/LocalObjectInputStream.java
new file mode 100644
index 00000000000..fa7e71e7034
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/LocalObjectInputStream.java
@@ -0,0 +1,54 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.java;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.util.List;
+
+
+public class LocalObjectInputStream extends ObjectInputStream {
+
+ private List _localLoaders;
+ public LocalObjectInputStream(InputStream in, List localLoaders) throws IOException
+ {
+ super(in);
+ _localLoaders = localLoaders;
+ }
+
+ protected Class resolveClass(ObjectStreamClass desc)
+ throws IOException, ClassNotFoundException
+ {
+ ClassNotFoundException ex = null;
+ String name = desc.getName();
+ for (int i = 0; i < _localLoaders.size(); i++)
+ {
+ ClassLoader cl = (ClassLoader)_localLoaders.get(i);
+ try
+ {
+ return cl.loadClass(name);
+ }
+ catch (ClassNotFoundException e)
+ {
+ ex = e;
+ }
+ }
+ throw ex;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteClassLoader.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteClassLoader.java
new file mode 100644
index 00000000000..24b58aa59cb
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteClassLoader.java
@@ -0,0 +1,486 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.java;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.model.DataStore;
+
+
+
+/**
+ * This class loads a class from a remote peer.
+ * This classloader is used just as any other classloader is used. However,
+ * when instantiating the RemoteClassLoader, a DataStore is associated with
+ * it. The RemoteClassLoader goes through the following steps when trying to load
+ * a class:
+ * 1) Attempts to load the class from memory. Any class that had been loaded
+ * already this session would reside here.
+ * 2) Attempts to find the class using its parent classloader.
+ * 3) If caching preference is turned on:
+ * a) Attempts to find the class from the disk cache.
+ * 4) Requests the class, through the DataStore, from the remote peer. Waits for
+ * response.
+ * 5) If class cannot be found, throws ClassNotFoundException
+ * 6) If class is found, loads the class.
+ * 7) If caching preference is turned on:
+ * a) Caches new class in the disk cache for use in the next session.
+ * Notes:
+ * i) If there are one or more classes on which the target class depends,
+ * the RemoteClassLoader will attempt to load those classes too (possibly remotely),
+ * before loading the target class.
+ * ii) Since most implementations of Java use lazy classloading, the JVM may not
+ * attempt to load all required classes for the target class during class definition
+ * or instantiation. However, if the RemoteClassLoader was used to load the target
+ * class, then at any time, any additional classes required by the target class will
+ * be loaded using the RemoteClassLoader. Clients should be aware that this could trigger
+ * class requests and class transfers during the operation of objects of the target class,
+ * not just during definition and instantiation of it.
+ * iii) On the remote peer side, if you wish a class to be a candidate for transfer using the
+ * RemoteClassLoader on the opposite side of the connection, you MUST register the classloader
+ * for that class with the DataStore corresponding to the DataStore with which the RemoteClassLoader
+ * was instantiated. For example, in a client-server connection there is a "client" DataStore and a
+ * corresponding "server" DataStore. Suppose the server wishes to use the RemoteClassLoader to load
+ * class A from the client. Suppose A is loaded on the client using ClassLoaderForA. On the client
+ * side, ClassLoaderForA must be registered with the "client" DataStore so that when the
+ * class request for A comes in from the server, the client DataStore know how to load class A.
+ *
+ * Caching:
+ * To set your preference for caching, on either the client or server DataStore, use the following command:
+ * _dataStore.setPreference(RemoteClassLoader.CACHING_PREFERENCE, "true");
+ * The cache of classes is kept in a jar in the following directory:
+ * $HOME/.eclipse/RSE/rmt_classloader_cache.jar
+ * To clear the cache, you must delete the jar.
+ *
+ * Threading Issues:
+ * It's safest to use the RemoteClassLoader on a separate thread, and preferably not
+ * from the CommandHandler or UpdateHandler threads. The RemoteClassLoader uses those
+ * threads to request and send the class. However, DataStore commands can be structured such that
+ * safe use of the RemoteClassLoader on these threads is possible. See below for an
+ * example.
+ *
+ * Using the RemoteClassLoader in your subsystem miner:
+ * Suppose you want the client to be able to kick off a class request in your host subsystem
+ * miner. In order to accomplish this, you would take the following steps:
+ * 1) Add a command to your miner in the extendSchema() method.
+ * 2) Add logic in the handleCommand() method to route command to another method when handleCommand
+ * receives your new command.
+ * 3) In your command handling method, get the name of the class to load from the subject
+ * DataElement.
+ * 4) Load the class using the RemoteClassLoader.
+ * 5) Make sure the class you are attempting to load exists on the client and that class's
+ * ClassLoader is registered with the DataStore!
+ *
+ * @author mjberger
+ *
+ */
+public class RemoteClassLoader extends ClassLoader
+{
+ public static String CACHING_PREFERENCE = "Class.Caching";
+ private DataStore _dataStore;
+ private boolean _useCaching = false;
+ private CacheClassLoader _urlClassLoader;
+
+ private class CacheClassLoader extends URLClassLoader
+ {
+ public CacheClassLoader(URL[] urls, ClassLoader parent)
+ {
+ super(urls, parent);
+ }
+
+ public Class findCachedClass(String className) throws ClassNotFoundException
+ {
+ return super.findClass(className);
+ }
+ }
+
+ /**
+ * Constructor
+ * @param dataStore A reference to the datastore to be used by this
+ * RemoteClassLoader.
+ */
+ public RemoteClassLoader(DataStore dataStore)
+ {
+ super(dataStore.getClass().getClassLoader());
+ //_urlClassLoader = new URLClassLoader(new URL[0]);
+ _dataStore = dataStore;
+ useCaching();
+ }
+
+ public boolean useCaching()
+ {
+ boolean useCaching = false;
+ String pref = _dataStore.getPreference(CACHING_PREFERENCE);
+ if (pref != null && pref.equals("true"))
+ {
+ useCaching = true;
+ }
+ if (useCaching != _useCaching)
+ {
+ if (useCaching && _dataStore.getRemoteClassLoaderCache() != null)
+ {
+ try
+ {
+ URL cache = _dataStore.getRemoteClassLoaderCache().toURL();
+ URL[] urls = new URL[] { cache };
+ _urlClassLoader = new CacheClassLoader(urls, this);
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ _useCaching = useCaching;
+ return _useCaching;
+ }
+
+ /**
+ * Finds the specified class. If the class cannot be found locally,
+ * a synchronous request for the class is sent to the client, and the calling thread
+ * waits for a response. If the client can find the class, it sends it back to
+ * the server. The server receives the class in a new thread, defines it, and
+ * then notifies this thread. The class is then returned by this method. If the class
+ * cannot be found, the client notifies the server, and this method throws a
+ * ClassNotFoundException.
+ * @param className the fully qualified classname to find
+ * @return the loaded class
+ * @throws ClassNotFoundException if the class cannot be found on either the client or the server.
+ *
+ */
+ protected Class findClass(String className) throws ClassNotFoundException
+ {
+ System.out.println("finding "+className);
+
+ // first try using the datastore's local classloaders
+
+ ArrayList localLoaders = _dataStore.getLocalClassLoaders();
+ if (localLoaders != null)
+ {
+ Class theClass = null;
+ for (int i = 0; i < localLoaders.size(); i++)
+ {
+ try
+ {
+ theClass = ((ClassLoader)localLoaders.get(i)).loadClass(className);
+ if (theClass != null) return theClass;
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ // next delegate the search to the superclass's find method.
+ try
+ {
+ Class theClass = super.findClass(className);
+ if (theClass != null)
+ {
+ System.out.println("Using super's: " + className);
+ return theClass;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+
+ // DKM
+ // only do lookup if the classname looks valid
+ // don't want to be requesting rsecomm from client
+ if (className.indexOf('.') == -1)
+ {
+ throw new ClassNotFoundException(className);
+ }
+
+ // if it cannot be found:
+
+ // search the class request repository to see if the class has been requested
+ // already
+ ClassRequest request;
+ request = (ClassRequest) _dataStore.getClassRequestRepository().get(className);
+
+ if (request == null)
+ {
+ // the class has not been requested before
+ // try to look in the disk cache first
+ if (useCaching())
+ {
+ try
+ {
+
+ Class theClass = _urlClassLoader.findCachedClass(className);
+
+ System.out.println("Using cached: " + className);
+ return theClass;
+ }
+ catch (Throwable e)
+ {
+ // its not in the disk cache, so request it synchronously
+ return requestClass(className);
+ }
+ }
+ else
+ {
+ return requestClass(className);
+ }
+ }
+ else if (!request.isLoaded())
+ {
+ // the class has been requested before, but it has not yet been received
+ // System.out.println(className + " already requested but not loaded. Waiting for request to load.");
+ request.waitForResponse(); // just wait until the class is received
+
+ // after the class is received, get it from the repository and return it
+ // or if the class failed to be received, throw an exception
+ if (request.isLoaded()) return request.getLoadedClass();
+ else throw new ClassNotFoundException(className);
+ }
+ else if (request.isLoaded())
+ {
+ // the class has been requested before, and has already been received and loaded,
+ // so just return it.
+ return request.getLoadedClass();
+ }
+ // if we ever get to this point, the class has not been found,
+ // throw the exception
+ else throw new ClassNotFoundException(className);
+ }
+
+
+ /**
+ * Receives a class sent by a remote agent and loads it.
+ * Notifies all threads waiting for this class to load that the
+ * class has been loaded.
+ * @param className the name of the class to receive
+ * @param bytes the bytes in the class
+ * @param the size of the class
+ */
+ public synchronized void receiveClass(String className, byte[] bytes, int size)
+ {
+ // System.out.println("receiving "+className);
+ // check the class request repository to see if the class is there
+ ClassRequest request = (ClassRequest) _dataStore.getClassRequestRepository().get(className);
+ if (request != null)
+ {
+ if (request.isLoaded()) return; // do not attempt to reload the class
+ }
+ if (size == 0)
+ {
+ // this is the signal that the class could not be found on the client
+ // System.out.println("Empty class/class not found: "+className);
+ // System.out.println("notifying requester");
+ request.notifyResponse(); // wake up the threads waiting for the class
+ return;
+ }
+ Class receivedClass = null;
+ try
+ {
+ // System.out.println("defining "+className+"...");
+ // try to define the class. If any dependent classes cannot be
+ // found the JRE implementation will call findClass to look for them.
+ // Thus we could end up with a stack of requests all waiting until the
+ // classes with no dependent classes load.
+ receivedClass = defineClass(className, bytes, 0, size);
+
+ // System.out.println("...finished defining "+className);
+ }
+ catch (NoClassDefFoundError e)
+ {
+ // the JRE implementation could not find a dependent class.
+ // (even after requesting it from the client). We must fail,
+ // but wake up the threads waiting for this class.
+ e.printStackTrace();
+ request.notifyResponse();
+ return;
+ }
+ catch (LinkageError e)
+ {
+ // this happens when the system tries to redefine a class.
+ // dont try to redefine the class, just reload it.
+ e.printStackTrace();
+ try
+ {
+ receivedClass = loadClass(className);
+ }
+ catch (NoClassDefFoundError err)
+ {
+ // we shouldn't really get here unless it has tried
+ // already to find the class on the client but couldnt,
+ // so we might as well just fail here and notify threads waiting
+ // for this class to load.
+ err.printStackTrace();
+ request.notifyResponse();
+ return;
+ }
+ catch (ClassNotFoundException ee)
+ {
+ // we definitely shouldnt get here
+ request.notifyResponse();
+ return;
+ }
+
+ // if after trying to define or trying to load the class
+ // we still dont have it, notify the threads and fail.
+ if (receivedClass == null)
+ {
+ request.notifyResponse();
+ return;
+ }
+ }
+ if (request == null)
+ {
+ // not used right now, this is the case where a class was sent by
+ // the client without us requesting it.
+ request = new ClassRequest(className, false);
+ request.setLoadedClass(receivedClass);
+ _dataStore.getClassRequestRepository().put(className, request);
+ return;
+ }
+ else
+ {
+ // SUCCESS! The class has been received, and defined, so just
+ // load it into the class request object. This action will
+ // also notify threads waiting for the class
+ // System.out.println("notifying requesters");
+ request.setLoadedClass(receivedClass);
+ if (useCaching())
+ {
+ _dataStore.cacheClass(className, bytes, size);
+ }
+ }
+ }
+
+ /**
+ * Kicks off a separate thread in which to request the class,
+ * rather than doing it synchronously.
+ * @param className The fully qualified name of the class to request.
+ */
+ protected void requestClassInThread(String className)
+ {
+ // System.out.println("requesting (in thread)"+className);
+ LoadClassThread thread = new LoadClassThread(className);
+ thread.start();
+ }
+
+ /**
+ * Requests a class (synchronously) from the client
+ * @param className The fully qualified name of the class to request.
+ * @return the requested class
+ * @throws ClassNotFoundException if the class was not found on the client
+ */
+ public Class requestClass(String className) throws ClassNotFoundException
+ {
+ // first check to see if the class has been requested before
+ // System.out.println("requesting "+className);
+ ClassRequest request;
+ request = (ClassRequest) _dataStore.getClassRequestRepository().get(className);
+ if (request == null)
+ {
+ // the class has not been requested yet, create a new ClassRequest
+ // object to represent it
+ request = new ClassRequest(className, true);
+ _dataStore.getClassRequestRepository().put(className, request);
+ request.setRequested(true);
+
+ // put in the request for the class
+ _dataStore.requestClass(className);
+
+ // wait for a response
+ // System.out.println("thread to wait: "+Thread.currentThread().getName());
+ if (!request.isLoaded()) request.waitForResponse();
+ // System.out.println("thread finished waiting: "+Thread.currentThread().getName());
+ if (request.isLoaded()) return request.getLoadedClass();
+ else throw new ClassNotFoundException(className);
+ }
+ else if (!request.isLoaded())
+ {
+ // class has already been requested, wait for it to load
+ // System.out.println("requested elsewhere, thread to wait: "+Thread.currentThread().getName());
+ if (!request.isLoaded()) request.waitForResponse();
+ // System.out.println("requested elsewhere, thread finished waiting: "+Thread.currentThread().getName());
+ if (request.isLoaded()) return request.getLoadedClass();
+ else throw new ClassNotFoundException(className);
+ }
+ else if (request.isLoaded())
+ {
+ // class has already been requested and loaded, just return it
+ return request.getLoadedClass();
+ }
+ // we shouldnt really get to this point, but if we do, it means the class
+ // was not found.
+ throw new ClassNotFoundException(className);
+ }
+
+ /**
+ * Causes a new thread to start in which the specified class is loaded
+ * into the repository. This method usually returns before the class has been
+ * loaded.
+ * @param className The fully qualified name of the class to load
+ */
+ public synchronized void loadClassInThread(String className)
+ {
+ // check if the class has been requested before
+ ClassRequest request;
+ request = (ClassRequest) _dataStore.getClassRequestRepository().get(className);
+ if (request == null)
+ {
+ // class has not been requested, request it in a thread
+ request = new ClassRequest(className, false);
+ _dataStore.getClassRequestRepository().put(className, request);
+ request.setRequested(true);
+ requestClassInThread(className);
+ return;
+ }
+ else if (!request.isLoaded())
+ {
+ // class has been requested already, but not loaded. Just return.
+ return;
+ }
+ else if (request.isLoaded())
+ {
+ // class has been requested already and already loaded. Just return.
+ return;
+ }
+ }
+
+ /**
+ * A new thread for loading classes in.
+ * @author mjberger
+ *
+ */
+ protected class LoadClassThread extends Thread
+ {
+ private String _className;
+
+ public LoadClassThread(String className)
+ {
+ _className = className;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Thread#run()
+ */
+ public void run()
+ {
+ _dataStore.requestClass(_className);
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteObjectInputStream.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteObjectInputStream.java
new file mode 100644
index 00000000000..6709e741781
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/RemoteObjectInputStream.java
@@ -0,0 +1,39 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.java;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+
+public class RemoteObjectInputStream extends ObjectInputStream {
+
+ private RemoteClassLoader _loader;
+ public RemoteObjectInputStream(InputStream in, RemoteClassLoader loader) throws IOException
+ {
+ super(in);
+ _loader = loader;
+ }
+
+ protected Class resolveClass(ObjectStreamClass desc)
+ throws IOException, ClassNotFoundException
+ {
+ String name = desc.getName();
+ return _loader.loadClass(name);
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/Miner.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/Miner.java
new file mode 100644
index 00000000000..eac5ff7c4af
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/Miner.java
@@ -0,0 +1,670 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.miners.miner;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.dstore.core.model.DataStoreResources;
+import org.eclipse.dstore.core.model.DataStoreSchema;
+import org.eclipse.dstore.core.model.Handler;
+import org.eclipse.dstore.core.model.ISchemaExtender;
+import org.eclipse.dstore.core.util.ExternalLoader;
+
+/**
+ * Miner is the abstact base class of all DataStore extensions).
+ * The DataStore framework knows how to load and route commands to miners
+ * because it interfaces miners through the restricted set of interfaces declared here.
+ * To add a new miner, developers must extend this class and implement the abstract methods declared here.
+ */
+public abstract class Miner extends Handler
+implements ISchemaExtender
+{
+
+
+ public DataStore _dataStore;
+ public DataElement _minerElement;
+ public DataElement _minerData;
+ public DataElement _minerTransient;
+
+
+
+ private boolean _initialized;
+ private boolean _connected;
+ private ExternalLoader _loader;
+
+ protected String _name = null;
+ protected String _value = null;
+ protected ArrayList _dependencies;
+ protected List _commandQueue;
+
+ protected ResourceBundle _resourceBundle = null;
+
+ /**
+ * Creates a new Miner
+ */
+ protected Miner()
+ {
+ _initialized = false;
+ _connected = false;
+ _commandQueue = new ArrayList();
+ }
+
+ /**
+ * Returns the qualified names of all miners that
+ * this miner depends on. A miner depends on another
+ * miner if it's schema extends or uses another's schema.
+ * By default it returns an empty list.
+ * @return a list of miner dependencies, each represented as a qualified name
+ */
+ public final ArrayList getMinerDependencies()
+ {
+ if (_dependencies == null)
+ {
+ _dependencies = getDependencies();
+ }
+ return _dependencies;
+ }
+
+
+ protected ArrayList getDependencies()
+ {
+ return new ArrayList();
+ }
+
+ /**
+ * Indicates whether the miner has been initialized yet
+ * @return whether the miner has been initialized
+ */
+ public final boolean isInitialized()
+ {
+ return _initialized;
+ }
+
+ /**
+ * Indicates whether the miner has been connected to
+ * the DataStore yet.
+ * @return whether the miner has been connected to the DataStore
+ */
+ public final boolean isConnected()
+ {
+ return _connected;
+ }
+
+ /**
+ * Shuts down the miner and cleans up it's meta-information.
+ * Override this function to do your own cleanup.
+ */
+ public void finish()
+ {
+ DataElement root = _dataStore.getMinerRoot();
+
+ _minerData.removeNestedData();
+ _minerElement.removeNestedData();
+ _dataStore.update(_minerElement);
+
+ if (root.getNestedData() != null)
+ {
+ root.getNestedData().remove(_minerElement);
+ }
+ root.setExpanded(false);
+ root.setUpdated(false);
+
+ _dataStore.update(root);
+ }
+
+ /**
+ * Interface to retrieve an NL enabled resource bundle.
+ * Override this function to get access to a real resource bundle.
+ */
+ public ResourceBundle getResourceBundle()
+ {
+ return null;
+ }
+
+ /**
+ * Default method that gets called on a Miner when it is loaded.
+ * Override this function to perform some initialization at miner loading time.
+ */
+ protected void load()
+ {
+ }
+
+ /**
+ * Default method that gets called on a Miner when it is loaded.
+ * Override this function to perform some initialization at miner loading time.
+ * If loading the miner can result in some failure, set that status to incomplete
+ *
+ * @param status the status of the initialize miner command
+ */
+ protected void load(DataElement status)
+ {
+ load();
+ }
+
+ /**
+ * This gets called after a miner is initialized.
+ * If you need to update element information at that time, override this method.
+ */
+ protected void updateMinerInfo()
+ {
+ }
+
+ /**
+ * Returns the qualified name of this miner
+ *
+ * @return the qualified name of this miner
+ */
+ public final String getMinerName()
+ {
+ if (_name == null)
+ _name = getClass().getName();
+ return _name;
+ }
+
+ /**
+ * Returns the name of this miner
+ *
+ * @return the name of this miner
+ */
+ public final String getValue()
+ {
+ if (_value == null)
+ {
+ String name = getMinerName();
+ int indexOfValue = name.lastIndexOf(".");
+ _value = name.substring(indexOfValue + 1, name.length());
+ }
+ return _value;
+ }
+
+ public final void handle()
+ {
+ while (!_commandQueue.isEmpty())
+ {
+ DataElement cmd = (DataElement)_commandQueue.remove(0);
+ command(cmd);
+ }
+ }
+
+ public final void requestCommand(DataElement command)
+ {
+ _commandQueue.add(command);
+ notifyInput();
+ }
+
+ public final void initMiner(DataElement status)
+ {
+ try
+ {
+ // System.out.println("initMiner:"+getMinerName());
+ if (!_initialized)
+ {
+ load(status);
+ _initialized = true;
+ }
+ updateMinerInfo();
+
+ DataElement minerRoot = _dataStore.getMinerRoot();
+ _dataStore.refresh(minerRoot);
+ if (status.getAttribute(DE.A_VALUE).equals(DataStoreResources.model_incomplete))
+ {
+ _dataStore.refresh(status);
+ }
+ else
+ {
+
+ status.setAttribute(DE.A_VALUE, DataStoreResources.model_done);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+
+
+ }
+
+ /**
+ * Issues a specified command on this miner from the DataStore framework.
+ * The base class handles "C_INIT_MINERS" but other commands are delegated to
+ * the concrete miner implementations through handleCommand()
+ *
+ * @param command the command that has been sent to this miner
+ * @return the status of the command
+ */
+ protected final DataElement command(DataElement command)
+ {
+ String name = getCommandName(command);
+ DataElement status = getCommandStatus(command);
+ long startTime = System.currentTimeMillis();
+
+ if (status == null)
+ {
+ _dataStore.trace("bad command: ");
+ _dataStore.trace("\tcmd=" + command);
+ _dataStore.trace("\tparent=" + command.getParent());
+ return null;
+ }
+
+ if (status.getAttribute(DE.A_NAME).equals("start"))
+ {
+ status.setAttribute(DE.A_NAME, DataStoreResources.model_working);
+ }
+
+ if (name.equals(DataStoreSchema.C_INIT_MINERS))
+ {
+ initMiner(status);
+ }
+ else
+ {
+ try
+ {
+ status = handleCommand(command);
+ }
+ catch (Exception e)
+ {
+ //e.printStackTrace();
+ _dataStore.trace(e);
+ status.setAttribute(DE.A_VALUE, "Failed with Exception:"+getStack(e));
+ status.setAttribute(DE.A_NAME, DataStoreResources.model_done);
+ //status.setAttribute(DE.A_SOURCE, getStack(e));
+ _dataStore.refresh(status);
+
+ String exc = null;
+ if (e.getMessage() != null)
+ exc = e.getMessage();
+ else
+ exc = "Exception";
+ DataElement exception = _dataStore.createObject(status, DataStoreResources.model_error, exc);
+ }
+ catch (Error er)
+ {
+ er.printStackTrace();
+ _dataStore.trace(er);
+ _dataStore.finish();
+ System.exit(-1);
+ }
+ }
+
+ _dataStore.refresh(status);
+ return status;
+ }
+
+ private String getStack(Throwable e)
+ {
+ StringBuffer buf = new StringBuffer();
+ StackTraceElement[] stack = e.getStackTrace();
+ for (int i = 0; i < stack.length; i++)
+ {
+ buf.append(stack[i].getClassName() + ":" + stack[i].getMethodName() + ":" + stack[i].getLineNumber());
+ buf.append(",");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Sets the DataStore and performs some fundamental initialization for this miner.
+ * The framework calls this method on a miner before any commands are issued.
+ * The extendSchema() is called on the miner.
+ *
+ * @param dataStore the DataStore that owns this miner
+ */
+ public final void setDataStore(DataStore dataStore)
+ {
+ _dataStore = dataStore;
+
+ DataElement root = _dataStore.getMinerRoot();
+ String name = getMinerName();
+ String value = getValue();
+
+ _resourceBundle = getResourceBundle();
+
+ // yantzi: Reuse existing miner root if found
+ _minerElement = _dataStore.find(root, DE.A_NAME, name, 1);
+ if (_minerElement == null || _minerElement.isDeleted())
+ {
+ // Create new child for this miner
+ _minerElement = _dataStore.createObject(root, DataStoreResources.model_miner, name, name);
+ _minerElement.setAttribute(DE.A_VALUE, value);
+ _minerElement.setAttribute(DE.A_SOURCE, getVersion());
+
+ _minerData = _dataStore.createObject(_minerElement, DataStoreResources.model_data, DataStoreResources.model_Data, name);
+ _minerTransient = _dataStore.createObject(_minerElement, DataStoreResources.model_transient, DataStoreResources.model_Transient_Objects, name);
+ }
+ else
+ {
+ // Reuse existing miner node
+ _minerData = _dataStore.find(_minerElement, DE.A_NAME, DataStoreResources.model_Data, 1);
+ if (_minerData == null || _minerData.isDeleted())
+ {
+ _minerData = _dataStore.createObject(_minerElement, DataStoreResources.model_data, DataStoreResources.model_Data, name);
+ }
+
+ _minerTransient = _dataStore.find(_minerElement, DE.A_NAME, DataStoreResources.model_Transient_Objects, 1);
+ if (_minerTransient == null || _minerData.isDeleted())
+ {
+ _minerTransient = _dataStore.createObject(_minerElement, DataStoreResources.model_transient, DataStoreResources.model_Transient_Objects, name);
+ }
+ }
+
+ _dataStore.refresh(root, true);
+ _dataStore.refresh(_minerElement);
+
+ _connected = true;
+ }
+
+ /**
+ * Creates an abstract command descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the command
+ * @param value the identifier for this command
+ * @return the new command descriptor
+ */
+ public final DataElement createAbstractCommandDescriptor(DataElement descriptor, String name, String value)
+ {
+ return _dataStore.createAbstractCommandDescriptor(descriptor, name, getMinerName(), value);
+ }
+
+ /**
+ * Creates a command descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the command
+ * @param value the identifier for this command
+ * @return the new command descriptor
+ */
+ public final DataElement createCommandDescriptor(DataElement descriptor, String name, String value)
+ {
+ return createCommandDescriptor(descriptor, name, value, true);
+ }
+
+ /**
+ * Creates a command descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the command
+ * @param value the identifier for this command
+ * @param visible an indication whether this command descriptor should be visible to an end-user
+ * @return the new command descriptor
+ */
+ public final DataElement createCommandDescriptor(DataElement descriptor, String name, String value, boolean visible)
+ {
+ DataElement cmdD = _dataStore.createCommandDescriptor(descriptor, name, getMinerName(), value);
+ if (!visible)
+ {
+ cmdD.setDepth(0);
+ }
+
+ return cmdD;
+ }
+
+ /**
+ * Creates an abstract object descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the object type
+ * @return the new object descriptor
+ */
+ public final DataElement createAbstractObjectDescriptor(DataElement descriptor, String name)
+ {
+ return _dataStore.createAbstractObjectDescriptor(descriptor, name);
+ }
+
+ /**
+ * Creates an abstract object descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the object type
+ * @param source the plugin location of the miner that owns this object type
+ * @return the new object descriptor
+ */
+ public final DataElement createAbstractObjectDescriptor(DataElement descriptor, String name, String source)
+ {
+ return _dataStore.createAbstractObjectDescriptor(descriptor, name, source);
+ }
+
+ /**
+ * Creates a object descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the object type
+ * @return the new object descriptor
+ */
+ public final DataElement createObjectDescriptor(DataElement descriptor, String name)
+ {
+ return _dataStore.createObjectDescriptor(descriptor, name);
+ }
+
+ /**
+ * Creates a object descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the object type
+ * @param source the plugin location of the miner that owns this object type
+ * @return the new object descriptor
+ */
+ public final DataElement createObjectDescriptor(DataElement descriptor, String name, String source)
+ {
+ return _dataStore.createObjectDescriptor(descriptor, name, source);
+ }
+
+ /**
+ * Creates a new type of relationship descriptor. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain
+ *
+ * @param descriptor the parent descriptor for the new descriptor
+ * @param name the name of the relationship type
+ * @return the new relationship descriptor
+ */
+ public final DataElement createRelationDescriptor(DataElement descriptor, String name)
+ {
+ return _dataStore.createRelationDescriptor(descriptor, name);
+ }
+
+ /**
+ * Creates an abstract relationship between two descriptors. An abstract relationship between two descriptors
+ * indicates that the first descriptor abstracts the second, while the second inherits the
+ * properties of the first. This is a helper method that miner may call
+ * when it creates or updates the schema for it's tool domain.
+ *
+ * @param from the abstacting descriptor
+ * @param to the descriptor that is abstracted
+ * @return the new relationship descriptor
+ */
+ public final DataElement createAbstractRelationship(DataElement from, DataElement to)
+ {
+ return _dataStore.createReference(from, to, "abstracts", "abstracted by");
+ }
+
+ /**
+ * Creates a contents relationship between any two elements.
+ *
+ * @param from the containing element
+ * @param to the element that is contained
+ * @return the new relationship
+ */
+ public final DataElement createReference(DataElement from, DataElement to)
+ {
+ return _dataStore.createReference(from, to);
+ }
+
+
+
+ /**
+ * Returns the element that represents this miner.
+ *
+ * @return the miner element
+ */
+ public final DataElement getMinerElement()
+ {
+ return _minerElement;
+ }
+
+ /**
+ * Returns the element that contains this miners meta-information.
+ *
+ * @return the miner data element
+ */
+ public final DataElement getMinerData()
+ {
+ return _minerData;
+ }
+
+ /**
+ * Returns the transient object container for this element.
+ *
+ * @return the transient element
+ */
+ public final DataElement getMinerTransient()
+ {
+ return _minerTransient;
+ }
+
+ /**
+ * Identifies a give object descriptor type to be transient in this miner.
+ *
+ * @param objectDescriptor the object descriptor type that is transient
+ */
+ public final void makeTransient(DataElement objectDescriptor)
+ {
+ _dataStore.createReference(_minerTransient, objectDescriptor);
+ }
+
+ /**
+ * Returns the name of a command.
+ * This is a helper method to be used inside handleCommand().
+ *
+ * @param command a tree of elements representing a command
+ * @return the name of the command
+ */
+ public final String getCommandName(DataElement command)
+ {
+ return (String) command.getAttribute(DE.A_NAME);
+ }
+
+ /**
+ * Returns the status of a command.
+ * This is a helper method to be used inside handleCommand().
+ *
+ * @param command a tree of elements representing a command
+ * @return the status element for the command
+ */
+ public final DataElement getCommandStatus(DataElement command)
+ {
+ //DKM - status is always last
+ return command.get(command.getNestedSize() - 1);
+ //_dataStore.find(command, DE.A_TYPE, DataStoreResources.model_status"), 1);
+ }
+
+
+
+ /**
+ * Returns the number of arguments for this command.
+ * This is a helper method to be used inside handleCommand().
+ *
+ * @param command a tree of elements representing a command
+ * @return the number of arguments for this command
+ */
+ public final int getNumberOfCommandArguments(DataElement command)
+ {
+ return command.getNestedSize();
+ }
+
+ /**
+ * Returns the argument of a command specified at a given index.
+ * This is a helper method to be used inside handleCommand().
+ *
+ * @param command a tree of elements representing a command
+ * @param arg the index into the commands children
+ * @return the argument of the command
+ */
+ public final DataElement getCommandArgument(DataElement command, int arg)
+ {
+ if (command.getNestedSize() > 0)
+ {
+ DataElement argument = command.get(arg);
+ if (argument != null)
+ {
+ return argument.dereference();
+ }
+ }
+
+ return null;
+ }
+
+
+
+ /**
+ * Returns the descriptor root for the DataStore schema
+ *
+ * @return the descriptor root
+ */
+ public final DataElement getSchemaRoot()
+ {
+ return _dataStore.getDescriptorRoot();
+ }
+
+ public void setExternalLoader(ExternalLoader loader)
+ {
+ _loader = loader;
+ }
+
+ public ExternalLoader getExternalLoader()
+ {
+ return _loader;
+ }
+
+ public synchronized void waitForInput()
+ {
+ if (_commandQueue.size() == 0)
+ {
+ super.waitForInput();
+ }
+ }
+
+
+
+ /**
+ * Handle commands that are routed to this miner.
+ * This interface must be implemented by each miner in order to
+ * perform tool actions driven from user interface interaction.
+ *
+ * @param theCommand an instance of a command containing a tree of arguments
+ */
+ public abstract DataElement handleCommand(DataElement theCommand);
+
+
+ /**
+ * Returns the version of this miner
+ * The expected format for this is "
+ * The ByteStreamHandler class is used to abstract file read and write operations
+ * across the network. By default this is used for sending and receiving files
+ * on the client and the server. The class can be extended if the default byte stream
+ * implementations are not sufficient for a particular platform or use.
+ *
+ * If ByteStreamHandler is extended, you need to tell the DataStore to use the
+ * extended implementation. To do that, call
+ * Abtract class for handling commands. A
+ * The CommandHandler is the means by which the DataStore sends information or files from
+ * the client to the remote tools.
+ *
+ * Every
+ * The ByteStreamHandler interface is used to abstract file read and write operations
+ * across the network.
+ *
+ */
+public interface IByteStreamHandler
+{
+
+ /**
+ * Returns the unique ID for this bytestream handler
+ * @return the unique id
+ */
+ public String getId();
+
+ /**
+ * Save a file in the specified location. This method is called by the
+ * DataStore when the communication layer receives a file transfer
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the bytes to insert in the file
+ * @param size the number of bytes to insert
+ * @param binary indicates whether to save the bytes as binary or text
+ */
+ public void receiveBytes(String remotePath, byte[] buffer, int size, boolean binary);
+
+ /**
+ * Append a bytes to a file at a specified location. This method is called by the
+ * DataStore when the communication layer receives a file transfer append.
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the bytes to append in the file
+ * @param size the number of bytes to append in the file
+ * @param binary indicates whether to save the bytes as binary or text
+ */
+ public void receiveAppendedBytes(String remotePath, byte[] buffer, int size, boolean binary);
+
+
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreProvider.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreProvider.java
new file mode 100644
index 00000000000..5604287afac
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreProvider.java
@@ -0,0 +1,22 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+public interface IDataStoreProvider
+{
+ public DataStore getDataStore();
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISSLProperties.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISSLProperties.java
new file mode 100644
index 00000000000..24654107a06
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISSLProperties.java
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+public interface ISSLProperties
+{
+ public boolean usingSSL();
+ public String getDaemonKeyStorePassword();
+ public String getDaemonKeyStorePath();
+ public String getServerKeyStorePassword();
+ public String getServerKeyStorePath();
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaExtender.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaExtender.java
new file mode 100644
index 00000000000..c20f9717d00
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaExtender.java
@@ -0,0 +1,49 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+
+import org.eclipse.dstore.core.util.ExternalLoader;
+
+/**
+ * ISchemaExtender describes the interfaces that tool extensions
+ * need to implement to add or extend other schemas in the DataStore.
+ */
+public interface ISchemaExtender
+{
+
+
+ /**
+ * Add this tool's schema to the global DataStore schema.
+ * This interface must be implemented by each miner in order to
+ * populate the DataStore schema with information about this tool's
+ * object model and information about how to communicate with the
+ * tool from objects available to the user interface.
+ *
+ * @param schemaRoot the descriptor root
+ */
+ public abstract void extendSchema(DataElement schemaRoot);
+
+ /**
+ * Implement this to returns the external class loader for this extender
+ * implementation. In order for a tool extension to be loaded by the DataStore, it's
+ * class loader needs to be supplied.
+ *
+ * @return the external loader
+ */
+ public abstract ExternalLoader getExternalLoader();
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaProvider.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaProvider.java
new file mode 100644
index 00000000000..47ca0e001f0
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaProvider.java
@@ -0,0 +1,25 @@
+/********************************************************************************
+ * Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+public interface ISchemaProvider
+{
+
+
+ public ISchemaRegistry getSchemaRegistry();
+ public ISchemaExtender getSchemaExtender();
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaRegistry.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaRegistry.java
new file mode 100644
index 00000000000..49f3d7f781f
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ISchemaRegistry.java
@@ -0,0 +1,50 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import org.eclipse.dstore.core.util.ExternalLoader;
+
+/**
+ * ISchemaRegistry describes the interface that needs to be
+ * implemented for external tools to contribute their
+ * schemas to the DataStore.
+ */
+public interface ISchemaRegistry
+{
+
+ /**
+ * This method gets called when a new schema extender needs to be
+ * registered.
+ *
+ * @param extender the new schema extender
+ */
+ public void registerSchemaExtender(ISchemaExtender extender);
+
+ /**
+ * This method is responsible for calling
+ * Abtract class for handling updates. A
+ * The UpdateHandler is the means by which the DataStore sends information or files from the remote tools to the client.
+ *
+ * This class is used to serialize data and send it either
+ * to a file or a socket.
+ *
+ * When a DataStore tree needs to be transmitted, it's DataElements are
+ * converted to XML before sending. Only those elements which have changed and
+ * are thus out of synch with the DataStore on the other end of the socket are
+ * actually transferred.
+ *
+ * When a byte stream or file needs to be transmitted, bytes are
+ * either send as is if binary transfer is requested or as unicode if
+ * binary transfer is not requested.
+ *
+ * This class is used to deserialize data received from a file or a socket.
+ *
+ * When tags indicate that data is being received, the byte stream is deserialized
+ * as a DataStore tree. When deserialized data maps to existing DataElements in
+ * the DataStore, those elements are updated directly. Any deserialized data
+ * that maps to within an existing DataElement, that does not already exist, gets
+ * created under the existing DataElement. When parsing DataElement XML, there is
+ * no intermediate DOM - rather the DOM is the DataStore itself.
+ *
+ * When tags indicate that a byte stream or file is being received, bytes are
+ * sent the the current DataStore February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content. February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.
+ * The universal subsystems are based on datastore technology so we use that
+ * to do the connection.
+ */
+public class DStoreConnectorService extends AbstractConnectorService implements IDataStoreProvider
+{
+
+ private ClientConnection clientConnection = null;
+ private ConnectionStatusListener _connectionStatusListener = null;
+
+ // Shortcut to sysInfo to save time
+ private transient DataElement sysInfo = null;
+ private transient DataElement installInfo = null;
+ private transient DataElement clientIP = null;
+ private static String DSTORE_PACKAGE = "org.eclipse.dstore.core";
+
+ private Exception connectException;
+ //private Hashtable restrictedTypes = null;
+ private IServerLauncher starter;
+
+
+ private class ShowConnectMessage implements Runnable
+ {
+ private SystemMessage _msg;
+ public ShowConnectMessage(SystemMessage msg)
+ {
+ _msg = msg;
+ }
+
+ public void run()
+ {
+ SystemMessageDialog dlg = new SystemMessageDialog(SystemBasePlugin.getActiveWorkbenchShell(), _msg);
+ dlg.open();
+ }
+ }
+
+ /**
+ * Constructor when we don't have a subsystem yet.
+ * Call setSubSystem after.
+ */
+ public DStoreConnectorService(String name, String description, IHost host)
+ {
+ super(name, description, host, 0);
+ }
+
+
+
+ /*
+ * Set the subsystem, when its not known at constructor time
+ *
+ public void setSubSystem(SubSystem ss)
+ {
+ super.setSubSystem(ss);
+ setDaemonLaunchEnabled((SubSystemImpl)ss, false);
+ }*/
+
+
+ public int getServerVersion()
+ {
+ return clientConnection.getServerVersion();
+ }
+
+ public int getServerMinor()
+ {
+ return clientConnection.getServerMinor();
+ }
+
+ /**
+ * Retrieve the value of a property which is contained in the environment miners
+ * system info child. Currently supported properties:
+ *
+ * The job of this manager is to manage and return ISystem objects.
+ * It ensures there is only ever one per unique SystemConnection,
+ * so that both the file and cmd subsystems can share the same system object.
+ */
+public class DStoreConnectorServiceManager extends AbstractConnectorServiceManager
+{
+ private static DStoreConnectorServiceManager inst = null;
+
+ /**
+ * Private constructor to ensure not instantiated this way.
+ * Use getTheUniversalSystemManager instead.
+ */
+ private DStoreConnectorServiceManager()
+ {
+ }
+
+ /**
+ * Return singleton instance of this class
+ */
+ public static DStoreConnectorServiceManager getTheUniversalSystemManager()
+ {
+ if (inst == null)
+ inst = new DStoreConnectorServiceManager();
+ return inst;
+ }
+
+ /**
+ * Return true if the singleton has been created.
+ * This saves creating it at shutdown just to test for isConnected.
+ */
+ public static boolean isInstantiated()
+ {
+ return (inst != null);
+ }
+
+ // -------------------------------------
+ // ABSTRACT METHODS FROM PARENT CLASS...
+ // -------------------------------------
+
+ /**
+ * Return the actual ISystem object. We return an instance of UniversalSystem.
+ */
+ public IConnectorService createConnectorService(IHost host)
+ {
+ IConnectorService service = new DStoreConnectorService(ConnectorServiceResources.DStore_ConnectorService_Label, ConnectorServiceResources.DStore_ConnectorService_Description, host);
+ return service;
+ }
+
+ /**
+ * For all subsystems in a particular SystemConnection, we need to know which
+ * ones are to share a single ISystem object. To do this, we need a key which
+ * is canonical for all subsystems in a given connection. This can be anything,
+ * but is typically a unique interface that all subsystems supported a shared
+ * ISystem object implement.
+ *
+ * Whatever is returned from here is used as the key into a hashtable to find the
+ * singleton ISystem object in getSystemObject.
+ *
+ * @return IUniversalSubSystem.class
+ */
+ public Class getSubSystemCommonInterface(ISubSystem subsystem)
+ {
+ return IUniversalDStoreSubSystem.class;
+ }
+ /**
+ * Given another subsystem, return true if that subsystem shares a single ISystem object
+ * with this one. You must override this to return true if you recognize that subsystem
+ * as one of your own. You are guaranteed the other subsystem will be from the same
+ * SystemConnection as this one.
+ *
+ * You can't assume a SystemConnection will you only have subsystems of that you created,
+ * so you should only return true if it implements your interface or you know it is an
+ * instance of your subsystem class.
+ *
+ * This should simply return (otherSubSystem instanceof interface) where interface is
+ * the same one returned from getSubSystemCommonInterface
+ *
+ * @return true if otherSubSystem instanceof IUniversalSubSystem
+ */
+ public boolean sharesSystem(ISubSystem otherSubSystem)
+ {
+ return (otherSubSystem instanceof IUniversalDStoreSubSystem);
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java
new file mode 100644
index 00000000000..960a0129a84
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java
@@ -0,0 +1,70 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+/**
+ * Constants used throughout the UniversalSystem plugin
+ */
+public interface IUniversalDStoreConstants
+{
+
+
+ public static final String PLUGIN_ID ="com.ibm.etools.systems.universal";
+
+ public static final String PREFIX = PLUGIN_ID + ".";
+
+ // prefix for context sensitive help
+ public static final String HELP_PREFIX = PREFIX;
+
+ // Resource Bundle ids
+ public static final String RESID_PREFIX = PREFIX + "ui.";
+
+ // Icons
+ public static final String ICON_DIR = "icons";
+ public static final String ICON_PATH = java.io.File.separator + ICON_DIR + java.io.File.separator;
+ public static final String ICON_SUFFIX = "Icon";
+ public static final String ICON_EXT = ".gif";
+
+ //public static final String ICON_SYSTEM_LIBRARY_ROOT = "system400Library";
+ //public static final String ICON_SYSTEM_LIBRARY = ICON_SYSTEM_LIBRARY_ROOT + ICON_EXT;
+ //public static final String ICON_SYSTEM_LIBRARY_ID = PREFIX + ICON_SYSTEM_LIBRARY_ROOT + ICON_SUFFIX;
+
+ // -------------------------
+ // Action prefixes.
+ // SYstemBaseAction class adds "label" to get text and "tooltip" and "description" to get hover help
+ // -------------------------
+ // action ids
+ public static final String ACTION_PREFIX = RESID_PREFIX + "action.";
+ public static final String RESID_RUN_REMOTECMD_PREFIX = ACTION_PREFIX+"RunRemoteCommand";
+
+
+ // -------------------------
+ // Preferences...
+ // -------------------------
+ public static final String RESID_PREF_PREFIX = RESID_PREFIX+"preferences.";
+ public static final String RESID_PREF_ROOT_TITLE = RESID_PREF_PREFIX+"root.title";
+
+ // RemoteClassLoader caching preferences
+ public static final String RESID_PREF_CACHE_REMOTE_CLASSES = RESID_PREF_PREFIX + "cacheremoteclasses";
+ public static final boolean DEFAULT_PREF_CACHE_REMOTE_CLASSES = true;
+
+ // Socket timeout preference
+ public static final String RESID_PREF_SOCKET_TIMEOUT = RESID_PREF_PREFIX + "sockettimeout";
+ public static final int DEFAULT_PREF_SOCKET_TIMEOUT = 300000;
+
+ public static final String RESID_PREF_DO_KEEPALIVE = RESID_PREF_PREFIX + "dokeepalive";
+ public static final boolean DEFAULT_PREF_DO_KEEPALIVE = true;
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreMessages.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreMessages.java
new file mode 100644
index 00000000000..0bd0666c6a4
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreMessages.java
@@ -0,0 +1,60 @@
+/********************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+
+/**
+ * Message IDs
+ */
+public interface IUniversalDStoreMessages
+{
+
+
+ public static final String PLUGIN_ID ="com.ibm.etools.systems.universal";
+ public static final String PREFIX = PLUGIN_ID+".";
+ // Resource Bundle ids
+ public static final String RESID_PREFIX = PREFIX+"ui.";
+ // Messages prefixes
+ public static final String MSG_PREFIX = RESID_PREFIX+"msg.";
+ public static final String MSG_TITLE = MSG_PREFIX + "Title";
+
+ // Messages
+ public static final String MSG_CONNECTION_PREFIX = MSG_PREFIX + "Connection.";
+ public static final String MSG_CONNECTION_FAILED = MSG_CONNECTION_PREFIX + "Failed";
+ public static final String MSG_CONNECTION_UNKNOWN_HOST = MSG_CONNECTION_PREFIX + "UnknownHost";
+ public static final String MSG_CONNECTION_VERIFY = MSG_CONNECTION_PREFIX + "Verify";
+ public static final String MSG_CONNECTION_COMMPROPERTIES = MSG_CONNECTION_PREFIX + "CommProperties";
+
+ // RSE Server Connection Messages
+ public static final String MSG_SIGNON_PREFIX = MSG_PREFIX + "Signon.";
+ public static final String MSG_SIGNON_PASSWORD_ERROR = MSG_SIGNON_PREFIX + "PasswordError";
+ public static final String MSG_SIGNON_PASSWORD_INCORRECT = MSG_SIGNON_PREFIX + "PasswordIncorrect";
+ public static final String MSG_SIGNON_PASSWORD_INCORRECT_USER_DISABLED= MSG_SIGNON_PREFIX + "PasswordIncorrectUserDisabled";
+ public static final String MSG_SIGNON_PASSWORD_EXPIRED = MSG_SIGNON_PREFIX + "PasswordExpired";
+ public static final String MSG_SIGNON_USERID_INVALID = MSG_SIGNON_PREFIX + "UserIDInvalid";
+ public static final String MSG_SIGNON_USERID_DISABLED = MSG_SIGNON_PREFIX + "UserIDDisabled";
+ public static final String MSG_SIGNON_USERID_ERROR = MSG_SIGNON_PREFIX + "UserIDError";
+
+ public static final String MSG_DATASTORE_PREFIX = MSG_PREFIX + "DataStore.";
+ public static final String MSG_DATASTORE_STARTSERVER = MSG_DATASTORE_PREFIX + "StartServer";
+ public static final String MSG_DATASTORE_CONNECTSERVER = MSG_DATASTORE_PREFIX + "ConnectServer";
+ public static final String MSG_DATASTORE_INITIALIZESERVER = MSG_DATASTORE_PREFIX + "InitializeServer";
+ public static final String MSG_DATASTORE_INITIALIZECODESERVER = MSG_DATASTORE_PREFIX + "InitializeCODEServer";
+
+ public static final String MSG_CMD_PREFIX = MSG_PREFIX + "Command.";
+ public static final String MSG_CMDNAME_EMPTY = MSG_CMD_PREFIX + "Required";
+ public static final String MSG_CMDNAME_NOTVALID = MSG_CMD_PREFIX + "NotValid";
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreSubSystem.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreSubSystem.java
new file mode 100644
index 00000000000..f291564a1d0
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreSubSystem.java
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+/**
+ * Simply a tag to indicate this factory is one our universal subsystems.
+ */
+public interface IUniversalDStoreSubSystem
+{
+
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalSubSystemFactory.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalSubSystemFactory.java
new file mode 100644
index 00000000000..9db520b9aa0
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalSubSystemFactory.java
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+/**
+ * Simply a tag to indicate this factory is one our universal subsystem factories.
+ */
+public interface IUniversalSubSystemFactory
+{
+
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/RexecDstoreServer.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/RexecDstoreServer.java
new file mode 100644
index 00000000000..67c8660d077
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/RexecDstoreServer.java
@@ -0,0 +1,1199 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.net.Socket;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.dstore.core.client.ClientConnection;
+import org.eclipse.dstore.core.client.ConnectionStatus;
+import org.eclipse.rse.core.SystemBasePlugin;
+import org.eclipse.rse.core.SystemPlugin;
+import org.eclipse.rse.core.subsystems.IIBMServerLauncher;
+import org.eclipse.rse.core.subsystems.IServerLauncher;
+import org.eclipse.rse.core.subsystems.IServerLauncherProperties;
+import org.eclipse.rse.model.SystemSignonInformation;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.ui.ISystemMessages;
+
+/**
+ * Launch Datastore server on selected host using the rexec
+ * protocol
+ */
+public class RexecDstoreServer implements IServerLauncher
+{
+ private SystemMessage _errorMessage;
+ private SystemSignonInformation signonInfo;
+ //private String host = null;
+ private String cwd = null;
+ private String invocation = null;
+ //private String userID = null;
+ private int rexecPort = 512; // the port where rexecd normally listens
+ private String cmd = null;
+ //private String pwd = null;
+ private static String ASCII_TEST_STRING = "ASCII";
+ private static String PORT_LEADING_STRING = "Server Started Successfully";
+ private static final String EZYRD11E="EZYRD11E";
+ private ClientConnection clientConnection;
+ private IServerLauncherProperties propertyInfo;
+ private boolean isModeChecked = false;
+ private boolean checkPort =true;
+ private boolean logInfo = false;
+ private int _socketTimeoutValue = IUniversalDStoreConstants.DEFAULT_PREF_SOCKET_TIMEOUT;
+
+ private static char[] ebcdictounicode =
+ {
+ 0x0000,
+ 0x0001,
+ 0x0002,
+ 0x0003,
+ 0x0000,
+ 0x0009,
+ 0x0000,
+ 0x007F,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x000B,
+ 0x000C,
+ 0x000D,
+ 0x000E,
+ 0x000F,
+ 0x0010,
+ 0x0011,
+ 0x0012,
+ 0x0013,
+ 0x0000,
+ 0x000A,
+ 0x0008,
+ 0x0000,
+ 0x0018,
+ 0x0019,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x001C,
+ 0x0000,
+ 0x0000,
+ 0x000A,
+ 0x0017,
+ 0x001B,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0005,
+ 0x0006,
+ 0x0007,
+ 0x0000,
+ 0x0000,
+ 0x0016,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0004,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0014,
+ 0x0015,
+ 0x0000,
+ 0x001A,
+ 0x0020,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x002E,
+ 0x003C,
+ 0x0028,
+ 0x002B,
+ 0x007C,
+ 0x0026,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0021,
+ 0x0024,
+ 0x002A,
+ 0x0029,
+ 0x003B,
+ 0x0000,
+ 0x002D,
+ 0x002F,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x007C,
+ 0x002C,
+ 0x0025,
+ 0x005F,
+ 0x003E,
+ 0x003F,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0060,
+ 0x003A,
+ 0x0023,
+ 0x0040,
+ 0x0027,
+ 0x003D,
+ 0x0022,
+ 0x0000,
+ 0x0061,
+ 0x0062,
+ 0x0063,
+ 0x0064,
+ 0x0065,
+ 0x0066,
+ 0x0067,
+ 0x0068,
+ 0x0069,
+ 0x0000,
+ 0x007B,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x002B,
+ 0x0000,
+ 0x006A,
+ 0x006B,
+ 0x006C,
+ 0x006D,
+ 0x006E,
+ 0x006F,
+ 0x0070,
+ 0x0071,
+ 0x0072,
+ 0x0000,
+ 0x007D,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0073,
+ 0x0074,
+ 0x0075,
+ 0x0076,
+ 0x0077,
+ 0x0078,
+ 0x0079,
+ 0x007A,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x005B,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x005D,
+ 0x0000,
+ 0x002D,
+ 0x007D,
+ 0x0041,
+ 0x0042,
+ 0x0043,
+ 0x0044,
+ 0x0045,
+ 0x0046,
+ 0x0047,
+ 0x0048,
+ 0x0049,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x007D,
+ 0x004A,
+ 0x004B,
+ 0x004C,
+ 0x004D,
+ 0x004E,
+ 0x004F,
+ 0x0050,
+ 0x0051,
+ 0x0052,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x005C,
+ 0x0000,
+ 0x0053,
+ 0x0054,
+ 0x0055,
+ 0x0056,
+ 0x0057,
+ 0x0058,
+ 0x0059,
+ 0x005A,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0030,
+ 0x0031,
+ 0x0032,
+ 0x0033,
+ 0x0034,
+ 0x0035,
+ 0x0036,
+ 0x0037,
+ 0x0038,
+ 0x0039,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000 };
+
+ /**
+ * Constructor
+ */
+ public RexecDstoreServer()
+ {
+ super();
+ }
+
+ /**
+ * Set the datastore client connection. This is reset for each connect()
+ */
+ public void setClientConnection(ClientConnection clientConnection)
+ {
+ this.clientConnection = clientConnection;
+ }
+
+ /**
+ * Set the remote system signon information
+ */
+ public void setSignonInformation(SystemSignonInformation info)
+ {
+ this.signonInfo = info;
+ }
+
+ /**
+ * Get the remote system signon information, as set in
+ * {@link #setSignonInformation(SystemSignonInformation)}
+ */
+ public SystemSignonInformation getSignonInformation()
+ {
+ return signonInfo;
+ }
+
+ /**
+ * Set the object which contains the user-specified properties that
+ * are used by this launcher
+ */
+ public void setServerLauncherProperties(IServerLauncherProperties propertyInfo)
+ {
+ this.propertyInfo = propertyInfo;
+ // set path...
+ this.cwd = ((IIBMServerLauncher)propertyInfo).getServerPath();
+ char separatorChar = signonInfo.getSystemType().equals("Windows") ? '\\' : '/';
+ if (cwd.length() > 0 && cwd.charAt(cwd.length() - 1) != separatorChar)
+ cwd += separatorChar;
+ // set script...
+ this.invocation = ((IIBMServerLauncher)propertyInfo).getServerScript();
+ }
+
+ /**
+ * Get the object which contians the user-specified properties that are
+ * used by this launcher. As set in {@link #setServerLauncherProperties(IServerLauncherProperties)}.
+ */
+ public IServerLauncherProperties getServerLauncherProperties()
+ {
+ return propertyInfo;
+ }
+
+ /**
+ * Determine if the remote server needs to be launched or not.
+ * Generally is always false.
+ */
+ public boolean isLaunched()
+ {
+ return false;
+ }
+
+ /**
+ * Send a command to the host via rexec to launch the datastore server
+ * under the specified user ID/pwd. the datastore server will emit
+ * messages that include the port number on which the server is listening
+ * for client connections
+ *
+ * @return port number as String
+ */
+ /*
+ * There used to be a problem in IBM Communications Server for z/OS and
+ * the message from the REXEC daemon was in EBCDIC. see APAR PQ76782.
+ * Since this problem was fixed in Communication Server, there is no need to convert EBCDIC to ASCII
+ */
+ // updated method
+ public Object launch(IProgressMonitor monitor) throws Exception
+ {
+
+ boolean isEBCDICTest=false;
+ isModeChecked= false;
+ checkPort=true;
+ _errorMessage = null;
+ String port = new String("0"); // default no port
+ //String hostResponse = ""; //buffer to hold all the messages, so that it can be printed out later
+ String originalHostResponse="";
+ String convertedHostResponse="";
+ String debugOptions = System.getProperty("REXEC_DEBUG");
+ if (debugOptions!= null){
+ if (debugOptions.toUpperCase().indexOf("LOG") > -1)
+ logInfo = true;
+ if (debugOptions.toUpperCase().indexOf("EBCDIC") > -1)
+ isEBCDICTest=true;
+ }
+ boolean isEBCDIC = false;
+ try
+ {
+
+ // establish socket for rexec connection
+ Socket rexecCall = new Socket(signonInfo.getHostname(), rexecPort); // rexec listens here - 512
+
+ // set socket timeout value
+ rexecCall.setSoTimeout(_socketTimeoutValue);
+
+ // set up data streams on rexec socket
+ DataOutputStream rxOut = new DataOutputStream(rexecCall.getOutputStream());
+ DataInputStream rxIn = new DataInputStream(rexecCall.getInputStream());
+
+ // we're not opening a socket for stderr to circumvent problems that
+ // may arise if the client is behind a firewall with respect to the
+ // host, in which case the rexec daemon may have trouble connecting
+ // to the client error port.
+ // Not sending a port number at this point indicates to the daemon
+ // that there is no error socket to establish.
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ // send userid and password on rexec socket
+ rxOut.writeBytes(signonInfo.getUserid());
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.writeBytes(signonInfo.getPassword());
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ // send the command on rexec socket to start datastore daemon listening
+ // on any port
+ // TODO - assumes a particular script and location to start the server,
+ // this should be stored in some resource bundle later
+ //cmd = new String ("echo USSTEST;cd ~/dstore;start_anyport");
+ //cmd = new String("echo " + ASCII_TEST_STRING + ";cd ~/rseserver;start_anyport");
+ cmd = new String("echo " + ASCII_TEST_STRING + ";cd " + this.cwd + ";" + this.invocation);
+ logMessage("The command is " + cmd);
+ SystemBasePlugin.logInfo("RexecDstoreServer :");
+
+ rxOut.writeBytes(cmd);
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ int inBytes = rxIn.available(); // any data available?
+
+ int timeout = 600; // 60 second to connect
+
+ while (inBytes == 0 && timeout > 0)
+ {
+ if (monitor.isCanceled()) // Cancel button pressed?
+ return "0";
+
+ // try for more input
+ Thread.sleep(100);
+ inBytes = rxIn.available();
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INVALID_LOGIN);
+ msg.makeSubstitution(signonInfo.getHostname(), "");
+ _errorMessage = msg;
+ return port;
+ }
+
+ // get command output on socket, one byte at a time until
+ // got the datastore port number or EOF is reached for this input
+ String maybePort=null;
+ while (true ){
+ if (monitor.isCanceled())
+ return "0";
+ byte aByte = rxIn.readByte();
+ if (isEBCDICTest)
+ aByte = convertFromASCIIToEBCDIC(aByte); // for EBCDIC Test
+ if (aByte == 0) // drop the null
+ continue;
+ originalHostResponse += (char)aByte;
+ logMessage("Host response is " + originalHostResponse);
+ if (!isModeChecked)
+ {
+ convertedHostResponse += convertFromEBCDICToASCII(aByte);
+ logMessage("Host response is converted to " + convertedHostResponse);
+ if (originalHostResponse.indexOf(ASCII_TEST_STRING) > -1)
+ { // It's ASCII mode
+ isModeChecked = true;
+ logMessage("This is the ASCII mode. ");
+ }
+ else if (convertedHostResponse.indexOf(ASCII_TEST_STRING) > -1)
+ { // It's EBCDIC mode
+ logMessage("This is the EBCDIC mode. ");
+ isModeChecked = true;
+ isEBCDIC = true;
+ }
+ }
+ else
+ {
+ if (isEBCDIC)
+ {
+ convertedHostResponse += convertFromEBCDICToASCII(aByte);
+ logMessage("Host response is converted to " + convertedHostResponse);
+ if(checkPort)
+ { // It's EBCDIC mode
+ maybePort = extractPortNumber (convertedHostResponse);
+ }
+ }
+ else if (checkPort)
+ { // it's ASCII
+ maybePort = extractPortNumber (originalHostResponse);
+ }
+ if (maybePort == null)
+ continue ;
+ port = maybePort;
+ break;
+ }
+ }
+ // -----------------------------------------------------------------
+ // Close input/output streams and socket
+ // -----------------------------------------------------------------
+ rxIn.close();
+ rxOut.close();
+ rexecCall.close();
+ logMessage("Going to return port " + port);
+ return port;
+ }
+ catch (EOFException e)
+ {
+ // do nothing
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ // if no port is found, create error message
+ String hostMessage = originalHostResponse;
+ if (isEBCDIC) // pick up the right messages
+ hostMessage = convertedHostResponse;
+ int index = hostMessage.indexOf(ASCII_TEST_STRING);
+ if (index > -1) // remove the embedded ASCII_TEST_STRING
+ hostMessage = hostMessage.substring(0,index) + hostMessage.substring(index+1+ASCII_TEST_STRING.length());
+ if (hostMessage.indexOf(EZYRD11E) >0 ){
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INVALID_LOGIN);
+ msg.makeSubstitution(signonInfo.getHostname(), hostMessage);
+ _errorMessage = msg;
+ } else {
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_REXEC_NOTSTARTED);
+ msg.makeSubstitution(""+rexecPort, signonInfo.getHostname(), hostMessage);
+ _errorMessage = msg;
+
+ }
+
+ return port;
+ }
+ /**
+ * @param newLine
+ * @return
+ */
+ /*
+ private String checkCodePage(String newLine) {
+ // check in which mode the host is sending the message back
+ if (isModeChecked)
+ return newLine;
+ if (newLine.indexOf(ASCII_TEST_STRING) > -1){ // It's ASCII mode
+ isASCIIMode = true;
+ isModeChecked = true;
+ } else { // Check whether it's EBCDIC mode
+ String convertedNewLine = convertFromEBCDICToASCII(newLine.toCharArray());
+ if (convertedNewLine.indexOf(ASCII_TEST_STRING) > -1){
+ isASCIIMode = false;
+ isModeChecked = true;
+ }
+ }
+ return newLine;
+ }
+ */
+ /* wait until host responds with some data - at least should send null byte */
+/* char cChar;
+ int inBytes = rxIn.available(); // any data available?
+ StringBuffer buf = new StringBuffer();
+ String chunk = null;
+
+ while (inBytes == 0)
+ {
+ if (monitor.isCanceled())
+ return "0";
+
+ // try for more input
+ Thread.sleep(100);
+
+ inBytes = rxIn.available();
+ }
+
+ // get command output on socket, one byte at a time until
+ // got the datastore port number or EOF is reached for this input
+ byte[] bDSPort = new byte[4];
+ byte[] byteBuf = new byte[8];
+ int index;
+ if (inBytes > 0)
+ {
+ byte aByte = rxIn.readByte();
+ cChar = (char)aByte; // discard first null byte
+
+// port = getPortASCII(rxIn);
+ // should have at least 8 bytes plus newline from the "echo USSTEST" command. This is
+ // used to test if the data being returned is ASCII or EBCDIC
+ for (index = 0; index < ASCII_TEST_STRING.length(); index++)
+ { // include newline too
+ aByte = rxIn.readByte();
+ cChar = (char)aByte;
+ buf.append(cChar);
+ byteBuf[index] = aByte;
+ }
+ chunk = new String(buf);
+
+ if (chunk.indexOf(ASCII_TEST_STRING) >= 0)
+ {
+ // returned data is ASCII
+ port = getPortASCII(rxIn);
+ }
+ else
+ {
+
+ chunk = convertFromEBCDICToASCII(byteBuf);
+ if (chunk.indexOf(ASCII_TEST_STRING) >= 0)
+ {
+
+ // returned data is EBCDIC
+ port = getPortEBCDIC(rxIn);
+ }
+ else
+ {
+ // rexec error!
+ // there's an error
+ while (cChar != '\n')
+ {
+ cChar = (char) rxIn.readByte();
+ buf.append(cChar);
+ }
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INVALID_LOGIN);
+ msg.makeSubstitution(signonInfo.getHostname(), buf.toString());
+ _errorMessage = msg;
+ }
+ }
+ }
+ rxIn.close();
+ rxOut.close();
+ rexecCall.close();
+
+ }
+ catch (Exception e)
+ {
+ System.out.println(e);
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_REXEC_NOTSTARTED);
+ msg.makeSubstitution(""+rexecPort, signonInfo.getHostname(), e.getMessage());
+ _errorMessage = msg;
+ }
+
+ return port;
+ } // end of launch method
+ */
+ /* original method
+ public Object launch(IProgressMonitor monitor) throws Exception
+ {
+ _errorMessage = null;
+ String port = new String("0"); // default no port
+ try
+ {
+
+ // establish socket for rexec connection
+ Socket rexecCall = new Socket(signonInfo.getHostname(), rexecPort); // rexec listens here - 512
+
+ // set up data streams on rexec socket
+ DataOutputStream rxOut = new DataOutputStream(rexecCall.getOutputStream());
+ DataInputStream rxIn = new DataInputStream(rexecCall.getInputStream());
+
+ // we're not opening a socket for stderr to circumvent problems that
+ // may arise if the client is behind a firewall with respect to the
+ // host, in which case the rexec daemon may have trouble connecting
+ // to the client error port.
+ // Not sending a port number at this point indicates to the daemon
+ // that there is no error socket to establish.
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ // send userid and password on rexec socket
+ rxOut.writeBytes(signonInfo.getUserid());
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.writeBytes(signonInfo.getPassword());
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ // send the command on rexec socket to start datastore daemon listening
+ // on any port
+ // TODO - assumes a particular script and location to start the server,
+ // this should be stored in some resource bundle later
+ //cmd = new String ("echo USSTEST;cd ~/dstore;start_anyport");
+ //cmd = new String("echo " + ASCII_TEST_STRING + ";cd ~/rseserver;start_anyport");
+ cmd = new String("echo " + ASCII_TEST_STRING + ";cd " + this.cwd + ";" + this.invocation);
+
+ rxOut.writeBytes(cmd);
+ rxOut.writeByte((int) 0); // send null terminator
+ rxOut.flush();
+
+ // wait until host responds with some data - at least should send null byte
+
+ char cChar;
+ int inBytes = rxIn.available(); // any data available?
+ StringBuffer buf = new StringBuffer();
+ String chunk = null;
+
+ while (inBytes == 0)
+ {
+ if (monitor.isCanceled())
+ return "0";
+
+ // try for more input
+ Thread.sleep(100);
+
+ inBytes = rxIn.available();
+ }
+
+ // get command output on socket, one byte at a time until
+ // got the datastore port number or EOF is reached for this input
+ byte[] bDSPort = new byte[4];
+ byte[] byteBuf = new byte[8];
+ int index;
+ if (inBytes > 0)
+ {
+ byte aByte = rxIn.readByte();
+ cChar = (char)aByte; // discard first null byte
+
+ // should have at least 8 bytes plus newline from the "echo USSTEST" command. This is
+ // used to test if the data being returned is ASCII or EBCDIC
+ for (index = 0; index < ASCII_TEST_STRING.length(); index++)
+ { // include newline too
+ aByte = rxIn.readByte();
+ cChar = (char)aByte;
+ buf.append(cChar);
+ byteBuf[index] = aByte;
+ }
+ chunk = new String(buf);
+
+ if (chunk.indexOf(ASCII_TEST_STRING) >= 0)
+ {
+ // returned data is ASCII
+ port = getPortASCII(rxIn);
+ }
+ else
+ {
+
+ chunk = convertFromEBCDICToASCII(byteBuf);
+ if (chunk.indexOf(ASCII_TEST_STRING) >= 0)
+ {
+
+ // returned data is EBCDIC
+ port = getPortEBCDIC(rxIn);
+ }
+ else
+ {
+ // rexec error!
+ // there's an error
+ while (cChar != '\n')
+ {
+ cChar = (char) rxIn.readByte();
+ buf.append(cChar);
+ }
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INVALID_LOGIN);
+ msg.makeSubstitution(signonInfo.getHostname(), buf.toString());
+ _errorMessage = msg;
+ }
+ }
+
+ }
+ rxIn.close();
+ rxOut.close();
+ rexecCall.close();
+
+ }
+ catch (Exception e)
+ {
+ System.out.println(e);
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_REXEC_NOTSTARTED);
+ msg.makeSubstitution(""+rexecPort, signonInfo.getHostname(), e.getMessage());
+ _errorMessage = msg;
+ }
+
+ return port;
+ } // end of launch method
+*/
+ /**
+ * Determine if we are connected to the remote server or not.
+ * @return true if we are connected, false otherwise.
+ */
+ public boolean isConnected()
+ {
+ if (clientConnection != null)
+ {
+ return clientConnection.isConnected();
+ }
+ return false;
+ }
+
+ /**
+ * Connect to the remote server.
+ * @see #getErrorMessage()
+ * @param monitor a monitor for showing progress
+ * @param connectPort the port to use for launching the server
+ * @return Anything you want.
+ */
+ public Object connect(IProgressMonitor monitor, int connectPort) throws Exception
+ {
+ clientConnection.setPort(Integer.toString(connectPort));
+
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECTING_TO_SERVER);
+ cmsg.makeSubstitution(clientConnection.getPort());
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+
+ // connect to launched server
+ ConnectionStatus connectStatus = clientConnection.connect(null);
+
+ return connectStatus;
+ }
+
+ /**
+ * Disconnect from the remote server
+ * @see #getErrorMessage()
+ */
+ public void disconnect() throws Exception
+ {
+ if (clientConnection != null)
+ {
+ /* TODO!
+ // Is disconnect being called because the network (connection) went down?
+ if (_connectionStatusListener != null && _connectionStatusListener.isConnectionDown())
+ {
+ fireCommunicationsEvent(CommunicationsEvent.CONNECTION_ERROR);
+ }
+ else
+ {
+ // Fire comm event to signal state about to change
+ fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT);
+ }
+
+ DataStore dataStore = getDataStore();
+ if (dataStore != null && _connectionStatusListener != null)
+ {
+ dataStore.getDomainNotifier().removeDomainListener(_connectionStatusListener);
+ }
+
+ clientConnection.disconnect();
+ clientConnection = null;
+ getUserId(); // Clear any cached local user IDs
+ sysInfo = null;
+
+ // Fire comm event to signal state changed
+ fireCommunicationsEvent(CommunicationsEvent.AFTER_DISCONNECT);
+ */
+ clientConnection.disconnect();
+ clientConnection = null;
+ }
+ }
+
+ /**
+ * Return the last error message issued
+ */
+ public SystemMessage getErrorMessage()
+ {
+ return _errorMessage;
+ }
+
+ // ------------------
+ // PRIVATE METHODS...
+ // ------------------
+/*
+ // sam private String convertFromEBCDICToASCII(byte[] eBytes)
+ private String convertFromEBCDICToASCII(char[] eBytes)
+ {
+
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < eBytes.length; i++)
+ {
+ byte bByte = (byte)eBytes[i];
+ int index = bByte;
+ if (index < 0)
+ {
+ index = 256 + index;
+ }
+ char cChar = ebcdictounicode[index];
+ buf.append(cChar);
+ }
+ return buf.toString();
+ }
+*/
+ /**
+ * Read the data returned on the rexec port as ASCII characters and
+ * detect the port number in the datastore server messages
+ * @param rxIn
+ * @return String port number
+ */
+ /*
+ private String getPortASCII(DataInputStream rxIn)
+ {
+ String port = new String("0"); // default to no port
+ char cChar;
+ byte bByte;
+ int numPortChars = 5;
+ byte[] bDSPort = new byte[numPortChars];
+ StringBuffer buf = new StringBuffer();
+ StringBuffer diagnosticString = new StringBuffer();
+ String chunk = null;
+ boolean serverStartedMsg = false;
+ while (true)
+ {
+ try
+ {
+ cChar = (char) rxIn.readByte();
+ if (cChar == '\n')
+ { // hit a newline
+ chunk = new String(buf);
+
+ // DKM: need to handle mixed order cases
+
+ if (chunk.indexOf("Server Started Successfully") >= 0)
+ {
+ serverStartedMsg = true;
+ // this server output precedes the datastore server port number
+ buf.delete(0, buf.length()); // clear buffer
+
+ // might have already got port
+ // check first
+ if (port.equals("0"))
+ {
+ rxIn.read(bDSPort, 0, numPortChars); // get next 4 bytes - datastore port #
+ for (int i = 0; i < numPortChars; i++)
+ {
+ char c = (char) bDSPort[i];
+ if (Character.isDigit(c))
+ buf.append(c);
+ }
+ port = new String(buf); // got port where datastore server is listening
+
+ // check for valid port
+ try
+ {
+ int possiblePort = Integer.parseInt(port);
+ break;
+
+ }
+ catch (Exception e)
+ {
+ // not valid
+ }
+ }
+
+ }
+ else
+ {
+ // might be the port
+ try
+ {
+ int possiblePort = Integer.parseInt(chunk);
+ port = chunk;
+ if (serverStartedMsg)
+ break;
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ buf.delete(0, buf.length()); // clear buffer
+ }
+ else
+ {
+ diagnosticString.append(cChar);
+ buf.append(cChar);
+ }
+ }
+ // EOF indicates no more lines to come through on error socket
+ catch (EOFException e)
+ {
+ break;
+ }
+ catch (IOException e)
+ {
+ break;
+ }
+ } // end of while true
+
+ // if port is somethign wierd...log this
+ if (port.equals("0"))
+ {
+ // port is weird!
+
+ try
+ {
+
+ int available = rxIn.available();
+ while (available > 0)
+ {
+ rxIn.read(bDSPort, 0, numPortChars);
+ for (int i = 0; i < numPortChars; i++)
+ {
+ char c = (char) bDSPort[i];
+ diagnosticString.append(c);
+ }
+ available = rxIn.available();
+ }
+
+ }
+ catch (Exception ex)
+ {
+ }
+
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_SERVER_NOTSTARTED);
+ diagnosticString.insert(0, "\n\n");
+ msg.makeSubstitution(signonInfo.getHostname(), diagnosticString.toString());
+
+ _errorMessage = msg;
+ }
+
+ return port;
+ }
+*/
+ /**
+ * Read the data returned on the rexec port as EBCDIC characters and
+ * convert to unicode. Detect the port number in the datastore server messages
+ * @param rxIn
+ * @return String port number
+ */
+ /*
+ private String getPortEBCDIC(DataInputStream rxIn)
+ {
+ String port = new String("0"); // default to no port
+ int index;
+ char cChar;
+ byte bByte;
+ byte[] bDSPort = new byte[4];
+ StringBuffer buf = new StringBuffer();
+ String chunk = null;
+ while (true)
+ {
+ try
+ {
+ bByte = rxIn.readByte();
+ index = bByte;
+ if (index < 0)
+ {
+ index = 256 + index;
+ }
+ cChar = ebcdictounicode[index];
+ if (cChar == '\n')
+ { // hit a newline
+ chunk = new String(buf);
+
+ if (chunk.indexOf("Server Started Successfully") >= 0)
+ {
+ // this server output precedes the datastore server port number
+ buf.delete(0, buf.length()); // clear buffer
+ rxIn.read(bDSPort, 0, 4); // get next 4 bytes - datastore port #
+ for (int i = 0; i < 4; i++)
+ {
+ index = bDSPort[i];
+ if (index < 0)
+ {
+ index = 256 + index;
+ }
+ buf.append(ebcdictounicode[index]);
+ }
+ port = new String(buf); // got port where datastore server is listening
+ break;
+ }
+ buf.delete(0, buf.length()); // clear buffer
+ }
+ else
+ {
+ buf.append(cChar);
+ }
+ }
+ // EOF indicates no more lines to come through on error socket
+ catch (EOFException e)
+ {
+ break;
+ }
+ catch (IOException e)
+ {
+ break;
+ }
+ } // end of while true
+ return port;
+ }
+ */
+ private String extractPortNumber (String hostResponse) {
+ String port ="0";
+ logMessage("Going to find port number. ");
+ int index = hostResponse.indexOf(PORT_LEADING_STRING);
+ if ( index < 0 )
+ return null;
+ logMessage("Found the leading string. ");
+ String portString = hostResponse.substring(index + PORT_LEADING_STRING.length());
+ logMessage("Removed the leading string as " + portString);
+ if (portString != null && portString.startsWith("\n"))
+ portString = portString.substring(1);
+ //if (portString.length() < 4)
+ // return null;
+
+ // change to support 5 digit ports
+ StringBuffer portBuffer = new StringBuffer();
+ for (int i = 0; i < portString.length(); i++)
+ {
+ char c = portString.charAt(i);
+ if (Character.isDigit(c))
+ {
+ portBuffer.append(c);
+ }
+ }
+
+ if (portString.length() != portBuffer.length())
+ {
+ port = portBuffer.toString();
+ // old code - didn't support 5 digits
+ //port = portString.substring(0,4);
+
+ logMessage("Got the port " + port);
+ try
+ {
+ int possiblePort = Integer.parseInt(port);
+ logMessage("Going to return port " + port);
+ return port;
+ //logMessage("Return the port " + port);
+ }
+ catch (RuntimeException e)
+ {
+ e.printStackTrace();
+ logMessage("Got the wrong port " + port);
+ checkPort=false;
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+ private char convertFromEBCDICToASCII(byte eByte)
+ {
+
+ StringBuffer buf = new StringBuffer();
+ int index = eByte;
+ if (index < 0)
+ {
+ index = 256 + index;
+ }
+ return ebcdictounicode[index];
+ }
+ private byte convertFromASCIIToEBCDIC(byte eByte)
+ {
+ int index = eByte;
+ for (int i = 0; i
+ * The following is one example of the use of the StatusMonitor. The code:
+ * February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.
+ * Returns System.getProperty("os.version")
+ */
+ public String getVersionReleaseModification()
+ {
+ return System.getProperty("os.version");
+ }
+ /**
+ * Return the home directory of the operating system for the current user, if available.
+ *
+ * Returns System.getProperty("user.home")
+ */
+ public String getHomeDirectory()
+ {
+ return System.getProperty("user.home");
+ }
+ /**
+ * Return the temp directory of the operating system for the current user, if available.
+ *
+ * Returns System.getProperty("java.io.tmpdir")
+ */
+ public String getTempDirectory()
+ {
+ return System.getProperty("java.io.tmpdir");
+ }
+
+
+
+
+ public boolean hasRemoteServerLauncherProperties()
+ {
+ return false;
+ }
+
+
+
+ public boolean supportsRemoteServerLaunching()
+ {
+ return false;
+ }
+
+
+
+ public boolean supportsServerLaunchProperties()
+ {
+ return false;
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorServiceManager.java b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorServiceManager.java
new file mode 100644
index 00000000000..9e2fa853468
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorServiceManager.java
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.local;
+
+import org.eclipse.rse.core.subsystems.AbstractConnectorServiceManager;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.model.IHost;
+
+
+/**
+ * ISystem manager class.
+ * There should be only one of these instantiated.
+ * Use getTheLocalSystemManager to get that singleton.
+ *
+ * The job of this manager is to manage and return ISystem objects.
+ * It ensures there is only ever one per unique SystemConnection,
+ * so that both the file and cmd subsystems can share the same system object.
+ */
+public class LocalConnectorServiceManager extends AbstractConnectorServiceManager
+{
+ private static LocalConnectorServiceManager inst = null;
+
+ /**
+ * Private constructor to ensure not instantiated this way.
+ * Use getTheLocalSystemManager instead.
+ */
+ private LocalConnectorServiceManager()
+ {
+ }
+
+ /**
+ * Return singleton instance of this class
+ */
+ public static LocalConnectorServiceManager getTheLocalSystemManager()
+ {
+ if (inst == null)
+ inst = new LocalConnectorServiceManager();
+ return inst;
+ }
+
+ /**
+ * Return true if the singleton has been created.
+ * This saves creating it at shutdown just to test for isConnected.
+ */
+ public static boolean isInstantiated()
+ {
+ return (inst != null);
+ }
+
+ // -------------------------------------
+ // ABSTRACT METHODS FROM PARENT CLASS...
+ // -------------------------------------
+
+
+
+ /**
+ * Return the actual ISystem object.
+ */
+ public IConnectorService createConnectorService(IHost host)
+ {
+ IConnectorService connectorService = new LocalConnectorService(host);
+ return connectorService;
+ }
+
+ /**
+ * For all subsystems in a particular SystemConnection, we need to know which
+ * ones are to share a single ISystem object. To do this, we need a key which
+ * is canonical for all subsystems in a given connection. This can be anything,
+ * but is typically a unique interface that all subsystems supported a shared
+ * ISystem object implement.
+ *
+ * Whatever is returned from here is used as the key into a hashtable to find the
+ * singleton ISystem object in getSystemObject.
+ *
+ * @return ILocalSubSystem.class
+ */
+ public Class getSubSystemCommonInterface(ISubSystem subsystem)
+ {
+ return ILocalSubSystem.class;
+ }
+ /**
+ * Given another subsystem, return true if that subsystem shares a single ISystem object
+ * with this one. You must override this to return true if you recognize that subsystem
+ * as one of your own. You are guaranteed the other subsystem will be from the same
+ * SystemConnection as this one.
+ *
+ * You can't assume a SystemConnection will you only have subsystems of that you created,
+ * so you should only return true if it implements your interface or you know it is an
+ * instance of your subsystem class.
+ *
+ * This should simply return (otherSubSystem instanceof interface) where interface is
+ * the same one returned from getSubSystemCommonInterface
+ *
+ * @return true if otherSubSystem instanceof ILocalSubSystem
+ */
+ public boolean sharesSystem(ISubSystem otherSubSystem)
+ {
+ return (otherSubSystem instanceof ILocalSubSystem);
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.core/.classpath b/rse/plugins/org.eclipse.rse.core/.classpath
new file mode 100644
index 00000000000..acad1c227c0
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.core/.classpath
@@ -0,0 +1,6 @@
+
+ February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content. February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content. February 24, 2005 The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content. If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.DataStore.setByteStreamHandler(ByteStreamHandler)
.
+ * sendBytes
to either save the bytes to a local file or transmit
+ * them to a remote file.
+ * @param path the path of the file
+ * @param bytes the bytes of the file
+ * @param size the size of the file
+ * @param binary indicates whether the bytes are to be sent as binary or text
+ */
+ protected void internalSendBytes(String path, byte[] bytes, int size, boolean binary)
+ {
+ if (_dataStore.isVirtual())
+ {
+ _dataStore.replaceFile(path, bytes, size, binary);
+ }
+ else
+ {
+ _dataStore.updateFile(path, bytes, size, binary);
+ }
+ }
+
+ /**
+ * Called by sendBytes
to either append the bytes to a local file or transmit
+ * them and append them to a remote file.
+ * @param path the path of the file
+ * @param bytes the bytes of the file
+ * @param size the size of the file
+ * @param binary indicates whether the bytes are to be sent as binary or text
+ */
+ protected void internalSendAppendBytes(String path, byte[] bytes, int size, boolean binary)
+ {
+ if (_dataStore.isVirtual())
+ {
+ _dataStore.replaceAppendFile(path, bytes, size, binary);
+ }
+ else
+ {
+ _dataStore.updateAppendFile(path, bytes, size, binary);
+ }
+ }
+
+ protected DataElement findStatusFor(String remotePath)
+ {
+ if (_log != null)
+ {
+ for (int i = 0; i < _log.getNestedSize(); i++)
+ {
+ DataElement child = _log.get(i);
+ if (child.getName().equals(remotePath))
+ {
+ return child;
+ }
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandlerRegistry.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandlerRegistry.java
new file mode 100644
index 00000000000..a424cf3f789
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandlerRegistry.java
@@ -0,0 +1,82 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.util.HashMap;
+
+/**
+ * Stores the set of registered byte stream handlers using the handler id
+ * as the key. Whenever a bytestream operation is required (i.e. for a save of bytes)
+ * The appropriate byte stream handler is retrieved via the specified id.
+ * If no such handler exists, then the default byte stream handler is returned.
+ *
+ */
+public class ByteStreamHandlerRegistry
+{
+ private HashMap _map;
+ private IByteStreamHandler _default;
+ public ByteStreamHandlerRegistry()
+ {
+ _map = new HashMap();
+ }
+
+ /**
+ * Registers the default byte stream handler
+ * @param handler the default byte stream handler
+ */
+ public void setDefaultByteStreamHandler(IByteStreamHandler handler)
+ {
+ _default = handler;
+ _map.put(DataStoreResources.DEFAULT_BYTESTREAMHANDLER, handler);
+ registerByteStreamHandler(handler);
+ }
+
+ /**
+ * Registers a byte stream handler.
+ * @param handler the handler to register
+ */
+ public void registerByteStreamHandler(IByteStreamHandler handler)
+ {
+ _map.put(handler.getId(), handler);
+ }
+
+ /**
+ * Returns the byte stream handler with the specified id.
+ * If "default" is specified or no such id has been registered,
+ * the default byte stream handler is returned.
+ * @param id the id of the byte stream handler
+ * @return the byte stream handler
+ */
+ public IByteStreamHandler getByteStreamHandler(String id)
+ {
+ IByteStreamHandler handler = (IByteStreamHandler)_map.get(id);
+ if (handler == null)
+ {
+ handler = _default;
+ }
+ return handler;
+ }
+
+ /**
+ * Returns the default byte stream handler
+ * @return the default
+ */
+ public IByteStreamHandler getDefault()
+ {
+ return _default;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/CommandHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/CommandHandler.java
new file mode 100644
index 00000000000..743c4229cfd
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/CommandHandler.java
@@ -0,0 +1,298 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.util.CommandGenerator;
+
+/**
+ * CommandHandler
is a Handler
that
+ * contains a queue of commands to be sent to miners. Each DataStore instance uses a single
+ * command handler that periodically sends it's queue either to a server or directly
+ * to miners.
+ * DataElement
constants. These constants
+ * are used to identify DataElement
attributes.
+ *
+ * DataElement
type attributes.
+ * DataElement
indexs into attributes.
+ * DataElement
.
+ */
+ public static final String P_CHILDREN = "children";
+
+ /*
+ * The image property identifier of a DataElement
. This is the same
+ * as the value property identifier
+ */
+ public static final String P_LABEL = "label";
+
+ /*
+ * The notifier property identifier of a DataElement
.
+ */
+ public static final String P_NOTIFIER = "notifier";
+
+ /*
+ * The DataStore
property identifier of a DataElement
.
+ */
+ public static final String P_DATASTORE = "dataStore";
+
+ /*
+ * The source name property identifier of a DataElement
. This is the
+ * name of a source location if one exists.
+ */
+ public static final String P_SOURCE_NAME = "source";
+
+ /*
+ * The source file property identifier of a DataElement
.
+ */
+ public static final String P_SOURCE = "sourcefile";
+
+ /*
+ * The source location property identifier of a DataElement
.
+ */
+ public static final String P_SOURCE_LOCATION = "sourcelocation";
+
+ public static final String P_SOURCE_LOCATION_COLUMN = "sourcelocationcolumn";
+
+ /*
+ * The nested data (children) property identifier of a DataElement
. Same as P_CHILDREN
.
+ */
+ public static final String P_NESTED = "nested";
+
+ /*
+ * The buffer property identifier of a DataElement
.
+ */
+ public static final String P_BUFFER = "buffer";
+
+ /*
+ * The type property identifier of a DataElement
.
+ */
+ public static final String P_TYPE = "type";
+
+ /*
+ * The id property identifier of a DataElement
.
+ */
+ public static final String P_ID = "id";
+
+ /*
+ * The name property identifier of a DataElement
.
+ */
+ public static final String P_NAME = "name";
+
+ /*
+ * The value property identifier of a DataElement
.
+ */
+ public static final String P_VALUE = "value";
+
+ /*
+ * The is reference? property identifier of a DataElement
.
+ */
+ public static final String P_ISREF = "isRef";
+
+ /*
+ * The visibility property identifier of a DataElement
.
+ */
+ public static final String P_DEPTH = "depth";
+
+ /*
+ * The attributes property identifier of a DataElement
.
+ */
+ public static final String P_ATTRIBUTES = "attribute";
+
+ /*
+ * The file property identifier of a DataElement
.
+ */
+ public static final String P_FILE = "file";
+
+ /*
+ * The file property identifier of a DataElement
.
+ */
+ public static final String P_DESCRIPTOR = "descriptor";
+
+ /*
+ * Reference type.
+ */
+ public static final String T_REFERENCE = "reference";
+
+ /*
+ * Command type.
+ */
+ public static final String T_COMMAND = "command";
+
+ /*
+ * UI Command Descriptor type.
+ */
+ public static final String T_UI_COMMAND_DESCRIPTOR = "ui_commanddescriptor";
+
+ /*
+ * Object Descriptor type.
+ */
+ public static final String T_OBJECT_DESCRIPTOR = "objectdescriptor";
+
+ /*
+ * Command Descriptor type.
+ */
+ public static final String T_COMMAND_DESCRIPTOR = "commanddescriptor";
+
+ /*
+ * Relation Descriptor type.
+ */
+ public static final String T_RELATION_DESCRIPTOR = "relationdescriptor";
+
+ /*
+ * Abstract Object Descriptor type.
+ */
+ public static final String T_ABSTRACT_OBJECT_DESCRIPTOR = "abstractobjectdescriptor";
+
+ /*
+ * Abstract Command Descriptor type.
+ */
+ public static final String T_ABSTRACT_COMMAND_DESCRIPTOR = "abstractcommanddescriptor";
+
+ /*
+ * Abstract Relation Descriptor type.
+ */
+ public static final String T_ABSTRACT_RELATION_DESCRIPTOR = "abstractrelationdescriptor";
+
+
+ /*
+ * Type attribute index.
+ */
+ public static final int A_TYPE = 0;
+
+ /*
+ * ID attribute index.
+ */
+ public static final int A_ID = 1;
+
+ /*
+ * Name attribute index.
+ */
+ public static final int A_NAME = 2;
+
+ /*
+ * Value attribute index.
+ */
+ public static final int A_VALUE = 3;
+
+ /*
+ * Source attribute index.
+ */
+ public static final int A_SOURCE = 4;
+
+ /*
+ * Source location attribute index.
+ * @deprecated
+ */
+ public static final int A_SOURCE_LOCATION = 5;
+
+ /*
+ * IsRef attribute index.
+ */
+ public static final int A_ISREF = 6;
+
+ /*
+ * Visibility attribute index.
+ */
+ public static final int A_DEPTH = 7;
+
+ /*
+ * Size attribute index.
+ */
+ public static final int A_SIZE = 8;
+
+ public static final String ENCODING_UTF_8 = "UTF-8";
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataElement.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataElement.java
new file mode 100644
index 00000000000..b9255fe16f8
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataElement.java
@@ -0,0 +1,1631 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.dstore.core.util.StringCompare;
+import org.eclipse.dstore.extra.internal.extra.DataElementActionFilter;
+import org.eclipse.dstore.extra.internal.extra.DesktopElement;
+import org.eclipse.dstore.extra.internal.extra.IDataElement;
+import org.eclipse.dstore.extra.internal.extra.PropertySource;
+
+/**
+ * DataElement
is the unit of information for the DataStore
. All objects including
+ * schema descriptors, commands and instance objects are represented by DataElement
s.
+ * DataElement
s should not be constructed directly, rather they are requested via the createObject()
+ * method in DataStore
+ *
+ */
+public final class DataElement implements IDataElement
+{
+
+
+ private String _attributes[];
+ private StringBuffer _buffer;
+
+ private boolean _isReference = false;
+ private boolean _isDescriptor = false;
+ private boolean _isExpanded = false;
+ private boolean _isUpdated = false;
+ private boolean _isPendingTransfer = false;
+
+ private int _depth = 1;
+
+ private DataStore _dataStore = null;
+ private DataElement _parent = null;
+ private DataElement _descriptor = null;
+
+ private ArrayList _nestedData = null;
+ private DataElement _referencedObject = null;
+
+ private PropertySource _propertySource = null;
+
+
+ /**
+ * Creates a new DataElement
without initializing it.
+ *
+ */
+ public DataElement()
+ {
+ _dataStore = null;
+ _parent = null;
+ }
+
+ /**
+ * Creates a new DataElement
without initializing it.
+ *
+ * @param dataStore the owner DataStore
for this element
+ */
+ protected DataElement(DataStore dataStore)
+ {
+ _dataStore = dataStore;
+ _parent = null;
+
+ }
+
+ /**
+ * Initializes a DataElement
to be reference to some other DataElement
.
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the element that contains this reference
+ * @param originalObject the element that gets referenced
+ * @param refType the type descriptor of the reference
+ */
+ public void reInit(DataElement parent, DataElement originalObject, DataElement refType)
+ {
+ if ((parent != null) && (originalObject != null))
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ String type = refType.getName();
+ _attributes[DE.A_TYPE] = type;
+
+ String originalId = originalObject.getId();
+ StringBuffer idBuf = new StringBuffer(parent.getId());
+ idBuf.append(type);
+ idBuf.append(originalId);
+ _attributes[DE.A_ID] = idBuf.toString();
+ _attributes[DE.A_NAME] = originalId;
+ _attributes[DE.A_VALUE] = originalId;
+
+ initialize(refType);
+
+ _referencedObject = originalObject;
+ _isReference = true;
+ }
+ }
+
+ /**
+ * Initializes a DataElement
to be reference to some other DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the element that contains this reference
+ * @param originalObject the element that gets referenced
+ * @param refType the a string representing the type of reference
+ */
+ public void reInit(DataElement parent, DataElement originalObject, String refType)
+ {
+ if ((parent != null) && (originalObject != null))
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ _attributes[DE.A_TYPE] = refType;
+
+ String originalId = originalObject.getId();
+ StringBuffer idBuf = new StringBuffer(parent.getId());
+ idBuf.append(refType);
+ idBuf.append(originalId);
+
+ _attributes[DE.A_ID] = idBuf.toString();
+ _attributes[DE.A_NAME] = originalId;
+ _attributes[DE.A_VALUE] = originalId;
+
+ initialize();
+
+ _referencedObject = originalObject;
+ _isReference = true;
+ }
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param type the type descriptor of the element
+ * @param id the ID of the element
+ * @param name the name of the element
+ * @param source the source location of the element
+ */
+ public void reInit(DataElement parent, DataElement type, String id, String name, String source)
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ _attributes[DE.A_TYPE] = type.getAttribute(DE.A_NAME);
+ _attributes[DE.A_ID] = id;
+ _attributes[DE.A_NAME] = name;
+ _attributes[DE.A_VALUE] = name;
+ _attributes[DE.A_SOURCE] = source;
+
+ initialize(type);
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param type a string representing the type descriptor of the element
+ * @param id the ID of the element
+ * @param name the name of the element
+ * @param source the source location of the element
+ */
+ public void reInit(DataElement parent, String type, String id, String name, String source)
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ _attributes[DE.A_TYPE] = type;
+ _attributes[DE.A_ID] = id;
+ _attributes[DE.A_NAME] = name;
+ _attributes[DE.A_VALUE] = name;
+ _attributes[DE.A_SOURCE] = source;
+
+ initialize();
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param type the type descriptor of the element
+ * @param id the ID of the element
+ * @param name the name of the element
+ * @param source the source location of the element
+ * @param isRef an indication of whether the element is a reference or not
+ */
+ public void reInit(DataElement parent, DataElement type, String id, String name, String source, boolean isRef)
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ _attributes[DE.A_TYPE] = type.getAttribute(DE.A_NAME);
+ _attributes[DE.A_ID] = id;
+ _attributes[DE.A_NAME] = name;
+ _attributes[DE.A_VALUE] = name;
+ _attributes[DE.A_SOURCE] = source;
+
+ initialize(type);
+ _isReference = isRef;
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param type a string representing the type descriptor of the element
+ * @param id the ID of the element
+ * @param name the name of the element
+ * @param source the source location of the element
+ * @param isRef an indication of whether the element is a reference or not
+ */
+ public void reInit(DataElement parent, String type, String id, String name, String source, boolean isRef)
+ {
+ _parent = parent;
+
+ _attributes = getAttributes();
+ _attributes[DE.A_TYPE] = type;
+ _attributes[DE.A_ID] = id;
+ _attributes[DE.A_NAME] = name;
+ _attributes[DE.A_VALUE] = name;
+ _attributes[DE.A_SOURCE] = source;
+
+ initialize();
+ _isReference = isRef;
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param type the type descriptor of the element
+ * @param attributes the attributes for this element (name, source, id, etc.)
+ */
+ public void reInit(DataElement parent, DataElement type, String[] attributes)
+ {
+ _parent = parent;
+
+ _attributes = attributes;
+ _attributes[DE.A_TYPE] = type.getName();
+
+ initialize(type);
+ }
+
+ /**
+ * Initializes a DataElement
+ * This method should only be called from the DataStore
.
+ *
+ * @param parent the parent of the element
+ * @param attributes the attributes for this element (type, name, source, id, etc.)
+ */
+ public void reInit(DataElement parent, String[] attributes)
+ {
+ _parent = parent;
+
+ _attributes = attributes;
+
+ initialize();
+ }
+
+ public void reInitAsTransient(String attributes[])
+ {
+ _attributes = attributes;
+
+ _isReference = false;
+ _isDescriptor = false;
+ _depth = 2;
+
+ _referencedObject = null;
+ _isExpanded = false;
+ _isUpdated = false;
+
+ String depthStr = getAttribute(DE.A_DEPTH);
+ if (depthStr != null && depthStr.length() > 0)
+ {
+ if (!depthStr.equals("2"))
+ {
+ try
+ {
+ _depth = Integer.parseInt(depthStr);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ if (_nestedData != null)
+ _nestedData.clear();
+ }
+
+ /**
+ * Indicates whether the DataElement
is deleted or not.
+ *
+ * @return whehther the element is deleted or not
+ */
+ public boolean isDeleted()
+ {
+ if (_attributes == null)
+ {
+ return true;
+ }
+
+ String valueAttribute = getAttribute(DE.A_VALUE);
+
+ if (_depth == -1)
+ {
+ return true;
+ }
+ else if (valueAttribute != null && valueAttribute.equals(DataStoreResources.DELETED))
+ {
+ _depth = -1;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds a set of elements as children to this element.
+ *
+ * @param nestedData a set of elements to add to this element
+ * @param checkUnique whether to prevent duplicates from being added
+ */
+ public void addNestedData(List nestedData, boolean checkUnique)
+ {
+ if (nestedData != null)
+ {
+ if (_nestedData == null)
+ {
+ _nestedData = new ArrayList(nestedData.size());
+ }
+
+ for (int i = 0; i < nestedData.size(); i++)
+ {
+ DataElement child = (DataElement) nestedData.get(i);
+ if (child != null && child != this)
+ {
+ addNestedData(child, checkUnique);
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds another element as a child to this element.
+ *
+ * @param obj the element to add
+ * @param checkUnique whether to prevent duplicates from being added
+ */
+ public void addNestedData(DataElement obj, boolean checkUnique)
+ {
+ if (_nestedData == null)
+ {
+ _nestedData = new ArrayList(4);
+ }
+
+ synchronized (_nestedData)
+ {
+ boolean alreadyThere = false;
+ if (checkUnique)
+ {
+ alreadyThere = _nestedData.contains(obj);
+ }
+
+ if (!checkUnique || !alreadyThere)
+ {
+ if (alreadyThere)
+ {
+ return;
+ }
+ else
+ {
+ _nestedData.add(obj);
+
+ if (obj.getParent() == null)
+ obj.setParent(this);
+ }
+ }
+
+ _isUpdated = false;
+ obj.setUpdated(false);
+ }
+ }
+
+ /**
+ * Removes a specified child element from this element.
+ *
+ * @param object the element to remove
+ */
+ public synchronized void removeNestedData(DataElement object)
+ {
+ if (_nestedData != null)
+ {
+ // synchronized(_nestedData)
+ {
+ _nestedData.remove(object);
+ }
+ }
+ _isExpanded = false;
+ _isUpdated = false;
+ }
+
+ /**
+ * Removes all the children from this element.
+ */
+ public synchronized void removeNestedData()
+ {
+ if (_nestedData != null)
+ {
+ while (_nestedData.size() > 0)
+ {
+ DataElement nestedObject = (DataElement) _nestedData.get(0);
+ _nestedData.remove(nestedObject);
+ }
+ }
+
+ _isExpanded = false;
+ _isUpdated = false;
+ }
+
+ /**
+ * Returns an attribute of this element.
+ *
+ * @param attributeIndex the index of the element
+ * @return the attribute
+ */
+ public String getAttribute(int attributeIndex)
+ {
+ return _attributes[attributeIndex];
+ }
+
+ /**
+ * Returns the set of attributes for this element.
+ *
+ * @return the set of attributes
+ */
+ public String[] getAttributes()
+ {
+ if (_attributes == null)
+ {
+ return new String[DE.A_SIZE];
+ }
+ return _attributes;
+ }
+
+ /**
+ * Returns the type attribute for this element.
+ *
+ * @return the type attribute
+ */
+ public String getType()
+ {
+ return getAttribute(DE.A_TYPE);
+ }
+
+ /**
+ * Returns the ID attribute for this element.
+ *
+ * @return the ID attribute
+ */
+ public String getId()
+ {
+ return getAttribute(DE.A_ID);
+ }
+
+ /**
+ * Returns the name attribute for this element.
+ *
+ * @return the name attribute
+ */
+ public String getName()
+ {
+ return getAttribute(DE.A_NAME);
+ }
+
+ /**
+ * Returns the value attribute for this element.
+ *
+ * @return the value attribute
+ */
+ public String getValue()
+ {
+ return getAttribute(DE.A_VALUE);
+ }
+
+ /**
+ * Returns the source attribute for this element.
+ *
+ * @return the source attribute
+ */
+ public String getSource()
+ {
+ return getAttribute(DE.A_SOURCE);
+ }
+
+ /**
+ * Returns the buffer for this element.
+ *
+ * @return the buffer
+ */
+ public StringBuffer getBuffer()
+ {
+ return _buffer;
+ }
+
+ /**
+ * Returns the DataStore
for this element.
+ *
+ * @return the DataStore
+ */
+ public DataStore getDataStore()
+ {
+ return _dataStore;
+ }
+
+ /**
+ * Initializes the children set of this element with a specified size.
+ *
+ * @param size the initial size
+ */
+ public void initializeNestedData(int size)
+ {
+ if (_nestedData == null)
+ {
+ _nestedData = new ArrayList(size);
+ }
+ }
+
+ /**
+ * Returns the children of this element.
+ *
+ * @return the children of this element
+ */
+ public List getNestedData()
+ {
+ return _nestedData;
+ }
+
+ /**
+ * Returns the child at the specified index.
+ *
+ * @param index the index of the child to retrieve
+ * @return the child element
+ */
+ public DataElement get(int index)
+ {
+ if (_nestedData == null)
+ {
+ return null;
+ }
+ else
+ {
+ if (getNestedSize() > index)
+ {
+ Object obj = _nestedData.get(index);
+ return (DataElement) obj;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Returns the number of children this element contains.
+ *
+ * @return the number of children
+ */
+ public int getNestedSize()
+ {
+ if (_nestedData == null)
+ {
+ return 0;
+ }
+ else
+ {
+ return _nestedData.size();
+ }
+ }
+
+ /**
+ * Returns the parent of this element.
+ *
+ * @return the parent
+ */
+ public DataElement getParent()
+ {
+ return _parent;
+ }
+
+ public boolean isDescriptor()
+ {
+ return _isDescriptor;
+ }
+
+ /**
+ * Explicitly sets the type descriptor for this element.
+ *
+ * @param theDescriptor the type descriptor for this element
+ */
+ public void setDescriptor(DataElement theDescriptor)
+ {
+ _descriptor = theDescriptor;
+ }
+
+ /**
+ * Returns the type descriptor for this element.
+ *
+ * @return the type descriptor for this element
+ */
+ public DataElement getDescriptor()
+ {
+ if (isDeleted())
+ {
+ return null;
+ }
+
+ if (_isReference)
+ {
+ if (_referencedObject == null)
+ {
+ _referencedObject = dereference();
+ }
+ if (this == _referencedObject || _referencedObject.isDeleted())
+ {
+ _referencedObject = null;
+ }
+ else
+ {
+ return _referencedObject.getDescriptor();
+ }
+ }
+ else if ((_descriptor == null) && (_dataStore != null))
+ {
+ if (_isDescriptor)
+ {
+ _descriptor = _dataStore.findDescriptor(getAttribute(DE.A_TYPE), getName());
+ }
+ else
+ {
+ _descriptor = _dataStore.findObjectDescriptor(getAttribute(DE.A_TYPE));
+ if (_descriptor == null)
+ {
+ _descriptor = _dataStore.find(_dataStore.getDescriptorRoot(), DE.A_NAME, getAttribute(DE.A_TYPE), 3);
+ }
+ }
+ }
+
+ return _descriptor;
+ }
+
+
+ /**
+ * Returns the visibility of this element.
+ *
+ * @return the level of visibility for this element
+ */
+ public int depth()
+ {
+ return _depth;
+ }
+
+ /**
+ * Indicates whether this is a reference or not.
+ *
+ * @return whether this is a reference or not
+ */
+ public boolean isReference()
+ {
+ return _isReference;
+ }
+
+ /**
+ * Indicates whether this element has been queried for it's children.
+ *
+ * @return whether element has been expanded
+ */
+ public boolean isExpanded()
+ {
+ return _isExpanded;
+ }
+
+ /**
+ * Indicates whether this element has been updated yet.
+ * On a server, an element is updated if it has been transfered the the client.
+ * On a client, an element is updated if a notification has been sent out for the ui
+ *
+ * @return whether element has been updated yet
+ */
+ public boolean isUpdated()
+ {
+ return _isUpdated;
+ }
+
+ /**
+ * Indicates whether this element is pending a transfer
+ * If the element is queued to be sent, the value will be true.
+ *
+ * @return whether element has been updated yet
+ */
+ public boolean isPendingTransfer()
+ {
+ return _isPendingTransfer;
+ }
+
+ /**
+ * Sets an attribute of the element.
+ *
+ * @param attributeIndex the index of the attribute to set
+ * @param attribute the new value for the specified attribute
+ */
+ public void setAttribute(int attributeIndex, String attribute)
+ {
+ if (attribute != null)
+ {
+ if ((attributeIndex == DE.A_NAME) && (getAttribute(DE.A_NAME).equals(getAttribute(DE.A_VALUE))))
+ {
+ _attributes[DE.A_VALUE] = attribute;
+ }
+ else if (attributeIndex == DE.A_DEPTH)
+ {
+ _depth = Integer.parseInt(attribute);
+ }
+ else if (attributeIndex == DE.A_TYPE)
+ {
+ _descriptor = null;
+ }
+
+ _attributes[attributeIndex] = attribute;
+ _isUpdated = false;
+ }
+ }
+
+ /**
+ * Sets all of the attributes of the element.
+ *
+ * @param attributes the new set of attributes for the element
+ */
+ public void setAttributes(String attributes[])
+ {
+ for (int i = 0; i < DE.A_SIZE; i++)
+ {
+ if (attributes[i] != null)
+ {
+ setAttribute(i, attributes[i]);
+ }
+ }
+
+ _isUpdated = false;
+ }
+
+ /**
+ * Sets the buffer for this element.
+ * The buffer is used if extra temporary information needs to be stored
+ * with this element
+ *
+ * @param buffer the new buffer for this element
+ */
+ public void setBuffer(StringBuffer buffer)
+ {
+ _buffer = buffer;
+ if (_depth < 2 && buffer.length() > 0)
+ {
+ setDepth(2);
+ }
+
+ _isUpdated = false;
+ }
+
+ /**
+ * Appends to the buffer for this element.
+ * The buffer is used if extra temporary information needs to be stored
+ * with this element
+ *
+ * @param text text to append to the buffer
+ */
+ public void appendToBuffer(String text)
+ {
+ if (_buffer == null)
+ {
+ _buffer = new StringBuffer();
+ }
+ _buffer.append(text);
+ _isUpdated = false;
+ }
+
+ /**
+ * Sets the expanded indication for this element.
+ *
+ * @param flag whether the element is expanded or not
+ */
+ public void setExpanded(boolean flag)
+ {
+ _isExpanded = flag;
+ }
+
+ /**
+ * Sets the updated indication for this element.
+ *
+ * @param flag whether the element is updated or not
+ */
+ public void setUpdated(boolean flag)
+ {
+ _isUpdated = flag;
+ }
+
+ /**
+ * Sets indication of whether this element is waiting to be transferred.
+ * If so, the updated flag should not be set to true
+ *
+ * @param flag whether the element is waiting to be transferred
+ */
+ public void setPendingTransfer(boolean flag)
+ {
+ _isPendingTransfer = flag;
+ }
+
+ /**
+ * Sets the parent for this element.
+ *
+ * @param parent the new parent
+ */
+ public void setParent(DataElement parent)
+ {
+ _parent = parent;
+ }
+
+ /**
+ * Sets the DataStore
for this element.
+ *
+ * @param dataStore the new dataStore
+ */
+ public void setDataStore(DataStore dataStore)
+ {
+ _dataStore = dataStore;
+ }
+
+ /**
+ * Sets the depth of visibility for this element.
+ *
+ * @param depth the level of visibility
+ */
+ public void setDepth(int depth)
+ {
+ _depth = depth;
+ setAttribute(DE.A_DEPTH, "" + _depth);
+ _isUpdated = false;
+ //_dataStore.refresh(this);
+ }
+
+ /**
+ * Tests if this element is of the specified type.
+ *
+ * @param typeStr a string representing the type descriptor to compare with
+ * @return whether the element is of the specified type
+ */
+ public boolean isOfType(String typeStr)
+ {
+ DataElement typeDescriptor = _dataStore.find(_dataStore.getDescriptorRoot(), DE.A_NAME, typeStr, 1);
+ return isOfType(typeDescriptor);
+ }
+
+ /**
+ * Tests if this element is of the specified type.
+ *
+ * @param typeStr a string representing the type descriptor to compare with
+ * @return whether the element is of the specified type
+ */
+ public boolean isOfType(String typeStr, boolean isDescriptor)
+ {
+ DataElement typeDescriptor = _dataStore.find(_dataStore.getDescriptorRoot(), DE.A_NAME, typeStr, 1);
+ return isOfType(typeDescriptor, isDescriptor);
+ }
+
+ /**
+ * Tests if this element is of the specified type.
+ *
+ * @param type the type descriptor to compare with
+ * @return whether the element is of the specified type
+ */
+ public boolean isOfType(DataElement type)
+ {
+ return isOfType(type, false);
+ }
+
+ /**
+ * Tests if this element is of the specified type.
+ *
+ * @param type the type descriptor to compare with
+ * @param isDescriptor whehter this element is a descriptor or an instance object
+ * @return whether the element is of the specified type
+ */
+ public boolean isOfType(DataElement type, boolean isDescriptor)
+ {
+ boolean result = false;
+
+ if (type == null)
+ {
+ return result;
+ }
+
+ DataElement descriptor = this;
+ if (!isDescriptor)
+ {
+ descriptor = getDescriptor();
+ }
+
+ if (descriptor == type)
+ {
+ return true;
+ }
+
+ if (descriptor != null && !descriptor.isDeleted())
+ {
+ String typeType = type.getType();
+ String typeName = type.getName();
+ if (typeType.equals(DE.T_OBJECT_DESCRIPTOR) || typeType.equals(DE.T_ABSTRACT_OBJECT_DESCRIPTOR))
+ {
+ if (descriptor.getName().equals(typeName) || (typeName.equals("all")))
+ {
+ result = true;
+ return result;
+ }
+ }
+
+ DataElement relationship = _dataStore.getAbstractedByRelation();
+ List abstracted = null;
+
+ if (relationship != null)
+ {
+ abstracted = descriptor.getAssociated(relationship);
+ }
+
+ for (int i = 0;(i < abstracted.size()) && !result; i++)
+ {
+ DataElement superDescriptor = (DataElement) abstracted.get(i);
+
+ result = superDescriptor.isOfType(type, true);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests if this element matches the specified patterns.
+ *
+ * @param attributes the attribute indexes to compare with
+ * @param patterns the values to compare the specified attributes with
+ * @param numAttributes the number of attributes to compare
+ * @param ignoreCase whether to ignore case or not
+ * @return whether the element matches the patterns
+ */
+ public boolean patternMatch(int attributes[], String patterns[], int numAttributes, boolean ignoreCase)
+ {
+ int index = 0;
+ while (index < numAttributes)
+ {
+ String attribute = getAttribute(attributes[index]);
+ String pattern = patterns[index];
+
+ if (!StringCompare.compare(pattern, attribute, ignoreCase))
+ {
+ return false;
+ }
+ index++;
+ }
+
+ return true;
+ }
+
+ /**
+ * Tests if this element contains a specified element in a particular relationship.
+ *
+ * @param object the object to look for
+ * @param property relationship under which to find the object
+ * @return whether the element is found
+ */
+ public boolean contains(DataElement object, DataElement property)
+ {
+ return contains(object, property, 1);
+ }
+
+ /**
+ * Tests if this element contains a specified element in a particular relationship.
+ *
+ * @param object the object to look for
+ * @param property relationship under which to find the object
+ * @param depth how deep to search for the specified element
+ * @return whether the element is found
+ */
+ public synchronized boolean contains(DataElement object, DataElement property, int depth)
+ {
+ if (depth > 0)
+ {
+ depth--;
+
+ if (object == null)
+ {
+ return false;
+ }
+
+ if (property == null)
+ {
+ property = _dataStore.getContentsRelation();
+ }
+
+ if (getNestedSize() == 0)
+ {
+ return false;
+ }
+
+ if (property != null)
+ {
+ if (property.getType().equals(DE.T_ABSTRACT_RELATION_DESCRIPTOR))
+ {
+ for (int i = 0; i < property.getNestedSize(); i++)
+ {
+ DataElement subProperty = property.get(i).dereference();
+ if (contains(object, subProperty))
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ String type = property.getName();
+ if (type.equals(DataStoreResources.model_parent) && (_parent != null))
+ {
+ if (object == _parent)
+ {
+ return true;
+ }
+ else
+ {
+ return _parent.contains(object, property, depth);
+ }
+ }
+ else if (_nestedData != null)
+ {
+ for (int i = 0; i < _nestedData.size(); i++)
+ {
+ DataElement nestedObject = (DataElement) _nestedData.get(i);
+ if (nestedObject != null)
+ {
+ if (nestedObject.isReference())
+ {
+ String relType = nestedObject.getAttribute(DE.A_TYPE);
+ if (relType.equals(type))
+ {
+ DataElement referenced = nestedObject.dereference();
+
+ if (referenced == object)
+ {
+ return true;
+ }
+ else
+ {
+ return referenced.contains(object, property, depth);
+ }
+ }
+ }
+ else if (type.equals("contents"))
+ {
+ if (nestedObject == object)
+ {
+ return true;
+ }
+ else
+ {
+ if (nestedObject.contains(object, property, depth))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tests if this element contains a specified element in the default contents relationship.
+ *
+ * @param object the object to look for
+ * @return whether the element is found
+ */
+ public boolean contains(DataElement object)
+ {
+ return contains(object, 1);
+ }
+
+ /**
+ * Tests if this element contains a specified element in the default contents relationship.
+ *
+ * @param object the object to look for
+ * @param depth how deep to search
+ * @return whether the element is found
+ */
+ public boolean contains(DataElement object, int depth)
+ {
+ boolean result = false;
+ if (_nestedData != null)
+ {
+ depth--;
+ for (int i = 0; i < getNestedSize(); i++)
+ {
+ DataElement child = get(i);
+
+ if (child == object)
+ {
+ return true;
+ }
+ else if (child.dereference() == object)
+ {
+ return true;
+ }
+ else if (depth > 0)
+ {
+ result = child.contains(object, depth);
+ if (result)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests if this element is the same as another.
+ *
+ * @param arg the object to compare with
+ * @return whether the element is the same
+ */
+ public boolean equals(Object arg)
+ {
+ if (arg instanceof DataElement)
+ {
+ return arg == this;
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets the set of elements that are related to this element via a specified relationship.
+ *
+ * @param propertyStr a string representing the relationship that is required
+ * @return the set of related elements
+ */
+ public List getAssociated(String propertyStr)
+ {
+ DataElement property = _dataStore.findObjectDescriptor(propertyStr);
+ if (property == null)
+ {
+ property = _dataStore.findRelationDescriptor(propertyStr);
+ }
+ if (property != null)
+ {
+ return getAssociated(property);
+ }
+ else
+ {
+ return new ArrayList(1);
+ }
+ }
+
+ /**
+ * Gets the set of elements that are related to this element via a specified relationship.
+ *
+ * @param property the relationship that is required
+ * @return the set of related elements
+ */
+ public List getAssociated(DataElement property)
+ {
+ ArrayList set = new ArrayList();
+
+ if (property == null || getNestedSize() == 0)
+ {
+ return set;
+ }
+ else
+ {
+ if (property.getType().equals(DE.T_ABSTRACT_RELATION_DESCRIPTOR))
+ {
+ // recursively concat the abstracted matches
+ for (int i = 0; i < property.getNestedSize(); i++)
+ {
+ DataElement subProperty = property.get(i).dereference();
+ List subSet = getAssociated(subProperty);
+ set.addAll(subSet);
+ }
+ }
+ else
+ {
+ String type = property.getName();
+ if (type.equals(DataStoreResources.model_parent) && (_parent != null))
+ {
+ set.add(_parent);
+ return set;
+ }
+ else if (type.equals(DataStoreResources.model_descriptor_for))
+ {
+ getDescriptor();
+ if (_descriptor != null)
+ set.add(_descriptor);
+ }
+ else if (_nestedData != null)
+ {
+ for (int i = 0; i < _nestedData.size(); i++)
+ {
+ DataElement nestedObject = (DataElement) _nestedData.get(i);
+ if (nestedObject != null)
+ {
+ if (nestedObject.isReference())
+ {
+ String relType = nestedObject.getType();
+ if (relType.equals(type))
+ {
+ DataElement referenced = nestedObject.dereference();
+ if ((referenced != null) && !referenced.isDeleted())
+ {
+ set.add(referenced);
+ }
+ }
+ }
+ else if (type.equals(DataStoreResources.model_contents))
+ {
+ if (!nestedObject.isDeleted())
+ set.add(nestedObject);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return set;
+ }
+
+ /**
+ * Returns the element that this references.
+ * If the element is not a reference, itself is returned
+ *
+ * @return the element that this references
+ */
+ public DataElement dereference()
+ {
+ if (_isReference)
+ {
+ String name = getAttribute(DE.A_NAME);
+ if ((_referencedObject != null))
+ {
+ if (_referencedObject.getId().equals(name))
+ {
+ return _referencedObject;
+ }
+ else
+ {
+ _referencedObject = null;
+ delete();
+ return null;
+ }
+ }
+ else
+ {
+ _referencedObject = _dataStore.find(name);
+ if ((_referencedObject != null))
+ {
+ return _referencedObject;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ else
+ {
+ return this;
+ }
+ }
+
+ /**
+ * Do the specified command on this element.
+ * This element becomes the subject of a command that has a value, command
+ *
+ * @param command the string representing the command to issue
+ * @param isSynchronized an indication of whether this command should be synchronized
+ * @return the status of the command
+ */
+ public DataElement doCommandOn(String command, boolean isSynchronized)
+ {
+ DataElement status = null;
+ if ((_dataStore != null) && (_dataStore.isConnected()))
+ {
+ DataElement cmdDescriptor = _dataStore.localDescriptorQuery(getDescriptor(), command);
+ if (cmdDescriptor != null)
+ {
+ if (isSynchronized)
+ {
+ status = _dataStore.synchronizedCommand(cmdDescriptor, this);
+ }
+ else
+ {
+ status = _dataStore.command(cmdDescriptor, this);
+ }
+ }
+ }
+ return status;
+ }
+
+
+
+ /**
+ * Gets the adapter specified by key for this element
+ *
+ * @param key the identifier for this adapter
+ * @return the adapter
+ */
+ public Object getAdapter(Class key)
+ {
+ Object adapter = DesktopElement.getPlatformAdapter(this, key);
+ if (adapter != null)
+ {
+ return adapter;
+ }
+ else if (PropertySource.matches(key))
+ {
+ if (_propertySource == null)
+ {
+ _propertySource = new PropertySource(this);
+ }
+
+ return _propertySource;
+ }
+ else if (DataElementActionFilter.matches(key))
+ {
+ return DataElementActionFilter.getInstance();
+ }
+ return null;
+ }
+
+ /**
+ * Returns a string showing the attributes of this element
+ *
+ * @return a printable string
+ */
+ public String toString()
+ {
+ return "DataElement "
+ + (_isReference ? "reference" : "")
+ + "\n{\n\tType:\t"
+ + getType()
+ + "\n\tName:\t"
+ + getName()
+ + "\n\tValue:\t"
+ + getValue()
+ + "\n\tID:\t"
+ + getId()
+ + "\n\tSource:\t"
+ + getSource()
+ + "\n\tDepth:\t"
+ + _depth
+ + "\n\tDataStore:\t"
+ + _dataStore.getName()
+ + "\n}\n";
+ }
+
+ /**
+ * Returns the property identified by name.
+ *
+ * @param name a specifier of which property to return
+ * @return the specified property
+ */
+ public Object getElementProperty(Object name)
+ {
+ return getElementProperty(name, 3);
+ }
+
+ private Object getElementProperty(Object name, int depth)
+ {
+ if (depth == 0)
+ {
+ return null;
+ }
+
+ if (_isReference)
+ {
+ if (_referencedObject == null)
+ {
+ dereference();
+ }
+
+ if (_referencedObject != null)
+ {
+ return _referencedObject.getElementProperty(name, depth - 1);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ if (DE.P_NOTIFIER.equals(name))
+ {
+ return _dataStore.getDomainNotifier();
+ }
+ else if (DE.P_LABEL.equals(name))
+ {
+ return getAttribute(DE.A_NAME);
+ }
+ else if (DE.P_TYPE.equals(name))
+ {
+ return getAttribute(DE.A_TYPE);
+ }
+ else if (DE.P_NAME.equals(name))
+ {
+ return getAttribute(DE.A_NAME);
+ }
+ else if (DE.P_VALUE.equals(name))
+ {
+ return getAttribute(DE.A_VALUE);
+ }
+ else if (DE.P_ID.equals(name))
+ {
+ return getAttribute(DE.A_ID);
+ }
+ else if (DE.P_DESCRIPTOR.equals(name))
+ {
+ return _descriptor;
+ }
+ else if (DE.P_SOURCE_NAME.equals(name))
+ {
+ String source = getAttribute(DE.A_SOURCE);
+ int locationIndex = source.lastIndexOf(":");
+ if (locationIndex > 3)
+ {
+ return source.substring(0, locationIndex);
+ }
+ return source;
+ }
+ else if (DE.P_BUFFER.equals(name))
+ {
+ return _buffer;
+ }
+ else if (DE.P_SOURCE.equals(name))
+ {
+ return getAttribute(DE.A_SOURCE);
+ }
+ else if (DE.P_SOURCE_LOCATION_COLUMN.equals(name))
+ {
+ return null;
+ }
+ else if (DE.P_DATASTORE.equals(name))
+ {
+ return _dataStore.getName();
+ }
+ else if (DE.P_NESTED.equals(name) || DE.P_CHILDREN.equals(name))
+ {
+ return getNestedData();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ }
+
+ private void initialize()
+ {
+ initialize(null);
+ }
+
+ private void initialize(DataElement typeDescriptor)
+ {
+ _isReference = false;
+ _isDescriptor = false;
+ _depth = 2;
+
+ _referencedObject = null;
+ _isExpanded = false;
+ _isUpdated = false;
+ _descriptor = typeDescriptor;
+
+
+ String depthStr = getAttribute(DE.A_DEPTH);
+ if (depthStr != null && depthStr.length() > 0)
+ {
+ if (!depthStr.equals("2"))
+ {
+ try
+ {
+ _depth = Integer.parseInt(depthStr);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+
+
+ String isRef = getAttribute(DE.A_ISREF);
+ if (isRef != null && isRef.equals(DataStoreResources.TRUE))
+ {
+ _isReference = true;
+ }
+
+ String type = getAttribute(DE.A_TYPE);
+ if (type.equals(DE.T_OBJECT_DESCRIPTOR)
+ || type.equals(DE.T_COMMAND_DESCRIPTOR)
+ || type.equals(DE.T_RELATION_DESCRIPTOR)
+ || type.equals(DE.T_ABSTRACT_OBJECT_DESCRIPTOR)
+ || type.equals(DE.T_ABSTRACT_COMMAND_DESCRIPTOR)
+ || type.equals(DE.T_ABSTRACT_RELATION_DESCRIPTOR))
+ {
+ _isDescriptor = true;
+ }
+
+ if (_nestedData != null)
+ _nestedData.clear();
+ }
+
+ /**
+ * Removes all the attributes of a DataElement
.
+ * This method should only be called from the UpdateHandlers.
+ */
+ protected synchronized void clear()
+ {
+ if (_attributes != null)
+ {
+ for (int i = 0; i < _attributes.length; i++)
+ {
+ String att = _attributes[i];
+ if (att != null)
+ {
+ att = null;
+ }
+ }
+
+ }
+
+ if (_nestedData != null)
+ {
+ _nestedData.clear();
+ }
+
+ _parent = null;
+ _descriptor = null;
+ _referencedObject = null;
+
+ _propertySource = null;
+ _buffer = null;
+ }
+
+ /**
+ * Marks a DataElement
as deleted.
+ * This method should only be called from the DataStore
+ */
+ public synchronized void delete()
+ {
+ if (!isDeleted())
+ {
+ // set delete attribute
+
+ setAttribute(DE.A_SOURCE, null);
+ setAttribute(DE.A_VALUE, DataStoreResources.DELETED);
+ setAttribute(DE.A_TYPE, null);
+ setAttribute(DE.A_NAME, null);
+
+ _isUpdated = false;
+ _isExpanded = true;
+ _buffer = null;
+ _nestedData = null;
+ }
+ }
+
+ public synchronized void notifyUpdate()
+ {
+ notify();
+ }
+
+ public synchronized void waitForUpdate(long timeout)
+ {
+ try
+ {
+ //System.out.println("waiting on:"+this);
+ wait(timeout);
+ //System.out.println("done waiting on:"+this);
+ }
+ catch (Exception e)
+ {
+ // timeed out
+ // System.out.println("timeout:"+this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java
new file mode 100644
index 00000000000..7f5bb3a9a31
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java
@@ -0,0 +1,3984 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Random;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.eclipse.dstore.core.java.ClassByteStreamHandler;
+import org.eclipse.dstore.core.java.ClassByteStreamHandlerRegistry;
+import org.eclipse.dstore.core.java.IClassByteStreamHandler;
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.java.RemoteClassLoader;
+import org.eclipse.dstore.core.util.ExternalLoader;
+import org.eclipse.dstore.core.util.StringCompare;
+import org.eclipse.dstore.core.util.XMLgenerator;
+import org.eclipse.dstore.core.util.XMLparser;
+import org.eclipse.dstore.extra.internal.extra.DomainNotifier;
+
+/**
+ * DataStore
is the heart of the DataStore
Distributed Tooling Framework.
+ * This class is used for creating, deleting and accessing DataElement
s and for communicating commands
+ * to miners (tools).
+ *
+ * DataStore
has both a command handler and an update handler. The command
+ * handler is responsible for sending commands, in the form of DataElement
trees, to the appropriate
+ * implementer, either directly to the miner, or indirectly over the communication layer through a server
+ * DataStore
. The update handler is responsible for notifying listeners about changes in the
+ * DataStore
, either directly via a DomainNotifier
or indirectly over the communication
+ * layer through a client DataStore
.
+ * DataStore
instance
+ *
+ * @param attributes the default attributes of the DataStore
+ */
+ public DataStore(DataStoreAttributes attributes)
+ {
+ _dataStoreAttributes = attributes;
+ _commandHandler = null;
+ _updateHandler = null;
+ _domainNotifier = null;
+ _isConnected = false;
+ _logTimes = false;
+ _initialSize = 100000;
+
+ initialize();
+ }
+
+ /**
+ * Creates a new DataStore instance
+ *
+ * @param attributes the default attributes of the DataStore
+ * @param initialSize the initial number of preallocated DataElement
s
+ */
+ public DataStore(DataStoreAttributes attributes, int initialSize)
+ {
+ _dataStoreAttributes = attributes;
+ _commandHandler = null;
+ _updateHandler = null;
+ _domainNotifier = null;
+ _isConnected = false;
+ _logTimes = false;
+ _initialSize = initialSize;
+
+ initialize();
+ }
+
+ /**
+ * Creates a new DataStore
instance
+ *
+ * @param attributes the default attributes of the DataStore
+ * @param commandHandler the DataStore's handler for sending commands
+ * @param updateHandler the DataStore's handler for doing updates
+ * @param domainNotifier the domain notifier
+ */
+ public DataStore(DataStoreAttributes attributes, CommandHandler commandHandler, UpdateHandler updateHandler, DomainNotifier domainNotifier)
+ {
+ _dataStoreAttributes = attributes;
+ _commandHandler = commandHandler;
+ _updateHandler = updateHandler;
+ _domainNotifier = domainNotifier;
+ _isConnected = true;
+ _logTimes = false;
+ _initialSize = 10000;
+
+ initialize();
+ createRoot();
+ }
+
+ /**
+ * Creates a new DataStore instance
+ *
+ * @param attributes the default attributes of the DataStore
+ * @param commandHandler the DataStore's handler for sending commands
+ * @param updateHandler the DataStore's handler for doing updates
+ * @param domainNotifier the domain notifier
+ * @param initialSize the initialNumber of preallocated DataElement
s
+ */
+ public DataStore(DataStoreAttributes attributes, CommandHandler commandHandler, UpdateHandler updateHandler, DomainNotifier domainNotifier, int initialSize)
+ {
+ _dataStoreAttributes = attributes;
+ _commandHandler = commandHandler;
+ _updateHandler = updateHandler;
+ _domainNotifier = domainNotifier;
+ _isConnected = true;
+ _logTimes = false;
+ _initialSize = initialSize;
+
+ initialize();
+ createRoot();
+ }
+
+
+ public void setServerVersion(int version)
+ {
+ _serverVersion = version;
+ }
+
+ public void setServerMinor(int minor)
+ {
+ _serverMinor = minor;
+ }
+
+ public int getServerVersion()
+ {
+ return _serverVersion;
+ }
+
+ public int getServerMinor()
+ {
+ return _serverMinor;
+ }
+
+ /**
+ * Sets the ticket for this DataStore
. A ticket is used to prevent unauthorized users
+ * from accessing the DataStore
+ *
+ * @param ticket the DataElement
representing the ticket
+ */
+ public void setTicket(DataElement ticket)
+ {
+ _ticket = ticket;
+ }
+
+ /**
+ * Sets the loaders for this DataStore
. The loaders are used to load miners (extension tools).
+ *
+ * @param loader the loader for the miners this DataStore
will be using
+ */
+ public void setLoaders(ArrayList loaders)
+ {
+ _loaders = loaders;
+ }
+
+ /**
+ * Adds a loader for this DataStore
. The loader is used to load miners (extension tools).
+ *
+ * @param loader the loader for the miners this DataStore
will be using
+ */
+ public void addLoader(ExternalLoader loader)
+ {
+ if (_loaders == null)
+ {
+ _loaders = new ArrayList();
+ }
+ _loaders.add(loader);
+ }
+
+
+ public boolean usingSSL()
+ {
+ if (_sslProperties != null)
+ {
+ return _sslProperties.usingSSL();
+ }
+ return false;
+ }
+
+ /**
+ * Specifies the security properties of this DataStore.
+ * These properties indicate whether or not to use ssl,
+ * the keystore location and password.
+ * @param properties
+ */
+ public void setSSLProperties(ISSLProperties properties)
+ {
+ _sslProperties = properties;
+ }
+
+ /*
+ * Returns the location for the keystore associated with the DataStore.
+ * The keystore is used when using SSL for remote communications. On the
+ * host the file typically resides in the server directory. On the client,
+ * the keystore location is normally customized vi setKeyStoreLocation
.
+ */
+ public String getKeyStoreLocation()
+ {
+ if (_sslProperties != null)
+ {
+ return _sslProperties.getServerKeyStorePath();
+ }
+ return null;
+ }
+
+ /*
+ * Returns the password to use when accessing the DataStore keystore.
+ */
+ public String getKeyStorePassword()
+ {
+ if (_sslProperties != null)
+ {
+ return _sslProperties.getServerKeyStorePassword();
+ }
+ return null;
+ }
+
+ /**
+ * Tells the DataStore
where to find the miners which it needs to load.
+ *
+ * @param minersLocation a string representing the location of the miners
+ */
+ public DataElement addMinersLocation(String minersLocation)
+ {
+ if (_minersLocations == null)
+ {
+ _minersLocations = new ArrayList();
+ }
+ if (!_minersLocations.contains(minersLocation))
+ {
+ _minersLocations.add(minersLocation);
+
+ if (isVirtual())
+ {
+ DataElement location = createObject(_tempRoot, "location", minersLocation);
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_ADD_MINERS);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_ADD_MINERS, 1);
+ ArrayList args = new ArrayList();
+ args.add(location);
+ return command(cmd, args, _dummy);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Tells the DataStore
where to find the miners which it needs to load.
+ *
+ * @param minersLocation a DataElement
representing the location of the miners
+ */
+ public void addMinersLocation(DataElement location)
+ {
+ String name = location.getName();
+ if (_minersLocations == null)
+ {
+ _minersLocations = new ArrayList();
+ }
+
+ if (!_minersLocations.contains(name))
+ {
+ _minersLocations.add(name);
+ }
+ }
+
+ /**
+ * Tells the DataStore
that it is connected to it's tools
+ *
+ * @param isConnected indicates whether it is connected or not
+ */
+ public void setConnected(boolean isConnected)
+ {
+ _isConnected = isConnected;
+ }
+
+ /**
+ * Sets the DataStore
's DomainNotifier
+ *
+ * @param domainNotifier the domainNotifier
+ */
+ public void setDomainNotifier(DomainNotifier domainNotifier)
+ {
+ _domainNotifier = domainNotifier;
+ }
+
+ /**
+ * Sets the DataStore
's handler for doing updates
+ *
+ * @param updateHandler the handler for doing updates
+ */
+ public void setUpdateHandler(UpdateHandler updateHandler)
+ {
+ _updateHandler = updateHandler;
+ }
+
+ /**
+ * Sets the DataStore
's handler for sending commands to miners
+ *
+ * @param commandHandler the handler for sending commands to miners
+ */
+ public void setCommandHandler(CommandHandler commandHandler)
+ {
+ _commandHandler = commandHandler;
+ }
+
+ /**
+ * Sets the time the update handler sleeps in between update requests
+ *
+ * @param time interval to wait
+ */
+ public void setUpdateWaitTime(int time)
+ {
+ _updateHandler.setWaitTime(time);
+ }
+
+ /**
+ * Sets the time the command handler sleeps in between command requests
+ *
+ * @param time interval to wait
+ */
+ public void setCommandWaitTime(int time)
+ {
+ _commandHandler.setWaitTime(time);
+ }
+
+ /**
+ * Sets the maximum amount of time that the DataStore
will wait to receive a response
+ * for a synchronous command
+ *
+ * @param time interval to wait
+ */
+ public void setTimeoutValue(int time)
+ {
+ _timeout = time;
+ }
+
+ public int getTimeoutValue()
+ {
+ return _timeout;
+ }
+
+
+ /**
+ * Sets an attribute of the DataStore
+ *
+ * @param attribute index of the attribute to set
+ * @param value value to set the attribute at the give index
+ */
+ public void setAttribute(int attribute, String value)
+ {
+ _dataStoreAttributes.setAttribute(attribute, value);
+ }
+
+ /**
+ * Tells the DataStore
to log durations of commands
+ *
+ * @param flag whether to log times or not
+ */
+ public void setLogTimes(boolean flag)
+ {
+ _logTimes = flag;
+ }
+
+ /**
+ * Indicates whether this DataStore
is virtual or not. A virtual DataStore
+ * is one that does not have it's own tools, but rather communicates with a non-virtual
+ * DataStore
that does.
+ *
+ * @return whether the DataStore
is virtual or not
+ */
+ public boolean isVirtual()
+ {
+ if (_commandHandler == null)
+ {
+ return true;
+ }
+ else if (_commandHandler instanceof org.eclipse.dstore.core.client.ClientCommandHandler)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Indicates whether this DataStore
is connected to it's miners or another DataStore
+ *
+ * @return whether the DataStore
is connected or not
+ */
+ public boolean isConnected()
+ {
+ return _isConnected;
+ }
+
+ /**
+ * Indicates whether this DataStore
logs the durations of commands
+ *
+ * @return whether the DataStore
logs command times or not
+ */
+ public boolean logTimes()
+ {
+ return _logTimes;
+ }
+
+ /**
+ * Returns the DataStore
's ticket
+ *
+ * @return the ticket
+ */
+ public DataElement getTicket()
+ {
+ return _ticket;
+ }
+
+ /**
+ * Returns the time the update handler waits between requests
+ *
+ * @return wait time
+ */
+ public int getUpdateWaitTime()
+ {
+ return _updateHandler.getWaitTime();
+ }
+
+ /**
+ * Returns the time the command handler waits between requests
+ *
+ * @return wait time
+ */
+ public int getCommandWaitTime()
+ {
+ return _commandHandler.getWaitTime();
+ }
+
+
+
+
+
+ /**
+ * Returns the name of the DataStore
+ *
+ * @return the name of the DataStore
+ */
+ public String getName()
+ {
+ return getAttribute(DataStoreAttributes.A_HOST_NAME);
+ }
+
+ /**
+ * Returns the root DataElement
in the DataStore
.
+ * The root DataElement
has no parent and contains every DataElement
+ * in the DataStore
through a DataElement
tree
+ *
+ * @return the root DataElement
+ */
+ public DataElement getRoot()
+ {
+ return _root;
+ }
+
+ public DataElement getDummy()
+ {
+ return _dummy;
+ }
+
+ /**
+ * Returns the host root DataElement
in the DataStore
.
+ * The host root DataElement
is a child of root and references
+ * DataElement
s in the DataStore
that are related to host information
+ *
+ * @return the host root DataElement
+ */
+ public DataElement getHostRoot()
+ {
+ return _hostRoot;
+ }
+
+ public DataElement getExternalRoot()
+ {
+ return _externalRoot;
+ }
+
+ /**
+ * Returns the miner root DataElement
in the DataStore
.
+ * The miner root DataElement
is a child of root and contains
+ * DataElement
s the represent tools and the information that tools possess
+ *
+ * @return the miner root DataElement
+ */
+ public DataElement getMinerRoot()
+ {
+ return _minerRoot;
+ }
+
+ /**
+ * Returns the status of the DataStore
.
+ *
+ * @return the status of the DataStore
+ */
+ public DataElement getStatus()
+ {
+ return _status;
+ }
+
+ /**
+ * Returns the log root DataElement
of the DataStore
.
+ * The log root contains all commands that are issued from the DataStore
+ *
+ * @return the log root
+ */
+ public DataElement getLogRoot()
+ {
+ return _logRoot;
+ }
+
+ /**
+ * Returns the descriptor root DataElement
of the DataStore
.
+ * The descriptor root contains the schema for the DataStore
and it's tools
+ *
+ * @return the descriptor root
+ */
+ public DataElement getDescriptorRoot()
+ {
+ return _descriptorRoot;
+ }
+
+ /**
+ * Returns the temp root DataElement
of the DataStore
.
+ * The temp root contains temporary information.
+ *
+ * @return the temp root
+ */
+ public DataElement getTempRoot()
+ {
+ return _tempRoot;
+ }
+
+ /**
+ * Returns the handler for sending commands.
+ *
+ * @return the command handler
+ */
+ public CommandHandler getCommandHandler()
+ {
+ return _commandHandler;
+ }
+
+ /**
+ * Returns the handler for doing updates.
+ *
+ * @return the update handler
+ */
+ public UpdateHandler getUpdateHandler()
+ {
+ return _updateHandler;
+ }
+
+ /**
+ * Returns the loader that is used for loading miners.
+ *
+ * @return the loader
+ */
+ public ArrayList getLoaders()
+ {
+ return _loaders;
+ }
+
+ /**
+ * Returns registered local classloaders.
+ */
+ public ArrayList getLocalClassLoaders()
+ {
+ return _localClassLoaders;
+ }
+
+ /**
+ * Registers a local class loader. On the client, each subsystem
+ * must register its local class loader using this method so that
+ * if the subsystem's classes cannot be found on the server, they can
+ * be requested from the client, loaded using loader
,
+ * transferred to the server, and then loaded on the server.
+ */
+ public void registerLocalClassLoader(ClassLoader loader)
+ {
+ if (_localClassLoaders == null)
+ {
+ _localClassLoaders = new ArrayList();
+ }
+ if (!_localClassLoaders.contains(loader)) _localClassLoaders.add(loader);
+ }
+
+ public DataElement getContentsRelation()
+ {
+ return _dataStoreSchema.getContentsRelation();
+ }
+
+ public DataElement getAttributesRelation()
+ {
+ return _dataStoreSchema.getAttributesRelation();
+ }
+
+ public DataElement getAbstractedByRelation()
+ {
+ return _dataStoreSchema.getAbstractedByRelation();
+ }
+
+ public DataElement getAbstractsRelation()
+ {
+ return _dataStoreSchema.getAbstractsRelation();
+ }
+
+ /**
+ * Returns the location of the miners.
+ *
+ * @return the location of the miners
+ */
+ public ArrayList getMinersLocation()
+ {
+ return _minersLocations;
+ }
+
+ /**
+ * Returns the domain notifier.
+ *
+ * @return the domain notifier
+ */
+ public DomainNotifier getDomainNotifier()
+ {
+ return _domainNotifier;
+ }
+
+ /**
+ * Returns the attribute indicated by an index.
+ *
+ * @param the index of the attribute to get
+ * @return the attribute
+ */
+ public String getAttribute(int attribute)
+ {
+ return _dataStoreAttributes.getAttribute(attribute);
+ }
+
+ /**
+ * Returns the number of live elements in the DataStore
.
+ *
+ * @return the number of live elements
+ */
+ public int getNumElements()
+ {
+ return _hashMap.size();
+ }
+
+ /**
+ * Returns the number of recycled elements in the DataStore
.
+ *
+ * @return the number of recycled elements
+ */
+ public int getNumRecycled()
+ {
+ return _recycled.size();
+ }
+ /**
+ * Returns the table of live elements in the DataStore
.
+ *
+ * @return the table of live elements
+ */
+ public HashMap getHashMap()
+ {
+ return _hashMap;
+ }
+
+ /**
+ * Initializes the DataStore
by creating the root elements
+ *
+ */
+ public void createRoot()
+ {
+ _root =
+ createObject(
+ null,
+ DataStoreResources.model_root,
+ _dataStoreAttributes.getAttribute(DataStoreAttributes.A_ROOT_NAME),
+ _dataStoreAttributes.getAttribute(DataStoreAttributes.A_ROOT_PATH),
+ "rootID");
+
+
+ _descriptorRoot = createObject(_root, DE.T_OBJECT_DESCRIPTOR, DataStoreResources.model_descriptors, "", "schemaID");
+
+ _ticket = createObject(_root, DataStoreResources.model_ticket, "null", "", "ticketID");
+
+ createRoots();
+ initializeDescriptors();
+ }
+
+ /**
+ * Creates a contents relationship between two DataElement
s
+ *
+ * @param from the element that contains the other
+ * @param to the element that is contained by the other
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement from, DataElement to)
+ {
+ // default reference is a containment relationship
+ return createReference(from, to, getContentsRelation());
+ }
+
+ /**
+ * Creates a relationship between two DataElement
s given a type of relationship
+ *
+ * @param parent the element that references the other element
+ * @param realObject the element that is referenced by the parent element
+ * @param relationType the descriptor element that represents the type of relationship between parent and realObject
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement parent, DataElement realObject, DataElement relationType)
+ {
+ if (parent != null)
+ {
+
+ // reference with a specified type of relationship
+ DataElement reference = createElement();
+
+ reference.reInit(parent, realObject, relationType);
+ parent.addNestedData(reference, false);
+
+ String sugId = reference.getId();
+ _hashMap.put(sugId, reference);
+
+ refresh(parent);
+
+ return reference;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates a relationship between two DataElement
s given a type of relationship
+ *
+ * @param parent the element that references the other element
+ * @param realObject the element that is referenced by the parent element
+ * @param relationType the string that represents the type of relationship between parent and realObject
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement parent, DataElement realObject, String relationType)
+ {
+ return createReference(parent, realObject, relationType, true);
+ }
+
+ /**
+ * Creates a relationship between two DataElement
s given a type of relationship
+ *
+ * @param parent the element that references the other element
+ * @param realObject the element that is referenced by the parent element
+ * @param relationType the string that represents the type of relationship between parent and realObject
+ * @param doRefresh indicates whether or not to refresh the parent of the new reference
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement parent, DataElement realObject, String relationType, boolean doRefresh)
+ {
+ if (parent != null)
+ {
+ // reference with a specified type of relationship
+ DataElement reference = createElement();
+
+ DataElement toDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, relationType);
+ if (toDescriptor != null)
+ {
+ reference.reInit(parent, realObject, toDescriptor);
+ }
+ else
+ {
+ reference.reInit(parent, realObject, relationType);
+ }
+
+ parent.addNestedData(reference, false);
+
+ String sugId = reference.getId();
+ _hashMap.put(sugId, reference);
+
+ if (doRefresh)
+ {
+ refresh(parent);
+ }
+
+ return reference;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a set of relationships between one DataElement
and a set of DataElement
s given a type of relationship
+ *
+ * @param from the element that references the other elements
+ * @param to a list of elements that from references
+ * @param type the string that represents the type of relationships between from and to
+ * @return the new reference
+ */
+ public void createReferences(DataElement from, ArrayList to, String type)
+ {
+ DataElement toDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, type);
+ if (toDescriptor != null)
+ {
+ createReferences(from, to, toDescriptor);
+ }
+ else
+ {
+ for (int i = 0; i < to.size(); i++)
+ {
+ DataElement toObject = (DataElement) to.get(i);
+ createReference(from, toObject, type);
+ }
+ }
+ }
+
+ /**
+ * Creates a set of relationships between one DataElement
and a set of DataElement
s given a type of relationship
+ *
+ * @param from the element that references the other elements
+ * @param to a list of elements that from references
+ * @param type the descriptor element that represents the type of relationships between from and to
+ */
+ public void createReferences(DataElement from, ArrayList to, DataElement type)
+ {
+ for (int i = 0; i < to.size(); i++)
+ {
+ DataElement toObject = (DataElement) to.get(i);
+ createReference(from, toObject, type);
+ }
+ }
+
+ /**
+ * Creates a two-way relationship between two elements
+ *
+ * @param parent an element that references the other element
+ * @param realObject an element that references the other element
+ * @param toRelation the descriptor element that represents the type of relationship between parent and realObject
+ * @param fromRelation the descriptor element that represents the type of relationship between realObject and parent
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement parent, DataElement realObject, DataElement toRelation, DataElement fromRelation)
+ {
+ if (parent != null)
+ {
+ // reference with "to" relationship
+ DataElement toReference = createElement();
+ toReference.reInit(parent, realObject, toRelation);
+
+ parent.addNestedData(toReference, false);
+
+ String toId = toReference.getId();
+ _hashMap.put(toId, toReference);
+
+ // reference with "from" relationship
+ DataElement fromReference = createElement();
+
+ fromReference.reInit(realObject, parent, fromRelation);
+
+ realObject.addNestedData(fromReference, false);
+
+ String fromId = fromReference.getId();
+ _hashMap.put(fromId, fromReference);
+ refresh(parent);
+
+
+ return toReference;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a two-way relationship between two elements
+ *
+ * @param parent an element that references the other element
+ * @param realObject an element that references the other element
+ * @param toRelation the string that represents the type of relationship between parent and realObject
+ * @param fromRelation the string that represents the type of relationship between realObject and parent
+ * @return the new reference
+ */
+ public DataElement createReference(DataElement parent, DataElement realObject, String toRelation, String fromRelation)
+ {
+ if (parent != null)
+ {
+ // reference with "to" relationship
+ DataElement toReference = createElement();
+ DataElement toDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, toRelation);
+ if (toDescriptor != null)
+ {
+ toReference.reInit(parent, realObject, toDescriptor);
+ }
+ else
+ {
+ toReference.reInit(parent, realObject, toRelation);
+ }
+
+ parent.addNestedData(toReference, false);
+
+ String toId = toReference.getId();
+ _hashMap.put(toId, toReference);
+
+ // reference with "from" relationship
+ DataElement fromReference = createElement();
+
+ DataElement fromDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, fromRelation);
+ if (fromDescriptor != null)
+ {
+ fromReference.reInit(realObject, parent, fromDescriptor);
+ }
+ else
+ {
+ fromReference.reInit(realObject, parent, fromRelation);
+ }
+
+ realObject.addNestedData(fromReference, false);
+
+ String fromId = fromReference.getId();
+ _hashMap.put(fromId, fromReference);
+
+ refresh(parent);
+
+
+ return toReference;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a set of two-way relationship between a DataElement
and a list of elements
+ *
+ * @param from an element that references the other elements
+ * @param to a list of elements that reference from
+ * @param toRel the descriptor element that represents the type of relationship between from and to
+ * @param fromRel the descriptor element that represents the type of relationship between to and from
+ */
+ public void createReferences(DataElement from, ArrayList to, DataElement toRel, DataElement fromRel)
+ {
+ for (int i = 0; i < to.size(); i++)
+ {
+ DataElement toObject = (DataElement) to.get(i);
+ createReference(from, toObject, toRel, fromRel);
+ }
+ }
+
+ /**
+ * Creates a set of two-way relationship between a DataElement and a list of elements
+ *
+ * @param from an element that references the other elements
+ * @param to a list of elements that reference from
+ * @param toRel the string that represents the type of relationship between from and to
+ * @param fromRel the string that represents the type of relationship between to and from
+ */
+ public void createReferences(DataElement from, ArrayList to, String toRel, String fromRel)
+ {
+ DataElement toDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, toRel);
+ DataElement fromDescriptor = findDescriptor(DE.T_RELATION_DESCRIPTOR, fromRel);
+
+ if ((toDescriptor != null) && (fromDescriptor != null))
+ {
+ createReferences(from, to, toDescriptor, fromDescriptor);
+ }
+ else
+ {
+ for (int i = 0; i < to.size(); i++)
+ {
+ DataElement toObject = (DataElement) to.get(i);
+ createReference(from, toObject, toRel, fromRel);
+ }
+ }
+ }
+
+ public DataElement createTransientObject(String attributes[])
+ {
+ DataElement newObject = createElement();
+
+ newObject.reInitAsTransient(attributes);
+ return newObject;
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the descriptor representing the type of the new element
+ * @param name the name of the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, DataElement type, String name)
+ {
+ return createObject(parent, type, name, "");
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the string representing the type of the new element
+ * @param name the name of the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, String type, String name)
+ {
+ return createObject(parent, type, name, "");
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the descriptor element representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, DataElement type, String name, String source)
+ {
+ String id = generateId();
+ return createObject(parent, type, name, source, id);
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the string representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, String type, String name, String source)
+ {
+ String id = generateId(parent, type, name);
+ if (id == null)
+ {
+ return null;
+ }
+
+ return createObject(parent, type, name, source, id);
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the descriptor element representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param sugId the suggested ID for the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, DataElement type, String name, String source, String sugId)
+ {
+ return createObject(parent, type, name, source, sugId, false);
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the string representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param sugId the suggested ID for the new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, String type, String name, String source, String sugId)
+ {
+ return createObject(parent, type, name, source, sugId, false);
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the descriptor element representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param sugId the suggested ID for the new element
+ * @param isReference an indication whether the new element is a reference
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, DataElement type, String name, String source, String sugId, boolean isReference)
+ {
+ String id = makeIdUnique(sugId);
+
+ DataElement newObject = createElement();
+ if (parent == null)
+ {
+ parent = _tempRoot;
+ }
+
+ newObject.reInit(parent, type, id, name, source, isReference);
+
+ if (parent != null)
+ {
+ parent.addNestedData(newObject, false);
+ }
+
+ _hashMap.put(id, newObject);
+
+ if (_autoRefresh)
+ refresh(parent);
+ return newObject;
+ }
+
+ /**
+ * Creates a new DataElement
+ *
+ * @param parent the parent of the new element
+ * @param type the string representing the type of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param sugId the suggested ID for the new element
+ * @param isReference an indication whether the new element is a reference
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, String type, String name, String source, String sugId, boolean isReference)
+ {
+ String id = makeIdUnique(sugId);
+
+ DataElement newObject = createElement();
+ if (parent == null)
+ {
+ parent = _tempRoot;
+ }
+
+
+ DataElement descriptor = findDescriptor(DE.T_OBJECT_DESCRIPTOR, type);
+ if (descriptor != null && (parent != _descriptorRoot))
+ {
+ newObject.reInit(parent, descriptor, id, name, source, isReference);
+ }
+ else
+ {
+ newObject.reInit(parent, type, id, name, source, isReference);
+ }
+
+ if (parent != null)
+ {
+ parent.addNestedData(newObject, false);
+ }
+
+ _hashMap.put(id, newObject);
+
+ if (_autoRefresh)
+ refresh(parent);
+ return newObject;
+ }
+
+ /**
+ * Creates a new DataElement
. This is normally called on client side via xml parser
+ *
+ * @param parent the parent of the new element
+ * @param attributes the attributes to use in this new element
+ * @return the new element
+ */
+ public DataElement createObject(DataElement parent, String attributes[])
+ {
+ DataElement newObject = createElement();
+
+ if (parent == null)
+ {
+ parent = _tempRoot;
+ }
+
+ DataElement descriptor = findObjectDescriptor(attributes[DE.A_TYPE]);
+
+ if (descriptor != null && (parent != _descriptorRoot))
+ {
+ newObject.reInit(parent, descriptor, attributes);
+ }
+ else
+ {
+ newObject.reInit(parent, attributes);
+ }
+
+ if (parent != null)
+ {
+ parent.addNestedData(newObject, false);
+ }
+
+ // cache descriptors in map for faster access
+ if (descriptor == _dataStoreSchema.getObjectDescriptor() || descriptor == _dataStoreSchema.getAbstractObjectDescriptor())
+ {
+ _objDescriptorMap.put(attributes[DE.A_NAME], newObject);
+ }
+ else if (descriptor == _dataStoreSchema.getCommandDescriptor() || descriptor == _dataStoreSchema.getAbstractCommandDescriptor())
+ {
+ _cmdDescriptorMap.put(attributes[DE.A_NAME], newObject);
+ }
+ else if (descriptor == _dataStoreSchema.getRelationDescriptor() || descriptor == _dataStoreSchema.getAbstractRelationDescriptor())
+ {
+ _relDescriptorMap.put(attributes[DE.A_NAME], newObject);
+ }
+
+ _hashMap.put(attributes[DE.A_ID], newObject);
+ return newObject;
+ }
+
+ /**
+ * Creates a new abstract object descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractObjectDescriptor(DataElement parent, String name)
+ {
+ DataElement descriptor = createObject(parent, DE.T_ABSTRACT_OBJECT_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ _objDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new abstract object descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractObjectDescriptor(DataElement parent, String name, String source)
+ {
+ DataElement descriptor = createObject(parent, DE.T_ABSTRACT_OBJECT_DESCRIPTOR, name, source, name);
+ _objDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new object descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createObjectDescriptor(DataElement parent, String name)
+ {
+ DataElement parentDescriptor = _dataStoreSchema.getObjectDescriptor();
+ DataElement descriptor = null;
+ if (parentDescriptor != null)
+ {
+ descriptor = createObject(parent, parentDescriptor, name, "org.eclipse.rse.dstore.core", name);
+ }
+ else
+ {
+ descriptor = createObject(parent, DE.T_OBJECT_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ }
+ _objDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new object descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createObjectDescriptor(DataElement parent, String name, String source)
+ {
+ DataElement parentDescriptor = _dataStoreSchema.getObjectDescriptor();
+ DataElement descriptor = null;
+ if (parentDescriptor != null)
+ {
+ descriptor = createObject(parent, parentDescriptor, name, source, name);
+ }
+ else
+ {
+ descriptor = createObject(parent, DE.T_OBJECT_DESCRIPTOR, name, source, name);
+ }
+ _objDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new abstract relation descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractRelationDescriptor(DataElement parent, String name)
+ {
+ DataElement descriptor = createObject(parent, DE.T_ABSTRACT_RELATION_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ _relDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new abstract relation descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractRelationDescriptor(DataElement parent, String name, String source)
+ {
+ DataElement descriptor = createObject(parent, DE.T_ABSTRACT_RELATION_DESCRIPTOR, name, source, name);
+ _relDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new relation descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createRelationDescriptor(DataElement parent, String name)
+ {
+ DataElement descriptor = createObject(parent, DE.T_RELATION_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ _relDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new relation descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createRelationDescriptor(DataElement parent, String name, String source)
+ {
+ DataElement descriptor = createObject(parent, DE.T_RELATION_DESCRIPTOR, name, source, name);
+ _relDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new abstract command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractCommandDescriptor(DataElement parent, String name)
+ {
+ DataElement descriptor = createAbstractCommandDescriptor(parent, name, name);
+ _cmdDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new abstract command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param value the value used to identify the command
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractCommandDescriptor(DataElement parent, String name, String value)
+ {
+ DataElement cmd = createObject(parent, DE.T_ABSTRACT_COMMAND_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ cmd.setAttribute(DE.A_VALUE, value);
+ _cmdDescriptorMap.put(value, cmd);
+ return cmd;
+ }
+
+ /**
+ * Creates a new abstract command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param value the value used to identify the command
+ * @return the new descriptor element
+ */
+ public DataElement createAbstractCommandDescriptor(DataElement parent, String name, String source, String value)
+ {
+ DataElement cmd = createObject(parent, DE.T_ABSTRACT_COMMAND_DESCRIPTOR, name, source, name);
+ cmd.setAttribute(DE.A_VALUE, value);
+ _cmdDescriptorMap.put(value, cmd);
+ return cmd;
+ }
+
+ /**
+ * Creates a new command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @return the new descriptor element
+ */
+ public DataElement createCommandDescriptor(DataElement parent, String name)
+ {
+ DataElement descriptor = createCommandDescriptor(parent, name, name);
+ _cmdDescriptorMap.put(name, descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Creates a new command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param value the value used to identify the command
+ * @return the new descriptor element
+ */
+ public DataElement createCommandDescriptor(DataElement parent, String name, String value)
+ {
+ DataElement parentDescriptor = _dataStoreSchema.getCommandDescriptor();
+ DataElement cmd = null;
+ if (parentDescriptor != null)
+ {
+ cmd = createObject(parent, parentDescriptor, name, "org.eclipse.rse.dstore.core", name);
+ }
+ else
+ {
+ cmd = createObject(parent, DE.T_COMMAND_DESCRIPTOR, name, "org.eclipse.rse.dstore.core", name);
+ }
+ cmd.setAttribute(DE.A_VALUE, value);
+ _cmdDescriptorMap.put(value, cmd);
+ return cmd;
+ }
+
+ /**
+ * Creates a new command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param value the value used to identify the command
+ * @return the new descriptor element
+ */
+ public DataElement createCommandDescriptor(DataElement parent, String name, String source, String value)
+ {
+ DataElement parentDescriptor = _dataStoreSchema.getCommandDescriptor();
+ DataElement cmd = null;
+ if (parentDescriptor != null)
+ {
+ cmd = createObject(parent, parentDescriptor, name, source, name);
+ }
+ else
+ {
+ cmd = createObject(parent, DE.T_COMMAND_DESCRIPTOR, name, source, name);
+ }
+ cmd.setAttribute(DE.A_VALUE, value);
+ _cmdDescriptorMap.put(value, cmd);
+ return cmd;
+ }
+
+ /**
+ * Creates a new command descriptor DataElement
+ *
+ * @param parent the parent of the new element
+ * @param name the name of the new element
+ * @param source the source location of the new element
+ * @param value the value used to identify the command
+ * @param visible indicates whether the command is visible or not
+ * @return the new descriptor element
+ */
+ public DataElement createCommandDescriptor(DataElement parent, String name, String source, String value, boolean visible)
+ {
+ DataElement parentDescriptor = _dataStoreSchema.getCommandDescriptor();
+ DataElement cmd = null;
+ if (parentDescriptor != null)
+ {
+ cmd = createObject(parent, parentDescriptor, name, source, name);
+ }
+ else
+ {
+ cmd = createObject(parent, DE.T_COMMAND_DESCRIPTOR, name, source, name);
+ }
+ cmd.setAttribute(DE.A_VALUE, value);
+ if (!visible)
+ {
+ cmd.setDepth(0);
+ }
+ _cmdDescriptorMap.put(value, cmd);
+
+ return cmd;
+ }
+
+ /**
+ * Moves a element from one location in the DataStore
tree to another
+ *
+ * @param source the element to move
+ * @param target the element to move source to
+ */
+ public void moveObject(DataElement source, DataElement target)
+ {
+ DataElement oldParent = source.getParent();
+ List nested = oldParent.getNestedData();
+ if (nested != null)
+ {
+ nested.remove(source);
+ }
+ refresh(oldParent, true);
+
+ target.addNestedData(source, false);
+ source.setParent(target);
+ refresh(target, true);
+ }
+
+ /**
+ * Deletes all the elements contained in from
+ *
+ * @param from the element from which to delete objects from
+ */
+ public void deleteObjects(DataElement from)
+ {
+ if (from != null)
+ {
+ for (int i = from.getNestedSize() - 1; i >= 0; i--)
+ {
+ DataElement deletee = from.get(i);
+ if (deletee != null)
+ {
+ deleteObjectHelper(from, deletee, 5);
+ }
+ }
+
+ // refresh(from);
+ }
+ }
+
+ /**
+ * Deletes an element from another element
+ *
+ * @param from the element from which to delete an object from
+ * @param toDelete the element to remove
+ */
+ public void deleteObject(DataElement from, DataElement toDelete)
+ {
+ if (toDelete != null)
+ {
+ deleteObjectHelper(from, toDelete, 5);
+ // refresh(toDelete);
+ // refresh(from);
+ }
+ }
+
+ /**
+ * Replaces a deleted object
+ */
+ public DataElement replaceDeleted(DataElement deletedObject)
+ {
+ if (deletedObject != null)
+ {
+ synchronized (deletedObject)
+ {
+ String name = deletedObject.getName();
+ String type = deletedObject.getType();
+
+ // find undeleted ancestor
+ DataElement parent = deletedObject.getParent();
+ if ((parent != null) && parent.isDeleted())
+ {
+ parent = replaceDeleted(parent);
+ }
+ if ((parent != null) && !parent.isDeleted())
+ {
+ for (int i = 0; i < parent.getNestedSize(); i++)
+ {
+ DataElement child = parent.get(i);
+ if (!child.isDeleted())
+ {
+ if (child.getName().equals(name) && child.getType().equals(type))
+ {
+ return child;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Checks if a DataElement
with a given ID exists in the DataStore
+ *
+ * @param id the id to look for
+ * @return whether it exists or not
+ */
+ public boolean contains(String id)
+ {
+ return _hashMap.containsKey(id);
+ }
+
+ /**
+ * Refresh a set of DataElement
s
+ *
+ * @param elements a list of elements to refresh
+ */
+ public void refresh(ArrayList elements)
+ {
+ // this gets called in response to a query
+ for (int i = 0; i < elements.size(); i++)
+ {
+ refresh((DataElement) elements.get(i));
+ }
+ }
+
+ /**
+ * Refresh a DataElement
+ *
+ * @param element an element to refresh
+ */
+ public void refresh(DataElement element)
+ {
+ if (element != null)
+ {
+ if (element.isReference())
+ {
+ refresh(element.dereference(), false);
+ }
+ refresh(element, false);
+ }
+ }
+
+ /**
+ * Refresh a DataElement
- immediately if indicated
+ *
+ * @param element an element to refresh
+ * @param immediate indicates to do the refresh immediately
+ */
+ public void refresh(DataElement element, boolean immediate)
+ {
+ if ((_updateHandler != null) && (element != null))
+ {
+ //element = findLastUpdatedAncestor(element, 5);
+
+ // update either client or ui
+ //element.setUpdated(false);
+ _updateHandler.update(element, immediate);
+ }
+ }
+
+ public void update(ArrayList objects)
+ {
+ // this gets called in response to a query
+ for (int i = 0; i < objects.size(); i++)
+ {
+ update((DataElement) objects.get(i));
+ }
+ }
+
+ public void update(DataElement dataElement)
+ {
+ refresh(dataElement);
+ }
+
+ public void updateRemoteClassInstance(IRemoteClassInstance instance, String byteStreamHandlerId)
+ {
+ getUpdateHandler().updateClassInstance(instance, byteStreamHandlerId);
+ }
+
+ /**
+ * Transfers a file from a server to a client. This should only be called from
+ * a miner on a different machine from the client. If a file exists on the client
+ * side that the server file maps to then the existing client file will be replaced.
+ *
+ * @param remotePath the path of the file on the client side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ */
+ public void updateFile(String remotePath, byte[] bytes, int size, boolean binary)
+ {
+ updateFile(remotePath, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+ /**
+ * Transfers a file from a server to a client. This should only be called from
+ * a miner on a different machine from the client. If a file exists on the client
+ * side that the server file maps to then the existing client file will be replaced.
+ *
+ * @param remotePath the path of the file on the client side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ * @param byteStreamHandlerId indicates the client byte stream handler to receive the bytes
+ */
+ public void updateFile(String remotePath, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ remotePath = new String(remotePath.replace('\\', '/'));
+ String fileName = mapToLocalPath(remotePath);
+ if (fileName != null)
+ {
+ _updateHandler.updateFile(remotePath, bytes, size, binary, byteStreamHandlerId);
+ }
+ }
+
+ /**
+ * Transfers and appends a file from a server to a client. This should only be called from
+ * a miner on a different machine from the client. If a file exists on the client
+ * side that the server file maps to then the existing client file will be appended to
+ *
+ * @param remotePath the path of the file on the client side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ */
+ public void updateAppendFile(String remotePath, byte[] bytes, int size, boolean binary)
+ {
+ updateAppendFile(remotePath, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+ /**
+ * Transfers and appends a file from a server to a client. This should only be called from
+ * a miner on a different machine from the client. If a file exists on the client
+ * side that the server file maps to then the existing client file will be appended to
+ *
+ * @param remotePath the path of the file on the client side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ * @param byteStreamHandlerId indicates the client byte stream handler to receive the bytes
+ */
+ public void updateAppendFile(String remotePath, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ remotePath = new String(remotePath.replace('\\', '/'));
+ String fileName = mapToLocalPath(remotePath);
+ if (fileName != null)
+ {
+ _updateHandler.updateAppendFile(remotePath, bytes, size, binary, byteStreamHandlerId);
+ }
+ }
+
+
+
+ /**
+ * Transfers a file from a client to a server. The should only be called from
+ * a client on a different machine from the server. If a file exists on the server
+ * side that the client file maps to then the existing server file will be replaced.
+ *
+ * @param remotePath the path of the file on the server side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ * @param byteStreamHandlerId indicates which byteStreamHandler to use to receive the bytes
+ */
+ public void replaceFile(String remotePath, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ remotePath = new String(remotePath.replace('\\', '/'));
+
+ _commandHandler.sendFile(remotePath, bytes, size, binary, byteStreamHandlerId);
+ }
+
+
+ /**
+ * Transfers a file from a client to a server. The should only be called from
+ * a client on a different machine from the server. If a file exists on the server
+ * side that the client file maps to then the existing server file will be replaced.
+ *
+ * @param remotePath the path of the file on the server side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ */
+ public void replaceFile(String remotePath, byte[] bytes, int size, boolean binary)
+ {
+ replaceFile(remotePath, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+ /**
+ * Transfers a file from a client to a server. The should only be called from
+ * a client on a different machine from the server. If a file exists on the server
+ * side that the client file maps to then the existing server file will be appended to.
+ *
+ * @param remotePath the path of the file on the server side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ * @param byteStreamHandlerId indicates which byte stream handler to use to receive the bytes
+ */
+ public void replaceAppendFile(String remotePath, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ remotePath = new String(remotePath.replace('\\', '/'));
+
+ _commandHandler.sendAppendFile(remotePath, bytes, size, binary, byteStreamHandlerId);
+ }
+
+ /**
+ * Transfers a file from a client to a server. The should only be called from
+ * a client on a different machine from the server. If a file exists on the server
+ * side that the client file maps to then the existing server file will be appended to.
+ *
+ * @param remotePath the path of the file on the server side
+ * @param bytes an array of bytes representing a file
+ * @param size the number of bytes to transfer
+ * @param binary indicates whether to send the bytes as binary or text
+ */
+ public void replaceAppendFile(String remotePath, byte[] bytes, int size, boolean binary)
+ {
+ replaceAppendFile(remotePath, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+ /**
+ * Makes a given client element available on the server
+ *
+ * @param localObject the element to transfer
+ */
+ public void setObject(DataElement localObject)
+ {
+ setObject(localObject, true);
+ }
+
+ /**
+ * Makes a given client element available on the server
+ *
+ * @param localObject the element to transfer
+ * @param noRef indicates whether the element is a reference or not
+ */
+ public void setObject(DataElement localObject, boolean noRef)
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SET);
+ //localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_SET, 1);
+ DataElement status = command(cmd, localObject, noRef);
+ }
+
+ public void modifyObject(DataElement localObject)
+ {
+ DataElement cmd = find(_descriptorRoot, DE.A_NAME, DataStoreResources.model_Modify, 2);
+ DataElement status = _commandHandler.command(cmd, localObject, true);
+ waitUntil(status, DataStoreResources.model_done);
+ }
+
+ /**
+ * Used at DataStore
initialization time to indicate where to point the host root
+ *
+ * @param localHostObject the client host element to transfer to the server site
+ */
+ public DataElement setHost(DataElement localHostObject)
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SET_HOST);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_SET_HOST, 1);
+ DataElement status = _commandHandler.command(cmd, localHostObject, false);
+ waitUntil(status, DataStoreResources.model_done);
+ return status;
+ }
+
+ /**
+ * Used at DataStore
initialization time to setup the schema
+ *
+ */
+ public DataElement getSchema()
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SCHEMA);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_SCHEMA, 1);
+ return command(cmd, _dummy);
+ }
+
+ public void setPreference(String property, String value)
+ {
+ _dataStorePreferences.put(property, value);
+ if (isVirtual())
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SET_PREFERENCE);
+ if (cmd != null)
+ {
+ DataElement prefObj = createObject(null, "preference", property);
+ prefObj.setAttribute(DE.A_VALUE, value);
+ command(cmd, prefObj, true);
+ }
+ }
+ }
+
+ public String getPreference(String property)
+ {
+ return (String)_dataStorePreferences.get(property);
+ }
+
+ /**
+ * Used to load and initialize a new miner on the host
+ * @param minerId the qualified classname of the miner to load
+ * @return the status of the activate miner command
+ */
+ public DataElement activateMiner(String minerId)
+ {
+ // check if the miner is loaded
+ DataElement minerInfo = findMinerInformation(minerId);
+ if (minerInfo == null)
+ {
+ if (isVirtual())
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_ACTIVATE_MINER);
+ DataElement minerObj = createObject(null, DataStoreResources.model_miner, minerId);
+ return command(cmd, minerObj, true);
+ }
+ else
+ {
+ }
+ }
+ return null;
+ }
+
+
+
+ /**
+ * Used at DataStore
initialization time to initialize the miners
+ *
+ * @return the status element for the initMiners command
+ */
+ public DataElement initMiners()
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_INIT_MINERS);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_INIT_MINERS, 1);
+
+ return command(cmd, _dummy);
+ }
+
+
+ public DataElement queryInstall()
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_QUERY_INSTALL);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_QUERY_INSTALL, 1);
+ return synchronizedCommand(cmd, _dummy);
+ }
+
+ public DataElement queryClientIP()
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_QUERY_CLIENT_IP);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_QUERY_INSTALL, 1);
+ return synchronizedCommand(cmd, _dummy);
+ }
+
+ public DataElement queryHostJVM()
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_QUERY_JVM);
+ return synchronizedCommand(cmd, _dummy);
+ }
+
+
+ public void runRemoteClassInstance(IRemoteClassInstance runnable)
+ {
+ getCommandHandler().sendClassInstance(runnable, ClassByteStreamHandler.class.getName());
+ }
+
+ /**
+ * Used at DataStore
initialization validate access to the DataStore
+ *
+ * @param ticketStr ticket string
+ * @return and indication of whether the ticket is valid or not
+ */
+ public boolean showTicket(String ticketStr)
+ {
+ DataElement ticket = createTicket(ticketStr);
+ DataElement status = queryShowTicket(ticket);
+
+ if (status != null)
+ {
+ waitUntil(status, DataStoreResources.model_done);
+ }
+ else
+ {
+ return true;
+ }
+
+ return ticketValid(ticket);
+ }
+
+ public boolean ticketValid(DataElement ticket)
+ {
+ return ticket.getAttribute(DE.A_VALUE).equals(DataStoreResources.model_valid);
+ }
+
+ public DataElement createTicket(String ticketStr)
+ {
+ if (ticketStr == null)
+ {
+ ticketStr = "null";
+ }
+ return createObject(_tempRoot, DataStoreResources.model_ticket, ticketStr);
+ }
+
+ public DataElement queryShowTicket(DataElement ticket)
+ {
+ DataElement cmd = findCommandDescriptor(DataStoreSchema.C_VALIDATE_TICKET);
+ DataElement status = _commandHandler.command(cmd, ticket, false);
+
+ if (ticket.getName().equals("null"))
+ {
+ return null;
+ }
+ return status;
+ }
+
+ /**
+ * Indicates whether a client has permission to access the DataStore
+ *
+ * @return and indication of whether the ticket is valid or not
+ */
+ public boolean validTicket()
+ {
+ if (_ticket.getAttribute(DE.A_VALUE).equals(DataStoreResources.model_valid))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ /**
+ * Wait until a given status element reached the specified state.
+ * This is used for issuing synchronized commands
+ *
+ * @param status the status element
+ * @param state the state to wait until
+ */
+ public void waitUntil(DataElement status, String state)
+ {
+ waitUntil(status, state, _timeout);
+ }
+
+ public boolean isWaiting(DataElement status)
+ {
+ return _waitingStatuses.contains(status);
+ }
+
+ public void stopWaiting(DataElement status)
+ {
+ _waitingStatuses.remove(status);
+ }
+
+ public void startWaiting(DataElement status)
+ {
+ _waitingStatuses.add(status);
+ }
+
+ public void waitUntil(DataElement status, String state, int timeout)
+ {
+ int timeToWait = 500;
+ int timeWaited = 0;
+ boolean timedOut = false;
+ startWaiting(status);
+
+ while ((status != null)
+ && (_status == null || _status.getName().equals("okay"))
+ && !status.getName().equals(state)
+ && !status.getValue().equals(state)
+ && !status.getName().equals(DataStoreResources.model_incomplete)
+ && !timedOut)
+ {
+ if ((timeout != -1) && (timeWaited > timeout))
+ {
+ // waited too long!
+ timedOut = true;
+ }
+
+ status.waitForUpdate(timeToWait);
+
+
+ timeWaited += timeToWait;
+
+ if (!isWaiting(status))
+ {
+ // stopped waiting
+ return;
+ }
+ }
+
+ stopWaiting(status);
+
+ if (timedOut)
+ {
+ status.setAttribute(DE.A_NAME, DataStoreResources.model_timeout);
+ }
+
+ }
+
+ public void cleanBadReferences(DataElement root)
+ {
+ }
+
+ /**
+ * Tells the command handler to cancel all pending commands.
+ */
+ public void cancelAllCommands()
+ {
+ _commandHandler.cancelAllCommands();
+ }
+
+ /**
+ * Creates and issues a synchronized command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @return the status of the command
+ */
+ public DataElement synchronizedCommand(DataElement commandDescriptor, DataElement dataObject)
+ {
+ return synchronizedCommand(commandDescriptor, dataObject, false);
+ }
+
+ /**
+ * Creates and issues a synchronized command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @param noRef and indication of whether the subject should be referenced or not
+ * @return the status of the command
+ */
+ public DataElement synchronizedCommand(DataElement commandDescriptor, DataElement dataObject, boolean noRef)
+ {
+ DataElement status = command(commandDescriptor, dataObject, noRef, true);
+ waitUntil(status, DataStoreResources.model_done);
+
+ return status;
+ }
+
+ /**
+ * Creates and issues a synchronized command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @param noRef and indication of whether the subject should be referenced or not
+ * @return the status of the command
+ */
+ public DataElement synchronizedCommand(DataElement commandDescriptor, ArrayList arguments, DataElement dataObject)
+ {
+ DataElement status = command(commandDescriptor, arguments, dataObject, true);
+ waitUntil(status, DataStoreResources.model_done);
+
+ return status;
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param arguments the arguments for the command
+ * @param dataObject the subject of the command
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, ArrayList arguments, DataElement dataObject)
+ {
+ return command(commandDescriptor, arguments, dataObject, false);
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param arguments the arguments for the command
+ * @param dataObject the subject of the command
+ * @param immediate indicates whether the command should be placed first on the request queue
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, ArrayList arguments, DataElement dataObject, boolean immediate)
+ {
+ if (_commandHandler != null)
+ {
+ return _commandHandler.command(commandDescriptor, arguments, dataObject, true, immediate);
+ }
+ return null;
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param arg an argument for the command
+ * @param dataObject the subject of the command
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, DataElement arg, DataElement dataObject)
+ {
+ return command(commandDescriptor, arg, dataObject, false);
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param arg an argument for the command
+ * @param dataObject the subject of the command
+ * @param immediate indicates whether the command should be placed first on the request queue
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, DataElement arg, DataElement dataObject, boolean immediate)
+ {
+ if (_commandHandler != null)
+ {
+ return _commandHandler.command(commandDescriptor, arg, dataObject, true, immediate);
+ }
+ return null;
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, DataElement dataObject)
+ {
+ return command(commandDescriptor, dataObject, false);
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @param noRef an indication of whether to reference the subject or not
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, DataElement dataObject, boolean noRef)
+ {
+ return command(commandDescriptor, dataObject, noRef, false);
+ }
+
+ /**
+ * Creates and issues a command.
+ *
+ * @param commandDescriptor the comamnd descriptor for the command
+ * @param dataObject the subject of the command
+ * @param noRef an indication of whether to reference the subject or not
+ * @param immediate an indication of whether
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandDescriptor, DataElement dataObject, boolean noRef, boolean immediate)
+ {
+ if (_commandHandler != null)
+ {
+ return _commandHandler.command(commandDescriptor, dataObject, !noRef);
+ }
+
+ return null;
+ }
+
+ /**
+ * Issues a command.
+ *
+ * @param commandObject an instance of a command
+ * @return the status of the command
+ */
+ public DataElement command(DataElement commandObject)
+ {
+ return _commandHandler.command(commandObject);
+ }
+
+ /**
+ * Delete information from the DataStore
.
+ *
+ */
+ public void flush()
+ {
+ // flush the whole thing
+ flush(_logRoot);
+ flush(_hostRoot);
+ flush(_minerRoot);
+ flush(_tempRoot);
+ }
+
+ /**
+ * Delete information from the DataStore
contained by an element.
+ *
+ * @param element the element from which to delete
+ */
+ public void flush(DataElement element)
+ {
+ if (element != null)
+ {
+ deleteObjects(element);
+ }
+ }
+
+ /**
+ * Find a command descriptor element in the schema with the given value.
+ *
+ * @param object the object descriptor representing the type of object that can issue such a command
+ * @param keyName the value of the command to search for
+ * @return the command descriptor for the specified command
+ */
+ public DataElement localDescriptorQuery(DataElement object, String keyName)
+ {
+ return localDescriptorQuery(object, keyName, 5);
+ }
+
+ /**
+ * Find a command descriptor element in the schema with the given value.
+ *
+ * @param object the object descriptor representing the type of object that can issue such a command
+ * @param keyName the value of the command to search for
+ * @param depth the depth of abstraction to search
+ * @return the command descriptor for the specified command
+ */
+ public DataElement localDescriptorQuery(DataElement descriptor, String keyName, int depth)
+ {
+ if ((descriptor != null) && (depth > 0))
+ {
+ for (int i = 0; i < descriptor.getNestedSize(); i++)
+ {
+ DataElement subDescriptor = (DataElement) descriptor.get(i).dereference();
+ String type = subDescriptor.getType();
+ if (type == null)
+ {
+ }
+ if (type.equals(DE.T_COMMAND_DESCRIPTOR))
+ {
+ if (keyName.equals(subDescriptor.getValue()))
+ return subDescriptor;
+ }
+ else if (type.equals(DE.T_ABSTRACT_COMMAND_DESCRIPTOR))
+ {
+ DataElement result = localDescriptorQuery(subDescriptor, keyName, depth - 1);
+ if (result != null)
+ return result;
+ }
+ }
+
+ DataElement abstractedBy = getAbstractedByRelation();
+ List abstractDescriptors = descriptor.getAssociated(abstractedBy);
+ int numInherited = abstractDescriptors.size();
+
+ for (int j = 0; j < numInherited; j++)
+ {
+ DataElement abstractDescriptor = (DataElement) abstractDescriptors.get(j);
+
+ DataElement result = localDescriptorQuery(abstractDescriptor, keyName, depth - 1);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void addToRecycled(DataElement toRecycle)
+ {
+ if (!_recycled.contains(toRecycle)) _recycled.add(0, toRecycle);
+ }
+
+ /**
+ * Finds the element that represents the miner that implements a particular command.
+ *
+ * @param commandDescriptor a command descriptor
+ * @return the element representing a miner
+ */
+ public DataElement getMinerFor(DataElement commandDescriptor)
+ {
+ String minerName = commandDescriptor.getSource();
+ DataElement theMinerElement = find(_minerRoot, DE.A_NAME, minerName, 1);
+ return theMinerElement;
+ }
+
+ /**
+ * Finds all the elements that are of a given type from a specified element.
+ *
+ * @param root where to search from
+ * @param type the descriptor representing the type of the objects to search for
+ * @return a list of elements
+ */
+ public List findObjectsOfType(DataElement root, DataElement type)
+ {
+ ArrayList results = new ArrayList();
+ List searchList = root.getAssociated(getContentsRelation());
+ if (searchList != null)
+ {
+ for (int i = 0; i < searchList.size(); i++)
+ {
+ DataElement child = (DataElement) searchList.get(i);
+ if (child.isOfType(type))
+ {
+ results.add(child);
+ }
+
+ List subResults = findObjectsOfType(child, type);
+ for (int j = 0; j < subResults.size(); j++)
+ {
+ results.add(subResults.get(j));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /**
+ * Finds all the elements that are of a given type from a specified element.
+ *
+ * @param root where to search from
+ * @param type the descriptor representing the type of the objects to search for
+ * @return a list of elements
+ */
+ public List findObjectsOfType(DataElement root, String type)
+ {
+ ArrayList results = new ArrayList();
+ List searchList = root.getAssociated(getContentsRelation());
+ if (searchList != null)
+ {
+ for (int i = 0; i < searchList.size(); i++)
+ {
+ DataElement child = (DataElement) searchList.get(i);
+ if (child.getType().equals(type) || child.isOfType(type))
+ {
+ results.add(child);
+ }
+
+ List subResults = findObjectsOfType(child, type);
+ for (int j = 0; j < subResults.size(); j++)
+ {
+ results.add(subResults.get(j));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /**
+ * Finds all the deleted elements
+ *
+ * @param root where to search from
+ * @param type the descriptor representing the type of the objects to search for
+ * @return a list of elements
+ */
+ public synchronized List findDeleted(DataElement root)
+ {
+ return findDeleted(root, 10);
+ }
+
+ /**
+ * Finds all the deleted elements
+ *
+ * @param root where to search from
+ * @param type the descriptor representing the type of the objects to search for
+ * @return a list of elements
+ */
+ public synchronized List findDeleted(DataElement root, int depth)
+ {
+ ArrayList results = new ArrayList();
+ synchronized (root)
+ {
+ if (root != null && root.getDataStore() == this)
+ {
+ if (results.contains(root))
+ {
+ return results;
+ }
+
+ if (root != null && root.isDeleted())
+ {
+ results.add(root);
+ }
+
+
+ List searchList = root.getNestedData();
+
+ if (searchList != null)
+ {
+ for (int i = 0; i < searchList.size(); i++)
+ {
+ DataElement child = (DataElement) searchList.get(i);
+ if (child != null)
+ {
+ synchronized (child)
+ {
+ if (child != null && child.isDeleted() && !results.contains(child))
+ {
+
+ results.add(child);
+ if (!child.isReference())
+ {
+ if (depth > 0)
+ {
+ List sResults = findDeleted(child, depth - 1);
+ for (int j = 0; j < sResults.size(); j++)
+ {
+ results.add(sResults.get(j));
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Finds all relationship descriptor types that can be applied to a particular element.
+ *
+ * @param descriptor the object descriptor that uses relationships
+ * @param fixateOn a filter for the type of relationships to look for
+ * @return a list of relationship descriptor elements
+ */
+ public ArrayList getRelationItems(DataElement descriptor, String fixateOn)
+ {
+ ArrayList result = new ArrayList();
+ if (descriptor != null)
+ {
+ // contained relationships
+ for (int i = 0; i < descriptor.getNestedSize(); i++)
+ {
+ DataElement object = ((DataElement) descriptor.get(i)).dereference();
+
+ String objType = (String) object.getElementProperty(DE.P_TYPE);
+ if (objType.equals(DE.T_RELATION_DESCRIPTOR) || objType.equals(DE.T_ABSTRACT_RELATION_DESCRIPTOR))
+ {
+ if (fixateOn != null)
+ {
+ String objName = (String) object.getElementProperty(DE.P_NAME);
+ if (objName.equals(fixateOn))
+ {
+ if (!result.contains(object))
+ result.add(object);
+ }
+ }
+ else
+ {
+ if (!result.contains(object))
+ result.add(object);
+ }
+ }
+ }
+
+ // abstracted relationships
+ List baseDescriptors = descriptor.getAssociated(getAbstractedByRelation());
+ for (int j = 0; j < baseDescriptors.size(); j++)
+ {
+
+ DataElement baseDescriptor = (DataElement) baseDescriptors.get(j);
+ ArrayList baseRelations = getRelationItems(baseDescriptor, fixateOn);
+ for (int k = 0; k < baseRelations.size(); k++)
+ {
+ DataElement relation = (DataElement) baseRelations.get(k);
+ if (!result.contains(relation))
+ {
+ result.add(relation);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+
+
+ /**
+ * Find all elements from a given element that match a certain attribute.
+ *
+ * @param root the element to search from
+ * @param attribute the index of the attribute to match
+ * @param pattern the value to compare with the attribute
+ * @param ignoreCase an indication whether to ignore case for the attribute or not
+ * @return the list of matches
+ */
+ public ArrayList searchForPattern(DataElement root, int attribute, String pattern, boolean ignoreCase)
+ {
+ int attributes[] = { attribute };
+ String patterns[] = { pattern };
+ return searchForPattern(root, attributes, patterns, 1, ignoreCase);
+ }
+
+ /**
+ * Find all elements from a given element that match a certain set of attributes.
+ *
+ * @param root the element to search from
+ * @param attributes a list of attributes to match
+ * @param patterns a list of values to compare with the attributes
+ * @param ignoreCase an indication whether to ignore case for the attributes or not
+ * @return the list of matches
+ */
+ public ArrayList searchForPattern(DataElement root, ArrayList attributes, ArrayList patterns, boolean ignoreCase)
+ {
+ int att[] = new int[attributes.size()];
+ String ptn[] = new String[attributes.size()];
+ for (int i = 0; i < attributes.size(); i++)
+ {
+ att[i] = ((Integer) attributes.get(i)).intValue();
+ ptn[i] = (String) (patterns.get(i));
+ }
+
+ return searchForPattern(root, att, ptn, attributes.size(), ignoreCase);
+ }
+
+ /**
+ * Find all elements from a given element that match a certain set of attributes.
+ *
+ * @param root the element to search from
+ * @param attributes a list of attribute indexes to match
+ * @param patterns a list of values to compare with the attributes
+ * @param numAttributes the number of attributes to match
+ * @param ignoreCase an indication whether to ignore case for the attributes or not
+ * @return the list of matches
+ */
+ public ArrayList searchForPattern(DataElement root, int attributes[], String patterns[], int numAttributes, boolean ignoreCase)
+ {
+ return searchForPattern(root, attributes, patterns, numAttributes, ignoreCase, 1);
+ }
+
+ /**
+ * Find all elements from a given element that match a certain set of attributes.
+ *
+ * @param root the element to search from
+ * @param attributes a list of attribute indexes to match
+ * @param patterns a list of values to compare with the attributes
+ * @param numAttributes the number of attributes to match
+ * @param ignoreCase an indication whether to ignore case for the attributes or not
+ * @param depth how deep to search
+ * @return the list of matches
+ */
+ public ArrayList searchForPattern(DataElement root, int attributes[], String patterns[], int numAttributes, boolean ignoreCase, int depth)
+ {
+ ArrayList searched = new ArrayList();
+ return searchForPattern(root, attributes, patterns, numAttributes, ignoreCase, depth, searched);
+ }
+
+ /**
+ * Find all elements from a given element that match a certain set of attributes.
+ *
+ * @param root the element to search from
+ * @param attributes a list of attribute indexes to match
+ * @param patterns a list of values to compare with the attributes
+ * @param numAttributes the number of attributes to match
+ * @param ignoreCase an indication whether to ignore case for the attributes or not
+ * @param depth how deep to search
+ * @param searched a list of objects already searched
+ * @return the list of matches
+ */
+ public ArrayList searchForPattern(DataElement root, int attributes[], String patterns[], int numAttributes, boolean ignoreCase, int depth, ArrayList searched)
+ {
+ ArrayList result = new ArrayList();
+ if (depth > 0)
+ {
+ for (int i = 0; i < root.getNestedSize(); i++)
+ {
+ DataElement child = (DataElement) root.get(i);
+ child = child.dereference();
+ if ((child != null) && !searched.contains(child))
+ {
+ searched.add(child);
+ if (child.patternMatch(attributes, patterns, numAttributes, ignoreCase))
+ {
+ result.add(child);
+ }
+
+ ArrayList subResults = searchForPattern(child, attributes, patterns, numAttributes, ignoreCase, depth - 1, searched);
+ for (int j = 0; j < subResults.size(); j++)
+ {
+ result.add(subResults.get(j));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the element that represents the specified miner's data.
+ *
+ * @param minerName the qualified name of the miner
+ * @return the element representing the miner information
+ */
+ public DataElement findMinerInformation(String minerName)
+ {
+ DataElement information = null;
+ DataElement minerElement = find(_minerRoot, DE.A_NAME, minerName, 1);
+ if (minerElement != null)
+ {
+ information = find(minerElement, DE.A_TYPE, DataStoreResources.model_data, 1);
+ }
+
+ return information;
+ }
+
+ /**
+ * Finds a descriptor element with a specified type and name.
+ *
+ * @param type the type of the descriptor
+ * @param name the name of the descriptor
+ * @return the found descriptor
+ */
+ public DataElement findDescriptor(String type, String name)
+ {
+ if (_descriptorRoot != null)
+ {
+ synchronized (_descriptorRoot)
+ {
+ if (type.equals(DE.T_OBJECT_DESCRIPTOR))
+ {
+ return (DataElement)_objDescriptorMap.get(name);
+ }
+ else if (type.equals(DE.T_COMMAND_DESCRIPTOR))
+ {
+ return (DataElement)_cmdDescriptorMap.get(name);
+
+ }
+ else if (type.equals(DE.T_RELATION_DESCRIPTOR))
+ {
+ return (DataElement)_relDescriptorMap.get(name);
+ }
+ else
+ {
+ for (int i = 0; i < _descriptorRoot.getNestedSize(); i++)
+ {
+ DataElement descriptor = _descriptorRoot.get(i);
+
+ if (descriptor.getName().equals(name) && descriptor.getType().equals(type))
+ {
+ return descriptor;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds an object descriptor element with a specified name.
+ *
+ * @param name the name of the descriptor
+ * @return the found descriptor
+ */
+ public DataElement findObjectDescriptor(String name)
+ {
+ return (DataElement)_objDescriptorMap.get(name);
+ }
+
+ /**
+ * Finds an relation descriptor element with a specified name.
+ *
+ * @param name the name of the descriptor
+ * @return the found descriptor
+ */
+ public DataElement findRelationDescriptor(String name)
+ {
+ return (DataElement)_relDescriptorMap.get(name);
+ }
+
+ /**
+ * Finds an command descriptor element with a specified name.
+ *
+ * @param name the name of the descriptor
+ * @return the found descriptor
+ */
+ public DataElement findCommandDescriptor(String name)
+ {
+ return (DataElement)_cmdDescriptorMap.get(name);
+ }
+
+ /**
+ * Finds an element with the specified ID.
+ *
+ * @param id the ID of the descriptor
+ * @return the found element
+ */
+ public DataElement find(String id)
+ {
+ DataElement result = (DataElement) _hashMap.get(id);
+ return result;
+ }
+
+ /**
+ * Finds an element matching a specified attribute and name.
+ *
+ * @param root the element to search from
+ * @param attribute the index of the attribute to compare
+ * @param name the name of the element
+ * @return the first found element
+ */
+ public DataElement find(DataElement root, int attribute, String name)
+ {
+ return find(root, attribute, name, 10);
+ }
+
+ /**
+ * Finds an element matching a specified attribute and name.
+ *
+ * @param root the element to search from
+ * @param attribute the index of the attribute to compare
+ * @param name the name of the element
+ * @param depth the depth of the search
+ * @return the first found element
+ */
+ public DataElement find(DataElement root, int attribute, String name, int depth)
+ {
+ if ((root != null) && (name != null) && !root.isReference() && depth > 0)
+ {
+
+ if (StringCompare.compare(name, root.getAttribute(attribute), false))
+ {
+ return root;
+ }
+ else if (depth > 0)
+ {
+ for (int h = 0; h < root.getNestedSize(); h++)
+ {
+ DataElement nestedObject = root.get(h);
+ String compareName = nestedObject.getAttribute(attribute);
+
+ if (!nestedObject.isReference() && (compareName != null))
+ {
+
+ if (name.compareTo(compareName) == 0)
+ {
+ return nestedObject;
+ }
+ else
+ {
+ DataElement foundObject = find(nestedObject, attribute, name, depth - 1);
+ if (foundObject != null)
+ {
+ return foundObject;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the mapping from a remote path to a local path.
+ *
+ * @param aPath the remote path
+ * @return the local path
+ */
+ public String mapToLocalPath(String aPath)
+ {
+ String result = null;
+
+ char slash = '/';
+ String remotePath = aPath.replace('\\', slash);
+ String localRoot = _dataStoreAttributes.getAttribute(DataStoreAttributes.A_LOCAL_PATH).replace('\\', slash);
+ String remoteRoot = getHostRoot().getSource().replace('\\', slash);
+
+ if (localRoot.equals(remoteRoot))
+ {
+ result = remotePath;
+ }
+ else if (remotePath.startsWith(localRoot))
+ {
+ result = remotePath;
+ }
+ else if (remotePath.startsWith(remoteRoot))
+ {
+ result = new String(localRoot + slash + remotePath.substring(remoteRoot.length(), remotePath.length()));
+ }
+ else
+ {
+ // file is outside of scope
+ // create temporary location
+ int indexOfDrive = remotePath.indexOf(":");
+ if (indexOfDrive > 0)
+ {
+ remotePath = remotePath.substring(indexOfDrive + 1, remotePath.length());
+ }
+
+ result = new String(localRoot + remotePath);
+ }
+
+ return result;
+ }
+
+ /**
+ * Persist the DataStore
tree from a given root
+ *
+ * @param root the element to persist from
+ * @param remotePath the path where the persisted file should be saved
+ * @param depth the depth of persistance from the root
+ */
+ public void saveFile(DataElement root, String remotePath, int depth)
+ {
+ remotePath = new String(remotePath.replace('\\', '/'));
+ String fileName = mapToLocalPath(remotePath);
+ try
+ {
+ // need to create directories as well
+ File file = new File(fileName);
+ try
+ {
+ file = file.getCanonicalFile();
+ }
+ catch (IOException e)
+ {
+ }
+
+ if (!file.exists())
+ {
+ File dir = new File(file.getParent());
+ dir.mkdirs();
+ file.createNewFile();
+ }
+
+ File newFile = new File(file.getCanonicalPath());
+
+ if (newFile.canWrite())
+ {
+ FileOutputStream fileStream = new FileOutputStream(newFile);
+ PrintStream fileWriter = new PrintStream(fileStream);
+ BufferedWriter dataWriter = new BufferedWriter(new OutputStreamWriter(fileStream, DE.ENCODING_UTF_8));
+
+ XMLgenerator generator = new XMLgenerator(this);
+ generator.setIgnoreDeleted(true);
+ generator.setFileWriter(fileWriter);
+ generator.setDataWriter(dataWriter);
+ generator.setBufferSize(1000);
+ generator.generate(root, depth);
+ generator.flushData();
+
+ fileStream.close();
+ }
+ }
+ catch (IOException e)
+ {
+ System.out.println(e);
+ }
+ }
+
+ /**
+ * Save a file in the specified location
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the buffer to save in the file
+ */
+ public void saveFile(String remotePath, byte[] buffer, int size, boolean binary)
+ {
+ getDefaultByteStreamHandler().receiveBytes(remotePath, buffer, size, binary);
+ }
+
+ /**
+ * Save a file in the specified location
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the buffer to save in the file
+ * @param byteStreamHandlerId indicates which byte stream handler to receive the bytes
+ */
+ public void saveFile(String remotePath, byte[] buffer, int size, boolean binary, String byteStreamHandlerId)
+ {
+
+ getByteStreamHandler(byteStreamHandlerId).receiveBytes(remotePath, buffer, size, binary);
+ }
+
+ /**
+ * Saves a class to memory (but not to disk) where it can then be loaded by
+ * the RemoteClassLoaders. The class will be saved in a new thread, so this method
+ * will potentially return before the class has been saved.
+ *
+ * @param className the fully qualified name of the class
+ * @param buffer the contents of the class
+ * @param size the size of the buffer
+ */
+ public void saveClass(String className, byte[] buffer, int size)
+ {
+ getDefaultClassByteStreamHandler().receiveBytes(className, buffer, size);
+ }
+
+
+ /**
+ * Saves a class instance
+ *
+ * @param className the fully qualified name of the class
+ * @param buffer the contents of the class
+ * @param size the size of the buffer
+ */
+ public void saveClassInstance(byte[] buffer, int size, String classbyteStreamHandlerId)
+ {
+ getDefaultClassByteStreamHandler().receiveInstanceBytes(buffer, size);
+ }
+
+
+ /**
+ * Saves a class to memory (but not to disk) where it can then be loaded by
+ * the RemoteClassLoaders. The class will be saved in a new thread, so this method
+ * will potentially return before the class has been saved.
+ *
+ * @param className the fully qualified name of the class
+ * @param buffer the contents of the class
+ * @param size the size of the buffer
+ * @param classbyteStreamHandlerId indicates which class byte stream handler to receive the bytes
+ */
+ public void saveClass(String className, byte[] buffer, int size, String classbyteStreamHandlerId)
+ {
+ getClassByteStreamHandler(classbyteStreamHandlerId).receiveBytes(className, buffer, size);
+ }
+
+ /**
+ * Append a file to the specified location
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the buffer to append into the file
+ */
+ public void appendToFile(String remotePath, byte[] buffer, int size, boolean binary)
+ {
+ getDefaultByteStreamHandler().receiveAppendedBytes(remotePath, buffer, size, binary);
+ }
+
+ /**
+ * Append a file to the specified location
+ *
+ * @param remotePath the path where to save the file
+ * @param buffer the buffer to append into the file
+ * @param byteStreamHandlerId indicates which byte stream handler to receive the bytes
+ */
+ public void appendToFile(String remotePath, byte[] buffer, int size, boolean binary, String byteStreamHandlerId)
+ {
+ getByteStreamHandler(byteStreamHandlerId).receiveAppendedBytes(remotePath, buffer, size, binary);
+ }
+
+ /**
+ * Load a persisted DataStore
tree into the specified DataElement
+ *
+ * @param root the root element of the persisted tree
+ * @param pathName the location of the persisted file
+ */
+ public void load(DataElement root, String pathName)
+ {
+ String fileName = pathName;
+
+ FileInputStream inFile = loadFile(fileName);
+ if (inFile != null)
+ {
+ BufferedInputStream document = new BufferedInputStream(inFile);
+
+ if (document != null)
+ {
+ try
+ {
+ XMLparser parser = new XMLparser(this);
+ DataElement subRoot = parser.parseDocument(document, null);
+ if (subRoot != null)
+ {
+ root.removeNestedData();
+ List nestedData = subRoot.getNestedData();
+ if (nestedData != null)
+ {
+ root.addNestedData(nestedData, true);
+ }
+ refresh(root);
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ }
+
+ public static FileInputStream loadFile(String fileName)
+ {
+ File file = new File(fileName);
+ if (file.exists() && (file.length() > 0))
+ {
+ try
+ {
+ FileInputStream inFile = new FileInputStream(file);
+
+ return inFile;
+ }
+ catch (FileNotFoundException e)
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Indicate whether a given descriptor can contain the specified element
+ *
+ * @param descriptor the object descriptor to test
+ * @param dataElement the object to test against
+ * @return and indication whether dataElement can be in an object of type descriptor
+ */
+ public boolean filter(DataElement descriptor, DataElement dataElement)
+ {
+ return filter(descriptor, dataElement, 2);
+ }
+
+ /**
+ * Indicate whether a given descriptor can contain the specified element
+ *
+ * @param descriptor the object descriptor to test
+ * @param dataElement the object to test against
+ * @param depth how far to search
+ * @return and indication whether dataElement can be in an object of type descriptor
+ */
+ public boolean filter(DataElement descriptor, DataElement dataElement, int depth)
+ {
+ if (depth > 0)
+ {
+ depth--;
+
+ String dataType = (String) dataElement.getElementProperty(DE.P_TYPE);
+ String typeStr = (String) descriptor.getElementProperty(DE.P_NAME);
+
+ if (((dataType != null) && (typeStr != null)) && (dataType.equals(typeStr) || typeStr.equals(DataStoreResources.model_all)))
+ {
+ return true;
+ }
+ else
+ {
+ for (int i = 0; i < descriptor.getNestedSize(); i++)
+ {
+ if (filter((DataElement) descriptor.get(i), dataElement, depth))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Indicate whether a given set of descriptors can contain the specified element
+ *
+ * @param descriptors the object descriptors to test
+ * @param dataElement the object to test against
+ * @return and indication whether dataElement can be in an object of type descriptor
+ */
+ public boolean filter(ArrayList descriptors, DataElement dataElement)
+ {
+ for (int i = 0; i < descriptors.size(); i++)
+ {
+ if (filter((DataElement) descriptors.get(i), dataElement))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Indicate whether an command is specified as transient
+ *
+ * @param commandObject the object descriptors to test
+ * @return and indication whether the command is transient
+ */
+ public boolean isTransient(DataElement commandObject)
+ {
+ boolean isTransient = false;
+ DataElement subject = (DataElement) commandObject.get(0);
+
+ DataElement subjectDescriptor = subject.getDescriptor();
+ if (subjectDescriptor != null)
+ {
+ DataElement minerElement = getMinerFor(commandObject);
+ DataElement transientObjects = find(minerElement, DE.A_TYPE, DataStoreResources.model_transient, 1);
+ if (transientObjects != null)
+ {
+ for (int i = 0; i < transientObjects.getNestedSize(); i++)
+ {
+ DataElement transientDescriptor = transientObjects.get(i).dereference();
+ if (transientDescriptor == subjectDescriptor)
+ {
+ isTransient = true;
+ }
+ }
+ }
+ }
+
+ return isTransient;
+ }
+
+ private void initializeDescriptors()
+ {
+ _dataStoreSchema.extendSchema(_descriptorRoot);
+ }
+
+ public void enableAutoRefresh(boolean flag)
+ {
+ _autoRefresh = flag;
+ }
+
+ public boolean isAutoRefreshOn()
+ {
+ return _autoRefresh;
+ }
+ /**
+ * getUserPreferencesDirectory() - returns directory on IFS where to store user settings
+ */
+ public String getUserPreferencesDirectory()
+ {
+ if (_userPreferencesDirectory == null) {
+
+ _userPreferencesDirectory = System.getProperty("user.home");
+ String userID = System.getProperty("user.name");
+
+ // append a '/' if not there
+ if ( _userPreferencesDirectory.length() == 0 ||
+ _userPreferencesDirectory.charAt( _userPreferencesDirectory.length() -1 ) != File.separatorChar ) {
+
+ _userPreferencesDirectory = _userPreferencesDirectory + File.separator;
+ }
+
+ _userPreferencesDirectory = _userPreferencesDirectory + ".eclipse" + File.separator +
+ "RSE" + File.separator + userID + File.separator;
+ File dirFile = new File(_userPreferencesDirectory);
+ if (!dirFile.exists()) {
+ dirFile.mkdirs();
+ }
+ }
+
+ return _userPreferencesDirectory;
+ }
+
+ private void initialize()
+ {
+ _lastCreatedElements = new ArrayList();
+ _minersLocations = new ArrayList();
+
+ _random = new Random(System.currentTimeMillis());
+
+ _objDescriptorMap = new HashMap(100);
+ _cmdDescriptorMap = new HashMap(100);
+ _relDescriptorMap = new HashMap(100);
+ _dataStorePreferences = new HashMap(10);
+
+ _hashMap = new HashMap(2 * _initialSize);
+ _recycled = new ArrayList(_initialSize);
+ initElements(_initialSize);
+
+ _timeout = 20000;
+ _autoRefresh = false;//true;
+
+
+ _dataStoreSchema = new DataStoreSchema(this);
+
+ String tracingProperty = System.getProperty("DSTORE_TRACING_ON");
+ if (tracingProperty != null && tracingProperty.equals("true"))
+ {
+ _tracingOn = true;
+ }
+ else
+ {
+ _tracingOn = false;
+ }
+
+ String logDir = getUserPreferencesDirectory();
+ if (_tracingOn)
+ {
+
+ _traceFileHandle = new File(logDir, ".dstoreTrace");
+
+ try
+ {
+ _traceFile = new RandomAccessFile(_traceFileHandle, "rw");
+ startTracing();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ //_remoteClassLoader = new RemoteClassLoader(this);
+ _classReqRepository = new HashMap();
+
+ _waitingStatuses = new ArrayList();
+
+ _byteStreamHandlerRegistry = new ByteStreamHandlerRegistry();
+ _classbyteStreamHandlerRegistry = new ClassByteStreamHandlerRegistry();
+ setDefaultByteStreamHandler();
+ setDefaultClassByteStreamHandler();
+
+ assignCacheJar();
+
+ registerLocalClassLoader(this.getClass().getClassLoader());
+ }
+
+
+ public IByteStreamHandler getDefaultByteStreamHandler()
+ {
+ return _byteStreamHandlerRegistry.getDefault();
+ }
+
+ public IClassByteStreamHandler getDefaultClassByteStreamHandler()
+ {
+ return _classbyteStreamHandlerRegistry.getDefault();
+ }
+
+ public IByteStreamHandler getByteStreamHandler(String id)
+ {
+ return _byteStreamHandlerRegistry.getByteStreamHandler(id);
+ }
+
+ public IClassByteStreamHandler getClassByteStreamHandler(String id)
+ {
+ return _classbyteStreamHandlerRegistry.getClassByteStreamHandler(id);
+ }
+
+ public void setRemoteIP(String remoteIP)
+ {
+ _remoteIP = remoteIP;
+ }
+
+ public String getRemoteIP()
+ {
+ return _remoteIP;
+ }
+
+ /**
+ * Sets the current ByteStreamHandler
to be the default.
+ */
+ public void setDefaultByteStreamHandler()
+ {
+ setDefaultByteStreamHandler(null);
+ }
+
+ /**
+ * Sets the current ClassByteStreamHandler
to be the default.
+ */
+ public void setDefaultClassByteStreamHandler()
+ {
+ setDefaultClassByteStreamHandler(null);
+ }
+
+ /**
+ * Sets the current ByteStreamHandler
to use for sending and receiving
+ * files.
+ * @param handler the ByteStreamHandler
to use
+ */
+ public void setDefaultByteStreamHandler(IByteStreamHandler handler)
+ {
+ if (handler == null)
+ {
+ DataElement log = null;
+ handler = new ByteStreamHandler(this, log);
+ }
+ _byteStreamHandlerRegistry.setDefaultByteStreamHandler(handler);
+ }
+
+ public RemoteClassLoader getRemoteClassLoader()
+ {
+ if (_remoteLoader == null)
+ {
+
+ _remoteLoader = new RemoteClassLoader(this);
+ }
+ return _remoteLoader;
+ }
+
+ /**
+ * Sets the current ClassByteStreamHandler
to use for sending and receiving
+ * classes.
+ * @param handler the ClassByteStreamHandler
to use
+ */
+ public void setDefaultClassByteStreamHandler(IClassByteStreamHandler handler)
+ {
+ if (handler == null)
+ {
+ DataElement log = null;
+ handler = new ClassByteStreamHandler(this, log);
+ }
+ _classbyteStreamHandlerRegistry.setDefaultClassByteStreamHandler(handler);
+ }
+
+ /**
+ * Registers a byte stream handler.
+ * @param handler the handler to register
+ */
+ public void registerByteStreamHandler(IByteStreamHandler handler)
+ {
+ _byteStreamHandlerRegistry.registerByteStreamHandler(handler);
+ }
+
+ /**
+ * Registers a class byte stream handler.
+ * @param handler the handler to register
+ */
+ public void registerClassByteStreamHandler(IClassByteStreamHandler handler)
+ {
+ _classbyteStreamHandlerRegistry.registerClassByteStreamHandler(handler);
+ }
+
+ public void setByteConverter(IByteConverter converter)
+ {
+ _byteConverter = converter;
+ }
+
+ public IByteConverter getByteConverter()
+ {
+ if (_byteConverter == null)
+ {
+ _byteConverter = new DefaultByteConverter();
+ }
+ return _byteConverter;
+ }
+
+
+ /**
+ * Preallocates a set of DataElement
s.
+ *
+ * @param the number of elements to preallocate
+ */
+ private void initElements(int size)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ _recycled.add(new DataElement(this));
+ }
+ }
+
+ /**
+ * Returns a new DataElement
by either using an existing preallocated DataElement
or
+ * by creating a new one.
+ *
+ * @return the new DataElement
+ */
+ private synchronized DataElement createElement()
+ {
+ DataElement newObject = null;
+
+ int numRecycled = _recycled.size();
+
+ if (numRecycled > 1)
+ {
+ synchronized (_recycled)
+ {
+
+ /*
+ if (numRecycled > _MAX_FREE)
+ {
+ int numRemoved = numRecycled - _MAX_FREE;
+ for (int i = 1; i <= numRemoved; i++)
+ {
+ DataElement toRemove = (DataElement)_recycled.remove(numRemoved - i);
+ toRemove = null;
+ }
+ }
+ */
+
+ newObject = (DataElement) _recycled.remove((_recycled.size() - 1));
+ }
+ }
+ else
+ {
+ newObject = new DataElement(this);
+ }
+
+ newObject.setUpdated(false);
+ updateLastCreated(newObject);
+ return newObject;
+ }
+
+ private void updateLastCreated(DataElement element)
+ {
+ _lastCreatedElements.add(0, element);
+ if (_lastCreatedElements.size() > 4)
+ {
+ for (int i = _lastCreatedElements.size() - 1; i > 4; i--)
+ {
+ _lastCreatedElements.remove(i);
+ }
+ }
+ }
+
+ public List getLastCreatedElements()
+ {
+ return _lastCreatedElements;
+ }
+
+ private void createRoots()
+ {
+ _externalRoot = createObject(_root, DataStoreResources.model_host, "External DataStores", "", "extID");
+
+ _tempRoot = createObject(_root, "temp", "Temp Root", "", "tempID");
+ _dummy = createObject(_root, "temp", "dummy");
+ _logRoot = createObject(_root, DataStoreResources.model_log, DataStoreResources.model_Log_Root, "", "logID");
+
+ _minerRoot = createObject(_root, DataStoreResources.model_miners, DataStoreResources.model_Tool_Root, "", "minersID");
+
+ _hostRoot =
+ createObject(
+ _root,
+ DataStoreResources.model_host,
+ _dataStoreAttributes.getAttribute(DataStoreAttributes.A_HOST_NAME),
+ _dataStoreAttributes.getAttribute(DataStoreAttributes.A_HOST_PATH),
+ "hostID");
+
+ _status = createObject(_root, DataStoreResources.model_status, "okay", "", "statusID");
+ }
+
+ private void deleteObjectHelper(DataElement from, DataElement toDelete, int depth)
+ {
+ if (depth > 0)
+ {
+ depth--;
+ toDelete.delete();
+ for (int i = 0; i < toDelete.getNestedSize(); i++)
+ {
+ DataElement subDelete = toDelete.get(i);
+ if (subDelete != null && subDelete.getDataStore() == this && !subDelete.isDeleted())
+ {
+ deleteObjectHelper(toDelete, subDelete, depth);
+ }
+ }
+
+ String id = toDelete.getAttribute(DE.A_ID);
+ _hashMap.remove(id);
+
+ }
+ }
+
+ private String makeIdUnique(String id)
+ {
+
+ if (!_hashMap.containsKey(id))
+ {
+ return id;
+ }
+ else
+ {
+ return generateId();
+ /*
+ String newId = String.valueOf(_random.nextInt());
+ while (_hashMap.containsKey(newId))
+ {
+ newId = String.valueOf(_random.nextInt());
+ }
+
+ return newId;
+ */
+ }
+
+
+ }
+
+ private String generateId(DataElement parent, String type, String name)
+ {
+ // by default, name will be the id
+ //return name;
+ return generateId();
+ }
+
+ /**
+ * Generates a new unique ID to be used by a DataElement
+ *
+ * @return the new id
+ */
+ protected String generateId()
+ {
+ //return "" + _uniqueNumber++;
+ ///*
+ String newId = String.valueOf(_random.nextInt());
+ while (_hashMap.containsKey(newId))
+ {
+ newId = String.valueOf(_random.nextInt());
+ }
+
+ return newId;
+// */
+ }
+
+ public void startTracing()
+ {
+ if (_tracingOn && _traceFile != null && _traceFileHandle != null)
+ {
+ try
+ {
+ _traceFile.seek(_traceFileHandle.length());
+ }
+ catch (IOException e)
+ {
+ }
+
+ trace("-----------------------------------------");
+ trace("Start Tracing at " + System.currentTimeMillis());
+ }
+ }
+
+ public void trace(String str)
+ {
+ internalTrace(str);
+ }
+
+ public void trace(Throwable e)
+ {
+ internalTrace(e.getMessage());
+ internalTrace(e);
+ }
+
+ private void internalTrace(Throwable e)
+ {
+ if (_tracingOn && _traceFile != null && e != null)
+ {
+ try
+ {
+ StackTraceElement[] stack = e.getStackTrace();
+ for (int i = 0;iextendSchema
on
+ * each of the registered schema extenders.
+ * @param dataStore the DataStore for which the schema will be extended
+ */
+ public void extendSchema(DataStore dataStore);
+
+ /**
+ * Returns an ExternalLoader
for the specified qualified class name
+ * @param qualfiedClassName the qualified class name of an external tool
+ * @return the external loader that can load to specified class
+ */
+ public ExternalLoader getLoaderFor(String qualifiedClassName);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/SchemaRegistry.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/SchemaRegistry.java
new file mode 100644
index 00000000000..3ec32b76aec
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/SchemaRegistry.java
@@ -0,0 +1,91 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.util.ExternalLoader;
+
+/**
+ * SchemaRegistry implements the interface for external tools to contribute their
+ * schemas to the DataStore.
+ */
+public class SchemaRegistry implements ISchemaRegistry
+{
+
+
+ private ArrayList _initializedDataStores = new ArrayList();
+ private ArrayList _extenders = new ArrayList();
+
+ /**
+ * Registers a schema extender with the associated DataStores
+ * @param extender the schema extender to register
+ */
+ public void registerSchemaExtender(ISchemaExtender extender)
+ {
+ if (!_extenders.contains(extender))
+ {
+ _extenders.add(extender);
+ for (int i = 0; i < _initializedDataStores.size(); i++)
+ {
+ DataStore dataStore = (DataStore) _initializedDataStores.get(i);
+ DataElement schemaRoot = dataStore.getDescriptorRoot();
+ extender.extendSchema(schemaRoot);
+ }
+ }
+ }
+
+ /**
+ * Calls extendSchema() on each of the registered schema extenders to
+ * extend the schema of the specified DataStore
+ *
+ * @param dataStore the DataStore whos schema will be updated
+ */
+ public void extendSchema(DataStore dataStore)
+ {
+ if (!_initializedDataStores.contains(dataStore))
+ {
+ DataElement schemaRoot = dataStore.getDescriptorRoot();
+ for (int i = 0; i < _extenders.size(); i++)
+ {
+ ISchemaExtender extender = (ISchemaExtender) _extenders.get(i);
+ extender.extendSchema(schemaRoot);
+ }
+ _initializedDataStores.add(dataStore);
+ }
+ }
+
+ /**
+ * Gets the ExternalLoader
for the specified qualified classname
+ *
+ * @param source the qualified classname
+ * @return the external loader for the specified classname
+ */
+ public ExternalLoader getLoaderFor(String source)
+ {
+ for (int i = 0; i < _extenders.size(); i++)
+ {
+ ISchemaExtender extender = (ISchemaExtender) _extenders.get(i);
+ ExternalLoader loader = extender.getExternalLoader();
+ if (loader.canLoad(source))
+ {
+ return loader;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/UpdateHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/UpdateHandler.java
new file mode 100644
index 00000000000..4b4c27352b7
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/UpdateHandler.java
@@ -0,0 +1,262 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+
+
+/**
+ * UpdateHandler
is a Handler
that
+ * contains a queue of data responses to be sent to the client. Each DataStore instance uses a single
+ * update handler that periodically sends it's data queue either to a client or directly
+ * to a domain listener on the client.
+ * ISchemaRegistry
used for
+ * loading and initializing miners.
+ */
+public class MinerLoader implements ISchemaRegistry
+{
+
+
+ private DataStore _dataStore;
+ private ArrayList _miners;
+ private ArrayList _minerList;
+ private ArrayList _minerFileList;
+ private ArrayList _connectedList;
+ private ArrayList _loaders;
+ private RemoteClassLoader _remoteLoader;
+ private ExternalLoader _externalRemoteLoader;
+
+ /**
+ * Constructor
+ *
+ * @param dataStore the associated DataStore
+ * @param loaders the list of ExternalLoader
s used be the miner loader
+ */
+ public MinerLoader(DataStore dataStore, ArrayList loaders)
+ {
+ _dataStore = dataStore;
+ _loaders = loaders;
+ _miners = new ArrayList();
+ _minerList = new ArrayList();
+ _minerFileList = new ArrayList();
+ _connectedList = new ArrayList();
+ }
+
+ /**
+ * Loads all miners that are specified in the default minerFile.dat as
+ * well as any others indicated by DataStore.getMinersLocation
that
+ * have not yet been loaded.
+ */
+ public void loadMiners()
+ {
+ // load the miners
+ String pluginDir = _dataStore.getAttribute(DataStoreAttributes.A_PLUGIN_PATH);
+
+ // default location
+ String defaultMinerFile = pluginDir + File.separator + "minerFile.dat";
+ File defaultMF = new File(defaultMinerFile);
+ if (defaultMF.exists())
+ {
+ try
+ {
+ loadMiners(defaultMinerFile, DE.ENCODING_UTF_8);
+ }
+ catch (Exception e)
+ {
+ _dataStore.trace("failed to load minerFile.data with UTF-8. Trying with native encoding");
+
+ try
+ {
+ loadMiners(defaultMinerFile, null);
+ }
+ catch (Exception ex)
+ {
+ _dataStore.trace(ex);
+ }
+ }
+ _minerFileList.add(defaultMinerFile);
+ }
+
+ ArrayList minerLocations = _dataStore.getMinersLocation();
+
+ for (int i = 0; i < minerLocations.size(); i++)
+ {
+ String minersDir = (String) minerLocations.get(i);
+ String minerFile = null;
+ if (minersDir.endsWith(".dat"))
+ {
+ minerFile = pluginDir + File.separator + minersDir;
+ }
+ else
+ {
+ minerFile = pluginDir + File.separator + minersDir + File.separator + "minerFile.dat";
+ }
+ //_dataStore.trace("load miners for " + minerFile);
+ if (!_minerFileList.contains(minerFile))
+ {
+ try
+ {
+ loadMiners(minerFile, DE.ENCODING_UTF_8);
+ }
+ catch (Exception e)
+ {
+ _dataStore.trace("failed to load minerFile.data with UTF-8. Trying with native encoding");
+ try
+ {
+ loadMiners(minerFile, null);
+ }
+ catch (Exception ex)
+ {
+ _dataStore.trace(ex);
+ }
+ }
+ _minerFileList.add(minerFile);
+ }
+ }
+ }
+
+ /**
+ * Loads that miners specified in a particular miner configuration file (i.e. minerFile.dat)
+ * @param minerFile a file specifying a list of miners
+ * @return a list of the loaded miners
+ */
+ public ArrayList loadMiners(String minerFile, String encoding) throws Exception
+ {
+ // load the miners
+ ArrayList unconnectedMiners = new ArrayList();
+ File file = new File(minerFile);
+
+ FileInputStream inFile = new FileInputStream(file);
+ BufferedReader in = null;
+ if (encoding == null)
+ {
+ in = new BufferedReader(new InputStreamReader(inFile));
+ }
+ else
+ {
+ in = new BufferedReader(new InputStreamReader(inFile, encoding));
+ }
+
+ String name = null;
+ while ((name = in.readLine()) != null)
+ {
+ // check name
+ name = name.trim();
+
+ if (!name.startsWith("#") && (name.length() > 5))
+ {
+ Miner miner = loadMiner(name);
+ if (miner != null)
+ {
+ unconnectedMiners.add(miner);
+ }
+ }
+ }
+
+ connectMiners(unconnectedMiners);
+ return _miners;
+ }
+
+
+
+ public Miner loadMiner(String name)
+ {
+ Miner miner = null;
+ if (!_minerList.contains(name))
+ {
+ // only load new miners
+ try
+ {
+ ExternalLoader loader = getLoaderFor(name);
+ if (loader != null)
+ {
+ // try to load and instantiate the miner
+ // the RemoteClassLoader will kick off a synchronous
+ // request to the client for any classes that cannot be found
+ // on the host.
+ Class theClass = loader.loadClass(name);
+ miner = (Miner) theClass.newInstance();
+ if (miner != null)
+ {
+ miner.setExternalLoader(loader);
+ _minerList.add(name);
+ }
+ }
+ }
+ catch (NoClassDefFoundError e)
+ {
+ e.printStackTrace();
+ handleNoClassFound(e.getMessage().replace('/','.'));
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ handleNoClassFound(name);
+ }
+ catch (InstantiationException e)
+ {
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ }
+ return miner;
+ }
+
+ private void handleNoClassFound(String name)
+ {
+ _remoteLoader.loadClassInThread(name);
+ }
+
+ private void connectMiners(ArrayList unconnectedMiners)
+ {
+ // init list
+ for (int i = 0; i < _miners.size(); i++)
+ {
+ _connectedList.add(((Miner) _miners.get(i)).getMinerName());
+ }
+
+ while (unconnectedMiners.size() > 0)
+ {
+ Miner miner = (Miner) unconnectedMiners.get(0);
+ unconnectedMiners.remove(miner);
+ if (connectMiner(miner))
+ {
+ _dataStore.trace("connected " + miner.getMinerName());
+ }
+ else
+ {
+ unconnectedMiners.add(miner);
+ }
+ }
+
+ }
+
+ public boolean connectMiner(Miner miner)
+ {
+ boolean canConnect = true;
+ ArrayList dependencies = miner.getMinerDependencies();
+ for (int i = 0; i < dependencies.size(); i++)
+ {
+ String dependency = (String) dependencies.get(i);
+ if (!_connectedList.contains(dependency))
+ {
+ canConnect = false;
+ }
+ }
+
+ if (canConnect)
+ {
+ // set the datastore for the miner
+ miner.setDataStore(_dataStore);
+ miner.extendSchema(_dataStore.getDescriptorRoot());
+ _dataStore.refresh(_dataStore.getDescriptorRoot());
+ _miners.add(miner);
+ _connectedList.add(miner.getMinerName());
+ miner.start();
+ }
+ return canConnect;
+ }
+
+ /**
+ * Currently not used for the miner loader
+ */
+ public void registerSchemaExtender(ISchemaExtender extender)
+ {
+ }
+
+ /**
+ * Calls extendSchema
on each of the loaded miners
+ *
+ * @param dataStore the DataStore containing the base schema to extend
+ */
+ public void extendSchema(DataStore dataStore)
+ {
+ DataElement schemaRoot = dataStore.getDescriptorRoot();
+ for (int i = 0; i < _miners.size(); i++)
+ {
+ Miner miner = (Miner) _miners.get(i);
+ miner.extendSchema(schemaRoot);
+ }
+
+ }
+
+ public ExternalLoader getExternalRemoteLoader()
+ {
+ if (_externalRemoteLoader == null)
+ {
+ _externalRemoteLoader = new ExternalLoader(getRemoteLoader(), "*");
+ }
+ return _externalRemoteLoader;
+ }
+
+ public RemoteClassLoader getRemoteLoader()
+ {
+ return _dataStore.getRemoteClassLoader();
+ }
+
+ /**
+ * Returns the ExternalLoader
for a particular
+ * class.
+ *
+ * @param source a qualified classname
+ * @return the loader for the specified class
+ */
+ public ExternalLoader getLoaderFor(String source)
+ {
+ ExternalLoader remoteLoader = getExternalRemoteLoader();
+
+ // for now we always return the RemoteClassLoader
+
+ //if (remoteLoader.canLoad(source))
+ if(true)
+ {
+ //System.out.println("using RemoteClassLoader");
+ return remoteLoader;
+ }
+
+ for (int i = 0; i < _loaders.size(); i++)
+ {
+ ExternalLoader loader = (ExternalLoader) _loaders.get(i);
+ if (loader.canLoad(source))
+ {
+ // System.out.println("using local loader");
+ return loader;
+ }
+ else
+ {
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the loaded miners
+ *
+ * @return the loaded miners
+ */
+ public ArrayList getMiners()
+ {
+ return _miners;
+ }
+
+ /**
+ * Returns the miner indicated with the specified name
+ *
+ * @param name the qualified classname of the miner
+ * @return the miner
+ */
+ public Miner getMiner(String name)
+ {
+ for (int i = 0; i < _miners.size(); i++)
+ {
+ Miner miner = (Miner) _miners.get(i);
+ if (miner.getClass().getName().equals(name))
+ {
+ return miner;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Terminates the specified miner
+ *
+ * @param name the qualified classname of the miner to terminate
+ */
+ public void finishMiner(String name)
+ {
+ Miner miner = getMiner(name);
+ miner.finish();
+ _miners.remove(miner);
+ }
+
+ /**
+ * Terminate all the miners
+ */
+ public void finishMiners()
+ {
+ for (int i = 0; i < _miners.size(); i++)
+ {
+ Miner miner = (Miner) _miners.get(i);
+ miner.finish();
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/Server.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/Server.java
new file mode 100644
index 00000000000..bb1fee65f89
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/Server.java
@@ -0,0 +1,158 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.util.StringTokenizer;
+
+/**
+ * Server is the standard way of instantiating and controlling a remote DataStore.
+ * The server runs a ConnectionEstablisher which manages client connections to
+ * the DataStore.
+ *
+ */
+public class Server
+{
+
+ private ConnectionEstablisher _establisher;
+
+ /**
+ * The startup interface to run the Server.
+ *
+ * @param args a list of arguments for running the server. These consist of
+ * the socket port to wait on, the timeout value, and the the ticket
+ */
+ public static void main(String[] args)
+ {
+
+ String jversion = System.getProperty("java.version");
+
+ StringTokenizer tokenizer = new StringTokenizer(jversion, ".");
+ try
+ {
+ String[] vers = new String[3];
+ vers[0] = tokenizer.nextToken();
+ vers[1] = tokenizer.nextToken();
+
+ int version = Integer.parseInt(vers[0]);
+ int major = Integer.parseInt(vers[1]);
+
+
+ if (version >= 1 && major >= 4)
+ {
+ // version is good
+ }
+ else
+ {
+ // version is bad
+ System.err.println(ServerReturnCodes.RC_JRE_VERSION_ERROR);
+ System.exit(-1);
+ }
+ }
+ catch (Exception e)
+ {
+ // version is bad
+ System.err.println(ServerReturnCodes.RC_JRE_VERSION_ERROR);
+ System.exit(-1);
+ }
+
+ try
+ {
+ Server theServer = null;
+ switch (args.length)
+ {
+ case 0 :
+ theServer = new Server();
+ break;
+ case 1 :
+ theServer = new Server(args[0]);
+ break;
+ case 2 :
+ theServer = new Server(args[0], args[1]);
+ break;
+ case 3 :
+ theServer = new Server(args[0], args[1], args[2]);
+ break;
+ default :
+ break;
+ }
+
+
+ if (theServer != null)
+ {
+ theServer.run();
+ }
+ }
+ catch (SecurityException e)
+ {
+ System.err.println(ServerReturnCodes.RC_SECURITY_ERROR);
+ throw e; // Optional
+ }
+ }
+
+ /**
+ * Creates a new Server with default DataStore and connection attributes.
+ *
+ */
+ public Server()
+ {
+ _establisher = new ConnectionEstablisher();
+ }
+
+ /**
+ * Creates a new Server that waits on the specified socket port.
+ *
+ * @param port the number of the socket port to wait on
+ */
+ public Server(String port)
+ {
+ _establisher = new ConnectionEstablisher(port);
+ }
+
+ /**
+ * Creates a new Server that waits on the specified socket port for
+ * the specified time interval before shutting down.
+ *
+ * @param port the number of the socket port to wait on
+ * @param timeout the idle time to wait before shutting down
+ */
+ public Server(String port, String timeout)
+ {
+ _establisher = new ConnectionEstablisher(port, timeout);
+ }
+
+ /**
+ * Creates a new Server that waits on the specified socket port for
+ * the specified time interval before shutting down.
+ *
+ * @param port the number of the socket port to wait on
+ * @param timeout the idle time to wait before shutting down
+ * @param ticket the ticket that the client needs to interact with the DataStore
+ */
+ public Server(String port, String timeout, String ticket)
+ {
+ _establisher = new ConnectionEstablisher(port, timeout, ticket);
+ }
+
+
+ /**
+ * Runs the server by starting the ConnectionEstablisher
+ */
+ public void run()
+ {
+ _establisher.start();
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerAttributes.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerAttributes.java
new file mode 100644
index 00000000000..84af717ca5c
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerAttributes.java
@@ -0,0 +1,72 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.eclipse.dstore.core.model.DataStoreAttributes;
+
+/**
+ * This class is used to store attributes that are required
+ * for configurating a remote connection.
+ */
+public class ServerAttributes extends DataStoreAttributes
+{
+
+ /**
+ * Constructor
+ */
+ public ServerAttributes()
+ {
+ super();
+
+ try
+ {
+ String pluginPath = System.getProperty("A_PLUGIN_PATH");
+ if (pluginPath != null) pluginPath = pluginPath.trim();
+ if ((pluginPath != null) && (pluginPath.length() > 0))
+ {
+ File f = new File(pluginPath);
+ try
+ {
+ pluginPath = f.getCanonicalPath();
+ }
+ catch (Exception e)
+ {
+ pluginPath = f.getAbsolutePath();
+ }
+
+ setAttribute(A_PLUGIN_PATH, pluginPath + File.separator);
+ }
+ else
+ {
+ setAttribute(A_PLUGIN_PATH, "/home/");
+ }
+
+ setAttribute(A_LOCAL_NAME, InetAddress.getLocalHost().getHostName());
+
+ setAttribute(A_HOST_NAME, "server_host");
+ setAttribute(A_HOST_PATH, "/home/");
+ }
+ catch (UnknownHostException e)
+ {
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerCommandHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerCommandHandler.java
new file mode 100644
index 00000000000..47b0d99b042
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerCommandHandler.java
@@ -0,0 +1,492 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.miners.miner.Miner;
+import org.eclipse.dstore.core.model.CommandHandler;
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.dstore.core.model.DataStoreAttributes;
+import org.eclipse.dstore.core.model.DataStoreResources;
+import org.eclipse.dstore.core.model.DataStoreSchema;
+
+/**
+ * The ServerCommandHandler is reponsible for maintaining
+ * a queue of commands and periodically routing commands
+ * from the queue to the appropriate miners.
+ */
+public class ServerCommandHandler extends CommandHandler
+{
+
+
+ private ArrayList _loaders;
+ private MinerLoader _minerLoader;
+
+ /**
+ * Constructor
+ *
+ * @param loaders a list of ExternalLoader
s used for loading miners
+ */
+ public ServerCommandHandler(ArrayList loaders)
+ {
+ super();
+ _loaders = loaders;
+ }
+
+ /**
+ * Sets the associated DataStore
+ *
+ * @param dataStore the associated DataStore
+ */
+ public void setDataStore(DataStore dataStore)
+ {
+ super.setDataStore(dataStore);
+ }
+
+ /**
+ * Loads the miners
+ */
+ public void loadMiners()
+ {
+ if (_dataStore != null)
+ {
+ if (_minerLoader == null)
+ {
+ _minerLoader = new MinerLoader(_dataStore, _loaders);
+ }
+ // load the miners
+ _minerLoader.loadMiners();
+
+ }
+ }
+
+ public Miner loadMiner(String minerId)
+ {
+
+ if (_dataStore != null)
+ {
+ if (_minerLoader == null)
+ {
+ _minerLoader = new MinerLoader(_dataStore, _loaders);
+ }
+
+ // load and connect the miner
+ Miner miner = _minerLoader.loadMiner(minerId);
+ if (miner != null)
+ {
+ _minerLoader.connectMiner(miner);
+ }
+ return miner;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the list of loaded miners
+ *
+ * @return the list of miners
+ */
+ public ArrayList getMiners()
+ {
+ return _minerLoader.getMiners();
+ }
+
+ /**
+ * Returns the specified miner
+ *
+ * @param name the qualified classname of the miner to return
+ * @return the miner
+ */
+ public Miner getMiner(String name)
+ {
+ return _minerLoader.getMiner(name);
+ }
+
+ /**
+ * Terminates a specified miner
+ *
+ * @param name the qualified classname of the miner to terminate
+ */
+ public void finishMiner(String name)
+ {
+ _minerLoader.finishMiner(name);
+ }
+
+ /**
+ * Called when the DataStore session is finished or when there is
+ * an unexpected error.
+ */
+ public void finish()
+ {
+ if (_minerLoader != null)
+ _minerLoader.finishMiners();
+ super.finish();
+ }
+
+ private void clearDeleted(DataElement element, int depth)
+ {
+ if (depth > 0 && element != null)
+ {
+ for (int i = 0; i < element.getNestedSize(); i++)
+ {
+ DataElement child = element.get(i);
+ if (child != null)
+ {
+ if (child.isReference())
+ child = child.dereference();
+
+
+ if (child != null)
+ {
+ if (child.isDeleted())
+ {
+ element.removeNestedData(child);
+ }
+ else
+ {
+ clearDeleted(child, depth - 1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Called periodically to route the current queue of commands to the appropriate miners
+ */
+ public void sendCommands()
+ {
+ // send commands to the appropriate miners
+ while (_commands.size() > 0)
+ {
+ DataElement command = null;
+
+ synchronized (_commands)
+ {
+ command = (DataElement) _commands.get(0);
+ clearDeleted(command, 2);
+ _commands.remove(command);
+ }
+
+ //DKM-status is always last
+ DataElement status = command.get(command.getNestedSize() - 1);
+ //_dataStore.find(command, DE.A_TYPE,DataStoreResources.model_status"), 1);
+
+ String commandSource = command.getSource();
+ String commandName = command.getName();
+ _dataStore.trace("command: " + commandName);
+ //System.out.println(commandName);
+
+
+ if (commandName.equals(DataStoreSchema.C_VALIDATE_TICKET))
+ {
+ DataElement serverTicket = _dataStore.getTicket();
+ DataElement clientTicket = (DataElement) command.get(0);
+ String st = serverTicket.getName();
+ String ct = clientTicket.getName();
+ if (ct.equals(st))
+ {
+ serverTicket.setAttribute(DE.A_VALUE,DataStoreResources.model_valid);
+ clientTicket.setAttribute(DE.A_VALUE,DataStoreResources.model_valid);
+
+ DataElement host = _dataStore.getHostRoot();
+ _dataStore.getHashMap().remove(host.getId());
+ host.setAttribute(DE.A_ID, "host." + serverTicket.getName());
+
+ _dataStore.getHashMap().put(host.getId(), host);
+ _dataStore.update(host);
+ }
+ else
+ {
+ serverTicket.setAttribute(DE.A_VALUE,DataStoreResources.model_invalid);
+ clientTicket.setAttribute(DE.A_VALUE,DataStoreResources.model_invalid);
+ }
+ _dataStore.update(clientTicket);
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_SET))
+ {
+ DataElement dataObject = (DataElement) command.get(0);
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_MODIFY))
+ {
+ DataElement dataObject = (DataElement) command.get(0);
+ DataElement original = _dataStore.find(dataObject.getId());
+ original.setAttributes(dataObject.getAttributes());
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_SET_HOST))
+ {
+ DataElement dataObject = (DataElement) command.get(0);
+
+ DataElement original = _dataStore.getHostRoot();
+ original.setAttributes(dataObject.getAttributes());
+
+ _dataStore.setAttribute(DataStoreAttributes.A_LOCAL_PATH, dataObject.getSource());
+ _dataStore.setAttribute(DataStoreAttributes.A_HOST_PATH, dataObject.getSource());
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_ADD_MINERS))
+ {
+ DataElement location = (DataElement) command.get(1);
+ _dataStore.addMinersLocation(location);
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_ACTIVATE_MINER))
+ {
+ DataElement minerId = (DataElement) command.get(0);
+ String minerName = minerId.getName();
+ Miner miner = loadMiner(minerName);
+ miner.initMiner(status);
+ //System.out.println("finished initing "+miner.getMinerName());
+ //status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_SET_PREFERENCE))
+ {
+ DataElement dataObject = (DataElement) command.get(0);
+ String property = dataObject.getName();
+ String value = dataObject.getValue();
+ _dataStore.setPreference(property, value);
+ }
+ else if (commandName.equals(DataStoreSchema.C_QUERY_INSTALL))
+ {
+ // determine where dstore is located
+ status.setAttribute(DE.A_SOURCE, _dataStore.getAttribute(DataStoreAttributes.A_PLUGIN_PATH));
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_QUERY_CLIENT_IP))
+ {
+ // determine where dstore is connected to
+ status.setAttribute(DE.A_SOURCE, _dataStore.getRemoteIP());
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_QUERY_JVM))
+ {
+ // get jvm stats
+ // check memory consuption
+ // if we're running low, try to free some
+ Runtime runtime = Runtime.getRuntime();
+ runtime.gc();
+ long freeMem = runtime.freeMemory();
+ long totalMem = runtime.totalMemory();
+ long maxMem = runtime.maxMemory();
+
+
+ StringBuffer statsBuffer = new StringBuffer();
+ statsBuffer.append(freeMem);
+ statsBuffer.append(',');
+ statsBuffer.append(totalMem);
+ statsBuffer.append(',');
+ statsBuffer.append(maxMem);
+ statsBuffer.append(',');
+ statsBuffer.append(_dataStore.getNumElements());
+ statsBuffer.append(',');
+
+ // last 7 dataelements created
+ List lastCreated = _dataStore.getLastCreatedElements();
+ for (int i = 0; i < lastCreated.size(); i++)
+ {
+ DataElement element = (DataElement)lastCreated.get(i);
+ statsBuffer.append(element.getName());
+ statsBuffer.append(":");
+ statsBuffer.append("id="+element.getId());
+ statsBuffer.append(";");
+ }
+
+
+ status.setAttribute(DE.A_SOURCE, statsBuffer.toString());
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (commandName.equals(DataStoreSchema.C_SCHEMA))
+ {
+ loadMiners();
+
+ DataElement schemaRoot = _dataStore.getDescriptorRoot();
+
+ // update all descriptor objects
+ _dataStore.refresh(schemaRoot);
+ status.setAttribute(DE.A_NAME,DataStoreResources.model_done);
+ }
+ else if (_dataStore.validTicket())
+ {
+
+
+ if (status != null)
+ {
+ boolean failure = false;
+ ArrayList miners = _minerLoader.getMiners();
+ for (int j = 0;(j < miners.size()) && !failure; j++)
+ {
+ Miner miner = (Miner) miners.get(j);
+
+ if (commandSource.equals("*") || commandSource.equals(miner.getClass().getName()))
+ {
+ if (_dataStore.isAutoRefreshOn())
+ {
+ _dataStore.enableAutoRefresh(false);
+ }
+ /*
+ status = miner.command(command);
+
+ if ((status != null) && status.getAttribute(DE.A_NAME).equals(DataStoreResources.model_incomplete))
+ {
+ failure = true;
+ }
+ */
+ miner.requestCommand(command);
+
+
+
+ }
+
+ }
+ if (commandName.equals(DataStoreSchema.C_INIT_MINERS))
+ {
+ // old way was to submit this command for all miners at once
+ // now we wait til activateMiner call is made per each miner
+ // for backward compatibility, we still call init miners
+ // so we need to make sure, in cases were miners are loaded dynamically,
+ // that we set this to done if there's no miners to init
+ status.setAttribute(DE.A_NAME, DataStoreResources.model_done);
+ }
+ }
+
+ }
+
+ _dataStore.refresh(status);
+
+ }
+ }
+
+ /**
+ * Set the contents of a file with the specified file
+ * @param fileName the name of the target file
+ * @param file the source file
+ */
+ public void sendFile(String fileName, File file)
+ {
+ //_dataStore.saveFile(fileName, file);
+ }
+
+ /**
+ * Sets the contents of a file with bytes sent from the client
+ * @param fileName the name of the file to append to
+ * @param bytes the bytes of a file to insert
+ * @param size the number of bytes to insert
+ * @param binary indicates whether to insert the bytes as binary or unicode
+ */
+ public void sendFile(String fileName, byte[] bytes, int size, boolean binary)
+ {
+ sendFile(fileName, bytes, size, binary, "default");
+ }
+
+/**
+ * Sets the contents of a file with bytes sent from the client
+ * @param fileName the name of the file to append to
+ * @param bytes the bytes of a file to insert
+ * @param size the number of bytes to insert
+ * @param binary indicates whether to insert the bytes as binary or unicode
+ * @param byteStreamHandlerId indicates which byte stream handler should receive the bytes
+ */
+ public void sendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ _dataStore.saveFile(fileName, bytes, size, binary, byteStreamHandlerId);
+ }
+
+ /**
+ * Appends bytes sent from the client to a file
+ * @param fileName the name of the file to append to
+ * @param bytes the bytes of a file to append
+ * @param size the number of bytes to append
+ * @param binary indicates whether to append the bytes as binary or unicode
+ */
+ public void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary)
+ {
+ sendAppendFile(fileName, bytes, size, binary, "default");
+ }
+
+ /**
+ * Appends bytes sent from the client to a file
+ * @param fileName the name of the file to append to
+ * @param bytes the bytes of a file to append
+ * @param size the number of bytes to append
+ * @param binary indicates whether to append the bytes as binary or unicode
+ * @param byteStreamHandlerId indicates which byte stream handler should receive the bytes
+ */
+ public void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ _dataStore.appendToFile(fileName, bytes, size, binary);
+ }
+
+ /**
+ * Implemented to provide the means by which classes are requested and sent
+ * across the comm channel.
+ * @param className the name of the class to request
+ */
+ public synchronized void sendClass(String className)
+ {
+ sendClass(className, "default");
+ }
+
+ /**
+ * Implemented to provide the means by which classes are requested and sent
+ * across the comm channel.
+ * @param className the name of the class to request
+ */
+ public synchronized void sendClass(String className, String classByteStreamHandlerId)
+ {
+ //_dataStore.sendClass(className, classByteStreamHandlerId);
+ }
+
+ public void sendClassInstance(IRemoteClassInstance runnable, String classByteStreamHandlerId)
+ {
+ notifyInput();
+ }
+
+ /**
+ * Does not apply to server. Use ServerUpdateHandler.requestClass().
+ */
+ public void requestClass(String className)
+ {
+ }
+
+ /**
+ * Does not apply to server. Use ServerUpdateHandler.sendKeepAliveConfirmation().
+ */
+ public void sendKeepAliveConfirmation()
+ {
+ }
+
+ /**
+ * Does not apply to server. Use ServerUpdateHandler.sendKeepAliveRequest().
+ */
+ public void sendKeepAliveRequest()
+ {
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerLauncher.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerLauncher.java
new file mode 100644
index 00000000000..16f151281b8
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerLauncher.java
@@ -0,0 +1,548 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.ISSLProperties;
+import org.eclipse.dstore.core.util.ssl.DStoreSSLContext;
+
+
+/**
+ * This class is the DataStore daemon. It is used for authenticating users,
+ * launching DataStore servers under particular user IDs, and providing a
+ * client with enough information to conntect to a launched server.
+ */
+public class ServerLauncher extends Thread
+{
+
+
+ /**
+ * An instances of this class get loaded whenever a client requests access
+ * to a DataStore server. The ConnectionListener attempts to launch a server
+ * under the client user's ID, communicating back information to the client
+ * so that if may connect to the launched server. If the authentification and
+ * connection to the server are successful, ConnectionListener continues to
+ * monitor the server connection until it is terminated.
+ */
+ public class ConnectionListener extends Thread implements HandshakeCompletedListener
+ {
+
+ private Socket _socket;
+ private PrintWriter _writer;
+ private BufferedReader _reader;
+ private Process _serverProcess;
+ private String _port;
+ private boolean _done;
+ private BufferedReader _outReader;
+ private BufferedReader _errReader;
+
+
+ /**
+ * Constructor
+ * @param socket a socket to the daemon
+ */
+ public ConnectionListener(Socket socket)
+ {
+
+ _socket = socket;
+ try
+ {
+ _writer = new PrintWriter(new OutputStreamWriter(_socket.getOutputStream(), DE.ENCODING_UTF_8));
+ _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream(), DE.ENCODING_UTF_8));
+ }
+ catch (java.io.IOException e)
+ {
+ System.out.println("ServerLauncher:" + e);
+ }
+ }
+
+ /**
+ * Called when shutdown
+ */
+ public void finalize() throws Throwable
+ {
+ if (_serverProcess != null)
+ {
+ _serverProcess.destroy();
+ }
+ super.finalize();
+ }
+
+ /**
+ * Listens to the connection and prints any output while the connection
+ * is active
+ */
+ public void run()
+ {
+ _done = true;
+ if (listen())
+ {
+ if (_serverProcess != null)
+ {
+ _done = false;
+
+ try
+ {
+ String line = null;
+
+ while ((_outReader != null) && ((line = _outReader.readLine()) != null))
+ {
+ if (line.equals(ServerReturnCodes.RC_FINISHED))
+ {
+ break;
+ }
+ else
+ {
+ System.out.println(line);
+ }
+ }
+
+ if (_outReader != null)
+ {
+ _outReader.close();
+ }
+ if (_errReader != null)
+ {
+ _errReader.close();
+ }
+
+ _serverProcess.waitFor();
+ }
+ catch (Exception e)
+ {
+ System.out.println("ServerLauncher:" + e);
+ }
+ }
+
+ System.out.println("finished on port " + _port);
+ _outReader = null;
+ _errReader = null;
+ _serverProcess = null;
+ _done = true;
+ }
+ else
+ {
+ _done = true;
+ }
+ }
+
+ /**
+ * Indicates whether the connection has terminated or not
+ * @return true if the connection has terminated
+ */
+ public boolean isDone()
+ {
+ return _done;
+ }
+
+ /**
+ * Returns the DataStore server port used
+ * @return the server port
+ */
+ public String getServerPort()
+ {
+ return _port;
+ }
+ /**
+ * Attempt to start a new DataStore server. The port and the ticket for a
+ * newly started DataStore are captured and sent back to the client so that it
+ * may connect to the server.
+ *
+ * @return whether the server started successfully
+ */
+ public boolean listen()
+ {
+ boolean connected = false;
+
+ String user = null;
+ String password = null;
+
+ _port = null;
+ try
+ {
+ user = _reader.readLine();
+ password = _reader.readLine();
+ _port = _reader.readLine();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ _port = "0";
+ }
+
+ {
+ // start new server
+ try
+ {
+ String launchStatus = null;
+ String ticket = new String("" + System.currentTimeMillis());
+
+ String theOS = System.getProperty("os.name");
+ String timeout = "120000";
+
+
+ if (!theOS.toLowerCase().startsWith("win"))
+ {
+ // assuming unix compatable
+ //
+ // Get the property which
+ // contains the authorization
+ // script path
+ //
+ String authPath = System.getProperty("RSE.AUTH");
+ File authFile = null;
+ if (authPath != null && authPath.length() > 0)
+ {
+ authFile = new File(authPath);
+ }
+ if (authFile == null || !authFile.exists())
+ {
+ authPath = "perl " + _path + File.separator + "auth.pl";
+ }
+
+ String authString =
+ authPath
+ + " "
+ + user
+ + " "
+ + _path
+ + " "
+ + _port
+ + " "
+ + timeout
+ + " "
+ + ticket
+ ;
+
+ String[] authArray = { "sh", "-c", authString };
+
+ // test password
+ _serverProcess = Runtime.getRuntime().exec(authArray);
+
+ _outReader = new BufferedReader(new InputStreamReader(_serverProcess.getInputStream()));
+ _errReader = new BufferedReader(new InputStreamReader(_serverProcess.getErrorStream()));
+ BufferedWriter inWriter = new BufferedWriter(new OutputStreamWriter(_serverProcess.getOutputStream()));
+ // write password
+ inWriter.write(password);
+ inWriter.newLine();
+ inWriter.flush();
+
+ launchStatus = _outReader.readLine();
+ }
+ else
+ {
+
+ // launch new server
+ String[] cmdArray =
+ {
+ "java",
+ "-DA_PLUGIN_PATH=" + _path,
+ "org.eclipse.dstore.core.server.Server",
+ _port,
+ timeout,
+ ticket};
+
+ _serverProcess = Runtime.getRuntime().exec(cmdArray);
+ _outReader = new BufferedReader(new InputStreamReader(_serverProcess.getInputStream()));
+ _errReader = new BufferedReader(new InputStreamReader(_serverProcess.getErrorStream()));
+
+ launchStatus = "success";
+ }
+
+ if ((launchStatus == null) || !launchStatus.equals("success"))
+ {
+ _writer.println("Authentification Failed");
+ }
+ else
+ {
+ String status = _errReader.readLine();
+ _port = _errReader.readLine();
+
+ if ((status != null) && status.equals(ServerReturnCodes.RC_SUCCESS))
+ {
+ _errReader.readLine();
+ _writer.println("connected");
+ _writer.println(_port);
+ _writer.println(ticket);
+
+ System.out.println("launched new server on " + _port);
+ connected = true;
+ }
+ else
+ {
+ if (status == null)
+ {
+ status = new String("unknown problem connecting to server");
+ }
+
+ _writer.println(status);
+
+ _serverProcess.destroy();
+ _serverProcess = null;
+ _outReader.close();
+ _outReader = null;
+
+ _errReader.close();
+ _errReader = null;
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ _writer.println("server failure: " + e);
+ }
+ }
+
+ _writer.flush();
+
+ // close socket
+ try
+ {
+ _socket.close();
+ }
+ catch (IOException e)
+ {
+ System.out.println("ServerLauncher:" + e);
+ }
+
+ return connected;
+ }
+
+
+ public void handshakeCompleted(HandshakeCompletedEvent event)
+ {
+ System.out.println("handshake completed");
+ System.out.println(event);
+
+ }
+ }
+
+
+ private ServerSocket _serverSocket;
+ private String _path;
+ private ArrayList _connections;
+ private ISSLProperties _sslProperties;
+
+
+ public static int DEFAULT_DAEMON_PORT = 4035;
+
+ /**
+ * Constructor
+ */
+ public ServerLauncher()
+ {
+ String pluginPath = System.getProperty("A_PLUGIN_PATH");
+ if (pluginPath == null)
+ {
+ System.out.println("A_PLUGIN_PATH is not defined");
+ System.exit(-1);
+ }
+
+ _path = pluginPath.trim();
+
+ _connections = new ArrayList();
+
+ init(DEFAULT_DAEMON_PORT);
+ }
+
+ /**
+ * Constructor
+ * @param portStr the port for the daemon socket to run on
+ */
+ public ServerLauncher(String portStr)
+ {
+ String pluginPath = System.getProperty("A_PLUGIN_PATH");
+ if (pluginPath == null)
+ {
+ System.out.println("A_PLUGIN_PATH is not defined");
+ System.exit(-1);
+ }
+
+ _path = pluginPath.trim();
+
+ _connections = new ArrayList();
+ int port = Integer.parseInt(portStr);
+ init(port);
+ }
+
+ private String getKeyStoreLocation()
+ {
+ return _sslProperties.getDaemonKeyStorePath();
+ }
+
+ private String getKeyStorePassword()
+ {
+ return _sslProperties.getDaemonKeyStorePassword();
+ }
+
+ /**
+ * initializes the DataStore daemon
+ *
+ * @param port the daemon port
+ */
+ public void init(int port)
+ {
+ // create server socket from port
+ _sslProperties = new ServerSSLProperties();
+
+
+ try
+ {
+ if (_sslProperties.usingSSL())
+ {
+ String keyStoreFileName = getKeyStoreLocation();
+ String keyStorePassword = getKeyStorePassword();
+
+ try
+ {
+ SSLContext sslContext = DStoreSSLContext.getServerSSLContext(keyStoreFileName, keyStorePassword);
+
+ _serverSocket = sslContext.getServerSocketFactory().createServerSocket(port);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ _serverSocket = new ServerSocket(port);
+ }
+ System.out.println("Daemon running on: " + InetAddress.getLocalHost().getHostName() + ", port: " + port);
+ }
+ catch (UnknownHostException e)
+ {
+ System.err.println("Networking problem, can't resolve local host");
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ catch (IOException e)
+ {
+ System.err.println("Failure to create ServerSocket");
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+ /**
+ * Return the connection listener for the specified port if there is one
+ * @param port the port
+ * @return the listener associated with the port
+ */
+ protected ConnectionListener getListenerForPort(String port)
+ {
+ for (int i = 0; i < _connections.size(); i++)
+ {
+ ConnectionListener listener = (ConnectionListener) _connections.get(i);
+ if (listener.getServerPort().equals(port))
+ {
+ return listener;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Run the daemon
+ */
+ public void run()
+ {
+ while (true)
+ {
+ try
+ {
+ boolean connectionOkay = true;
+ Socket newSocket = _serverSocket.accept();
+ if (_sslProperties.usingSSL())
+ {
+
+ SSLSocket sslSocket = (SSLSocket) newSocket;
+ sslSocket.addHandshakeCompletedListener(new HandshakeCompletedListener()
+ {
+
+ public void handshakeCompleted(HandshakeCompletedEvent event)
+ {
+ System.out.println("handshake completed");
+ }
+
+ });
+ SSLSession session = sslSocket.getSession();
+ if (session == null)
+ {
+ System.out.println("handshake failed");
+
+
+ sslSocket.close();
+ connectionOkay = false;
+ }
+ }
+ if (connectionOkay)
+ {
+ ConnectionListener listener = new ConnectionListener(newSocket);
+ listener.start();
+ _connections.add(listener);
+ }
+ }
+ catch (IOException ioe)
+ {
+ System.err.println("Server: error initializing socket: " + ioe);
+ System.exit(-1);
+ }
+ }
+ }
+
+ /**
+ * Entry point into the DataStore daemon
+ *
+ * @param args the port for the daemon to run on (default is 4035). Optionally, the second arg specifies whether to use SSL or not.
+ */
+ public static void main(String args[])
+ {
+ if (args.length > 0)
+ {
+ ServerLauncher theServer = new ServerLauncher(args[0]);
+ theServer.start();
+ }
+ else
+ {
+ ServerLauncher theServer = new ServerLauncher();
+ theServer.start();
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReceiver.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReceiver.java
new file mode 100644
index 00000000000..b0b57cb8ebf
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReceiver.java
@@ -0,0 +1,91 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.net.Socket;
+
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.util.Receiver;
+
+/**
+ * The ServerReciever is responsible for recieving data from
+ * the client side.
+ */
+public class ServerReceiver extends Receiver
+{
+
+ private ConnectionEstablisher _connection;
+
+ /**
+ * Constructor
+ *
+ * @param socket the socket to receive from
+ * @param connection the connection establisher
+ */
+ public ServerReceiver(Socket socket, ConnectionEstablisher connection)
+ {
+ super(socket, connection.getDataStore());
+ _connection = connection;
+ }
+
+
+ /**
+ * Implementation for handling the receiving on documents on
+ * the server side.
+ *
+ * @param documentObject to tree root of received data.
+ */
+ public void handleDocument(DataElement documentObject)
+ {
+ // parse request and determine what is wanted
+ for (int a = 0; a < documentObject.getNestedSize(); a++)
+ {
+ DataElement rootOutput = (DataElement) documentObject.get(a);
+
+ DataElement log = _dataStore.getLogRoot();
+ log.addNestedData(rootOutput, false);
+
+ if (rootOutput.getName().equals("C_EXIT"))
+ {
+ finish();
+
+ }
+ else
+ {
+ _dataStore.command(rootOutput);
+ }
+ }
+ }
+
+ public void finish()
+ {
+ super.finish();
+ _connection.finished(this);
+ }
+
+ /**
+ * @see Receiver#finish()
+ */
+ public void handleError(Throwable e)
+ {
+ System.out.println("RECEIVER ERROR");
+ // e.printStackTrace();
+ System.out.println(e);
+ _connection.finished(this);
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReturnCodes.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReturnCodes.java
new file mode 100644
index 00000000000..cf8d9317585
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerReturnCodes.java
@@ -0,0 +1,39 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+/**
+ * This class contains a list of server return codes that are used
+ * to negociate server communication with a client
+ */
+public class ServerReturnCodes
+{
+
+
+ public static final String RC_SUCCESS = "Server Started Successfully";
+
+ public static final String RC_UNKNOWN_HOST_ERROR = "Unknown host error";
+ public static final String RC_BIND_ERROR = "Error binding socket";
+ public static final String RC_GENERAL_IO_ERROR = "General IO error creating socket";
+ public static final String RC_CONNECTION_ERROR = "Connection error";
+
+ public static final String RC_SECURITY_ERROR = "Security error creating socket";
+
+ public static final String RC_FINISHED = "Server Finished";
+
+ public static final String RC_JRE_VERSION_ERROR = "JRE 1.4 or higher required";
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerSSLProperties.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerSSLProperties.java
new file mode 100644
index 00000000000..e3b6dc68d19
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerSSLProperties.java
@@ -0,0 +1,125 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.dstore.core.model.ISSLProperties;
+
+
+
+public class ServerSSLProperties implements ISSLProperties
+{
+ private boolean _enableSSL = false;
+ private String _daemonKeyStorePath;
+ private String _daemonKeyStorePassword;
+
+ private String _serverKeyStorePath;
+ private String _serverKeyStorePassword;
+
+
+ private static final String ENABLE_SSL = "enable_ssl";
+
+ private static final String DAEMON_KEYSTORE_FILE = "daemon_keystore_file";
+ private static final String DAEMON_KEYSTORE_PASSWORD = "daemon_keystore_password";
+
+ private static final String SERVER_KEYSTORE_FILE = "server_keystore_file";
+ private static final String SERVER_KEYSTORE_PASSWORD = "server_keystore_password";
+
+
+ public ServerSSLProperties()
+ {
+ try
+ {
+ ResourceBundle properties = ResourceBundle.getBundle("ssl");
+ _enableSSL = properties.getString(ENABLE_SSL).equals("true");
+ if (_enableSSL)
+ {
+ try
+ {
+ _daemonKeyStorePath = properties.getString(DAEMON_KEYSTORE_FILE);
+ _daemonKeyStorePassword = properties.getString(DAEMON_KEYSTORE_PASSWORD);
+ }
+ catch (Exception e)
+ {
+ }
+ try
+ {
+ _serverKeyStorePath = properties.getString(SERVER_KEYSTORE_FILE);
+ _serverKeyStorePassword = properties.getString(SERVER_KEYSTORE_PASSWORD);
+ }
+ catch (Exception e)
+ {
+ }
+
+ if (_daemonKeyStorePath == null && _serverKeyStorePath != null)
+ {
+ _daemonKeyStorePath = _serverKeyStorePath;
+ _daemonKeyStorePassword = _serverKeyStorePassword;
+ }
+ if (_serverKeyStorePath == null && _daemonKeyStorePath != null)
+ {
+ _serverKeyStorePath = _daemonKeyStorePath;
+ _serverKeyStorePassword = _daemonKeyStorePassword;
+ }
+
+ }
+
+ if (_enableSSL)
+ {
+ System.out.println("SSL Settings");
+ System.out.println("[daemon keystore:\t"+_daemonKeyStorePath+"]");
+ System.out.println("[daemon keystore pw:\t"+_daemonKeyStorePassword+"]");
+ System.out.println("[server keystore:\t"+_serverKeyStorePath+"]");
+ System.out.println("[server keystore pw:\t"+_serverKeyStorePassword+"]");
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+ public boolean usingSSL()
+ {
+ return _enableSSL;
+ }
+
+
+ public String getDaemonKeyStorePath()
+ {
+ return _daemonKeyStorePath;
+ }
+
+ public String getServerKeyStorePath()
+ {
+ return _serverKeyStorePath;
+ }
+
+ public String getDaemonKeyStorePassword()
+ {
+ return _daemonKeyStorePassword;
+ }
+
+ public String getServerKeyStorePassword()
+ {
+ return _serverKeyStorePassword;
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerUpdateHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerUpdateHandler.java
new file mode 100644
index 00000000000..cde5b289c5e
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ServerUpdateHandler.java
@@ -0,0 +1,453 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.server;
+
+import java.net.Socket;
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.dstore.core.model.DataStoreResources;
+import org.eclipse.dstore.core.model.UpdateHandler;
+import org.eclipse.dstore.core.util.CommandGenerator;
+import org.eclipse.dstore.core.util.Sender;
+
+/**
+ * The ServerUpdateHandler is contains a queue of data update requests
+ * and periodically transmits it's queue to the client
+ */
+public class ServerUpdateHandler extends UpdateHandler
+{
+
+
+ private ArrayList _senders;
+ private CommandGenerator _commandGenerator;
+ protected DataElement _classDocumentElement;
+ protected DataElement _keepAliveDocumentElement;
+ protected DataElement _confirmKeepAliveDocumentElement;
+ protected DataElement _pendingKeepAliveRequest;
+ protected DataElement _pendingKeepAliveConfirmation;
+
+ private static String[] _keepAliveAttributes = {
+ DataStoreResources.KEEPALIVE_TYPE,
+ "server.keepalive.root.id",
+ "server.keepalive",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _confirmKeepAliveAttributes = {
+ DataStoreResources.KEEPALIVECONFIRM_TYPE,
+ "server.keepalive.confirm.root.id",
+ "server.confirmkeepalive",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _docAttributes = {
+ DataStoreResources.DOCUMENT_TYPE,
+ "server.doc.root.id",
+ "server.document",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _fileAttributes = {
+ DataStoreResources.FILE_TYPE,
+ "server.file.root.id",
+ "server.file",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _classAttributes = {
+ DataStoreResources.CLASS_TYPE,
+ "server.class.root.id",
+ "server.class",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _requestClassAttributes = {
+ DataStoreResources.REQUEST_CLASS_TYPE,
+ "server.requestclass.root.id",
+ "server.requestclass",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ private static String[] _serializeAttributes = {
+ DataStoreResources.SERIALIZED_TYPE,
+ "server.serialized.root.id",
+ "server.serialized",
+ "doc",
+ "",
+ "",
+ DataStoreResources.FALSE,
+ "2"};
+
+ protected DataElement _fileDocumentElement;
+ protected DataElement _docDocumentElement;
+ protected DataElement _requestClassDocumentElement;
+ protected DataElement _serializedDocumentElement;
+
+ /**
+ * Constructor
+ */
+ public ServerUpdateHandler()
+ {
+ _senders = new ArrayList();
+ _commandGenerator = new CommandGenerator();
+
+ }
+
+ /**
+ * Sets the associated DataStore
+ */
+ public void setDataStore(DataStore dataStore)
+ {
+ super.setDataStore(dataStore);
+ _commandGenerator.setDataStore(dataStore);
+ _fileDocumentElement = dataStore.createTransientObject(_fileAttributes);
+ _docDocumentElement = dataStore.createObject(null, _docAttributes);
+ _requestClassDocumentElement = dataStore.createTransientObject(_requestClassAttributes);
+ _serializedDocumentElement = dataStore.createTransientObject(_serializeAttributes);
+ _classDocumentElement = dataStore.createTransientObject(_classAttributes);
+ _keepAliveDocumentElement = dataStore.createTransientObject(_keepAliveAttributes);
+ _confirmKeepAliveDocumentElement = dataStore.createTransientObject(_confirmKeepAliveAttributes);
+
+ }
+
+ /**
+ * Add a sender to the list of senders. Normally there is only one
+ * client for the server, which requires one Sender
. If
+ * there are more than one clients, then this is how senders are added.
+ *
+ * @param sender a sender connected to a socket
+ */
+ public void addSender(Sender sender)
+ {
+ _senders.add(sender);
+ }
+
+ /**
+ * Remove a sender from the list of senders.
+ * @param sender the sender to remove
+ */
+ public void removeSender(Sender sender)
+ {
+ _senders.remove(sender);
+ if (_senders.size() == 0)
+ {
+ finish();
+ }
+ }
+
+ /**
+ * Sends bytes to the specified file on the client.
+ *
+ * @param path the name of the file on the client
+ * @param bytes the bytes to send
+ * @param size the number of bytes to send
+ * @param binary indicates whether to send the bytes and binary or text
+ */
+ public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary)
+ {
+ updateFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+ /**
+ * Sends bytes to the specified file on the client.
+ *
+ * @param path the name of the file on the client
+ * @param bytes the bytes to send
+ * @param size the number of bytes to send
+ * @param binary indicates whether to send the bytes and binary or text
+ * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes
+ *
+ */
+ public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path);
+ DataElement document = _fileDocumentElement;
+ document.setAttribute(DE.A_NAME, byteStreamHandlerId);
+ document.setAttribute(DE.A_VALUE, byteStreamHandlerId);
+ document.setAttribute(DE.A_SOURCE, path);
+ document.setPendingTransfer(true);
+ document.setParent(null);
+
+ for (int j = 0; j < _senders.size(); j++)
+ {
+ Sender sender = (Sender) _senders.get(j);
+ sender.sendFile(document, bytes, size, binary);
+ }
+ }
+
+ /**
+ * Appends bytes to the specified file on the client.
+ *
+ * @param path the name of the file on the client
+ * @param bytes the bytes to send
+ * @param size the number of bytes to send
+ * @param binary indicates whether to send the bytes and binary or text
+ */
+ public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary)
+ {
+ updateAppendFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
+ }
+
+/**
+ * Appends bytes to the specified file on the client.
+ *
+ * @param path the name of the file on the client
+ * @param bytes the bytes to send
+ * @param size the number of bytes to send
+ * @param binary indicates whether to send the bytes and binary or text
+ * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes
+ */
+ public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
+ {
+ //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path);
+ DataElement document = _fileDocumentElement;
+ document.setAttribute(DE.A_NAME, byteStreamHandlerId);
+ document.setAttribute(DE.A_VALUE, byteStreamHandlerId);
+ document.setAttribute(DE.A_SOURCE, path);
+ document.setPendingTransfer(true);
+ document.setParent(null);
+
+ for (int j = 0; j < _senders.size(); j++)
+ {
+ Sender sender = (Sender) _senders.get(j);
+ sender.sendAppendFile(document, bytes, size, binary);
+ }
+ }
+
+
+ /**
+ * Periodically called on the handler thread to sends data updates.
+ */
+ public void handle()
+ {
+ if (!_dataObjects.isEmpty() || _pendingKeepAliveConfirmation != null || _pendingKeepAliveRequest != null || !_classesToSend.isEmpty())
+ {
+ sendUpdates();
+ }
+ }
+
+ /**
+ * Periodically called to send data in the queue from the server to the client
+ */
+ public void sendUpdates()
+ {
+ synchronized (_dataObjects)
+ {
+ //DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "server.doc");
+ DataElement document = _docDocumentElement;
+ document.removeNestedData();
+ document.setPendingTransfer(true);
+ document.setUpdated(true);
+ document.setParent(null);
+
+ DataElement response = _commandGenerator.generateResponse(document, _dataObjects);
+
+ for (int j = 0; j < _senders.size(); j++)
+ {
+ Sender sender = (Sender) _senders.get(j);
+ sender.sendDocument(document, 5);
+ if (_pendingKeepAliveConfirmation != null)
+ {
+ sender.sendKeepAliveConfirmation(_pendingKeepAliveConfirmation);
+ _pendingKeepAliveConfirmation = null;
+ }
+ if (_pendingKeepAliveRequest != null)
+ {
+ sender.sendKeepAliveRequest(_pendingKeepAliveRequest);
+ _pendingKeepAliveRequest = null;
+ }
+ }
+
+ for (int i = 0; i < _dataObjects.size(); i++)
+ {
+ DataElement obj = (DataElement) _dataObjects.get(i);
+ clean(obj);
+ }
+
+ _dataObjects.clear();
+ //_dataStore.getLogRoot().removeNestedData();
+ //_dataStore.getTempRoot().removeNestedData();
+ }
+
+ // finished sending updates, now send all classes that are waiting
+ // in the queue
+ while (_classesToSend.size() > 0)
+ {
+ DataElement document = null;
+ synchronized (_classesToSend)
+ {
+ document = (DataElement)_classesToSend.remove(0);
+ for (int i = 0; i < _senders.size(); i++)
+ {
+ Sender sender = (Sender) _senders.get(i);
+ sender.sendClass(document);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Removes the sender that is associated with the specified socket. This causes
+ * A disconnect for the client that is associated with this socket.
+ *
+ * @param socket the socket on which a sender communicates
+ */
+ public void removeSenderWith(Socket socket)
+ {
+ for (int i = 0; i < _senders.size(); i++)
+ {
+ Sender sender = (Sender) _senders.get(i);
+ if (sender.socket() == socket)
+ {
+ // sender sends last ack before death
+ DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "exit", "exit");
+ sender.sendDocument(document, 2);
+ removeSender(sender);
+ }
+ }
+ }
+
+ /**
+ * Implemented to provide the means by which classes are sent
+ * across the comm channel.
+ * @param className the name of the class to request
+ */
+ public synchronized void requestClass(String className)
+ {
+ DataElement document = _requestClassDocumentElement;
+ document.setPendingTransfer(true);
+ document.setAttribute(DE.A_NAME, className);
+ document.setAttribute(DE.A_VALUE, className);
+ document.setParent(null);
+ //DataElement document = _dataStore.createObject(null, DataStoreResources.REQUEST_CLASS_TYPE, className);
+
+ for (int j = 0; j < _senders.size(); j++)
+ {
+ Sender sender = (Sender) _senders.get(j);
+ sender.requestClass(document);
+ }
+
+ }
+
+
+ public synchronized void updateClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId)
+ {
+ DataElement document = _serializedDocumentElement;
+ document.setAttribute(DE.A_NAME, runnable.toString());
+ document.setAttribute(DE.A_SOURCE, deserializebyteStreamHandlerId);
+ document.setPendingTransfer(true);
+ document.setParent(null);
+
+ for (int j = 0; j < _senders.size(); j++)
+ {
+ Sender sender = (Sender) _senders.get(j);
+ sender.sendRemoteClassRunnable(document, runnable);
+ }
+ notifyInput();
+ }
+
+ /**
+ * Implemented to provide the means by which classes are sent
+ * across the comm channel.
+ * @param className the name of the class to send
+ * @param classbyteStreamHandlerId the name of the byte stream handler to use to receive the class
+ */
+ public synchronized void sendClass(String className, String classByteStreamHandlerId)
+ {
+ // send pending updates before sending class
+ if (_dataObjects.size() > 0)
+ sendUpdates();
+
+ DataElement document = _classDocumentElement;
+ document.setAttribute(DE.A_NAME, className);
+ document.setAttribute(DE.A_SOURCE, classByteStreamHandlerId);
+ document.setPendingTransfer(true);
+ document.setParent(null);
+
+ addClassToSend(document);
+ }
+
+ /**
+ * Adds a class to the queue of classes (represented by DataElements) to
+ * be sent to the client.
+ * @param classElement the DataElement representing the class to be sent
+ */
+ public void addClassToSend(DataElement classElement)
+ {
+ synchronized (_classesToSend)
+ {
+ if (!_classesToSend.contains(classElement))
+ {
+ _classesToSend.add(classElement);
+ }
+ }
+ }
+
+ /**
+ * Implemented to provide the means by which classes are requested and sent
+ * across the comm channel.
+ * @param className the name of the class to send
+ */
+ public synchronized void sendClass(String className)
+ {
+ sendClass(className, "default");
+ }
+
+ public void sendKeepAliveRequest()
+ {
+ DataElement document = _keepAliveDocumentElement;
+ document.setPendingTransfer(true);
+ document.setAttribute(DE.A_NAME, "request");
+ document.setAttribute(DE.A_VALUE, "request");
+ document.setParent(null);
+ _pendingKeepAliveRequest = document;
+ }
+
+ public void sendKeepAliveConfirmation()
+ {
+ DataElement document = _confirmKeepAliveDocumentElement;
+ document.setPendingTransfer(true);
+ document.setAttribute(DE.A_NAME, "confirm");
+ document.setAttribute(DE.A_VALUE, "confirm");
+ document.setParent(null);
+ _pendingKeepAliveConfirmation = document;
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/CommandGenerator.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/CommandGenerator.java
new file mode 100644
index 00000000000..3fec222e167
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/CommandGenerator.java
@@ -0,0 +1,320 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.dstore.core.model.DataStoreResources;
+
+/**
+ * This class is used to generate command object instances from command descriptors and arguments to commands.
+ * Command instances are instances of command descriptors. Each command instance contains a set of data arguments
+ * and a status object, that represents the current state of a command. After a command instance is created,
+ * it is referenced in the command log for the DataStore.
+ */
+public class CommandGenerator
+{
+ private DataStore _dataStore = null;
+ private DataElement _log = null;
+
+ static private int _id = 0;
+
+ /**
+ * Constructor
+ */
+ public CommandGenerator()
+ {
+ }
+
+ /**
+ * Sets the associated DataStore
+ * @param dataStore the associated DataStore
+ */
+ public void setDataStore(DataStore dataStore)
+ {
+ _dataStore = dataStore;
+ _log = _dataStore.getLogRoot();
+ }
+
+ /**
+ * This method logs the current command object in the DataStore command log. For each
+ * logged command, a status object is created and returned.
+ * @param commandObject the commandObject to log
+ * @return the status object of the command
+ */
+ public DataElement logCommand(DataElement commandObject)
+ {
+ try
+ {
+ // prevent duplicate queries
+ String name = commandObject.getAttribute(DE.A_NAME);
+
+ // create time and status objects
+ DataElement status = null;
+
+ if (status == null)
+ {
+ StringBuffer id = new StringBuffer(commandObject.getId());
+ id.append(DataStoreResources.model_status);
+ status =
+ _dataStore.createObject(
+ commandObject,
+ DataStoreResources.model_status,
+ DataStoreResources.model_start,
+ "",
+ id.toString());
+ }
+ _log.addNestedData(commandObject, false);
+
+ }
+ catch (Exception e)
+ {
+ _dataStore.trace(e);
+ }
+
+ return commandObject;
+ }
+
+ /**
+ * Creates a new command instance object from a command descriptor
+ * @param commandDescriptor the descriptor of the command to create
+ * @return the new command instance
+ */
+ public DataElement createCommand(DataElement commandDescriptor)
+ {
+ if (commandDescriptor != null)
+ {
+ if (commandDescriptor.getType().equals(DE.T_COMMAND_DESCRIPTOR))
+ {
+ DataElement commandInstance = _dataStore.createObject(null, commandDescriptor.getName(), commandDescriptor.getValue(), commandDescriptor.getSource());
+ commandInstance.setDescriptor(commandDescriptor);
+ return commandInstance;
+ }
+ else
+ {
+ System.out.println("not cd -> " + commandDescriptor);
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private void clearDeleted(DataElement element)
+ {
+ for (int i = 0; i < element.getNestedSize(); i++)
+ {
+ DataElement child = element.get(i).dereference();
+ if (child.isDeleted())
+ {
+ element.removeNestedData(child);
+ }
+ }
+ }
+
+ /**
+ * Creates a new command from a command descriptor and it's arguments.
+ *
+ * @param commandDescriptor the command type of the new command
+ * @param arguments the arguments for the command, besides the subject
+ * @param dataObject the subject of the command
+ * @param refArg indicates whether the subject should be represented as a reference or directly
+ * @return the status object of the command
+ */
+ public DataElement generateCommand(DataElement commandDescriptor, ArrayList arguments, DataElement dataObject, boolean refArg)
+ {
+
+ DataElement commandObject = createCommand(commandDescriptor);
+ if (commandObject != null)
+ {
+ clearDeleted(dataObject);
+ DataElement tempRoot = _dataStore.getTempRoot();
+
+ commandObject.setAttribute(DE.A_VALUE, commandDescriptor.getName());
+
+ if (dataObject.isUpdated())
+ {
+ _dataStore.createReference(commandObject, dataObject,DataStoreResources.model_contents);
+ }
+ else
+ {
+ dataObject.setPendingTransfer(true);
+ commandObject.addNestedData(dataObject, false);
+ }
+
+ if (arguments != null)
+ {
+ for (int i = 0; i < arguments.size(); i++)
+ {
+ DataElement arg = (DataElement) arguments.get(i);
+ if (arg != null)
+ {
+ if (!arg.isUpdated())
+ {
+ commandObject.addNestedData(arg, false);
+ }
+ else
+ {
+ _dataStore.createReference(commandObject, arg, "argument");
+ }
+ }
+ }
+ }
+
+ return logCommand(commandObject);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Creates a new command from a command descriptor and it's arguments.
+ *
+ * @param commandDescriptor the command type of the new command
+ * @param arg the arguement for the command, besides the subject
+ * @param dataObject the subject of the command
+ * @param refArg indicates whether the subject should be represented as a reference or directly
+ * @return the status object of the command
+ */
+ public DataElement generateCommand(DataElement commandDescriptor, DataElement arg, DataElement dataObject, boolean refArg)
+ {
+ _id++;
+
+ DataElement commandObject = createCommand(commandDescriptor);
+ if (commandObject != null)
+ {
+ DataElement tempRoot = _dataStore.getTempRoot();
+ commandObject.setAttribute(DE.A_VALUE, commandDescriptor.getName());
+ clearDeleted(dataObject);
+ if (refArg || dataObject.isUpdated())
+ {
+ _dataStore.createReference(commandObject, dataObject,DataStoreResources.model_contents);
+ }
+ else
+ {
+ dataObject.setPendingTransfer(true);
+ commandObject.addNestedData(dataObject, false);
+ }
+
+ if (!arg.isUpdated())
+ {
+ commandObject.addNestedData(arg, false);
+ }
+ else
+ {
+ _dataStore.createReference(commandObject, arg, "argument");
+ }
+
+
+ return logCommand(commandObject);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new command from a command descriptor and it's arguments.
+ *
+ * @param commandDescriptor the command type of the new command
+ * @param dataObject the subject of the command
+ * @param refArg indicates whether the subject should be represented as a reference or directly
+ * @return the status object of the command
+ */
+ public DataElement generateCommand(DataElement commandDescriptor, DataElement dataObject, boolean refArg)
+ {
+ _id++;
+
+ DataElement commandObject = createCommand(commandDescriptor);
+ if (commandObject != null)
+ {
+ commandObject.setAttribute(DE.A_VALUE, commandDescriptor.getName());
+
+ clearDeleted(dataObject);
+ if (refArg || dataObject.isUpdated())
+ {
+ _dataStore.createReference(commandObject, dataObject,DataStoreResources.model_arguments);
+ }
+ else
+ {
+ dataObject.setPendingTransfer(true);
+ commandObject.addNestedData(dataObject, false);
+ }
+
+ return logCommand(commandObject);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates a response tree for transmitting a set of data from a server to a client.
+ *
+ * @param document the root of the response
+ * @param objects the data contained in the response
+ * @return the response tree root
+ */
+ public DataElement generateResponse(DataElement document, ArrayList objects)
+ {
+ document.addNestedData(objects, false);
+ return document;
+ }
+
+ /**
+ * Creates a response tree for transmitting a set of data from a server to a client.
+ *
+ * @param responseType the type of data to respond with
+ * @param dataObject the child object in the response tree
+ * @return the response tree root
+ */
+ public DataElement generateResponse(String responseType, DataElement dataObject)
+ {
+ if (dataObject != null)
+ {
+ DataElement commandObject = _dataStore.createObject(null, "RESPONSE", responseType);
+ commandObject.addNestedData(dataObject, true);
+ return commandObject;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates a simple response object of the specified type
+ *
+ * @param responseType the type of data to respond with
+ * @return the response object
+ */
+ public DataElement generateResponse(String responseType)
+ {
+ DataElement commandObject = _dataStore.createObject(null, "RESPONSE", responseType);
+ return commandObject;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ExternalLoader.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ExternalLoader.java
new file mode 100644
index 00000000000..dbeeaafb143
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ExternalLoader.java
@@ -0,0 +1,106 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.java.RemoteClassLoader;
+
+
+/**
+ * ExternalLoader is a ClassLoader
wrapper used for loading external
+ * tools that are not in the same classpath as the DataStore. Each ExternalLoader
+ * contains a load scope, a list of classpaths that it's class loader is able
+ * to load.
+ */
+public class ExternalLoader
+{
+
+ private ClassLoader _classLoader;
+ private ArrayList _loadScope;
+
+ /**
+ * Constructor
+ *
+ * @param classLoader the classloader
+ * @param loadScope the scope in which the classloader can load classes
+ */
+ public ExternalLoader(ClassLoader classLoader, String loadScope)
+ {
+ _classLoader = classLoader;
+ _loadScope = new ArrayList();
+ _loadScope.add(loadScope);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param classLoader the classloader
+ * @param loadScope the scope in which the classloader can load classes
+ */
+ public ExternalLoader(ClassLoader classLoader, ArrayList loadScope)
+ {
+ _classLoader = classLoader;
+ _loadScope = loadScope;
+ }
+
+ /**
+ * Indicates whether this external loader can load a particular class
+ * @param source a qualified classname
+ * @return true if it can load the clas
+ */
+ public boolean canLoad(String source)
+ {
+ if (_classLoader instanceof RemoteClassLoader)
+ {
+ return true;
+ }
+
+ boolean result = false;
+ if (_loadScope != null)
+ {
+ for (int i = 0; i < _loadScope.size(); i++)
+ {
+ String scope = (String) _loadScope.get(i);
+ result = StringCompare.compare(scope, source, true);
+ if (result)
+ {
+ return result;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Loads the specified class
+ * @param source a qualified classname
+ * @return the loaded class
+ * @throws ClassNotFoundException
+ */
+ public Class loadClass(String source) throws ClassNotFoundException
+ {
+ try
+ {
+ return _classLoader.loadClass(source);
+ }
+ catch (NoClassDefFoundError e)
+ {
+ throw new ClassNotFoundException(source);
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ISender.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ISender.java
new file mode 100644
index 00000000000..e5c4c4bfb2b
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ISender.java
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import org.eclipse.dstore.core.model.DataElement;
+
+public interface ISender
+{
+
+
+ public void sendDocument(String document);
+ public void sendDocument(DataElement objectRoot, int depth);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Pattern.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Pattern.java
new file mode 100644
index 00000000000..0e5b38ae00c
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Pattern.java
@@ -0,0 +1,165 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.util.ArrayList;
+
+/**
+ * This class is used to define a wildcard string pattern. Strings
+ * can be compared against a pattern to determine whether they match
+ * or not.
+ */
+public class Pattern
+{
+
+ private String _pattern;
+ private ArrayList _subMatches;
+ private ArrayList _matchSchema;
+
+ /**
+ * Constructor
+ * @param pattern a wildcard string
+ * @param matchSchema
+ */
+ public Pattern(String pattern, ArrayList matchSchema)
+ {
+ _pattern = pattern;
+
+ _matchSchema = matchSchema;
+ }
+
+ /**
+ * Returns a list of submatches
+ * @return a list of submatches
+ */
+ public ArrayList getSubMatches()
+ {
+ return _subMatches;
+ }
+
+ /**
+ * Returns a submatch
+ * @param attribute an attribute to match
+ * @return a submatch
+ */
+ public String getSubMatch(String attribute)
+ {
+ // find attribute index in match schema
+ int index = _matchSchema.indexOf(attribute);
+ if ((index >= 0) && (index < _subMatches.size()))
+ {
+ Object match = _subMatches.get(index);
+ return new String((String) match);
+ }
+ else
+ {
+ return new String("null");
+ }
+ }
+
+ /**
+ * Checks whther a compare string matches the pattern
+ * @param compareStr to string to compare
+ * @return true if there is a match
+ */
+ public boolean matches(String compareStr)
+ {
+ String currentMatch = new String("");
+ _subMatches = new ArrayList();
+
+ int iText = 0;
+ int iPattern = 0;
+ int lastStar = 0;
+ int len = compareStr.length();
+
+ int patternLen = _pattern.length();
+
+ while (iPattern < patternLen)
+ {
+ char p = _pattern.charAt(iPattern++);
+ if (p == '*')
+ {
+ if (currentMatch.length() > 0)
+ {
+ _subMatches.add(new String(currentMatch));
+ }
+ currentMatch = new String("");
+
+ if (iPattern >= patternLen)
+ {
+ while (iText < len)
+ {
+ currentMatch += compareStr.charAt(iText++);
+ }
+ _subMatches.add(new String(currentMatch));
+
+ return true;
+ }
+ else
+ {
+ lastStar = iPattern;
+ }
+ }
+ else
+ {
+ if (iText >= len)
+ {
+ return false;
+ }
+ else
+ {
+ char t = compareStr.charAt(iText++);
+ if (p == t)
+ {
+ if ((lastStar > 0) && (iPattern >= patternLen) && (iText < len))
+ {
+ }
+ else
+ {
+ continue;
+ }
+
+ }
+ else
+ {
+ currentMatch += t;
+ if (lastStar == 0)
+ {
+ return false;
+ }
+ }
+
+ int matched = iPattern - lastStar - 1;
+ iPattern = lastStar;
+
+ iText -= matched;
+ }
+ }
+ }
+
+ if (iText >= len)
+ {
+ _subMatches.add(new String(currentMatch));
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Receiver.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Receiver.java
new file mode 100644
index 00000000000..58ddb684bc6
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Receiver.java
@@ -0,0 +1,165 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+
+/**
+ * This class is used for receiving data from a socket in the DataStore
+ * communication layer.
+ */
+public abstract class Receiver extends Thread
+{
+
+
+ private Socket _socket;
+
+ protected DataStore _dataStore;
+
+ private XMLparser _xmlParser;
+ private BufferedInputStream _in;
+
+ protected boolean _canExit;
+
+ /**
+ * Constructor
+ * @param socket the socket to read from
+ * @param dataStore the associated DataStore
+ */
+ public Receiver(Socket socket, DataStore dataStore)
+ {
+ _socket = socket;
+ _dataStore = dataStore;
+ _canExit = false;
+ _xmlParser = new XMLparser(dataStore);
+
+ try
+ {
+ _in = new BufferedInputStream(socket.getInputStream());
+ }
+ catch (UnknownHostException uhe)
+ {
+ //System.out.println("Receiver:" + uhe);
+ }
+ catch (IOException ioe)
+ {
+ //System.out.println("Receiver:" + ioe);
+ }
+ }
+
+ /**
+ * Called when a DataStore connection is terminated.
+ */
+ public void finish()
+ {
+ _canExit = true;
+ }
+
+ /**
+ * Indicates that the receiver can stop receiving data from the socket.
+ * @return true if the receiver can stop
+ */
+ public boolean canExit()
+ {
+ return _canExit;
+ }
+
+ /**
+ * Called when the receiver thread is running
+ */
+ public void run()
+ {
+ try
+ {
+ while (!_canExit)
+ {
+ handleInput();
+ }
+ }
+ catch (Exception e)
+ {
+ _canExit = true;
+ e.printStackTrace();
+ handleError(e);
+ }
+ }
+
+ /**
+ * Periodically called to receive data from the socket
+ */
+ public void handleInput()
+ {
+ try
+ {
+ // wait on the socket
+ DataElement rootObject = _xmlParser.parseDocument(_in, _socket);
+
+ if (rootObject != null)
+ {
+ String type = rootObject.getType();
+ if (!type.equals("FILE"))
+ {
+
+ handleDocument(rootObject);
+ }
+ }
+ else
+ {
+ // something really bad happened
+ _canExit = true;
+ if (_xmlParser.getPanicException() != null)
+ handleError(_xmlParser.getPanicException());
+ }
+ }
+ catch (IOException ioe)
+ {
+ _canExit = true;
+ handleError(ioe);
+ }
+ catch (Exception e)
+ {
+ handleError(e);
+ }
+ }
+
+ /**
+ * Returns the associated socket
+ * @return the socket
+ */
+ public Socket socket()
+ {
+ return _socket;
+ }
+
+ /**
+ * Implemented to provide a means of handling received input
+ * @param documentObject the root object of the received data
+ */
+ public abstract void handleDocument(DataElement documentObject);
+
+ /**
+ * Implemented to provide a means of handling errors in the communication layer
+ * @param e an exception that occurred
+ */
+ public abstract void handleError(Throwable e);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sender.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sender.java
new file mode 100644
index 00000000000..87b4287a54c
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sender.java
@@ -0,0 +1,341 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+
+/**
+ * This class is used for sending data to a socket in the DataStore
+ * communication layer.
+ */
+public class Sender implements ISender
+{
+
+ private Socket _socket;
+ private PrintStream _outFile;
+ private BufferedWriter _outData;
+ private XMLgenerator _xmlGenerator;
+ private DataStore _dataStore;
+
+ /**
+ * Constructor
+ * @param socket the associated socket
+ * @param dataStore the associated DataStore
+ */
+ public Sender(Socket socket, DataStore dataStore)
+ {
+ _socket = socket;
+ _dataStore = dataStore;
+
+ _xmlGenerator = new XMLgenerator(_dataStore);
+ try
+ {
+ int bufferSize = _socket.getSendBufferSize();
+
+ _socket.setSendBufferSize(bufferSize);
+ _xmlGenerator.setBufferSize(bufferSize);
+ }
+ catch (SocketException e)
+ {
+ }
+ try
+ {
+ _outFile = new PrintStream(_socket.getOutputStream());
+ _outData = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream(), DE.ENCODING_UTF_8));
+
+ _xmlGenerator.setFileWriter(_outFile);
+ _xmlGenerator.setDataWriter(_outData);
+ _xmlGenerator.setGenerateBuffer(false);
+ InetSocketAddress address = (InetSocketAddress)socket.getRemoteSocketAddress();
+ if (address != null)
+ {
+ if (address.getAddress() != null)
+ {
+ String remoteIP = address.getAddress().getHostAddress();
+ _dataStore.setRemoteIP(remoteIP);
+ }
+ else
+ {
+ String remoteIP = address.getHostName();
+ _dataStore.setRemoteIP(remoteIP);
+ }
+ }
+ else
+ {
+ String remoteIP = socket.getInetAddress().getHostAddress();
+ _dataStore.setRemoteIP(remoteIP);
+ }
+ }
+ catch (java.io.IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Returns the associated socket
+ * @return the socket
+ */
+ public Socket socket()
+ {
+ return _socket;
+ }
+
+ /**
+ * Sends a string through the socket
+ * @param document the string to send
+ */
+ public void sendDocument(String document)
+ {
+ synchronized (_outData)
+ {
+ try
+ {
+ _outData.write(document, 0, document.length());
+ _outData.flush();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Sends the bytes of a file through the socket
+ * @param objectRoot the object representing the file to send
+ * @param bytes the bytes to send over the socket
+ * @param size the number of bytes to send over the socket
+ * @param binary indicates whether to send the bytes and binary or text
+ */
+ public void sendFile(DataElement objectRoot, byte[] bytes, int size, boolean binary)
+ {
+
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(objectRoot, bytes, size, false, binary);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+
+ /**
+ * Sends a class through the socket
+ * @param classElement the object representing the class to send
+ */
+ public void sendClass(DataElement classElement)
+ {
+ String className = classElement.getName();
+
+ ArrayList loaders = _dataStore.getLocalClassLoaders();
+ if (loaders == null)
+ {
+ // could not get the registered classLoaders. Fail.
+ generateEmptyClass(classElement);
+ return;
+ }
+
+ InputStream classInStream = null;
+ className = className.replace('.', '/');
+ className = className + ".class";
+ URL classLocation = null;
+ for (int i = 0; i < loaders.size(); i++)
+ {
+ ClassLoader loader = (ClassLoader) loaders.get(i);
+
+ classInStream = loader.getResourceAsStream(className);
+ classLocation = loader.getResource(className);
+ if (classInStream != null && classLocation != null) break;
+ }
+ if (classLocation == null || classInStream == null)
+ {
+ // could not load the class with any of the class loaders. Fail.
+ generateEmptyClass(classElement);
+ return;
+ }
+
+ // got a stream to read the classfile. Now read the class into a buffer.
+ BufferedInputStream bufInputStream = new BufferedInputStream(classInStream);
+ if (bufInputStream == null)
+ {
+ generateEmptyClass(classElement);
+ return; // throw new IOException("BufferedInputStream could not be instantiated on " + className);
+ }
+ try
+ {
+ int classSize = bufInputStream.available();
+ byte[] bytes = new byte[classSize];
+ int result = 0;
+ result = bufInputStream.read(bytes);
+
+ if (result != classSize)
+ {
+ generateEmptyClass(classElement);
+ return; // throw new IOException("Could not read class from BufferedInputStream: " + className);
+ }
+
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(classElement, bytes, classSize);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ generateEmptyClass(classElement);
+ return;
+ }
+ }
+
+ /**
+ * Generates an empty class and sends it across the pipe, as a signal that the
+ * class could not be found or loaded or read on the client.
+ * @param classElement
+ */
+ private void generateEmptyClass(DataElement classElement)
+ {
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(classElement, new byte[0], 0);
+ _xmlGenerator.flushData();
+ }
+
+ /**
+ * Sends the bytes of a file through the socket to be appended to a file on the other end
+ *
+ * @param objectRoot the object representing the file to send
+ * @param bytes the bytes to send over the socket
+ * @param size the number of bytes to send over the socket
+ * @param binary indicates whether to send the bytes and binary or text
+ */
+ public void sendAppendFile(DataElement objectRoot, byte[] bytes, int size, boolean binary)
+ {
+ synchronized (_outData)
+ {
+
+ synchronized (_outFile)
+ {
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(objectRoot, bytes, size, true, binary);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+
+ /**
+ * Sends a DataStore tree of data through the socket
+ *
+ * @param objectRoot the root of the tree to send
+ * @param depth the depth of the tree to send
+ */
+ public void sendDocument(DataElement objectRoot, int depth)
+ {
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(objectRoot, depth);
+ _xmlGenerator.flushData();
+ }
+
+ }
+
+// if (objectRoot.getParent() != null)
+ // objectRoot.getDataStore().deleteObject(objectRoot.getParent(), objectRoot);
+ }
+
+ /**
+ * Requests a class from the client
+ */
+ public void requestClass(DataElement classRequest)
+ {
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+
+ _xmlGenerator.empty();
+ _xmlGenerator.generateClassRequest(classRequest);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+
+ public void sendRemoteClassRunnable(DataElement objectRoot, IRemoteClassInstance runnable)
+ {
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+ _xmlGenerator.empty();
+ _xmlGenerator.generateSerializedObject(objectRoot, runnable);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+
+ public void sendKeepAliveRequest(DataElement document)
+ {
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(document, 2);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+
+ public void sendKeepAliveConfirmation(DataElement document)
+ {
+ synchronized (_outData)
+ {
+ synchronized (_outFile)
+ {
+ _xmlGenerator.empty();
+ _xmlGenerator.generate(document, 2);
+ _xmlGenerator.flushData();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sorter.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sorter.java
new file mode 100644
index 00000000000..d8bc24338c7
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/Sorter.java
@@ -0,0 +1,71 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.dstore.core.model.DataElement;
+
+/**
+ * Utility class used for sorting a list of DataElements based on
+ * their depth attributes.
+ */
+public class Sorter
+{
+
+ /**
+ * Sort a list of DataElements based on their depth attributes
+ * @param list a list of DataElements
+ * @return a sorted list of DataElements
+ */
+ public static ArrayList sort(ArrayList list)
+ {
+ ArrayList sortedList = new ArrayList(list.size());
+ while (list.size() > 0)
+ {
+ DataElement first = findFirst(list);
+ sortedList.add(first);
+ }
+
+ return sortedList;
+ }
+
+ /**
+ * Find the DataElement with the highest depth in the list
+ * @param list a list of DataElements
+ * @return the DataElement with the highest depth
+ */
+ private static DataElement findFirst(ArrayList list)
+ {
+ DataElement result = null;
+ for (int i = 0; i < list.size(); i++)
+ {
+ DataElement item = (DataElement) list.get(i);
+ if (item != null)
+ {
+ int depth = item.depth();
+ if ((result == null) || (depth > result.depth()))
+ {
+ result = item;
+ }
+ }
+ }
+
+ list.remove(result);
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/StringCompare.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/StringCompare.java
new file mode 100644
index 00000000000..25f9b5e6050
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/StringCompare.java
@@ -0,0 +1,125 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+/**
+ * Utility class for comparing a wildcard string to another string
+ */
+public class StringCompare
+{
+
+ /**
+ * Constructor
+ */
+ public StringCompare()
+ {
+ }
+
+ /**
+ * Compare two strings
+ *
+ * @param pattern the pattern to match
+ * @param compareStr the string to compare against the pattern
+ * @param noCase indicates whether the strings should be compared based on case
+ * @return true if the compare string matches the pattern
+ */
+ public static boolean compare(String pattern, String compareStr, boolean noCase)
+ {
+ if ((pattern == null) || (compareStr == null))
+ return false;
+
+ if (noCase)
+ {
+ pattern = pattern.toUpperCase();
+ compareStr = compareStr.toUpperCase();
+ }
+
+ String currentMatch = new String("");
+
+ int iText = 0;
+ int iPattern = 0;
+ int lastStar = 0;
+ int len = compareStr.length();
+
+ int patternLen = pattern.length();
+
+ while (iPattern < patternLen)
+ {
+ char p = pattern.charAt(iPattern++);
+ if (p == '*')
+ {
+
+ if (iPattern >= patternLen)
+ {
+ while (iText < len)
+ {
+ iText++;
+ }
+ return true;
+ }
+ else
+ {
+ lastStar = iPattern;
+ }
+ }
+ else
+ {
+ if (iText >= len)
+ {
+ return false;
+ }
+ else
+ {
+ char t = compareStr.charAt(iText++);
+ if (p == t)
+ {
+ if ((lastStar > 0) && (iPattern >= patternLen) && (iText < len))
+ {
+ }
+ else
+ {
+ continue;
+ }
+
+ }
+ else
+ {
+ if (lastStar == 0)
+ {
+ return false;
+ }
+ }
+
+ int matched = iPattern - lastStar - 1;
+ iPattern = lastStar;
+
+ iText -= matched;
+ }
+ }
+ }
+
+ if (iText >= len)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLgenerator.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLgenerator.java
new file mode 100644
index 00000000000..36f322fd319
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLgenerator.java
@@ -0,0 +1,691 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.Stack;
+
+import org.eclipse.dstore.core.java.IRemoteClassInstance;
+import org.eclipse.dstore.core.model.DE;
+import org.eclipse.dstore.core.model.DataElement;
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.dstore.core.model.DataStoreResources;
+
+/**
+ * ByteStreamHandler
to be saved on disk.
+ * ByteStreamHandler
.
+ *
+ * @param reader the pipe reader
+ * @return the root DataElement of the parsed document
+ * @throws IOException
+ */
+ public DataElement parseDocument(BufferedInputStream reader, Socket socket) throws IOException
+ {
+ _tagStack.clear();
+ _objStack.clear();
+
+ _rootDataElement = null;
+ _isFile = false;
+ _isClass = false;
+ _isRequestClass = false;
+ _isKeepAlive = false;
+ _isKeepAliveConfirm = false;
+ _isSerialized = false;
+ _tagType = STR_DATAELEMENT;
+
+ DataElement parent = null;
+ String matchTag = null;
+
+ boolean done = false;
+ while (!done)
+ {
+ String xmlTag = readLine(reader, socket);
+
+ if (xmlTag != null)
+ {
+ String trimmedTag = xmlTag.trim();
+
+ if (!_tagStack.empty())
+ {
+ matchTag = (String) _tagStack.peek();
+ }
+ if (trimmedTag.equals(STR_BUFFER_START))
+ {
+ _tagType = STR_BUFFER;
+ _tagStack.push(STR_BUFFER_END);
+ }
+ else if (trimmedTag.equals(STR_BUFFER_END))
+ {
+ _tagType = STR_DATAELEMENT;
+ _tagStack.pop();
+ }
+ else if (_tagType.equals(STR_BUFFER))
+ {
+ String buffer = convertStringFromXML(xmlTag);
+ parent.appendToBuffer(buffer);
+ }
+ else if ((matchTag != null) && trimmedTag.equals(matchTag))
+ {
+ if (parent.getType().equals(STR_STATUS))
+ {
+ if (parent.getName().equals(STR_STATUS_ALMOST_DONE))
+ {
+
+ parent.setAttribute(DE.A_NAME, STR_STATUS_DONE);
+ if (parent.getValue().equals(STR_STATUS_ALMOST_DONE))
+ {
+ parent.setAttribute(DE.A_VALUE,STR_STATUS_DONE);
+ }
+ if (_dataStore.isWaiting(parent))
+ {
+ _dataStore.stopWaiting(parent);
+ parent.notifyUpdate();
+ }
+ }
+ }
+
+ _tagStack.pop();
+ if (_tagStack.empty())
+ {
+ done = true;
+ }
+ else if (_tagStack.size() == 1)
+ {
+ parent = _rootDataElement;
+ }
+ else
+ {
+ parent = (DataElement) _objStack.pop();
+ }
+
+ }
+ else
+ {
+ xmlTag = xmlTag.trim();
+
+ if (xmlTag.length() > 3)
+ {
+
+ try
+ {
+ if (parent != null)
+ {
+ if (_objStack.contains(parent))
+ {
+ }
+ else
+ {
+ _objStack.push(parent);
+ }
+ }
+
+ DataElement result = parseTag(xmlTag, parent);
+
+ if (_panic)
+ {
+ return null;
+ }
+
+ if (result != null)
+ {
+ result.setUpdated(true);
+
+ if (parent == null && _rootDataElement == null)
+ {
+ _rootDataElement = result;
+ _rootDataElement.setParent(null);
+ }
+
+ parent = result;
+
+ if (_isFile && (result != null))
+ {
+ int size = result.depth();
+ String path = result.getSource();
+
+ String byteStreamHandler = result.getName();
+ if (path.equals(byteStreamHandler))
+ {
+ // older client or server, fall back to default
+ byteStreamHandler = DataStoreResources.DEFAULT_BYTESTREAMHANDLER;
+ }
+ if (path != null)
+ {
+ readFile(reader, size, path, byteStreamHandler);
+ }
+ _isFile = false;
+ //_dataStore.deleteObject(parent, result);
+ }
+ else if (_isClass && (result != null))
+ {
+ int size = result.depth();
+
+ String classbyteStreamHandler = result.getSource();
+
+ if (result.getName() != null)
+ {
+ boolean success = readClass(reader, size, result.getName(), classbyteStreamHandler);
+ }
+ _isClass = false;
+ }
+ else if (_isRequestClass && (result != null))
+ {
+ result.getDataStore().sendClass(result.getName());
+ _isRequestClass = false;
+ }
+ else if (_isKeepAlive && (result != null))
+ {
+ result.getDataStore().sendKeepAliveConfirmation();
+ _isKeepAlive = false;
+ }
+ else if (_isKeepAliveConfirm && (result != null))
+ {
+ if (_initialKart != null) _initialKart.interrupt();
+ _isKeepAliveConfirm = false;
+ }
+ else if (_isSerialized && (result != null))
+ {
+ int size = result.depth();
+ String classbyteStreamHandler = result.getSource();
+ if (result.getName() != null)
+ {
+ boolean success = readInstance(reader, size, classbyteStreamHandler);
+ }
+ _isSerialized = false;
+ }
+
+ StringBuffer endTag = new StringBuffer("");
+ endTag.append(_tagType);
+ endTag.append('>');
+ _tagStack.push(endTag.toString());
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ _dataStore.trace(e);
+ return _rootDataElement;
+ }
+ }
+ }
+ }
+
+ if (_panic)
+ return null;
+ }
+
+ DataElement result = _rootDataElement;
+ _rootDataElement.setParent(null); // this root is transient
+
+ _rootDataElement = null;
+ return result;
+ }
+
+ /**
+ * Deserializes a single DataElement from the XML stream.
+ *
+ * @param fullTag the DataElement XML tag
+ * @param parent the DataElement that container for the deserialized DataElement
+ * @return the parsed DataElement
+ */
+ protected synchronized DataElement parseTag(String fullTag, DataElement parent)
+ {
+ if (!fullTag.startsWith("<"))
+ return null;
+
+ try
+ {
+ fullTag = fullTag.substring(1, fullTag.length() - 1);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+
+ // get type
+ int nextSpace = fullTag.indexOf(' ');
+ if (nextSpace > 0)
+ {
+ String[] attributes = new String[DE.A_SIZE];
+
+ // tag type
+ String tagType = fullTag.substring(0, nextSpace);
+ if (tagType.startsWith(STR_FILE))
+ {
+ _isFile = true;
+ _tagType = tagType;
+ }
+ else if (tagType.startsWith(STR_CLASS))
+ {
+ _isClass = true;
+ _tagType = tagType;
+ }
+ else if (tagType.startsWith(STR_REQUEST_CLASS))
+ {
+ _isRequestClass = true;
+ _tagType = tagType;
+ }
+ else if (tagType.startsWith(STR_SERIALIZED))
+ {
+ _isSerialized = true;
+ _tagType = tagType;
+ }
+
+ int index = 0;
+ int nextQuote = 0;
+ int nextnextQuote = nextSpace;
+ while ((index < DE.A_SIZE) && (nextQuote >= 0))
+ {
+ nextQuote = fullTag.indexOf('\"', nextnextQuote + 1);
+ nextnextQuote = fullTag.indexOf('\"', nextQuote + 1);
+
+ if ((nextQuote >= 0) && (nextnextQuote > nextQuote) && (fullTag.length() > nextnextQuote))
+ {
+ String attribute = fullTag.substring(nextQuote + 1, nextnextQuote);
+
+ attributes[index] = convertStringFromXML(attribute);
+ index++;
+ }
+ }
+
+ DataElement result = null;
+ if (attributes.length == DE.A_SIZE)
+ {
+ String type = attributes[DE.A_TYPE];
+ if (type.equals(DataStoreResources.KEEPALIVE_TYPE))
+ {
+ _isKeepAlive= true;
+ result = _dataStore.createTransientObject(attributes);
+ }
+ else if (type.equals(DataStoreResources.KEEPALIVECONFIRM_TYPE))
+ {
+ _isKeepAliveConfirm = true;
+ result = _dataStore.createTransientObject(attributes);
+ }
+
+ else if (type.equals(DataStoreResources.DOCUMENT_TYPE))
+ {
+ String id = attributes[DE.A_ID];
+ if (_dataStore.contains(id))
+ {
+ result = _dataStore.find(id);
+ result.removeNestedData();
+ }
+ else
+ {
+ result = _dataStore.createObject(null, attributes);
+ }
+ }
+
+ else if (_isFile || _isClass || _isSerialized || parent == null)
+ {
+ result = _dataStore.createTransientObject(attributes);
+ }
+ else
+ {
+ String isRefStr = attributes[DE.A_ISREF];
+
+ if ((isRefStr != null) && isRefStr.equals("true"))
+ {
+ // new reference
+ String origId = attributes[DE.A_NAME];
+ if (_dataStore.contains(origId))
+ {
+
+ DataElement to = _dataStore.find(origId);
+ if (parent != null)
+ {
+ result = _dataStore.createReference(parent, to, attributes[DE.A_TYPE], false);
+
+ }
+ else
+ {
+ _dataStore.trace("NULL2!");
+ }
+ }
+ else
+ {
+ // creating reference to unknown object
+ result = _dataStore.createObject(parent, attributes);
+ }
+ }
+ else
+ {
+ String id = attributes[DE.A_ID];
+ if (id == null)
+ {
+ handlePanic(new Exception(fullTag));
+ return null;
+ }
+
+ if (parent != null && _dataStore.contains(id))
+ {
+ result = _dataStore.find(id);
+
+ // treat status special test
+ String name = attributes[DE.A_NAME];
+ String value = attributes[DE.A_VALUE];
+ if (type.equals(STR_STATUS) && name.equals(STR_STATUS_DONE))
+ {
+ attributes[DE.A_NAME] = STR_STATUS_ALMOST_DONE;
+ if (value.equals(STR_STATUS_DONE))
+ {
+ attributes[DE.A_VALUE] = STR_STATUS_ALMOST_DONE;
+ }
+
+ result.setAttributes(attributes);
+ }
+ else
+ {
+ result.setAttributes(attributes);
+ }
+
+ if (parent == null)
+ {
+ return result;
+ }
+ else if (parent == _rootDataElement)
+ {
+ DataElement rParent = result.getParent();
+ parent = rParent;
+
+ _rootDataElement.addNestedData(result, false);
+ }
+ else
+ {
+ if (result.getParent() == null)
+ {
+ if (result != _dataStore.getRoot())
+ {
+ result.setParent(parent);
+ }
+ }
+ }
+
+ if (parent != null)
+ {
+ parent.addNestedData(result, true);
+ }
+ else
+ {
+ if (result != _dataStore.getRoot())
+ {
+ _dataStore.trace("parent of " + result.getName() + " is NULL!");
+ }
+ else
+ {
+ result.setParent(null);
+ }
+ }
+ if (result.isDeleted())
+ //_dataStore.deleteObject(result.getParent(), result);
+ result.delete();
+ }
+ else
+ {
+ // new object
+ result = _dataStore.createObject(parent, attributes);
+
+ }
+
+ }
+ }
+ }
+
+ if (result != null && result.isDeleted())
+ {
+ _dataStore.deleteObject(parent, result);
+ }
+
+ return result;
+ }
+
+ return null;
+ }
+
+
+ public static String replaceSpecial(String input)
+ {
+ int indexOfAmp = input.indexOf('&');
+ int indexOfSemi = input.indexOf(';');
+ if (indexOfAmp >= 0 && indexOfSemi > indexOfAmp)
+ {
+ String converted = input.replaceAll(STR_AMP, "&")
+ .replaceAll(STR_SEMI, ";")
+ .replaceAll(STR_QUOTE, "\"")
+ .replaceAll(STR_APOS, "\'")
+ .replaceAll(STR_LT, "<")
+ .replaceAll(STR_GT, ">");
+ return converted;
+ }
+ else
+ {
+ return input;
+ }
+ }
+
+ /**
+ * Converts XML special character representations to the appropriate characters
+ * @param input buffer to convert
+ * @return the converted buffer
+ */
+ public static String convertStringFromXML(String input)
+ {
+ if (input.indexOf('&') > -1)
+ {
+ return replaceSpecial(input);
+ /*
+ StringBuffer result = new StringBuffer();
+
+ String[] tokens = splitString(input);
+ for (int i = 0; i < tokens.length; i++)
+ {
+ String token = tokens[i];
+ if (token.equals(STR_AMP_TRIMMED))
+ {
+ result.append('&');
+ }
+ else if (token.equals(STR_SEMI_TRIMMED))
+ {
+ result.append(';');
+ }
+ else if (token.equals(STR_QUOTE_TRIMMED))
+ {
+ result.append('"');
+ }
+ else if (token.equals(STR_APOS_TRIMMED))
+ {
+ result.append('\'');
+ }
+ else if (token.equals(STR_LT_TRIMMED))
+ {
+ result.append('<');
+ }
+ else if (token.equals(STR_GT_TRIMMED))
+ {
+ result.append('>');
+ }
+ else
+ result.append(token);
+ }
+
+
+ return result.toString();
+ */
+ }
+ else
+ {
+ return input;
+ }
+ }
+
+ public class KeepAliveRequestThread extends Thread
+ {
+ private long _timeout;
+ private DataStore _dataStore;
+ private boolean _failed;
+
+ public KeepAliveRequestThread(long timeout, DataStore datastore)
+ {
+ _timeout = timeout;
+ _dataStore = datastore;
+ _failed = false;
+ }
+
+ public void run()
+ {
+ _dataStore.sendKeepAliveRequest();
+ try
+ {
+ sleep(_timeout);
+ }
+ catch (InterruptedException e)
+ {
+ return;
+ }
+ _failed = true;
+ }
+
+ public boolean failed()
+ {
+ return _failed;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreKeyStore.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreKeyStore.java
new file mode 100644
index 00000000000..e0a500ff697
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreKeyStore.java
@@ -0,0 +1,128 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util.ssl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+
+
+public class DStoreKeyStore
+{
+ public static DStoreKeyStore _instance = null;
+
+ public DStoreKeyStore()
+ {
+ _instance = this;
+ }
+
+ public static DStoreKeyStore getInstance()
+ {
+ if (_instance == null)
+ {
+ new DStoreKeyStore();
+ }
+ return _instance;
+ }
+
+ public static KeyStore getKeyStore(String filePath, String password)
+ throws KeyStoreException, NoSuchAlgorithmException,
+ CertificateException, IOException, NoSuchProviderException
+
+ {
+ KeyStore keyStore= null;
+
+
+ if (filePath != null)
+ {
+ File keyStoreFile = new File(filePath);
+
+ /* Do not stomp an existing file */
+ if(!keyStoreFile.exists())
+ {
+ keyStore = KeyStore.getInstance("JKS");
+ keyStore.load(null, password.toCharArray());
+ persistKeyStore(keyStore, filePath, password);
+ }
+ else {
+ keyStore = loadKeyStore(filePath, password);
+ }
+ }
+
+ return keyStore;
+ }
+
+
+ public static KeyStore loadKeyStore(String pathname, String password)
+ throws KeyStoreException,
+ NoSuchAlgorithmException,
+ CertificateException,
+ IOException,
+ NoSuchProviderException {
+
+ KeyStore ks=null;
+ File file=new File(pathname);
+
+ /* Do not stomp an existing file */
+ if(file.exists()) {
+ ks=KeyStore.getInstance("JKS");
+ /* Initialize the keystore with no information */
+ FileInputStream is=new FileInputStream(file);
+ ks.load(is, password.toCharArray());
+ is.close();
+ }
+ return ks;
+ }
+
+ public static Certificate loadCertificate(String certFilename)
+ throws CertificateException,
+ FileNotFoundException {
+
+ CertificateFactory factory=CertificateFactory.getInstance("X.509");
+
+ return factory.generateCertificate(new FileInputStream(certFilename));
+ }
+
+ public static void addCertificateToKeyStore(KeyStore ks, Certificate cert, String alias)
+ throws KeyStoreException {
+ ks.setCertificateEntry(alias, cert);
+
+ }
+
+ public static void persistKeyStore(KeyStore ks, String pathname, String password)
+ throws KeyStoreException,
+ FileNotFoundException,
+ NoSuchAlgorithmException,
+ CertificateException,
+ IOException {
+ FileOutputStream os=new FileOutputStream(pathname);
+ ks.store(os, password.toCharArray());
+ os.close();
+
+
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreSSLContext.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreSSLContext.java
new file mode 100644
index 00000000000..cf443ffe05e
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DStoreSSLContext.java
@@ -0,0 +1,74 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util.ssl;
+
+import java.security.KeyStore;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+
+
+public class DStoreSSLContext
+{
+
+ public static SSLContext getServerSSLContext(String filePath, String password)
+ {
+ SSLContext serverContext = null;
+
+ try
+ {
+ KeyStore ks = DStoreKeyStore.getKeyStore(filePath, password);
+ String keymgrAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(keymgrAlgorithm);
+ kmf.init(ks, password.toCharArray());
+
+ serverContext = SSLContext.getInstance("SSL");
+ serverContext.init(kmf.getKeyManagers(), null, null);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ return serverContext;
+ }
+
+ public static SSLContext getClientSSLContext(String filePath, String password, DataStoreTrustManager trustManager)
+ {
+ SSLContext clientContext = null;
+
+ try
+ {
+ trustManager.setKeystore(filePath, password);
+ clientContext = SSLContext.getInstance("SSL");
+ TrustManager[] mgrs = new TrustManager[1];
+ mgrs[0] = trustManager;
+
+
+ clientContext.init(null, mgrs, null);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ return clientContext;
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DataStoreTrustManager.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DataStoreTrustManager.java
new file mode 100644
index 00000000000..e861caf789f
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/ssl/DataStoreTrustManager.java
@@ -0,0 +1,150 @@
+/********************************************************************************
+ * Copyright (c) 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.core.util.ssl;
+
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.net.ssl.X509TrustManager;
+
+
+public class DataStoreTrustManager implements X509TrustManager
+{
+ private KeyStore _keystore;
+ private List _untrustedCerts;
+ private List _verifyExceptions;
+
+ //private X509Certificate _untrustedCert;
+ //private Exception _verifyException;
+
+ private List _trustedCerts;
+
+ public DataStoreTrustManager()
+ {
+ _trustedCerts = new ArrayList();
+ _untrustedCerts = new ArrayList();
+ _verifyExceptions = new ArrayList();
+ }
+
+
+ public void setKeystore(String filePath, String password)
+ {
+ try
+ {
+ KeyStore ks = DStoreKeyStore.getKeyStore(filePath, password);
+ _keystore = ks;
+ loadTrustedCertificates();
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ private void loadTrustedCertificates()
+ {
+ _trustedCerts.clear();
+ try
+ {
+ Enumeration aliases = _keystore.aliases();
+
+ while (aliases.hasMoreElements())
+ {
+ String alias = (String) (aliases.nextElement());
+
+ /* The alias may be either a key or a certificate */
+ java.security.cert.Certificate cert = _keystore.getCertificate(alias);
+ _trustedCerts.add(cert);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+ public List getUntrustedCerts()
+ {
+ return _untrustedCerts;
+ }
+
+ public List getVerifyExceptions()
+ {
+ return _verifyExceptions;
+ }
+
+ private void checkTrusted(X509Certificate[] certs, String arg1) throws CertificateException
+ {
+ _untrustedCerts.clear();
+ _verifyExceptions.clear();
+
+
+ for (int i = 0; i < certs.length; i++)
+ {
+ X509Certificate cert = certs[i];
+ boolean foundMatch = false;
+ if (_trustedCerts.size() > 0)
+ {
+
+ for (int j = 0; j < _trustedCerts.size() && !foundMatch; j++)
+ {
+ X509Certificate tcert = (X509Certificate)_trustedCerts.get(j);
+ try
+ {
+ tcert.verify(cert.getPublicKey());
+ foundMatch = true;
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+ if (!foundMatch)
+ {
+ _untrustedCerts.add(cert);
+ }
+ }
+ if (_trustedCerts.size() == 0 || _untrustedCerts.size() > 0)
+ {
+ throw new CertificateException();
+ }
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String arg1) throws CertificateException
+ {
+ checkTrusted(certs, arg1);
+
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String arg1) throws CertificateException
+ {
+ checkTrusted(certs,arg1);
+ }
+
+ public X509Certificate[] getAcceptedIssuers()
+ {
+ return null;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/.classpath b/rse/plugins/org.eclipse.dstore.extra/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/.classpath
@@ -0,0 +1,7 @@
+
+About This Content
+
+License
+
+
+ *
+ *
+ * The above contribution uses the RSE pop-up extension point to contribute an action
+ * to any single RSE object but not anything beginning with SPECIAL.
+ * @see IActionFilter#testAttribute(Object, String, String)
+ */
+ public boolean testAttribute(Object target, String name, String value) {
+ if (name.equals(_type) && target instanceof IDataElement) {
+ // support for "type" filter
+ IDataElement le = (IDataElement) target;
+ if (le.getType().equals(value) || le.isOfType(value))
+ return true;
+ } else if (name.equals(_name) && target instanceof IDataElement) {
+ // support for "name" filter.
+ IDataElement le = (IDataElement) target;
+ if (value.endsWith("*")) {
+ // we have a wild card test, and * is the last character in the value
+ if (le
+ .getName()
+ .startsWith(value.substring(0, value.length() - 1)))
+ return true;
+ } else if (le.getName().equals(value))
+ return true;
+ }
+
+ // type and name filter do not match, or we have a filter we do not support.
+ return false;
+ }
+
+ public static boolean matches(Class aClass) {
+ return (aClass == org.eclipse.ui.IActionFilter.class);
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DesktopElement.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DesktopElement.java
new file mode 100644
index 00000000000..90122b9eff2
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DesktopElement.java
@@ -0,0 +1,82 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import org.eclipse.jface.resource.*;
+
+import java.util.*;
+
+
+public class DesktopElement implements org.eclipse.ui.model.IWorkbenchAdapter
+{
+
+
+ private IDataElement _element;
+
+ public DesktopElement (IDataElement e)
+ {
+ _element = e;
+ }
+
+ public IDataElement toElement(Object object)
+ {
+ IDataElement element = null;
+ if (object instanceof IDataElement)
+ {
+ element = (IDataElement)object;
+ }
+ else
+ {
+ element = _element;
+ }
+ return element;
+ }
+
+ public Object[] getChildren(Object o)
+ {
+ IDataElement element = toElement(o);
+
+
+ List objs = element.getAssociated("contents");
+ return objs.toArray();
+ }
+
+ public ImageDescriptor getImageDescriptor(Object object)
+ {
+ return null;
+ }
+
+ public String getLabel(Object o)
+ {
+ return (String)_element.getElementProperty("value");
+ }
+
+ public Object getParent(Object o)
+ {
+ return null;
+ }
+
+ public static boolean matches(Class aClass)
+ {
+ return (aClass == org.eclipse.ui.model.IWorkbenchAdapter.class);
+ }
+
+ public static Object getPlatformAdapter(Object obj, Class aClass)
+ {
+ return org.eclipse.core.runtime.Platform.getAdapterManager().getAdapter(obj, aClass);
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainEvent.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainEvent.java
new file mode 100644
index 00000000000..74ff86a1b89
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainEvent.java
@@ -0,0 +1,101 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import java.util.*;
+
+public class DomainEvent
+{
+
+
+ public static final int UNKNOWN= 0;
+ public static final int INSERT= 1;
+ public static final int REMOVE= 2;
+ public static final int STRUCTURE_CHANGE= 3;
+ public static final int NON_STRUCTURE_CHANGE= 4;
+ public static final int FILE_CHANGE=5;
+
+
+ public static final int FIRST_CUSTOM_CHANGE= 10;
+ public static final int LAST_CUSTOM_CHANGE= 255;
+
+ public static final int MASK= 0xFF;
+ public static final int REVEAL= 0x100;
+ public static final int SELECT= 0x200;
+
+ public static final int INSERT_REVEAL= INSERT | REVEAL;
+ public static final int INSERT_REVEAL_SELECT= INSERT_REVEAL | SELECT;
+
+ private IDataElement _parent;
+ private int _type;
+
+ public DomainEvent(int type, IDataElement parent, Object property)
+ {
+ _type = type;
+ _parent = parent;
+ }
+
+ public DomainEvent(int type, IDataElement parent, Object property, IDataElement child)
+ {
+ _type = type;
+ _parent = parent;
+ }
+
+
+ public DomainEvent(IDomainNotifier source, int type, IDataElement parent, Object property)
+ {
+ _type = type;
+ _parent = parent;
+ }
+
+
+ public boolean equals(Object event)
+ {
+ return (((DomainEvent)event).getParent() == getParent());
+ }
+
+ public String getId()
+ {
+ return _parent.getId();
+ }
+
+ public String getName()
+ {
+ return _parent.getName();
+
+ }
+
+ public int getType()
+ {
+ return _type;
+ }
+
+ public IDataElement getParent()
+ {
+ return _parent;
+ }
+
+ public List getChildren()
+ {
+ return _parent.getNestedData();
+ }
+
+ public int getChildrenCount()
+ {
+ return _parent.getNestedSize();
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java
new file mode 100644
index 00000000000..5cd75f0e675
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java
@@ -0,0 +1,118 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import java.util.*;
+
+public class DomainNotifier implements IDomainNotifier
+{
+
+
+ private ArrayList _listeners;
+
+ private boolean _enabled;
+
+/*
+ public class FireMainThread extends Job
+ {
+ public boolean _isWorking;
+
+ private DomainEvent _event;
+
+ public FireMainThread(DomainEvent event)
+ {
+ super("DStore Events Fired");
+ _isWorking = false;
+ _event = event;
+ setPriority(Job.INTERACTIVE);
+ }
+
+ public IStatus run(IProgressMonitor monitor)
+ {
+ _isWorking = true;
+
+ if (_event.getType() != DomainEvent.FILE_CHANGE)
+ {
+ for (int i = 0; i < _listeners.size(); i++)
+ {
+ IDomainListener listener = (IDomainListener) _listeners.get(i);
+ if ((listener != null) && listener.listeningTo(_event))
+ {
+ listener.domainChanged(_event);
+ }
+ }
+ }
+
+ _isWorking = false;
+ return Status.OK_STATUS;
+ }
+ }
+*/
+ public DomainNotifier()
+ {
+ _listeners = new ArrayList();
+ _enabled = false;
+ }
+
+
+
+ public void enable(boolean on)
+ {
+ _enabled = on;
+ }
+
+ public boolean isEnabled()
+ {
+ return _enabled;
+ }
+
+ public void addDomainListener(IDomainListener listener)
+ {
+ if (!_listeners.contains(listener))
+ {
+ _listeners.add(listener);
+ }
+ }
+
+
+ public void fireDomainChanged(DomainEvent event)
+ {
+ if (_enabled)
+ {
+ for (int i = 0; i < _listeners.size(); i++)
+ {
+ IDomainListener listener = (IDomainListener) _listeners.get(i);
+ if ((listener != null) && listener.listeningTo(event))
+ {
+ listener.domainChanged(event);
+ }
+ }
+ //FireMainThread fireJob = new FireMainThread(event);
+ //fireJob.schedule();
+ }
+ }
+
+ public boolean hasDomainListener(IDomainListener listener)
+ {
+ return _listeners.contains(listener);
+ }
+
+ public void removeDomainListener(IDomainListener listener)
+ {
+ _listeners.remove(listener);
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IActionFilter.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IActionFilter.java
new file mode 100644
index 00000000000..2372b259f17
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IActionFilter.java
@@ -0,0 +1,23 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+public interface IActionFilter extends org.eclipse.ui.IActionFilter
+{
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDataElement.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDataElement.java
new file mode 100644
index 00000000000..a67588eb1b5
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDataElement.java
@@ -0,0 +1,35 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import java.util.*;
+
+public interface IDataElement extends IElement
+{
+
+
+ String getName();
+ String getType();
+ String getId();
+ List getNestedData();
+ int getNestedSize();
+
+ Object getElementProperty(Object obj);
+ List getAssociated(String key);
+
+ boolean isOfType(String typeStr);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java
new file mode 100644
index 00000000000..b5cfa19a36c
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java
@@ -0,0 +1,24 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+
+public interface IDesktopElement extends org.eclipse.ui.model.IWorkbenchAdapter
+{
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainListener.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainListener.java
new file mode 100644
index 00000000000..aa61d23c7fc
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainListener.java
@@ -0,0 +1,24 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+public interface IDomainListener
+{
+
+ public boolean listeningTo(DomainEvent e);
+ public void domainChanged(DomainEvent e);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.java
new file mode 100644
index 00000000000..322a75414ae
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.java
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+public interface IDomainNotifier
+{
+
+
+ public void addDomainListener(IDomainListener listener);
+ public void fireDomainChanged(DomainEvent event);
+ public boolean hasDomainListener(IDomainListener listener);
+ public void removeDomainListener(IDomainListener listener);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IElement.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IElement.java
new file mode 100644
index 00000000000..86a13eae81f
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IElement.java
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import org.eclipse.core.runtime.*;
+
+public interface IElement extends IAdaptable
+{
+
+
+ public Object getElementProperty(Object key);
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IPropertySource.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IPropertySource.java
new file mode 100644
index 00000000000..0720e8c9470
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/IPropertySource.java
@@ -0,0 +1,23 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+public interface IPropertySource extends org.eclipse.ui.views.properties.IPropertySource
+{
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/PropertySource.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/PropertySource.java
new file mode 100644
index 00000000000..2f0aa98c8f9
--- /dev/null
+++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/PropertySource.java
@@ -0,0 +1,147 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.dstore.extra.internal.extra;
+
+import org.eclipse.ui.views.properties.*;
+
+
+import java.util.*;
+
+public class PropertySource implements IPropertySource
+{
+
+
+ private IDataElement _dataElement;
+ private HashMap _properties;
+ private IPropertyDescriptor[] _descriptors;
+
+ public PropertySource(IDataElement element)
+ {
+ _dataElement = element;
+
+ _properties = new HashMap();
+
+ IDataElement descriptor = (IDataElement)element.getElementProperty("descriptor");
+
+ List attributes = null;
+ int attributesSize = 0;
+ if (descriptor != null)
+ {
+ attributes = descriptor.getAssociated("attributes");
+ attributesSize = attributes.size();
+ }
+
+ _descriptors = new IPropertyDescriptor[attributesSize + 2];
+ _descriptors[0] = new TextPropertyDescriptor("type", "type");
+ _descriptors[1] = new TextPropertyDescriptor("name", "name");
+
+ for (int i = 0; i < attributesSize; i++)
+ {
+ IDataElement attribute = (IDataElement)attributes.get(i);
+ List types = attribute.getAssociated("attributes");
+
+ String type = null;
+ if (types.size() > 0)
+ type = ((IDataElement)types.get(0)).getName();
+ else
+ type = "String";
+
+ _properties.put(attribute.getName(), type);
+ _descriptors[i+2] = new TextPropertyDescriptor(attribute.getName(), attribute.getName());
+ }
+
+ }
+
+ public static boolean matches(Class aClass)
+ {
+ return (aClass == org.eclipse.ui.views.properties.IPropertySource.class);
+ }
+
+
+ public Object getEditableValue()
+ {
+ return this;
+ }
+
+ public IPropertyDescriptor[] getPropertyDescriptors()
+ {
+ return _descriptors;
+ }
+
+ public Object getPropertyValue(Object name)
+ {
+ return getPropertyValue((String)name);
+ }
+
+ public Object getPropertyValue(String name)
+ {
+ Object result = null;
+
+ // find the appropriate attribute
+ List attributes = _dataElement.getAssociated("attributes");
+ for (int i = 0; i < attributes.size(); i++)
+ {
+ IDataElement attribute = (IDataElement)attributes.get(i);
+ if (attribute.getType().equals(name))
+ {
+ result = attribute.getElementProperty("value");
+ }
+ }
+
+ if (result == null)
+ {
+ String type = (String)_properties.get(name);
+
+ if (type != null && type.equals("Integer"))
+ result = "0";
+ else if (type != null && type.equals("Float"))
+ result = "0.0";
+ else
+ result = _dataElement.getElementProperty(name);
+ }
+
+ return result;
+ }
+
+ public boolean isPropertySet(Object property)
+ {
+ return isPropertySet((String)property);
+ }
+
+ public boolean isPropertySet(String property)
+ {
+ return false;
+ }
+
+ public void resetPropertyValue(Object property)
+ {
+ }
+
+ public void resetPropertyValue(String property)
+ {
+ }
+
+ public void setPropertyValue(Object name, Object value)
+ {
+ setPropertyValue((String)name, value);
+ }
+
+ public void setPropertyValue(String name, Object value)
+ {
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/.classpath b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.classpath
@@ -0,0 +1,7 @@
+
+About This Content
+
+License
+
+
+ *
+ * @return The String value of the property or "" if the property was not found.
+ */
+ private String getSystemInfoProperty(String propertyName)
+ {
+ // System properties require a connection
+ if (!isConnected())
+ {
+ try
+ {
+ getPrimarySubSystem().connect();
+ }
+ catch (Exception e)
+ {
+ SystemBasePlugin.logError("UniversalSystem.getSystemInfoProperty: error during connect", e);
+ return "";
+ }
+ }
+
+ String propertyValue = null;
+ DataElement envMinerData = null;
+ DataStore ds = getDataStore();
+
+ // Check if we have sysInfo cached already
+ if (sysInfo == null)
+ {
+ envMinerData = ds.findMinerInformation(EnvironmentMiner.MINER_ID);
+ if (envMinerData != null)
+ {
+ sysInfo = ds.find(envMinerData, DE.A_NAME, "systemInfo", 1);
+ }
+ }
+
+ if (sysInfo != null)
+ {
+ DataElement propertyNode = ds.find(sysInfo, DE.A_NAME, propertyName, 1);
+ if (propertyNode != null)
+ {
+ propertyValue = propertyNode.getSource();
+ }
+ else
+ propertyValue = "";
+ }
+ else
+ {
+ SystemBasePlugin.logError("UniversalSystem.getSystemInfoNode: sysInfo node not found", null);
+ SystemBasePlugin.logError("UniversalSystem.getSystemInfoNode: miner data = " + envMinerData, null);
+ propertyValue = "";
+ }
+
+ return propertyValue;
+ }
+
+ /**
+ * Return the version, release, modification of the remote system
+ */
+ public String getVersionReleaseModification()
+ {
+ if (!isConnected())
+ return SystemPropertyResources.RESID_TERM_NOTAVAILABLE;
+
+ StringBuffer buffer = new StringBuffer(getSystemInfoProperty("os.name"));
+ buffer.append(" ");
+ buffer.append(getSystemInfoProperty("os.version"));
+
+ return buffer.toString();
+ }
+
+ /**
+ * Return the home directory of the remote system for the current user, if available.
+ */
+ public String getHomeDirectory()
+ {
+ return getSystemInfoProperty("user.home");
+ }
+
+ public boolean runClassInstanceRemotely(IRemoteClassInstance instance)
+ {
+ DataStore dataStore = getDataStore();
+ dataStore.registerLocalClassLoader(instance.getClass().getClassLoader());
+ dataStore.runRemoteClassInstance(instance);
+ return true;
+ }
+
+ /**
+ * Return the location where the RSE server is installed
+ * @return the server install location
+ */
+ public String getServerInstallPath()
+ {
+ if (clientConnection != null)
+ {
+ if (installInfo == null)
+ {
+ DataStore ds = clientConnection.getDataStore();
+ installInfo = ds.queryInstall();
+ }
+ return installInfo.getAttribute(DE.A_SOURCE);
+ }
+ return "";
+ }
+
+ /**
+ * Return the Client IP that the RSE server is connected to. When connected,
+ * the client IP is obtained from the server-side. When not-connected,
+ * the fall back is to get the IP locally (note that the IP obtained locally
+ * may be not be what you want when using VPN).
+ * @return the client ip
+ */
+ public String getClientIP()
+ {
+ if (clientConnection != null && clientConnection.isConnected())
+ {
+ if (clientIP == null)
+ {
+ DataStore ds = clientConnection.getDataStore();
+ clientIP = ds.queryClientIP();
+ }
+ return clientIP.getAttribute(DE.A_SOURCE);
+ }
+
+ // fall back to getting local machine ip address
+ // this may be incorrect for the server in certain cases
+ // like over VPN
+ return SystemPlugin.getLocalMachineIPAddress();
+ }
+
+ /**
+ * Return the temp directory of the remote system for the current user, if available.
+ */
+ public String getTempDirectory()
+ {
+ return getSystemInfoProperty("temp.dir");
+ }
+
+ protected int getSocketTimeOutValue()
+ {
+ IPreferenceStore store = SystemPlugin.getDefault().getPreferenceStore();
+ return store.getInt(IUniversalDStoreConstants.RESID_PREF_SOCKET_TIMEOUT);
+ }
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.IConnectorService#disconnect()
+ */
+ public void disconnect() throws Exception
+ {
+ try
+ {
+ if (clientConnection != null)
+ {
+ // Is disconnect being called because the network (connection) went down?
+ if (_connectionStatusListener != null && _connectionStatusListener.isConnectionDown())
+ {
+ notifyError();
+ }
+ else
+ {
+ // Fire comm event to signal state about to change
+ fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT);
+ }
+
+ DataStore dataStore = getDataStore();
+ if (dataStore != null && _connectionStatusListener != null)
+ {
+ dataStore.getDomainNotifier().removeDomainListener(_connectionStatusListener);
+ }
+
+ clientConnection.disconnect();
+
+// Fire comm event to signal state changed
+ notifyDisconnection();
+ clientConnection = null;
+ // DKM - no need to clear uid cache
+ clearPasswordCache(false); // clear in-memory password
+ //clearUserIdCache(); // Clear any cached local user IDs
+ sysInfo = null;
+ installInfo = null;
+ clientIP = null;
+
+
+ }
+ }
+ catch (Exception exc)
+ {
+ throw new java.lang.reflect.InvocationTargetException(exc);
+ }
+ }
+
+ private IIBMServerLauncher getIBMServerLauncher()
+ {
+ IServerLauncherProperties sl = getRemoteServerLauncherProperties();
+ //System.out.println("in UniversalSystem#getServerLauncher: sl = "+sl);
+ if (sl != null && sl instanceof IIBMServerLauncher)
+ {
+ return (IIBMServerLauncher)sl;
+ }
+ else
+ //return ((SubSystemFactoryImpl)ss.getParentSubSystemFactory()).getDefaultIBMServerLauncher(ss);
+ return null; // should never happen!
+ }
+
+ protected void setPluginPathProperty()
+ {
+ Bundle bundle = SystemPlugin.getDefault().getBundle();
+ URL pluginsURL = bundle.getEntry("/");
+
+ try
+ {
+ String path = Platform.resolve(pluginsURL).getPath();
+ File systemsPluginDir = new File(path);
+ path = systemsPluginDir.getParentFile().getAbsolutePath();
+ String version = (String)(bundle.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION));
+ String versionString = (new PluginVersionIdentifier(version)).toString();
+
+ String dstorePath = getDStorePath(path, versionString);
+ System.setProperty("A_PLUGIN_PATH", dstorePath);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ private String getDStorePath(String pluginDir, String version)
+ {
+ File dstorePath = new File(pluginDir + "/" + DSTORE_PACKAGE + "_" + version);
+ if (!dstorePath.exists())
+ {
+ // might be in workspace
+ dstorePath = new File(pluginDir + "/" + DSTORE_PACKAGE);
+ }
+
+ return dstorePath.getAbsolutePath();
+ }
+
+ /**
+ * Specify if you support connecting to a running daemon
+ * @deprecated use {@link #enableServerLaunchType(ISubSystem, ServerLaunchType, boolean)}
+ * or your subsystem factory should override {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public void setDaemonLaunchEnabled(SubSystem subsystemImpl, boolean enable) {
+ enableServerLaunchType(subsystemImpl, ServerLaunchType.DAEMON_LITERAL, enable);
+ }
+
+ /**
+ * Return if you support connecting to a running daemon
+ * @deprecated Use instead {@link #isEnabledServerLaunchType(ISubSystem, ServerLaunchType)}
+ * or {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public boolean getDaemonLaunchEnabled(SubSystem subsystemImpl) {
+ return isEnabledServerLaunchType(subsystemImpl, ServerLaunchType.DAEMON_LITERAL);
+ }
+
+ /**
+ * Specify if you support remotely launching a server script
+ * @deprecated use {@link #enableServerLaunchType(ISubSystem, ServerLaunchType, boolean)}
+ * or your subsystem factory should override {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public void setRexecLaunchEnabled(SubSystem subsystemImpl, boolean enable) {
+ enableServerLaunchType(subsystemImpl, ServerLaunchType.REXEC_LITERAL, enable);
+ }
+
+ /**
+ * Return if you support remotely launching a server script
+ * @deprecated Use instead {@link #isEnabledServerLaunchType(ISubSystem, ServerLaunchType)}
+ * or {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public boolean getRexecLaunchEnabled(SubSystem subsystemImpl) {
+ return isEnabledServerLaunchType(subsystemImpl, ServerLaunchType.REXEC_LITERAL);
+ }
+
+ /**
+ * Specify if you support connecting to a server already running
+ * @deprecated use {@link #enableServerLaunchType(ISubSystem, ServerLaunchType, boolean)}
+ * or your subsystem factory should override {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public void setNoLaunchEnabled(SubSystem subsystemImpl, boolean enable) {
+ enableServerLaunchType(subsystemImpl, ServerLaunchType.RUNNING_LITERAL, enable);
+ }
+
+ /**
+ * Return if you support connecting to a server already running
+ * @deprecated Use instead {@link #isEnabledServerLaunchType(ISubSystem, ServerLaunchType)}
+ * or {@link org.eclipse.rse.core.subsystems.SubSystemConfiguration#supportsServerLaunchType(ServerLaunchType)}
+ */
+ public boolean getNoLaunchEnabled(SubSystem subsystemImpl) {
+ return isEnabledServerLaunchType(subsystemImpl, ServerLaunchType.RUNNING_LITERAL);
+ }
+
+ /**
+ * Return the remote server launcher, which implements IServerLauncher.
+ * This is called by the default implementation of connect, if
+ * subsystem.getParentSubSystemFactory().supportsServerLaunchProperties returns true.
+ */
+ public IServerLauncher getRemoteServerLauncher()
+ {
+ if (starter == null)
+ starter = new RexecDstoreServer();
+ ((RexecDstoreServer)starter).setClientConnection(clientConnection);
+ ((RexecDstoreServer)starter).setSocketTimeoutValue(getSocketTimeOutValue());
+ return starter;
+ }
+
+
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.IConnectorService#connect(IProgressMonitor)
+ */
+ protected synchronized void internalConnect(IProgressMonitor monitor) throws Exception
+ {
+ if (isConnected())
+ {
+ // could have been called b4
+ return;
+ }
+
+ // set A_PLUGIN_PATH so that dstore picks up the property
+ setPluginPathProperty();
+
+ // Fire comm event to signal state about to change
+ fireCommunicationsEvent(CommunicationsEvent.BEFORE_CONNECT);
+
+ ConnectionStatus connectStatus = null;
+ ConnectionStatus launchStatus = null;
+
+ clientConnection = new ClientConnection(getPrimarySubSystem().getHost().getAliasName());
+
+ boolean useSSL = isUsingSSL();
+ if (useSSL)
+ {
+ ISystemKeystoreProvider provider = SystemKeystoreProviderManager.getInstance().getDefaultProvider();
+ if (provider != null)
+ {
+ String keyStore = provider.getKeyStorePath();
+ String password = provider.getKeyStorePassword();
+
+ ISSLProperties properties = new ClientSSLProperties(true, keyStore, password);
+ clientConnection.setSSLProperties(properties);
+ }
+ }
+
+ clientConnection.setHost(getHostName());
+ clientConnection.setPort(Integer.toString(getPort()));
+
+ ISubSystem ss = getPrimarySubSystem();
+ IIBMServerLauncher serverLauncher = getIBMServerLauncher();
+
+ ServerLaunchType serverLauncherType = null;
+ if (serverLauncher != null)
+ {
+ serverLauncherType = serverLauncher.getServerLaunchType();
+ }
+ else
+ {
+ System.out.println("server launcher is null");
+ }
+
+ long t1 = System.currentTimeMillis();
+ SystemMessage msg = null;
+ boolean launchFailed = false;
+
+ // get Socket Timeout Value Preference
+ int timeout = getSocketTimeOutValue();
+ if (timeout <= 0) timeout = IUniversalDStoreConstants.DEFAULT_PREF_SOCKET_TIMEOUT;
+
+ if (serverLauncherType == ServerLaunchType.REXEC_LITERAL)
+ {
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_STARTING_SERVER_VIA_REXEC);
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+
+ SystemSignonInformation info = getPasswordInformation();
+
+ // GC: - if failed to get a connection in another way, try
+ // starting the datastore server with rexec
+ IServerLauncher starter = getRemoteServerLauncher();
+ starter.setSignonInformation(info);
+ starter.setServerLauncherProperties(serverLauncher);
+
+
+ String serverPort = (String)starter.launch(monitor);
+ if (monitor.isCanceled())
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_OPERATION_CANCELLED);
+ throw new SystemMessageException(msg);
+ }
+
+ if(!serverPort.equals("0"))
+ {
+ int iServerPort = 0;
+ if (serverPort != null)
+ {
+ iServerPort = Integer.parseInt(serverPort);
+ }
+
+ clientConnection.setPort(serverPort);
+
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECTING_TO_SERVER);
+ cmsg.makeSubstitution(clientConnection.getPort());
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+
+ // connect to launched server
+ connectStatus = clientConnection.connect(null, timeout);
+
+ }
+ else
+ {
+ launchFailed = true;
+ connectStatus = new ConnectionStatus(false);
+ msg = starter.getErrorMessage();
+ String errorMsg = null;
+ if (msg == null)
+ {
+ errorMsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_CONNECT_FAILED).getLevelOneText();
+ }
+ else
+ {
+ errorMsg = msg.getLevelTwoText();
+ }
+ connectStatus.setMessage(errorMsg);
+ }
+ }
+ // Start the server via the daemon
+ else if (serverLauncherType == ServerLaunchType.DAEMON_LITERAL)
+ {
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_STARTING_SERVER_VIA_DAEMON);
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+
+ // DY: getLocalUserId() may return null for Windows connections because
+ // we no longer prompt for userid / pwd. But for other connections the userid
+ // should be the same as the one stored in the password info (and for Windows
+ // this will be the temp remoteuser userid.
+ //launchStatus = clientConnection.launchServer(getLocalUserId(), getPassword(getPasswordInformation()));
+ SystemSignonInformation info = getPasswordInformation();
+ int daemonPort = serverLauncher.getDaemonPort();
+
+ /* String daemonPortStr = getSubSystem().getVendorAttribute("IBM", "DAEMON_PORT");
+ if (daemonPortStr != null && daemonPortStr.length() > 0)
+ {
+ daemonPort = Integer.parseInt(daemonPortStr);
+ }*/
+
+ // DKM - changed to use protected member so that others can override
+ //launchStatus = clientConnection.launchServer(info.getUserid(), info.getPassword(), daemonPort);
+ launchStatus = launchServer(clientConnection, info, daemonPort, monitor);
+
+ if (!launchStatus.isConnected())
+ {
+ launchFailed = true;
+ SystemBasePlugin.logError("Error launching server: " + launchStatus.getMessage(), null);
+ }
+ if (launchStatus.isConnected())
+ {
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECTING_TO_SERVER);
+ cmsg.makeSubstitution(clientConnection.getPort());
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+ // connect to launched server
+ connectStatus = clientConnection.connect(launchStatus.getTicket(), timeout);
+
+ if (!connectStatus.isConnected() && connectStatus.isSLLProblem())
+ {
+
+
+ List certs = connectStatus.getUntrustedCertificates();
+ if (certs != null && certs.size() > 0)
+ {
+ ISystemKeystoreProvider provider = SystemKeystoreProviderManager.getInstance().getDefaultProvider();
+ if (provider != null)
+ {
+ if (provider.importCertificates(certs))
+ {
+ connect(monitor);
+ }
+ }
+ }
+ }
+
+ /*
+ if (connectStatus != null && connectStatus.getMessage().startsWith(ClientConnection.INCOMPATIBLE_UPDATE))
+ {
+ // offer to update it
+ clientConnection.getDataStore().queryInstall();
+ }
+ */
+ }
+ else
+ {
+ connectStatus = new ConnectionStatus(false);
+ connectStatus.setMessage(
+ SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_CONNECT_FAILED).getLevelOneText());
+ }
+ }
+ else if (serverLauncherType == ServerLaunchType.RUNNING_LITERAL)
+ {
+ if (monitor != null)
+ {
+ SystemMessage cmsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECTING_TO_SERVER);
+ cmsg.makeSubstitution(clientConnection.getPort());
+ monitor.subTask(cmsg.getLevelOneText());
+ }
+ // connection directly
+ connectStatus = clientConnection.connect(null, timeout);
+ }
+ // server launcher type is unknown
+ else
+ {
+ SystemSignonInformation info = getPasswordInformation();
+ connectStatus = launchServer(clientConnection, info, serverLauncher, monitor);
+ }
+
+ // if connected
+ if (connectStatus != null && connectStatus.isConnected())
+ {
+ DataStore dataStore = clientConnection.getDataStore();
+
+ _connectionStatusListener = new ConnectionStatusListener(dataStore.getStatus(), this);
+ dataStore.getDomainNotifier().addDomainListener(_connectionStatusListener);
+
+
+
+ // DKM: dataStore needs a miners location
+ // for now, I'll use dstore.miners as default location
+ // (I've inserted the universal miner in it's minerFile.dat file)
+
+ // DY: defect 46811 The minerFile.dat does not exist in this directory which causes a
+ // java.io.FileNotFoundException to be printed to the console (not very
+ // encouraging for the end user.) So I'm setting it to the current directory (.)
+ // which should be where the code is run from
+ //dataStore.addMinersLocation("org.eclipse.dstore.miners");
+
+
+ StatusMonitor statusMonitor = StatusMonitorFactory.getInstance().getStatusMonitorFor(this, dataStore);
+
+ if (launchStatus != null && launchStatus.isConnected())
+ {
+ //dataStore.showTicket(launchStatus.getTicket()); // send security token to server, this must be done first
+ DataElement ticket = dataStore.createTicket(launchStatus.getTicket());
+ DataElement ticketStatus = dataStore.queryShowTicket(ticket);
+ //statusMonitor.waitForUpdate(ticketStatus);
+ }
+ else
+ {
+ dataStore.showTicket(null);
+ }
+
+ // Fire comm event to signal state changed
+ fireCommunicationsEvent(CommunicationsEvent.AFTER_CONNECT);
+
+ // is there a warning message?
+ String message = connectStatus.getMessage();
+ if (message != null)
+ {
+ if (message.startsWith(ClientConnection.CLIENT_OLDER))
+ {
+
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_CLIENT_OLDER_WARNING);
+ msg.makeSubstitution(getHostName());
+ }
+ else if (message.startsWith(ClientConnection.SERVER_OLDER))
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_SERVER_OLDER_WARNING);
+ msg.makeSubstitution(getHostName());
+ }
+ ShowConnectMessage msgAction = new ShowConnectMessage(msg);
+ Display.getDefault().asyncExec(msgAction);
+ }
+
+ // register the classloader for this plugin with the datastore
+ dataStore.registerLocalClassLoader(getClass().getClassLoader());
+
+ int serverVersion = getServerVersion();
+ if (serverVersion >= 8 || (serverVersion == 7 && getServerMinor() >= 1))
+ {
+ // register the preference for remote class caching with the datastore
+ IPreferenceStore store = SystemPlugin.getDefault().getPreferenceStore();
+ store.setDefault(IUniversalDStoreConstants.RESID_PREF_CACHE_REMOTE_CLASSES, IUniversalDStoreConstants.DEFAULT_PREF_CACHE_REMOTE_CLASSES);
+ boolean cacheRemoteClasses = store.getBoolean(IUniversalDStoreConstants.RESID_PREF_CACHE_REMOTE_CLASSES);
+
+ dataStore.setPreference(RemoteClassLoader.CACHING_PREFERENCE, cacheRemoteClasses ? "true" : "false");
+ }
+ else
+ {
+ dataStore.addMinersLocation(".");
+ // older servers initialized in one shot
+ DataElement schemaStatus = dataStore.getSchema();
+
+ // Initialzie the miners
+ if (monitor != null)
+ {
+ SystemMessage imsg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_INITIALIZING_SERVER);
+ monitor.subTask(imsg.getLevelOneText());
+ }
+ DataElement initStatus = dataStore.initMiners();
+ statusMonitor.waitForUpdate(schemaStatus);
+ statusMonitor.waitForUpdate(initStatus);
+ }
+
+ long t2 = System.currentTimeMillis();
+
+ System.out.println("connect time = "+(t2 - t1));
+
+
+
+ }
+ else
+ {
+ // if daemon launch failed because of an SSL problem
+ if (launchFailed && launchStatus != null && launchStatus.isSLLProblem())
+ {
+ if (launchStatus.isSLLProblem())
+ {
+ Throwable exception = launchStatus.getException();
+
+ List certs = launchStatus.getUntrustedCertificates();
+ if (certs.size() > 0)
+ {
+ ISystemKeystoreProvider provider = SystemKeystoreProviderManager.getInstance().getDefaultProvider();
+ if (provider != null)
+ {
+ if (provider.importCertificates(certs))
+ {
+ connect(monitor);
+ return;
+ }
+ }
+ }
+ else
+ {
+
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_SSL_EXCEPTION);
+ msg.makeSubstitution(launchStatus.getMessage());
+ }
+ }
+ }
+
+ // if daemon launch failed (SSL or otherwise)
+ if (launchFailed && launchStatus != null)
+ {
+ String launchMsg = launchStatus.getMessage();
+ if (launchStatus.getException() != null)
+ {
+ Throwable exception = launchStatus.getException();
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_DAEMON_FAILED_EXCEPTION);
+ msg.makeSubstitution(getHostName(), ""+serverLauncher.getDaemonPort(), exception);
+ }
+ else if (launchMsg != null && launchMsg.indexOf("Authentification Failed") != -1)
+ {
+ if (launchFailed)
+ {
+ clearPasswordCache(true);
+ }
+
+ // Display error message
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_AUTH_FAILED);
+ msg.makeSubstitution(getHostName());
+ DisplaySystemMessageAction msgAction = new DisplaySystemMessageAction(msg);
+ Display.getDefault().syncExec(msgAction);
+
+ // Re-prompt for password
+ connectException = null;
+ Display.getDefault().syncExec(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ promptForPassword(Display.getDefault().getActiveShell(), true);
+ }
+ catch (InterruptedException e)
+ {
+ connectException = e;
+ }
+ }
+ });
+
+ // Check if the user cancelled the prompt
+ if (connectException instanceof InterruptedException)
+ {
+ throw connectException;
+ }
+
+ // Try to connect again. This is a recursive call, but will only
+ // call if the user presses OK on the password prompt dialog, otherwise
+ // it will continue and return
+ connect(monitor);
+
+ // Since we got here we must be connected so skip error checking below
+ return;
+ }
+ else if (launchMsg != null)
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_DAEMON_FAILED);
+ msg.makeSubstitution(getHostName(), clientConnection.getPort(), launchMsg);
+ }
+ }
+
+ // if connection failed for known reason
+ else if (connectStatus != null && !connectStatus.isConnected())
+ {
+ if (connectStatus.getMessage().startsWith(ClientConnection.INCOMPATIBLE_SERVER_UPDATE))
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INCOMPATIBLE_UPDATE);
+ msg.makeSubstitution(getHostName());
+ }
+ else if (connectStatus.getMessage().startsWith(ClientConnection.INCOMPATIBLE_PROTOCOL))
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_INCOMPATIBLE_PROTOCOL);
+ msg.makeSubstitution(getHostName());
+ }
+ else
+ {
+ Throwable exception = connectStatus.getException();
+ if (exception != null)
+ {
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_FAILED);
+ msg.makeSubstitution(getHostName(), exception);
+ }
+ }
+ }
+
+ // if connect failed for unknown reason
+ else if (connectStatus == null)
+ {
+ SystemBasePlugin.logError("Failed to connect to remote system", null);
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_CONNECT_FAILED);
+ msg.makeSubstitution(getHostName());
+ }
+
+ // if, for some reason, we don't have a message
+ if (msg == null)
+ {
+ SystemBasePlugin.logError("Failed to connect to remote system" + connectStatus.getMessage(), null);
+ msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_COMM_CONNECT_FAILED);
+ msg.makeSubstitution(getHostName());
+ }
+
+ clientConnection.disconnect();
+ clientConnection = null;
+
+ // yantzi: artemis 6.0, check for invalid login (user ID / pwd) and reprompt for signon information
+ if (msg.getFullMessageID().startsWith(ISystemMessages.MSG_COMM_INVALID_LOGIN))
+ {
+ if (launchFailed)
+ {
+ clearPasswordCache(true);
+ }
+
+ DisplaySystemMessageAction msgAction = new DisplaySystemMessageAction(msg);
+ Display.getDefault().syncExec(msgAction);
+
+ // Re-prompt for password
+ connectException = null;
+ Display.getDefault().syncExec(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ promptForPassword(Display.getDefault().getActiveShell(), true);
+ }
+ catch (InterruptedException e)
+ {
+ connectException = e;
+ }
+ }
+ });
+
+ // Check if the user cancelled the prompt
+ if (connectException instanceof InterruptedException)
+ {
+ throw connectException;
+ }
+
+ // Try to connect again. This is a recursive call, but will only
+ // call if the user presses OK on the password prompt dialog, otherwise
+ // it will continue and return
+ connect(monitor);
+
+ // we are connected from recursive so continue
+ return;
+ }
+
+ throw new SystemMessageException(msg);
+ }
+ }
+
+ protected boolean promptForTrusting(Shell shell, X509Certificate cert)
+ {
+ return true;
+ }
+
+
+ /*
+ * Launch a DataStore server using a daemon. This method can be overridden if a custom implementation is required.
+ * The default implementation uses the daemon client that is built into ClientConnection.
+ */
+ protected ConnectionStatus launchServer(ClientConnection clientConnection, SystemSignonInformation info, int daemonPort, IProgressMonitor monitor)
+ {
+ return clientConnection.launchServer(info.getUserid(), info.getPassword(), daemonPort);
+ }
+
+ /*
+ * Launch a DataStore server using a specified server launcher. By default, this method does nothing since UniversalSystem does
+ * not know how to handle this particular launch type. This method should be overridden to provide a custom implementation
+ * of the launch.
+ */
+ protected ConnectionStatus launchServer(ClientConnection clientConnection, SystemSignonInformation info, IServerLauncherProperties launcher, IProgressMonitor monitor)
+ {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.IConnectorService#isConnected()
+ */
+ public boolean isConnected()
+ {
+ if (clientConnection != null)
+ {
+ return clientConnection.isConnected();
+ }
+
+ return false;
+ }
+
+ /**
+ * Shortcut to checking if the network is down
+ */
+ public boolean isNetworkError()
+ {
+ if (_connectionStatusListener != null)
+ {
+ return _connectionStatusListener.isConnectionDown();
+ }
+
+ return false;
+ }
+
+ /**
+ * Show any warning messages returned by host api calls.
+ * @param shell Parent UI
+ * @param warnings Vector of String or toString()'able messages.
+ */
+ public void showWarningMsgs(Shell shell, Vector warnings)
+ {
+ for (int idx = 0; idx < warnings.size(); idx++)
+ {
+ SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_GENERIC_W);
+ msg.makeSubstitution((warnings.elementAt(idx)).toString());
+ SystemMessageDialog msgDlg = new SystemMessageDialog(shell, msg);
+ msgDlg.open();
+ }
+ }
+
+ /**
+ * @return The DataStore currently being used by this connection.
+ */
+ public DataStore getDataStore()
+ {
+ if (clientConnection != null)
+ {
+ return clientConnection.getDataStore();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.AbstractConnectorService#getPasswordInformation()
+ */
+ public SystemSignonInformation getPasswordInformation()
+ {
+ // For Windows we want to avoid the signon prompt (because we never
+ // really authenticate with the remote system and this would be decieving
+ // for the end user
+
+ if (getPrimarySubSystem().getHost().getSystemType().equals(ISystemTypes.SYSTEMTYPE_WINDOWS))
+ {
+ String userid = getPrimarySubSystem().getUserId();
+ if (userid == null)
+ {
+ userid = "remoteuser";
+ }
+ SystemSignonInformation info = new SystemSignonInformation(getPrimarySubSystem().getHost().getHostName(),
+ userid, "", ISystemTypes.SYSTEMTYPE_WINDOWS);
+ return info;
+ }
+ else
+ {
+ return super.getPasswordInformation();
+ }
+ }
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.AbstractConnectorService#isPasswordCached()
+ */
+ public boolean isPasswordCached()
+ {
+ // For Windows we never prompt for userid / password so we don't need
+ // to clear the password cache
+ if (getPrimarySubSystem().getHost().getSystemType().equals(ISystemTypes.SYSTEMTYPE_WINDOWS))
+ {
+ return false;
+ }
+ else
+ {
+ return super.isPasswordCached();
+ }
+ }
+
+
+
+
+
+ public boolean hasRemoteServerLauncherProperties()
+ {
+ return getRemoteServerLauncherProperties() != null;
+ }
+
+
+
+ public boolean supportsRemoteServerLaunching()
+ {
+ return true;
+ }
+
+
+
+ public boolean supportsServerLaunchProperties()
+ {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorServiceManager.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorServiceManager.java
new file mode 100644
index 00000000000..14d42ea474c
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorServiceManager.java
@@ -0,0 +1,113 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore;
+import org.eclipse.rse.core.subsystems.AbstractConnectorServiceManager;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.model.IHost;
+
+
+
+/**
+ * ISystem manager class.
+ * There should be only one of these instantiated.
+ * Use getTheUniversalSystemManager to get that singleton.
+ *
+ */
+public class StatusMonitor implements IDomainListener, ICommunicationsListener
+{
+
+ protected Shell _shell;
+ protected IConnectorService _system;
+
+
+ protected boolean _networkDown = false;
+
+ protected List _workingStatuses;
+ protected List _cancelledStatuses;
+ protected List _doneStatuses;
+
+ protected DataStore _dataStore;
+
+ protected class FindShell implements Runnable
+ {
+ private Shell shell;
+
+ /**
+ * @see Runnable#run()
+ */
+ public void run()
+ {
+ try {
+ Shell[] shells = Display.getCurrent().getShells();
+ for (int loop = 0; loop < shells.length && shell == null; loop++) {
+ if (shells[loop].isEnabled()) {
+ shell = shells[loop];
+ }
+ }
+ } catch (Exception e) {
+ SystemBasePlugin.logError("StatusChangeListener.FindShell exception: ", e);
+ }
+ }
+ }
+
+ /**
+ * Construct a StatusChangeListener
+ *
+ * @param system the system associated with this monitor
+ * @param dataStore the dataStore associated with this monitor
+ * @param factory the diagnostic factory for this monitor
+ */
+ public StatusMonitor(IConnectorService system, DataStore dataStore, ICommunicationsDiagnosticFactory factory)
+ {
+ _system = system;
+ _dataStore = dataStore;
+ reInit();
+ }
+
+ /**
+ * Construct a StatusChangeListener
+ *
+ * @param system the system associated with this monitor
+ * @param dataStore the dataStore associated with this monitor
+ */
+ public StatusMonitor(IConnectorService system, DataStore dataStore)
+ {
+ this(system, dataStore, null);
+ }
+
+ public void reInit()
+ {
+ _networkDown = false;
+ _system.addCommunicationsListener(this);
+ _workingStatuses = new ArrayList();
+ _doneStatuses = new ArrayList();
+ _cancelledStatuses = new ArrayList();
+ _dataStore.getDomainNotifier().addDomainListener(this);
+ }
+
+ public DataStore getDataStore()
+ {
+ return _dataStore;
+ }
+
+ public void dispose()
+ {
+ _system.removeCommunicationsListener(this);
+ _workingStatuses.clear();
+ _doneStatuses.clear();
+ _cancelledStatuses.clear();
+ _dataStore.getDomainNotifier().removeDomainListener(this);
+ }
+
+ /**
+ * @see IDomainListener#listeningTo(DomainEvent)
+ */
+ public boolean listeningTo(DomainEvent event)
+ {
+ if (_workingStatuses.size() == 0)
+ {
+ return true;
+ }
+
+ DataElement parent = (DataElement)event.getParent();
+ if (_workingStatuses.contains(parent))
+ {
+ return determineStatusDone(parent);
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * @see IDomainListener#domainChanged(DomainEvent)
+ */
+ public void domainChanged(DomainEvent event)
+ {
+ if (_workingStatuses.size() == 0)
+ {
+ return;
+ }
+
+ DataElement parent = (DataElement)event.getParent();
+ if (_workingStatuses.contains(parent))
+ {
+ boolean isStatusDone = determineStatusDone(parent);
+ if (isStatusDone)
+ {
+ setDone(parent);
+ }
+ }
+ }
+
+
+ /**
+ * Determines whether the status is done.
+ * @return
+ * DataElement status = dataStore.command(dsCmd, args, deObj);
+ *
+ * StatusMonitor smon = StatusMonitorFactory.getInstance().getStatusMonitorFor(getSystem(), ds);
+ * smon.waitForUpdate(status, monitor);
+ *
true
if status done, false
otherwise.
+ */
+ protected boolean determineStatusDone(DataElement status)
+ {
+ return status.getAttribute(DE.A_VALUE).equals("done") || status.getAttribute(DE.A_NAME).equals("done");
+ }
+
+ /**
+ * @see org.eclipse.rse.core.subsystems.ICommunicationsListener#isPassiveCommunicationsListener()
+ */
+ public boolean isPassiveCommunicationsListener()
+ {
+ return false;
+ }
+
+ /**
+ * setDone(boolean)
+ */
+ public synchronized void setDone(DataElement status)
+ {
+ _workingStatuses.remove(status);
+ _doneStatuses.add(status);
+ }
+
+
+ public synchronized void setCancelled(DataElement status)
+ {
+ _workingStatuses.remove(status);
+ _cancelledStatuses.add(status);
+ }
+
+ public synchronized void setWorking(DataElement status)
+ {
+ _workingStatuses.add(status);
+ }
+
+
+ public boolean wasCancelled(DataElement status)
+ {
+ if (_cancelledStatuses.contains(status))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @see IDomainListener#getShell()
+ */
+ public Shell getShell()
+ {
+ // dy: DomainNotifier (which calls this method) requires the shell not be disposed
+ //if (shell == null) {
+ if (_shell == null || _shell.isDisposed())
+ {
+ FindShell findShell = new FindShell();
+ Display.getDefault().syncExec(findShell);
+ _shell = findShell.shell;
+ }
+ return _shell;
+ }
+
+ /**
+ * @see ICommunicationsListener#communicationsStateChange(CommunicationsEvent)
+ */
+ public void communicationsStateChange(CommunicationsEvent e)
+ {
+ if (e.getState() == CommunicationsEvent.CONNECTION_ERROR)
+ {
+ _networkDown = true;
+ }
+ else if (e.getState() == CommunicationsEvent.AFTER_DISCONNECT)
+ {
+ _networkDown = true;
+ }
+ }
+
+ /**
+ * Test if the StatusChangeListener returned because the network connection to the
+ * remote system was broken.
+ */
+ public boolean isNetworkDown()
+ {
+ return _networkDown;
+ }
+
+ public DataElement waitForUpdate(DataElement status) throws InterruptedException
+ {
+ return waitForUpdate(status, null, 0);
+ }
+
+ public DataElement waitForUpdate(DataElement status, IProgressMonitor monitor) throws InterruptedException
+ {
+ return waitForUpdate(status, monitor, 0);
+ }
+
+ public DataElement waitForUpdate(DataElement status, int wait) throws InterruptedException
+ {
+ return waitForUpdate(status, null, wait);
+ }
+
+ public synchronized DataElement waitForUpdate(DataElement status, IProgressMonitor monitor, int wait) throws InterruptedException
+ {
+ if (_networkDown && status.getDataStore().isConnected())
+ {
+ reInit();
+ }
+ if (determineStatusDone(status))
+ {
+ setDone(status);
+ return status;
+ }
+
+ setWorking(status);
+
+ Display display = Display.getCurrent();
+
+ // Prevent infinite looping by introducing a threshold for wait
+ int WaitThreshold = 600; //default. sleep(100ms) for 600 times
+ if ( wait > 0 )
+ WaitThreshold = wait*10; // 1 second means 10 sleep(100ms)
+ else if ( wait == -1 ) // force a diagnostic
+ WaitThreshold = -1;
+
+ if (display != null)
+ {
+ // Current thread is UI thread
+ while (_workingStatuses.contains(status))
+ {
+ // Process everything on event queue
+ while (display.readAndDispatch()) {}
+
+ if ((monitor != null) && (monitor.isCanceled()))
+ {
+ setCancelled(status);
+ throw new InterruptedException();
+ }
+
+ boolean statusDone = determineStatusDone(status);
+
+ if (statusDone)
+ {
+ setDone(status);
+ }
+ else
+ {
+ Thread.sleep(100);
+
+ if (WaitThreshold > 0) // update timer count if
+ // threshold not reached
+ --WaitThreshold; // decrement the timer count
+
+ if (WaitThreshold == 0)
+ {
+ // no diagnostic factory but there is a timeout
+ return status; // returning the undone status object
+ }
+ else if (_networkDown)
+ {
+ dispose();
+ throw new InterruptedException();
+ }
+ }
+ }
+
+ }
+ else
+ {
+ // Current thread is not UI thread
+ while (_workingStatuses.contains(status))
+ {
+
+ if ((monitor != null) && (monitor.isCanceled()))
+ {
+ setCancelled(status);
+ throw new InterruptedException();
+ }
+
+ boolean statusDone = determineStatusDone(status);
+
+ if (statusDone)
+ {
+ setDone(status);
+ }
+ else
+ {
+ Thread.sleep(100);
+
+ if (WaitThreshold > 0) // update timer count if
+ // threshold not reached
+ --WaitThreshold; // decrement the timer count
+
+ if (WaitThreshold == 0)
+ {
+ // no diagnostic factory but there is a timeout
+ return status; // returning the undone status object
+ }
+ else if (_networkDown)
+ {
+ dispose();
+ throw new InterruptedException();
+ }
+ }
+ }
+ }
+
+
+ return status;
+ }
+
+
+ /**
+ * Start diagnostic
+ *
+ * @param Class diagnostic is the an implementation of ICommunicationsDiagnostic
+ * @param boolean quiet is the flag to indicate if user should be prompted
+ * - true for no prompt
+ * @return ICommunciationsDiagnostic class instance
+ */
+ public ICommunicationsDiagnostic whatIsGoingOn(ICommunicationsDiagnosticFactory factory, boolean quiet, DataElement target) throws InterruptedException //@01
+ {
+ if (target == null)
+ return null;
+
+ ICommunicationsDiagnostic d = null;
+ try {
+ String name = target.getName(); /* Get the current element status name: started/working/done */
+ /* Log the current status */
+ SystemBasePlugin.logError("StatusChangeListener."+name+": " + "Communications Diagnostic started");
+ SystemBasePlugin.logError("StatusChangeListener."+name +
+ ": done = " + _doneStatuses.contains(target) +
+ "; cancelled = " + _cancelledStatuses.contains(target)+
+ "; _networkDown = " + _networkDown );
+
+ DataStore ds = _dataStore;
+ /* Log the status in DataStore */
+ SystemBasePlugin.logError("StatusChangeListener."+name+"(DataStore): " + " isConnected = " + ds.isConnected() + "; isWaiting = " + ds.isWaiting(target));
+
+ /*Log all nested DataElement's in target's parent*/
+ List deList = target.getParent().getNestedData();
+ if ( deList != null && !deList.isEmpty() ) {
+ int num = deList.size();
+ for ( int i = 0; i < num; i++)
+ {
+ DataElement child = (DataElement) deList.get(i);
+ if (child != null) {
+ SystemBasePlugin.logError("StatusChangeListener."+name+".child"+i+"(DataElement): " + child.toString());
+ DataElement descriptor = child.getDescriptor();
+ if (descriptor != null)
+ SystemBasePlugin.logError("StatusChangeListener."+name+".child"+i+"(Descriptor): " + descriptor.toString());
+ }
+ }
+ }
+ //Spawn off a diagnostic to check more stuff
+ if (factory != null) {
+ d = factory.createInstance();
+
+ //Initialize the diagnostic instance
+ //Set diagnostic id(name), server name(ds.getName()), this connection(system)
+ d.setUp(name, quiet, ds.getName(),_system, null ,null, null);
+
+ new Thread(d).start();
+ }
+
+ }
+ catch (Exception e)
+ {
+ SystemBasePlugin.logError("StatusChangeListener.ICommunicationsDiagnostic exception: ", e);
+ }
+
+ return d; // return the created diagnostic class instance
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitorFactory.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitorFactory.java
new file mode 100644
index 00000000000..a132b6e5df0
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitorFactory.java
@@ -0,0 +1,78 @@
+/********************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.connectorservice.dstore.util;
+
+import java.util.HashMap;
+
+import org.eclipse.dstore.core.model.DataStore;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+
+/**
+ * Factory for finding and creating the StatusMonitor class for a given system
+ */
+public class StatusMonitorFactory
+{
+ protected HashMap _monitorMap;
+ protected static StatusMonitorFactory _instance;
+
+ public static StatusMonitorFactory getInstance()
+ {
+ if (_instance == null)
+ {
+ _instance = new StatusMonitorFactory();
+ }
+ return _instance;
+ }
+
+ public StatusMonitorFactory()
+ {
+ _monitorMap= new HashMap();
+ }
+
+ public void removeStatusMonitorFor(IConnectorService system)
+ {
+ StatusMonitor monitor = (StatusMonitor)_monitorMap.remove(system);
+ if (monitor != null)
+ {
+ monitor.dispose();
+ }
+ }
+
+ public StatusMonitor getStatusMonitorFor(IConnectorService system, DataStore dataStore)
+ {
+ return getStatusMonitorFor(system, dataStore, null);
+ }
+
+ public StatusMonitor getStatusMonitorFor(IConnectorService system, DataStore dataStore, ICommunicationsDiagnosticFactory diagnosticFactory)
+ {
+ StatusMonitor monitor = (StatusMonitor)_monitorMap.get(system);
+ if (monitor == null)
+ {
+ monitor = new StatusMonitor(system, dataStore, diagnosticFactory);
+ _monitorMap.put(system, monitor);
+ }
+ DataStore mDataStore = monitor.getDataStore();
+ if (mDataStore != dataStore)
+ {
+ removeStatusMonitorFor(system);
+ monitor = new StatusMonitor(system, dataStore, diagnosticFactory);
+ _monitorMap.put(system, monitor);
+ }
+
+ return monitor;
+ }
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/.classpath b/rse/plugins/org.eclipse.rse.connectorservice.local/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.connectorservice.local/.classpath
@@ -0,0 +1,7 @@
+
+About This Content
+
+License
+
+About This Content
+
+License
+
+About This Content
+
+License
+
+ISystemValidator
object.
+ * If the ISystemValidator
reports an error the error message is displayed
+ * in the Dialog's message line.
+ */
+ protected SystemMessage validateNameInput()
+ {
+ errorMessage = null;
+ this.clearErrorMessage();
+ if (nameValidator != null)
+ errorMessage= nameValidator.validate(_alias.getText());
+ if (errorMessage != null)
+ setErrorMessage(errorMessage);
+ setPageComplete(errorMessage==null);
+ return errorMessage;
+ }
+
+ /**
+ * Completes processing of the wizard. If this
+ * method returns true, the wizard will close;
+ * otherwise, it will stay active.
+ * This method is an override from the parent Wizard class.
+ *
+ * @return whether the wizard finished successfully
+ */
+ public boolean performFinish()
+ {
+
+ return true;
+ }
+
+ // --------------------------------- //
+ // METHODS FOR EXTRACTING USER DATA ...
+ // --------------------------------- //
+ /**
+ * Return user-entered new file name.
+ * Call this after finish ends successfully.
+ */
+ public String getAlias()
+ {
+ return _alias.getText();
+ }
+
+ /**
+ * Return true if the page is complete, so to enable Finish.
+ * Called by wizard framework.
+ */
+ public boolean isPageComplete()
+ {
+ return (errorMessage==null) && (_alias.getText().trim().length()>0);
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardMainPage.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardMainPage.java
new file mode 100644
index 00000000000..4d5c2c1c831
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardMainPage.java
@@ -0,0 +1,218 @@
+/********************************************************************************
+ * Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * {Name} (company) - description of contribution.
+ ********************************************************************************/
+
+package org.eclipse.rse.dstore.security.wizards;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.rse.dstore.security.UniversalSecurityPlugin;
+import org.eclipse.rse.dstore.security.UniversalSecurityProperties;
+import org.eclipse.rse.dstore.security.preference.CertTableContentProvider;
+import org.eclipse.rse.dstore.security.preference.X509CertificateElement;
+import org.eclipse.rse.dstore.security.preference.X509CertificatePropertiesDialog;
+import org.eclipse.rse.dstore.security.util.GridUtil;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.ui.ISystemMessages;
+import org.eclipse.rse.ui.SystemWidgetHelpers;
+import org.eclipse.rse.ui.messages.ISystemMessageLine;
+import org.eclipse.rse.ui.validators.ISystemValidator;
+import org.eclipse.rse.ui.wizards.AbstractSystemWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+
+public class SystemImportCertWizardMainPage
+ extends AbstractSystemWizardPage
+ implements ISystemMessages, Listener
+{
+
+
+ protected SystemMessage errorMessage;
+ protected ISystemValidator nameValidator;
+ protected ISystemMessageLine msgLine;
+
+ private List _certificates;
+ private Button _propertiesButton;
+
+ private TableViewer _viewer;
+
+ /**
+ * Constructor.
+ */
+ public SystemImportCertWizardMainPage(Wizard wizard, List certs)
+ {
+ super(wizard, "NewCertificate",
+ UniversalSecurityProperties.RESID_SECURITY_TRUST_WIZ_CERTIFICATE_TITLE,
+ UniversalSecurityProperties.RESID_SECURITY_TRUST_WIZ_CERTIFICATE_DESC);
+ _certificates = certs;
+ }
+
+ /**
+ * CreateContents is the one method that must be overridden from the parent class.
+ * In this method, we populate an SWT container with widgets and return the container
+ * to the caller (JFace). This is used as the contents of this page.
+ */
+ public Control createContents(Composite parent)
+ {
+
+ Composite verbage = new Composite(parent, SWT.NULL);
+ GridLayout vlayout = new GridLayout();
+ GridData vdata = new GridData(GridData.FILL_BOTH);
+ vlayout.numColumns = 1;
+ verbage.setLayout(vlayout);
+ verbage.setLayoutData(vdata);
+
+ SystemWidgetHelpers.createLabel(verbage, UniversalSecurityProperties.RESID_SECURITY_CERTIFICATE_INFORMATION);
+ createTableViewer(verbage);
+
+ Composite b = new Composite(parent, SWT.NULL);
+ GridLayout blayout = new GridLayout();
+ GridData bdata = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.END);
+ blayout.numColumns = 3;
+ b.setLayout(blayout);
+ b.setLayoutData(bdata);
+ _propertiesButton = SystemWidgetHelpers.createPushButton(b, UniversalSecurityProperties.RESID_SECURITY_PROPERTIES_LBL, this);
+
+ return _propertiesButton;
+ }
+
+
+ private void createTableViewer(Composite parent)
+ {
+ // Create the table viewer.
+ _viewer = new TableViewer(parent, SWT.BORDER | SWT.READ_ONLY);
+
+ // Create the table control.
+ Table table = _viewer.getTable();
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ GridData data = GridUtil.createFill();
+ data.heightHint = 30;
+ data.widthHint = 80;
+ table.setLayoutData(data);
+
+ TableLayout tableLayout = new TableLayout();
+
+ TableColumn toColumn = new TableColumn(table, SWT.LEFT);
+ toColumn.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_PREF_ISSUED_TO));
+ tableLayout.addColumnData(new ColumnPixelData(90));
+
+ TableColumn frmColumn = new TableColumn(table, SWT.LEFT);
+ frmColumn.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_PREF_ISSUED_FROM));
+ tableLayout.addColumnData(new ColumnPixelData(90));
+
+ TableColumn expColumn = new TableColumn(table, SWT.RIGHT);
+ expColumn.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_PREF_EXPIRES));
+ tableLayout.addColumnData(new ColumnPixelData(180));
+ table.setLayout(tableLayout);
+
+ // Adjust the table viewer.
+ String[] properties = new String[] {"STRING", "STRING", "NUMBER"};
+ _viewer.setColumnProperties(properties);
+ _viewer.setContentProvider(new CertTableContentProvider());
+ _viewer.setLabelProvider(new NewCertTableLabelProvider());
+
+ for (int i = 0; i < _certificates.size(); i++)
+ {
+ _viewer.add(getElement(_certificates.get(i)));
+ }
+ }
+
+
+
+ public void handleEvent(Event e)
+ {
+ if (e.widget == _propertiesButton)
+ {
+ IStructuredSelection sel = (IStructuredSelection)_viewer.getSelection();
+ sel.getFirstElement();
+
+ X509CertificatePropertiesDialog dlg = new X509CertificatePropertiesDialog(getShell(), (X509CertificateElement)sel.getFirstElement());
+ dlg.open();
+ }
+ }
+
+ public X509CertificateElement getElement(Object cert)
+ {
+ if (cert instanceof X509Certificate)
+ {
+ return new X509CertificateElement(null,
+ UniversalSecurityProperties.RESID_SECURITY_TRUSTED_CERTIFICATE,
+ (X509Certificate)cert);
+ }
+ return null;
+ }
+
+ /**
+ * Return the Control to be given initial focus.
+ * Override from parent. Return control to be given initial focus.
+ */
+ protected Control getInitialFocusControl()
+ {
+ return _propertiesButton;
+ }
+
+ /**
+ * Init values using input data
+ */
+ protected void initializeInput()
+ {
+ }
+
+
+
+ /**
+ * Completes processing of the wizard. If this
+ * method returns true, the wizard will close;
+ * otherwise, it will stay active.
+ * This method is an override from the parent Wizard class.
+ *
+ * @return whether the wizard finished successfully
+ */
+ public boolean performFinish()
+ {
+
+ return true;
+ }
+
+
+
+ /**
+ * Return true if the page is complete, so to enable Finish.
+ * Called by wizard framework.
+ */
+ public boolean isPageComplete()
+ {
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/.classpath b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.classpath
@@ -0,0 +1,7 @@
+
+About This Content
+
+License
+
+