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 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.dstore.core/.cvsignore b/rse/plugins/org.eclipse.dstore.core/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.dstore.core/.project b/rse/plugins/org.eclipse.dstore.core/.project new file mode 100644 index 00000000000..f7348997d6f --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dstore.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.dstore.core/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.dstore.core/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..af4c4f485b3 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.dstore.core +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dstore.core.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.dstore.extra, + org.eclipse.ui.views +Eclipse-LazyStart: true +Export-Package: org.eclipse.dstore.core, + org.eclipse.dstore.core.client, + org.eclipse.dstore.core.java, + org.eclipse.dstore.core.miners.miner, + org.eclipse.dstore.core.model, + org.eclipse.dstore.core.server, + org.eclipse.dstore.core.util, + org.eclipse.dstore.core.util.ssl +Bundle-Vendor: Eclipse.org +Bundle-ClassPath: dstore_core.jar diff --git a/rse/plugins/org.eclipse.dstore.core/about.html b/rse/plugins/org.eclipse.dstore.core/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

About This Content

+ +

February 24, 2005

+

License

+ +

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 = ; + chomp($pwdIN); + + + @passwdStruct = getpwnam($userIN); + + if (@passwdStruct == 0) + { + print("invalid user name\n"); + 0; + } + else + { + $passwd=$passwdStruct[1]; + $encryptedPWD = crypt($pwdIN, $passwd); + $classpath=$ENV{CLASSPATH}; + $suOptions="-lp"; + + if ($passwd eq $encryptedPWD) + { + print("success\n"); + + $os = uname(); + chomp($os); + + if (lc($os) eq "aix") + { + $suOptions="-"; + } + + system("su $suOptions $userIN -c 'java -cp $classpath -DA_PLUGIN_PATH=$pathIN org.eclipse.dstore.core.server.Server $portIN $timeoutIN $ticketIN -Xshareclasses:name=RSE,verbose'"); + 1; + } + else + { + print("incorrect password\n"); + 0; + } + } +} diff --git a/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.linux b/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.linux new file mode 100644 index 00000000000..106069603a4 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.linux @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w + + +$port = "4035"; +$helpFlag = "-h"; + +if (defined($ARGV[0])) +{ + $port = $ARGV[0]; +} + + +$isHelp = $helpFlag cmp $port; +if ($isHelp == 0) +{ + print("command usage:\n"); + print("daemon.linux [ | -]\n"); + 0; +} +else +{ + $trace = $ENV{DSTORE_TRACING_ON}; + $user=`whoami`; chomp($user); + $match = $user cmp "root"; + + if ($match != 0) + { + print("To run the server daemon, you must be root\n"); + 0; + } + else + { + $dir= $ENV{PWD}; + $plugins_dir=$dir; + + $ENV{A_PLUGIN_PATH}="$plugins_dir/"; + + $oldClasspath = $ENV{CLASSPATH}; + + $ENV{"CLASSPATH"}="$plugins_dir:$plugins_dir/dstore_extra_server.jar:$plugins_dir/dstore_core.jar:$plugins_dir/dstore_miners.jar:$plugins_dir/universalminers.jar:$plugins_dir/clientserver.jar:$oldClasspath"; + + system("java -DA_PLUGIN_PATH=\$A_PLUGIN_PATH -DDSTORE_TRACING_ON=$trace org.eclipse.dstore.core.server.ServerLauncher $port"); + $ENV{CLASSPATH}=$oldClasspath; + } +} diff --git a/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.win.bat b/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.win.bat new file mode 100644 index 00000000000..558ae55ecce --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/serverscripts/daemon.win.bat @@ -0,0 +1,2 @@ +java -DA_PLUGIN_PATH=%A_PLUGIN_PATH% org.eclipse.dstore.core.server.ServerLauncher + diff --git a/rse/plugins/org.eclipse.dstore.core/serverscripts/run.win.bat b/rse/plugins/org.eclipse.dstore.core/serverscripts/run.win.bat new file mode 100644 index 00000000000..e5a5ec92cbb --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/serverscripts/run.win.bat @@ -0,0 +1 @@ +java -DA_PLUGIN_PATH=%A_PLUGIN_PATH% org.eclipse.dstore.core.server.Server 4033 120000 \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/serverscripts/ssl.properties b/rse/plugins/org.eclipse.dstore.core/serverscripts/ssl.properties new file mode 100644 index 00000000000..cf522e0b443 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/serverscripts/ssl.properties @@ -0,0 +1,41 @@ +################################################################################ +# 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. +################################################################################ + +# +# SSL Security Properties for RSE server and daemon +# + +# Specify this property as true to enable SSL +enable_ssl=false + +################################### +# Daemon Properties +################################### +# The keystore file and password need to be specified for daemon +# to use. +# +#daemon_keystore_file= +#daemon_keystore_password= + +################################### +# Server Properties +################################### +# The keystore file and password need to be specified for the +# server to use. If none is specified, the server falls back +# to use the same keystore and password as the daemon +# +#server_keystore_file= +#server_keystore_password= \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/Activator.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/Activator.java new file mode 100644 index 00000000000..38764a1d2aa --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/Activator.java @@ -0,0 +1,70 @@ +/******************************************************************************** + * 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; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.dstore.core", path); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientAttributes.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientAttributes.java new file mode 100644 index 00000000000..0a50c0c8d06 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientAttributes.java @@ -0,0 +1,57 @@ +/******************************************************************************** + * 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.client; + +import java.io.File; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.eclipse.dstore.core.model.DataStoreAttributes; + +/** + * ClientAttributes is a container of communication related + * information. + */ +public class ClientAttributes extends DataStoreAttributes +{ + + /** + * Constructor + */ + public ClientAttributes() + { + super(); + + try + { + String pluginPath = System.getProperty("A_PLUGIN_PATH"); + if ((pluginPath != null) && (pluginPath.length() > 0)) + { + setAttribute(A_PLUGIN_PATH, pluginPath + File.separator); + } + + setAttribute(A_LOCAL_NAME, InetAddress.getLocalHost().getHostName()); + setAttribute(A_LOCAL_PATH, "/tmp/"); + setAttribute(A_HOST_NAME, "local"); + setAttribute(A_HOST_PATH, "/"); + } + + catch (UnknownHostException e) + { + } + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientCommandHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientCommandHandler.java new file mode 100644 index 00000000000..f6803046ae2 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientCommandHandler.java @@ -0,0 +1,371 @@ +/******************************************************************************** + * 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.client; + +import org.eclipse.dstore.core.java.IRemoteClassInstance; +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.DataStoreResources; +import org.eclipse.dstore.core.util.Sender; + + +/** + * The ClientCommandHandler is reponsible for maintaining + * a queue of commands and periodically sending commands + * from the queue to the server side. + */ +public class ClientCommandHandler extends CommandHandler +{ + + private Sender _sender; + protected DataElement _requestClassDocumentElement; + protected DataElement _keepAliveDocumentElement; + protected DataElement _confirmKeepAliveDocumentElement; + protected DataElement _pendingKeepAliveRequest; + protected DataElement _pendingKeepAliveConfirmation; + + private static String[] _docAttributes = { + DataStoreResources.DOCUMENT_TYPE, + "client.doc.root.id", + "client.document", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _fileAttributes = { + DataStoreResources.FILE_TYPE, + "client.file.root.id", + "client.file", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _classAttributes = { + DataStoreResources.CLASS_TYPE, + "client.class.root.id", + "client.class", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _serializeAttributes = { + DataStoreResources.SERIALIZED_TYPE, + "client.serialized.root.id", + "client.serialized", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _requestClassAttributes = { + DataStoreResources.REQUEST_CLASS_TYPE, + "client.requestclass.root.id", + "client.requestclass", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _keepAliveAttributes = { + DataStoreResources.KEEPALIVE_TYPE, + "client.keepalive.root.id", + "server.keepalive", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + private static String[] _confirmKeepAliveAttributes = { + DataStoreResources.KEEPALIVECONFIRM_TYPE, + "client.keepalive.confirm.root.id", + "server.confirmkeepalive", + "doc", + "", + "", + DataStoreResources.FALSE, + "2"}; + + + protected DataElement _fileDocumentElement; + protected DataElement _docDocumentElement; + protected DataElement _classDocumentElement; + protected DataElement _serializedDocumentElement; + + /** + * Constructor + * @param sender the Sender + */ + public ClientCommandHandler(Sender sender) + { + super(); + _sender = sender; + } + + + public void setDataStore(DataStore dataStore) + { + super.setDataStore(dataStore); + _fileDocumentElement = dataStore.createTransientObject(_fileAttributes); + _docDocumentElement = dataStore.createObject(null, _docAttributes); + _classDocumentElement = dataStore.createTransientObject(_classAttributes); + _serializedDocumentElement = dataStore.createTransientObject(_serializeAttributes); + _requestClassDocumentElement = dataStore.createTransientObject(_requestClassAttributes); + _keepAliveDocumentElement = dataStore.createTransientObject(_keepAliveAttributes); + _confirmKeepAliveDocumentElement = dataStore.createTransientObject(_confirmKeepAliveAttributes); + } + + /** + * Transmits the bytes of a file from the client to the server + * @param bytes the bytes of a file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or unicode + * @param bytesStreamHandlerId indicates wwhich byte stream handler should receive the bytes + */ + public synchronized void sendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) + { + // send pending commands before file + if (_commands.size() > 0) + sendCommands(); + + //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, fileName, fileName); + DataElement document = _fileDocumentElement; + document.setAttribute(DE.A_NAME, byteStreamHandlerId); + document.setAttribute(DE.A_VALUE, byteStreamHandlerId); + document.setAttribute(DE.A_SOURCE, fileName); + document.setPendingTransfer(true); + document.setParent(null); + _sender.sendFile(document, bytes, size, binary); + } + + /** + * Transmits the bytes of a file from the client to the server + * @param bytes the bytes of a file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or unicode + */ + public synchronized void sendFile(String fileName, byte[] bytes, int size, boolean binary) + { + sendFile(fileName, bytes, size, binary, "default"); + } + + /** + * Appends bytes of a file from the client to the server + * @param bytes the bytes of a file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or unicode + * @param byteStreamHandlerId indicates which byte stream handler should receive the bytes + */ + public synchronized void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) + { + // send pending commands before file + if (_commands.size() > 0) + sendCommands(); + + //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, fileName, fileName); + + DataElement document = _fileDocumentElement; + document.setAttribute(DE.A_NAME, byteStreamHandlerId); + document.setAttribute(DE.A_VALUE, byteStreamHandlerId); + document.setAttribute(DE.A_SOURCE, fileName); + document.setPendingTransfer(true); + document.setParent(null); + _sender.sendAppendFile(document, bytes, size, binary); + } + + + /** + * Appends bytes of a file from the client to the server + * @param bytes the bytes of a file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or unicode + */ + public synchronized void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary) + { + sendAppendFile(fileName, bytes, size, binary, "default"); + } + + /** + * Called periodically to send the current queue of commands to the server + */ + public synchronized void sendCommands() + { + //DataElement commandRoot = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "client.doc"/*"client.doc." + _requests++*/); + DataElement commandRoot = _docDocumentElement; + commandRoot.removeNestedData(); + commandRoot.setPendingTransfer(true); + commandRoot.setParent(null); + while (_commands.size() > 0) + { + DataElement command = null; + //synchronized (_commands) + { + command = (DataElement)_commands.remove(0); + } + + commandRoot.addNestedData(command, false); + } + + _sender.sendDocument(commandRoot, 3); + + if (_pendingKeepAliveConfirmation != null) + { + _sender.sendKeepAliveConfirmation(_pendingKeepAliveConfirmation); + _pendingKeepAliveConfirmation = null; + } + if (_pendingKeepAliveRequest != null) + { + _sender.sendKeepAliveRequest(_pendingKeepAliveRequest); + _pendingKeepAliveRequest = null; + } + + // finished sending commands, now send all classes that are waiting + // in the queue + while (_classesToSend != null && _classesToSend.size() > 0) + { + DataElement document = null; + synchronized (_classesToSend) + { + document = (DataElement)_classesToSend.remove(0); + } + _sender.sendClass(document); + } + + + } + + public void handle() + { + if (!_commands.isEmpty() || _pendingKeepAliveConfirmation != null || _pendingKeepAliveRequest != null || !_classesToSend.isEmpty()) + { + sendCommands(); + } + } + + /** + * 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 commands before sending class + if (_commands.size() > 0) + sendCommands(); + + DataElement document = _classDocumentElement; + document.setAttribute(DE.A_NAME, className); + document.setAttribute(DE.A_SOURCE, classbyteStreamHandlerId); + //document.setAttribute(DE.A_SOURCE, className); + document.setPendingTransfer(true); + document.setParent(null); + + addClassToSend(document); + } + + /** + * 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"); + } + + /** + * Adds a class to the queue of classes (represented by DataElements) to + * be sent to the server. + * @param classElement the DataElement representing the class to be sent + */ + public void addClassToSend(DataElement classElement) + { + synchronized (_classesToSend) + { + if (!_classesToSend.contains(classElement)) + { + _classesToSend.add(classElement); + } + } + notifyInput(); + } + + + public synchronized void sendClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId) + { + // send pending commands before sending class + if (_commands.size() > 0) + sendCommands(); + + DataElement document = _serializedDocumentElement; + document.setAttribute(DE.A_NAME, runnable.toString()); + document.setAttribute(DE.A_SOURCE, deserializebyteStreamHandlerId); + document.setPendingTransfer(true); + document.setParent(null); + + + _sender.sendRemoteClassRunnable(document, runnable); + } + + /** + * Implemented to provide the means by which classes are requested + * across the comm channel. + * @param className the name of the class to request + */ + public 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); + + _sender.requestClass(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; + } + + 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; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java new file mode 100644 index 00000000000..daac64734f7 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java @@ -0,0 +1,848 @@ +/******************************************************************************** + * 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.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +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.ISSLProperties; +import org.eclipse.dstore.core.server.ServerCommandHandler; +import org.eclipse.dstore.core.server.ServerLauncher; +import org.eclipse.dstore.core.util.ExternalLoader; +import org.eclipse.dstore.core.util.Sender; +import org.eclipse.dstore.core.util.ssl.DStoreSSLContext; +import org.eclipse.dstore.core.util.ssl.DataStoreTrustManager; +import org.eclipse.dstore.extra.internal.extra.DomainNotifier; + + +/** + * ClientConnection provides the standard means of creating a new connection to + * a DataStore. + * + *
  • + * If a connection is local, then a DataStore is instantiated + * in the same process to be used by the client to communicate with miners (tools). + *
  • + * + *
  • + * If a connection is not local, then a virtual DataStore is instantiated in the + * current process to communicate with the remote DataStore. If the client wishes + * to instantiate a remote DataStore through a daemon, then ClientConnection first connects + * to the daemon requesting a DataStore at a given port, and then connects to the + * newly launched DataStore. Otherwise, a DataStore is expected to be running on + * the remote machine under the same port that the client tries to connect to. + *
  • + * + * + */ +public class ClientConnection +{ + + + private ClientAttributes _clientAttributes; + + private Socket _theSocket; + private boolean _isConnected = false; + private boolean _isRemote = false; + private DataStore _dataStore; + private DomainNotifier _domainNotifier; + private Sender _sender; + private ClientReceiver _receiver; + private ClientUpdateHandler _updateHandler; + private CommandHandler _commandHandler; + + private int _clientVersion; + private int _clientMinor; + + + private String _name; + private String _host; + private String _port; + private String _hostDirectory; + + private DataStoreTrustManager _trustManager; + + private ArrayList _loaders; + + private static final int HANDSHAKE_INCORRECT = 0; + private static final int HANDSHAKE_SERVER_OLDER = 1; + private static final int HANDSHAKE_CORRECT = 2; + private static final int HANDSHAKE_UNEXPECTED = 3; + private static final int HANDSHAKE_SERVER_NEWER = 4; + private static final int HANDSHAKE_SERVER_RECENT_OLDER = 5; + private static final int HANDSHAKE_SERVER_RECENT_NEWER = 6; + + private static final int VERSION_INDEX_PROTOCOL = 0; + private static final int VERSION_INDEX_VERSION = 1; + private static final int VERSION_INDEX_MINOR = 2; + public static String INCOMPATIBLE_SERVER_UPDATE = "Incompatible DataStore."; + public static String INCOMPATIBLE_CLIENT_UPDATE = "Incompatible DataStore."; + public static String SERVER_OLDER = "Older DataStore Server."; + public static String CLIENT_OLDER = "Older DataStore Client."; + public static String INCOMPATIBLE_PROTOCOL = "Incompatible Protocol."; + + /** + * Creates a new ClientConnection instance + * + * @param name an identifier for this connection + */ + public ClientConnection(String name) + { + _domainNotifier = new DomainNotifier(); + _name = name; + init(); + } + + /** + * Creates a new ClientConnection instance + * + * @param name an identifier for this connection + * @param initialSize the number of elements to preallocate in the DataStore + */ + public ClientConnection(String name, int initialSize) + { + _domainNotifier = new DomainNotifier(); + _name = name; + init(initialSize); + } + + /** + * Creates a new ClientConnection instance + * + * @param name an identifier for this connection + * @param notifier the notifier used to keep the user interface in synch with the DataStore + */ + public ClientConnection(String name, DomainNotifier notifier) + { + _domainNotifier = notifier; + _name = name; + init(); + } + + /** + * Creates a new ClientConnection instance + * + * @param name an identifier for this connection + * @param notifier the notifier used to keep the user interface in synch with the DataStore + * @param initialSize the number of elements to preallocate in the DataStore + */ + public ClientConnection(String name, DomainNotifier notifier, int initialSize) + { + _domainNotifier = notifier; + _name = name; + init(initialSize); + } + + + public int getClientVersion() + { + return _clientVersion; + } + + public int getClientMinor() + { + return _clientMinor; + } + + public int getServerVersion() + { + return _dataStore.getServerVersion(); + } + + public int getServerMinor() + { + return _dataStore.getServerMinor(); + } + + public void setSSLProperties(ISSLProperties properties) + { + _dataStore.setSSLProperties(properties); + } + + + + /** + * Specifies the loaders used to instantiate the miners + * + * @param loaders the loaders + */ + public void setLoaders(ArrayList loaders) + { + _loaders = loaders; + } + + /** + * Adds a loader to be used to instantiate the miners + * + * @param loader the loader + */ + public void addLoader(ExternalLoader loader) + { + if (_loaders == null) + { + _loaders = new ArrayList(); + } + _loaders.add(loader); + } + + /** + * Specifies the hostname or IP of the host to connect to + * + * @param host the hostname or IP of the machine to connect to + */ + public void setHost(String host) + { + _host = host; + _clientAttributes.setAttribute(DataStoreAttributes.A_HOST_NAME, _host); + } + + /** + * Specifies the number of the socket port to connect to + * + * @param port the number of the socket port to connect to + */ + public void setPort(String port) + { + if (port == null || port.length() == 0) + { + port = "0"; + } + + _port = port; + _clientAttributes.setAttribute(DataStoreAttributes.A_HOST_PORT, _port); + } + + /** + * Specifies the default working directory on the remote machine + * + * @param directory the remote working directory + */ + public void setHostDirectory(String directory) + { + _hostDirectory = directory; + _clientAttributes.setAttribute(DataStoreAttributes.A_HOST_PATH, _hostDirectory); + } + + /** + * Returns the hostname/IP of the host to connect to + * + * @return the hostname/IP + */ + public String getHost() + { + return _host; + } + + /** + * Returns the number of the socket port to connect to + * + * @return the number of the socket port to connect to + */ + public String getPort() + { + return _port; + } + + /** + * Returns the default working directory on the host machine + * + * @return the working directory on the host + */ + public String getHostDirectory() + { + return _hostDirectory; + } + + /** + * Indicates whether the client is connected to the DataStore + * + * @return whether the client is connected + */ + public boolean isConnected() + { + if (_isConnected) + { + return _dataStore.isConnected(); + } + + return _isConnected; + } + + /** + * Disconnects from the DataStore and cleans up DataStore meta-information + */ + public void disconnect() + { + if (_isConnected) + { + _dataStore.setConnected(false); + + if (_isRemote) + { + _commandHandler.command( + _dataStore.find(_dataStore.getRoot(), DE.A_NAME, "Exit"), + _dataStore.getHostRoot(), + false); + _receiver.finish(); + } + + _commandHandler.finish(); + + try + { + Thread.sleep(200); + } + catch (InterruptedException e) + { + System.out.println(e); + } + + _updateHandler.finish(); + _dataStore.finish(); + + _isConnected = false; + } + } + + /** + * Creates and connects to a local DataStore to work with in the current process. + * + * @return the status of the DataStore connection + */ + public ConnectionStatus localConnect() + { + _updateHandler = new ClientUpdateHandler(); + _updateHandler.start(); + + if (_loaders == null) + { + _loaders = new ArrayList(); + _loaders.add(new ExternalLoader(getClass().getClassLoader(), "*")); + } + + _commandHandler = new ServerCommandHandler(_loaders); + _commandHandler.start(); + + _dataStore.setCommandHandler(_commandHandler); + _dataStore.setUpdateHandler(_updateHandler); + _dataStore.setConnected(true); + _dataStore.setLoaders(_loaders); + _dataStore.getDomainNotifier().enable(true); + + _commandHandler.setDataStore(_dataStore); + _updateHandler.setDataStore(_dataStore); + ((ServerCommandHandler) _commandHandler).loadMiners(); + + _clientAttributes.setAttribute( + DataStoreAttributes.A_LOCAL_NAME, + _clientAttributes.getAttribute(DataStoreAttributes.A_HOST_NAME)); + _clientAttributes.setAttribute( + DataStoreAttributes.A_LOCAL_PATH, + _clientAttributes.getAttribute(DataStoreAttributes.A_HOST_PATH)); + + _isConnected = true; + + DataElement ticket = _dataStore.getTicket(); + ticket.setAttribute(DE.A_NAME, "null"); + + ConnectionStatus result = new ConnectionStatus(_isConnected); + result.setTicket(ticket.getName()); + + return result; + } + + /** + * Connects to a remote DataStore by first communicating with a remote daemon and then + * connecting to the DataStore. + * + * @param launchServer an indication of whether to launch a DataStore on the daemon on not + * @param user the user ID of the current user on the remote machine + * @param password the password of the current user on the remote machine + * @return the status of the connection + */ + public ConnectionStatus connect(boolean launchServer, String user, String password) + { + ConnectionStatus launchStatus = null; + if (launchServer) + { + launchStatus = launchServer(user, password); + if (!launchStatus.isConnected()) + { + return launchStatus; + } + } + else + { + launchStatus = new ConnectionStatus(true); + launchStatus.setTicket("null"); + } + + return connect(launchStatus.getTicket()); + } + + public DataStoreTrustManager getTrustManager() + { + if (_trustManager == null) + { + _trustManager = new DataStoreTrustManager(); + } + return _trustManager; + } + + /** + * Connects to a remote DataStore. + * A socket is created and the virtual DataStore is initialized with an update handler, command handler, + * socket sender and socket receiver. + * + * @param ticket the ticket required to be granted access to the remote DataStore + * @return the status of the connection + */ + public ConnectionStatus connect(String ticket) + { + return connect(ticket, -1); + } + + public ConnectionStatus connect(String ticket, int timeout) + { + boolean doTimeOut = (timeout > 0); + ConnectionStatus result = null; + try + { + int port = 0; + if (_port != null && _port.length() > 0) + { + port = Integer.parseInt(_port); + } + + if (_dataStore.usingSSL()) + { + String location = _dataStore.getKeyStoreLocation(); + String pw = _dataStore.getKeyStorePassword(); + DataStoreTrustManager mgr = getTrustManager(); + SSLContext context = DStoreSSLContext.getClientSSLContext(location, pw, mgr); + SSLSocketFactory factory = context.getSocketFactory(); + + _theSocket = factory.createSocket(_host, port); + if (doTimeOut && (_theSocket != null)) + _theSocket.setSoTimeout(timeout); + try + { + + ((SSLSocket) _theSocket).startHandshake(); + SSLSession session = ((SSLSocket) _theSocket).getSession(); + + } + catch (SSLHandshakeException e) + { + result = new ConnectionStatus(false, e, true, mgr.getUntrustedCerts()); + return result; + } + catch (Exception e) + { + e.printStackTrace(); + _theSocket.close(); + result = new ConnectionStatus(false, e); + return result; + } + } + else + { + _theSocket = new Socket(_host, port); + if (doTimeOut && (_theSocket != null)) + _theSocket.setSoTimeout(timeout); + } + + String msg = null; + int handshakeResult = doHandShake(); + switch (handshakeResult) + { + case HANDSHAKE_CORRECT: + result = doConnect(ticket); + break; + case HANDSHAKE_SERVER_RECENT_NEWER: + result = doConnect(ticket); + result.setMessage(CLIENT_OLDER); + break; + case HANDSHAKE_SERVER_RECENT_OLDER: + result = doConnect(ticket); + result.setMessage(SERVER_OLDER); + break; + case HANDSHAKE_SERVER_NEWER: + { + msg = INCOMPATIBLE_CLIENT_UPDATE; + msg += "\nThe server running on " + + _host + + " under port " + + _port + + " is a newer DataStore server."; + break; + } + case HANDSHAKE_SERVER_OLDER: + { + msg = INCOMPATIBLE_SERVER_UPDATE; + msg += "\nThe server running on " + + _host + + " under port " + + _port + + " is an older DataStore server."; + break; + } + case HANDSHAKE_INCORRECT: + { + msg = INCOMPATIBLE_PROTOCOL; + msg += "\nThe server running on " + + _host + + " under port " + + _port + + " is not a valid DataStore server."; + break; + } + case HANDSHAKE_UNEXPECTED: + { + msg = "Unexpected exception"; + break; + } + default: + break; + } + + if (result == null && msg != null) + { + result = new ConnectionStatus(false, msg); + } + } + catch (java.net.ConnectException e) + { + String msg = "Connection Refused."; + msg += "\nMake sure that the DataStore server is running on " + _host + " under port " + _port + "."; + result = new ConnectionStatus(false, msg); + } + catch (UnknownHostException uhe) + { + _isConnected = false; + result = new ConnectionStatus(_isConnected, uhe); + } + catch (IOException ioe) + { + _isConnected = false; + result = new ConnectionStatus(_isConnected, ioe); + } + + return result; + } + + protected ConnectionStatus doConnect(String ticket) + { + _sender = new Sender(_theSocket, _dataStore); + _updateHandler = new ClientUpdateHandler(); + _updateHandler.start(); + + _commandHandler = new ClientCommandHandler(_sender); + _commandHandler.start(); + + _dataStore.setCommandHandler(_commandHandler); + _dataStore.setUpdateHandler(_updateHandler); + _dataStore.setConnected(true); + _dataStore.getDomainNotifier().enable(true); + + _commandHandler.setDataStore(_dataStore); + _updateHandler.setDataStore(_dataStore); + + _receiver = new ClientReceiver(_theSocket, _dataStore); + _receiver.start(); + + _isConnected = true; + _isRemote = true; + ConnectionStatus result = new ConnectionStatus(_isConnected); + result.setTicket(ticket); + return result; + } + + /** + * Connects to a remote daemon and tells the daemon to launch + * a DataStore server. + * + * @param user the user ID of the current user on the remote machine + * @param password the password of the current user on the remote machine + * @return the status of the connection + */ + public ConnectionStatus launchServer(String user, String password) + { + // default daemon port is 4035 + return launchServer(user, password, ServerLauncher.DEFAULT_DAEMON_PORT); + } + + /** + * Connects to a remote daemon and tells the daemon to launch + * a DataStore server. + * + * @param user the user ID of the current user on the remote machine + * @param password the password of the current user on the remote machine + * @param daemonPort the port of the daemon + * @return the status of the connection + */ + public ConnectionStatus launchServer(String user, String password, int daemonPort) + { + ConnectionStatus result = null; + try + { + Socket launchSocket = null; + if (_dataStore.usingSSL()) + { + try + { + String location = _dataStore.getKeyStoreLocation(); + String pw = _dataStore.getKeyStorePassword(); + DataStoreTrustManager mgr = getTrustManager(); + SSLContext context = DStoreSSLContext.getClientSSLContext(location, pw, mgr); + + try + { + SocketFactory factory = context.getSocketFactory(); + SSLSocket lSocket = (SSLSocket) factory.createSocket(_host, daemonPort); + launchSocket = lSocket; + + lSocket.startHandshake(); + + SSLSession session = lSocket.getSession(); + if (session == null) + { + System.out.println("handshake failed"); + lSocket.close(); + } + } + catch (SSLHandshakeException e) + { + + result = new ConnectionStatus(false, e, true, mgr.getUntrustedCerts()); + return result; + } + catch (Exception e) + { + if (launchSocket != null) + { + launchSocket.close(); + } + e.printStackTrace(); + result = new ConnectionStatus(false, e); + + return result; + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + else + { + launchSocket = new Socket(_host, daemonPort); + } + + PrintWriter writer = null; + BufferedReader reader = null; + + // create output stream for server launcher + try + { + writer = new PrintWriter(new OutputStreamWriter(launchSocket.getOutputStream(), DE.ENCODING_UTF_8)); + writer.println(user); + writer.println(password); + writer.println(_port); + writer.flush(); + + reader = new BufferedReader(new InputStreamReader(launchSocket.getInputStream(), DE.ENCODING_UTF_8)); + String status = reader.readLine(); + + if (status != null && !status.equals("connected")) + { + result = new ConnectionStatus(false, status); + } + else + { + result = new ConnectionStatus(true); + + _port = reader.readLine(); + String ticket = reader.readLine(); + result.setTicket(ticket); + } + } + catch (java.io.IOException e) + { + e.printStackTrace(); + result = new ConnectionStatus(false, e); + } + + if (reader != null) + reader.close(); + + if (writer != null) + writer.close(); + launchSocket.close(); + } + catch (java.net.ConnectException e) + { + String msg = "Connection Refused."; + msg += "\nMake sure that the DataStore daemon is running on " + _host + "."; + result = new ConnectionStatus(false, msg); + } + catch (UnknownHostException uhe) + { + result = new ConnectionStatus(false, uhe); + } + catch (IOException ioe) + { + System.out.println(ioe); + ioe.printStackTrace(); + result = new ConnectionStatus(false, ioe); + } + + return result; + } + + /** + * Returns the DataStore that the client is connected to. + * @return the DataStore + */ + public DataStore getDataStore() + { + return _dataStore; + } + + private void init() + { + init(10000); + } + + private void init(int initialSize) + { + _clientAttributes = new ClientAttributes(); + _clientAttributes.setAttribute(DataStoreAttributes.A_ROOT_NAME, _name); + + + _dataStore = new DataStore(_clientAttributes, initialSize); + _dataStore.setDomainNotifier(_domainNotifier); + _dataStore.createRoot(); + + _host = _clientAttributes.getAttribute(DataStoreAttributes.A_HOST_NAME); + _hostDirectory = _clientAttributes.getAttribute(DataStoreAttributes.A_HOST_PATH); + _port = _clientAttributes.getAttribute(DataStoreAttributes.A_HOST_PORT); + + String[] clientVersionStr = DataStoreAttributes.DATASTORE_VERSION.split("\\."); + _clientVersion = Integer.parseInt(clientVersionStr[VERSION_INDEX_VERSION]); + _clientMinor = Integer.parseInt(clientVersionStr[VERSION_INDEX_MINOR]); + } + + private int doHandShake() + { + try + { + BufferedReader reader = new BufferedReader(new InputStreamReader(_theSocket.getInputStream(), DE.ENCODING_UTF_8)); + + + String handshake = reader.readLine(); + + _theSocket.setSoTimeout(0); + + String[] clientVersionStr = DataStoreAttributes.DATASTORE_VERSION.split("\\."); + String[] serverVersionStr = handshake.split("\\."); + + _dataStore.setServerVersion(Integer.parseInt(serverVersionStr[VERSION_INDEX_VERSION])); + _dataStore.setServerMinor(Integer.parseInt(serverVersionStr[VERSION_INDEX_MINOR])); + + + if (handshake.equals(DataStoreAttributes.DATASTORE_VERSION)) + { + return HANDSHAKE_CORRECT; + } + else + { + if (handshake.startsWith(" _clientVersion) + { + // newer server + if (_dataStore.getServerVersion() - 1 == _clientVersion) + { + return HANDSHAKE_SERVER_RECENT_NEWER; + } + else + { + return HANDSHAKE_SERVER_NEWER; + } + } + else + { + // newer client + if (_dataStore.getServerVersion() + 1 == _clientVersion) + { + return HANDSHAKE_SERVER_RECENT_OLDER; + } + else + { + return HANDSHAKE_SERVER_OLDER; + } + } + } + } + else + { + System.out.println("handshake=" + handshake); + return HANDSHAKE_INCORRECT; + } + } + + } + catch (Exception e) + { + return HANDSHAKE_UNEXPECTED; + } + + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientReceiver.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientReceiver.java new file mode 100644 index 00000000000..2eabb44a018 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientReceiver.java @@ -0,0 +1,77 @@ +/******************************************************************************** + * 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.client; + +import java.net.Socket; + +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.util.Receiver; + +/* + * The ClientReciever is responsible for recieving data from + * the server side. + */ +public class ClientReceiver extends Receiver +{ + + /** + * Constructor + */ + public ClientReceiver(Socket socket, DataStore dataStore) + { + super(socket, dataStore); + } + + /** + * Called when new data is received from the server side. + * @param documentObject the root object of incoming data + */ + public void handleDocument(DataElement documentObject) + { + if (documentObject.getName().equals("exit")) + { + _canExit = true; + } + else + { + synchronized (documentObject) + { + for (int i = 0; i < documentObject.getNestedSize(); i++) + { + DataElement rootOutput = documentObject.get(i); + _dataStore.refresh(rootOutput); + } + documentObject.removeNestedData(); + //_dataStore.deleteObject(documentObject.getParent(), documentObject); + } + } + } + + /** + * Called when an error occurs + * @param e the exception that occurred + */ + public void handleError(Throwable e) + { + DataElement status = _dataStore.getStatus(); + status.setAttribute(DE.A_NAME, e.getMessage()); + _dataStore.refresh(status); + _dataStore.setConnected(false); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientSSLProperties.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientSSLProperties.java new file mode 100644 index 00000000000..c1bba3784c2 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientSSLProperties.java @@ -0,0 +1,77 @@ +/******************************************************************************** + * 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.client; + +import org.eclipse.dstore.core.model.ISSLProperties; + +public class ClientSSLProperties implements ISSLProperties +{ + private boolean _enableSSL = false; + private String _daemonKeyStorePath; + private String _daemonKeyStorePassword; + + private String _serverKeyStorePath; + private String _serverKeyStorePassword; + + public ClientSSLProperties(boolean enableSSL, + String daemonKeystore, String daemonPassword, + String serverKeystore, String serverPassword) + { + _enableSSL = enableSSL; + _daemonKeyStorePath = daemonKeystore; + _daemonKeyStorePassword = daemonPassword; + _serverKeyStorePath = serverKeystore; + _serverKeyStorePassword = serverPassword; + } + + public ClientSSLProperties(boolean enableSSL, String keystore, String password) + { + _enableSSL = enableSSL; + _daemonKeyStorePath = keystore; + _daemonKeyStorePassword = password; + + _serverKeyStorePath = keystore; + _serverKeyStorePassword = password; + } + + public boolean usingSSL() + { + return _enableSSL; + } + + + public String getDaemonKeyStorePassword() + { + return _daemonKeyStorePassword; + } + + public String getDaemonKeyStorePath() + { + return _daemonKeyStorePath; + } + + public String getServerKeyStorePassword() + { + return _serverKeyStorePassword; + } + + public String getServerKeyStorePath() + { + return _serverKeyStorePath; + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientUpdateHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientUpdateHandler.java new file mode 100644 index 00000000000..1d3660a6fdb --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientUpdateHandler.java @@ -0,0 +1,190 @@ +/******************************************************************************** + * 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.client; + +import java.io.File; + +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.UpdateHandler; +import org.eclipse.dstore.extra.internal.extra.DomainEvent; +import org.eclipse.dstore.extra.internal.extra.IDomainNotifier; + +/** + * The ClientUpdateHandler is contains a queue of data update requests + * and periodically sends out domain notifications to domain listeners + */ +public class ClientUpdateHandler extends UpdateHandler +{ + + /** + * Constructor + */ + public ClientUpdateHandler() + { + super(); + _waitIncrement = 200; + } + + /** + * Not applicable - this is only applicable on the server side + */ + public void updateFile(String path, byte[] bytes, int size, boolean binary) + { + } + + /** + * Not applicable - this is only applicable on the server side + */ + public void updateAppendFile(String path, byte[] bytes, int size, boolean binary) + { + } + + /** + * Not applicable - this is only applicable on the server side + */ + public void updateFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) + { + } + + /** + * Not applicable - this is only applicable on the server side + */ + public void updateAppendFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) + { + } + + /** + * Notifies domain listeners that a file has been updated + * @param file the updated file + * @param object the element associated with the updated file + */ + public void updateFile(File file, DataElement object) + { + IDomainNotifier notifier = _dataStore.getDomainNotifier(); + notifier.fireDomainChanged(new DomainEvent(DomainEvent.FILE_CHANGE, object, DE.P_NESTED)); + } + + /** + * Periodically called to notify domain listeners of updated data from the + * server + */ + public void sendUpdates() + { + if (_dataStore != null && !isFinished()) + { + IDomainNotifier notifier = _dataStore.getDomainNotifier(); + while (_dataObjects.size() > 0) + { + DataElement object = null; + synchronized (_dataObjects) + { + if (_dataObjects.size() > 0) + { + object = (DataElement) _dataObjects.get(0); + _dataObjects.remove(object); + } + } + + if ((object != null)) + { + + if (!object.isUpdated() && !object.isDescriptor()) + { + + //DataElement parent = object.getParent(); + //System.out.println("notifying "+parent); + notify(object); + } + clean(object); + } + } + } + } + + private void notify(DataElement object) + { + if (object.isExpanded()) + { + object.setUpdated(true); + } + + object.setExpanded(true); + + IDomainNotifier notifier = _dataStore.getDomainNotifier(); + + if (object.getNestedSize() == 0) + { + notifier.fireDomainChanged(new DomainEvent(DomainEvent.NON_STRUCTURE_CHANGE, object, DE.P_NESTED)); + + } + else + { + notifier.fireDomainChanged(new DomainEvent(DomainEvent.INSERT, object, DE.P_NESTED)); + } + } + + /** + * Implemented to provide the means by which classes are requested + * across the comm channel. (Only applies to ServerUpdateHandler, so is a dummy method here) + * @param className the name of the class to request + */ + public void requestClass(String className) + { + } + + /** + * Impleted to provide the means by which a class on the host is updated on the client + * @param runnable + * @param deserializebyteStreamHandlerId + */ + public synchronized void updateClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId) + { + notifyInput(); + } + + /** + * Does not apply in this case. Use ClientCommandHandler.sendClass(). + */ + public void sendClass(String className, String classByteStreamHandlerId) + { + } + + /** + * Does not apply in this case. Use ClientCommandHandler.sendClass(). + */ + public void sendClass(String className) + { + } + + /** + * Does not apply in this case. Use ClientCommandHandler.sendKeepAliveRequest(). + */ + public void sendKeepAliveRequest() + { + } + + /** + * Does not apply in this case. Use ClientCommandHandler.sendKeepAliveConfirmation(). + */ + public void sendKeepAliveConfirmation() + { + } + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ConnectionStatus.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ConnectionStatus.java new file mode 100644 index 00000000000..d0635c8d0d3 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ConnectionStatus.java @@ -0,0 +1,150 @@ +/******************************************************************************** + * 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.client; + +import java.util.List; + +/** + * ConnectionStatus represents the state of a connection. This class is + * used for feedback, when a client attempts to connect to a server. + */ +public class ConnectionStatus +{ + + private boolean _connected; + private Throwable _exception; + private String _message; + private String _ticket; + private boolean _SSLProblem = false; + private List _untrustedCertificates; + + /** + * Constructor + * @param connected indicates whether a connection has been made + */ + public ConnectionStatus(boolean connected) + { + _connected = connected; + } + + /** + * Constructor + * @param connected indicates whether a connection has been made + * @param e the exception that occurred when attempting to connect + */ + public ConnectionStatus(boolean connected, Throwable e) + { + _connected = connected; + _exception = e; + _message = e.toString(); + } + + /** + * Constructor + * @param connected indicates whether a connection has been made + * @param msg a connection error message + */ + public ConnectionStatus(boolean connected, String msg) + { + _connected = connected; + _message = msg; + } + + public ConnectionStatus(boolean connected, Throwable e, boolean sslProblem, List untrustedCerts) + { + _connected = connected; + _exception = e; + _message = e.toString(); + _SSLProblem = sslProblem; + _untrustedCertificates = untrustedCerts; + } + + /** + * Sets whether the connection is successful or not + * @param flag indication of whether the connection is successful + */ + public void setConnected(boolean flag) + { + _connected = flag; + } + + /** + * Sets the connection error message + * @param message the error message + */ + public void setMessage(String message) + { + _message = message; + } + + /** + * Sets the ticket to use when connecting to a server. Typically, + * a ticket gets sent back from a server daemon so that the client + * can be granted access to the launched server DataStore + * @param ticket the ticket + */ + public void setTicket(String ticket) + { + _ticket = ticket; + } + + /** + * Indicates whether the connection was successful or not + * @return whether the connection was successful or not + */ + public boolean isConnected() + { + return _connected; + } + + /** + * Returns the error message for a connection attempt + * @return the error message + */ + public String getMessage() + { + return _message; + } + + /** + * Returns the ticket required for connecting to a server + * @return the ticket + */ + public String getTicket() + { + return _ticket; + } + + /* + * Returns the exception if there is one + * @return the exception + */ + public Throwable getException() + { + return _exception; + } + + public boolean isSLLProblem() + { + return _SSLProblem; + } + + public List getUntrustedCertificates() + { + return _untrustedCertificates; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandler.java new file mode 100644 index 00000000000..7fb752222aa --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandler.java @@ -0,0 +1,211 @@ +/******************************************************************************** + * 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.dstore.core.java; + +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +import org.eclipse.dstore.core.model.DataElement; +import org.eclipse.dstore.core.model.DataStore; + + +/** + *

    + * 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). + *

    + * + */ +public class ClassByteStreamHandler implements IClassByteStreamHandler +{ + + protected DataStore _dataStore; + protected DataElement _log; + protected static final String FILEMSG_REMOTE_SAVE_FAILED = "RSEF5006"; + + /** + * Contructor + * @param dataStore the DataStore instance + * @param the log in which to log status and messages + */ + public ClassByteStreamHandler(DataStore dataStore, DataElement log) + { + _dataStore = dataStore; + _log = log; + } + + public String getIdentifier() + { + return getClass().getName(); + } + + /** + * 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) + { + ReceiveClassThread rct = new ReceiveClassThread(className, buffer, size); + rct.start(); + } + + + /** + * Receive a class instance 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 buffer the bytes that comprise the class instance + * @param size the number of bytes in the class instance + */ + public void receiveInstanceBytes(byte[] buffer, int size) + { + ReceiveClassInstanceThread rct = new ReceiveClassInstanceThread(buffer, size); + rct.start(); + } + + 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; + } + + /** + * A new thread that can be spawned to receive the class + * + */ + protected class ReceiveClassThread extends Thread + { + private String _className; + private byte[] _buffer; + private int _size; + + public ReceiveClassThread(String className, byte[] buffer, int size) + { + _className = className; + _buffer = buffer; + _size = size; + } + + /* (non-Javadoc) + * @see java.lang.Thread#run() + */ + public void run() + { + RemoteClassLoader remoteLoader = new RemoteClassLoader(_dataStore); + remoteLoader.receiveClass(_className, _buffer, _size); + } + + } + + /** + * A new thread that can be spawned to receive the class + * + */ + protected class ReceiveClassInstanceThread extends Thread + { + private byte[] _buffer; + private int _size; + + public ReceiveClassInstanceThread(byte[] buffer, int size) + { + _buffer = buffer; + _size = size; + } + + /* (non-Javadoc) + * @see java.lang.Thread#run() + */ + public void run() + { + try + { + PipedInputStream ins = new PipedInputStream(); + + PipedOutputStream outStream = new PipedOutputStream(ins); + outStream.write(_buffer, 0, _size); + outStream.flush(); + outStream.close(); + + IRemoteClassInstance instance = loadInstance(ins); + runInstance(instance); + + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + protected IRemoteClassInstance loadInstance(InputStream ins) + { + ObjectInputStream inStream = null; + try + { + inStream = new RemoteObjectInputStream(ins, _dataStore.getRemoteClassLoader()); + + return (IRemoteClassInstance)inStream.readObject(); + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + protected void runInstance(IRemoteClassInstance instance) + { + + if (_dataStore.isVirtual()) + { + // on client notify + instance.updatedOnClient(); + } + else + { + // on server run and update client + instance.arrivedOnServer(); + _dataStore.updateRemoteClassInstance(instance, getIdentifier()); + } + } + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandlerRegistry.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandlerRegistry.java new file mode 100644 index 00000000000..7bef3a6f592 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassByteStreamHandlerRegistry.java @@ -0,0 +1,78 @@ +/******************************************************************************** + * 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.util.HashMap; + +import org.eclipse.dstore.core.model.DataStoreResources; + + +public class ClassByteStreamHandlerRegistry +{ + private HashMap _map; + private IClassByteStreamHandler _default; + public ClassByteStreamHandlerRegistry() + { + _map = new HashMap(); + } + + /** + * Registers the default class byte stream handler + * @param handler the default byte stream handler + */ + public void setDefaultClassByteStreamHandler(IClassByteStreamHandler handler) + { + _default = handler; + _map.put(DataStoreResources.DEFAULT_CLASSBYTESTREAMHANDLER, handler); + registerClassByteStreamHandler(handler); + } + + /** + * Registers a class byte stream handler. + * @param handler the handler to register + */ + public void registerClassByteStreamHandler(IClassByteStreamHandler handler) + { + _map.put(handler.getIdentifier(), handler); + } + + /** + * Returns the class 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 IClassByteStreamHandler getClassByteStreamHandler(String id) + { + IClassByteStreamHandler handler = (IClassByteStreamHandler)_map.get(id); + if (handler == null) + { + handler = _default; + } + return handler; + } + + /** + * Returns the default class byte stream handler + * @return the default + */ + public IClassByteStreamHandler getDefault() + { + return _default; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassInstanceOutputStream.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassInstanceOutputStream.java new file mode 100644 index 00000000000..e11a4c27c7f --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassInstanceOutputStream.java @@ -0,0 +1,29 @@ +/******************************************************************************** + * 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.OutputStream; + +public class ClassInstanceOutputStream extends OutputStream { + + public void write(int b) throws IOException { + // TODO Auto-generated method stub + + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassRequest.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassRequest.java new file mode 100644 index 00000000000..38601ba5e22 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/ClassRequest.java @@ -0,0 +1,141 @@ +/******************************************************************************** + * 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; + +/** + * Represents a remote class request in the RemoteClassLoader. Contains + * methods for getting the status of the request, as well as getting the + * actual class after it has been loaded. + * @author mjberger + * + */ +public class ClassRequest +{ + private boolean _requested; + private boolean _loaded; + private boolean _synchronous; + private String _className; + private Class _class = null; + + /** + * Constructs a new ClassRequest + * @param className The name of the class requested + * @param Thread optional thread that requested the class + * @param synchronous whether or not the request is synchronous + */ + public ClassRequest(String className, boolean synchronous) + { + _synchronous = synchronous; + _className = className; + _requested = false; + _loaded = false; + } + + /** + * Causes the current thread to wait until this class request has been + * fulfilled. + */ + public synchronized void waitForResponse() + { + try + { + if (!_loaded) wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + /** + * Causes all threads waiting for this class request to be filled + * to wake up. + */ + public synchronized void notifyResponse() + { + notifyAll(); + } + + /** + * Returns the class loaded, or null if it has not been loaded yet. + */ + public Class getLoadedClass() + { + return _class; + } + + /** + * Returns whether or not the class has been loaded yet. + */ + public boolean isLoaded() + { + return _loaded; + } + + /** + * Returns the name of the class requested/loaded. + */ + public String getClassName() + { + return _className; + } + + /** + * Returns whether or not the class has been requested yet. + */ + public boolean isRequested() + { + return _requested; + } + + /** + * Returns whether or not the class request is synchronous. + */ + public boolean isSynchronous() + { + return _synchronous; + } + + /** + * Call this method when the request for the class has been sent. + */ + public void setRequested(boolean requested) + { + _requested = requested; + } + + /** + * Call this method when the class has been received and loaded. + */ + public void setLoaded(boolean loaded) + { + _loaded = loaded; + } + + /** + * Sets the class represented by this object after it has been loaded. + * (Sets loaded to be true and requested to be false). Notifies all threads + * waiting on this class request that the class has been loaded. + */ + public synchronized void setLoadedClass(Class loadedClass) + { + _class = loadedClass; + setRequested(false); + setLoaded(true); + notifyAll(); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IClassByteStreamHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IClassByteStreamHandler.java new file mode 100644 index 00000000000..ec99d47133f --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/java/IClassByteStreamHandler.java @@ -0,0 +1,54 @@ +/******************************************************************************** + * Copyright (c) 2003, 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; + +/** + *

    + * 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 ".." + */ + public abstract String getVersion(); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/MinerThread.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/MinerThread.java new file mode 100644 index 00000000000..da7074eeb11 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/miners/miner/MinerThread.java @@ -0,0 +1,122 @@ +/******************************************************************************** + * 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; + +/** + * MinerThread is a utility class used for doing threaded operations in a miner. + */ +public abstract class MinerThread extends Thread +{ + + private volatile Thread minerThread; + protected boolean _isCancelled; + + /** + * Constructor + */ + public MinerThread() + { + super(); + _isCancelled = false; + } + + /** + * stops the thread + */ + public synchronized void stopThread() + { + if (minerThread != null) + { + _isCancelled = true; + + try + { + minerThread = null; + } + catch (Exception e) + { + System.out.println(e); + } + + } + notify(); + } + + /** + * runs the thread + */ + public void run() + { + Thread thisThread = Thread.currentThread(); + minerThread = thisThread; + //thisThread.setPriority(thisThread.getPriority()+1); + + //This function lets derived classes do some initialization + initializeThread(); + + while (minerThread != null && minerThread == thisThread && minerThread.isAlive() && !_isCancelled) + { + try + { + sleep(100); + // yield(); + } + catch (InterruptedException e) + { + System.out.println(e); + } + + //This function is where the Threads do real work, and return false when finished + if (!doThreadedWork()) + { + try + { + minerThread = null; + } + catch (Exception e) + { + System.out.println(e); + } + } + } + + //This function lets derived classes cleanup or whatever + cleanupThread(); + } + + /** + * Implement this method to provide initialization of this thread. + */ + public abstract void initializeThread(); + + /** + * Implement this method to provide the work implementation of this thread. + * This method gets called periodically by the miner thread so te work done + * here must be atomic. Each time this is called a incremental unit of + * work should be done. Once all the work is done, true should be + * returned. + * + * @return true if all the work is done. + */ + public abstract boolean doThreadedWork(); + + /** + * Implement this method to provide any cleanup that is required after + * all the work is done. + */ + public abstract void cleanupThread(); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandler.java new file mode 100644 index 00000000000..e1e92288d2b --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/ByteStreamHandler.java @@ -0,0 +1,282 @@ +/******************************************************************************** + * 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.File; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + *

    + * 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 DataStore.setByteStreamHandler(ByteStreamHandler). + *

    + * + */ +public class ByteStreamHandler implements IByteStreamHandler +{ + + protected DataStore _dataStore; + protected DataElement _log; + protected static final String FILEMSG_REMOTE_SAVE_FAILED = "RSEF5006"; + + /** + * Contructor + * @param dataStore the DataStore instance + */ + public ByteStreamHandler(DataStore dataStore, DataElement log) + { + _dataStore = dataStore; + _log = log; + } + + public String getId() + { + return getClass().getName(); + } + + /** + * 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) + { + remotePath = new String(remotePath.replace('\\', '/')); + DataElement status = findStatusFor(remotePath); + String fileName = _dataStore.mapToLocalPath(remotePath); + + if (fileName != null) + { + try + { + // need to create directories as well + File file = new File(fileName); + if (!file.exists()) + { + File parent = new File(file.getParent()); + parent.mkdirs(); + } + else + { + } + + File newFile = new File(fileName); + FileOutputStream fileStream = new FileOutputStream(newFile); + + if (binary) + { + fileStream.write(buffer, 0, size); + } + else + { + IByteConverter byteConverter = _dataStore.getByteConverter(); + byteConverter.setContext(file); + byte[] convertedBytes = byteConverter.convertClientBytesToHostBytes(buffer, 0, size); + fileStream.write(convertedBytes, 0, convertedBytes.length); + + /* + String bufferString = new String(buffer, 0, size, DE.ENCODING_UTF_8); + + // hack for zOS + String theOS = System.getProperty("os.name"); + if (theOS.toLowerCase().startsWith("z")) + { + bufferString = bufferString.replace('\r', ' '); + } + + OutputStreamWriter writer = new OutputStreamWriter(fileStream); + writer.write(bufferString, 0, size); + writer.flush(); + */ + } + + fileStream.close(); + if (status == null) + return; + status.setAttribute(DE.A_SOURCE, "success"); + _dataStore.refresh(status.getParent()); + } + catch (IOException e) + { + System.out.println(e); + if (status == null) + return; + status.setAttribute(DE.A_VALUE, FILEMSG_REMOTE_SAVE_FAILED); + status.setAttribute(DE.A_SOURCE, "failed"); + _dataStore.refresh(status.getParent()); + } + catch (Exception e) + { + System.out.println(e); + if (status == null) + return; + status.setAttribute(DE.A_VALUE, FILEMSG_REMOTE_SAVE_FAILED); + status.setAttribute(DE.A_SOURCE, "failed"); + _dataStore.refresh(status.getParent()); + } + } + } + + /** + * 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) + { + remotePath = new String(remotePath.replace('\\', '/')); + DataElement status = findStatusFor(remotePath); + String fileName = _dataStore.mapToLocalPath(remotePath); + + if (fileName != null) + { + try + { + // need to create directories as well + File file = new File(fileName); + if (!file.exists()) + { + File parent = new File(file.getParent()); + parent.mkdirs(); + + File newFile = new File(fileName); + FileOutputStream fileStream = new FileOutputStream(newFile); + + if (binary) + { + fileStream.write(buffer, 0, size); + } + else + { + IByteConverter byteConverter = _dataStore.getByteConverter(); + byteConverter.setContext(file); + + byte[] convertedBytes = byteConverter.convertClientBytesToHostBytes(buffer, 0, size); + fileStream.write(convertedBytes, 0, convertedBytes.length); + } + + fileStream.close(); + } + else + { + FileOutputStream outStream = new FileOutputStream(fileName, true); + + if (binary) + { + outStream.write(buffer, 0, size); + } + else + { + IByteConverter byteConverter = _dataStore.getByteConverter(); + byteConverter.setContext(file); + byte[] convertedBytes = byteConverter.convertClientBytesToHostBytes(buffer, 0, size); + outStream.write(convertedBytes, 0, convertedBytes.length); + } + + outStream.close(); + } + if (status == null) + return; + status.setAttribute(DE.A_SOURCE, "success"); + _dataStore.refresh(status.getParent()); + } + catch (IOException e) + { + System.out.println(e); + if (status == null) + return; + status.setAttribute(DE.A_VALUE, FILEMSG_REMOTE_SAVE_FAILED); + status.setAttribute(DE.A_SOURCE, "failed"); + _dataStore.refresh(status.getParent()); + } + } + } + + + + /** + * Called by 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; + +/** + *

    + * Abtract class for handling commands. A 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. + *

    + *

    + * The CommandHandler is the means by which the DataStore sends information or files from + * the client to the remote tools. + *

    + */ +public abstract class CommandHandler extends Handler +{ + + protected ArrayList _commands; + protected ArrayList _classesToSend; + + private CommandGenerator _commandGenerator; + + /** + * Constructor + */ + public CommandHandler() + { + super(); + _commands = new ArrayList(); + _classesToSend = new ArrayList(); + _commandGenerator = new CommandGenerator(); + } + + /** + * Sets the associated DataStore + */ + public void setDataStore(DataStore dataStore) + { + super.setDataStore(dataStore); + _commandGenerator.setDataStore(dataStore); + } + + /** + * Returns the associated DataStore + * @return the associated DataStore + */ + public DataStore getDataStore() + { + return _dataStore; + } + + /** + * Adds a command object to the queue + * @param command the command to add to the queue + * @param immediate indicates whether the command should be inserted first in the queue + * or whether it should be appended. + */ + public void addCommand(DataElement command, boolean immediate) + { + synchronized (_commands) + { + if (!_commands.contains(command)) + { + if (immediate) + { + _commands.add(0, command); + } + else + { + _commands.add(command); + } + } + notifyInput(); + } + } + + /** + * Periodically called to send commands from the queue. + */ + public void handle() + { + if (!_commands.isEmpty() || !_classesToSend.isEmpty()) + { + sendCommands(); + } + } + + /** + * Create and add a new command object to the command queue. + * + * @param commandDescriptor the descriptor for the new command + * @param arguments the arguments for the command + * @param object the subject of the command + * @param refArg indicates whether the subject should be represented in the command as a + * reference to the subject or the actual subject, itself + * @param immediate indicates whether the command should be first in the queue or appended to it + * @return the status object of the command + */ + public DataElement command(DataElement commandDescriptor, ArrayList arguments, DataElement object, boolean refArg, boolean immediate) + { + DataElement command = _commandGenerator.generateCommand(commandDescriptor, arguments, object, refArg); + return command(command, immediate); + } + + /** + * Create and add a new command object to the command queue. + * + * @param commandDescriptor the descriptor for the new command + * @param arg the arg for the command + * @param object the subject of the command + * @param refArg indicates whether the subject should be represented in the command as a + * reference to the subject or the actual subject, itself + * @param immediate indicates whether the command should be first in the queue or appended to it + * @return the status object of the command + */ + public DataElement command(DataElement commandDescriptor, DataElement arg, DataElement object, boolean refArg, boolean immediate) + { + DataElement command = _commandGenerator.generateCommand(commandDescriptor, arg, object, refArg); + return command(command, immediate); + } + + /** + * Create and add a new command object to the command queue. + * + * @param commandDescriptor the descriptor for the new command + * @param object the subject of the command + * @param refArg indicates whether the subject should be represented in the command as a + * reference to the subject or the actual subject, itself + * @return the status object of the command + */ + public DataElement command(DataElement commandDescriptor, DataElement object, boolean refArg) + { + DataElement command = _commandGenerator.generateCommand(commandDescriptor, object, refArg); + return command(command); + } + + /** + * Add a command object to the command queue + * @param cmd the command object to add to the queue + * @return the status object of the command + */ + public DataElement command(DataElement cmd) + { + return command(cmd, false); + } + + /** + * Add a command object to the command queue + * @param cmd the command object to add to the queue + * @param immediate indicates whether the command is to be inserted first in the queue or appended + * @return the status object of the command + */ + public DataElement command(DataElement cmd, boolean immediate) + { + DataElement status = null; + if ((cmd != null) && _dataStore != null) + { + + status = cmd.get(cmd.getNestedSize() -1); + if (status != null && !status.getName().equals(DataStoreResources.model_done)) + { + addCommand(cmd, immediate); + } + } + + return status; + } + + /** + * Removes and affectively cancels all commands from the current queue of commands + */ + public synchronized void cancelAllCommands() + { + DataElement log = _dataStore.getLogRoot(); + for (int i = 0; i < _commands.size(); i++) + { + log.removeNestedData((DataElement) _commands.get(i)); + } + + _commands.clear(); + } + + public CommandGenerator getCommandGenerator() + { + return _commandGenerator; + } + + /** + * Implemented to provide the means by which commands in the queue are sent + */ + public abstract void sendCommands(); + + + /** + * Implemented to provide the means by which file bytes are sent + * @param fileName the name of the file to send + * @param bytes to bytes of the file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + */ + public abstract void sendFile(String fileName, byte[] bytes, int size, boolean binary); + + + /** + * Implemented to provide the means by which file bytes are sent + * @param fileName the name of the file to send + * @param bytes to bytes of the file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + * @param byteStreamHandlerId indicates which byte stream handler to receive the bytes with + */ + public abstract void sendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId); + + /** + * Implemented to provide the means by which file bytes are sent and appended + * @param fileName the name of the file to send + * @param bytes to bytes of the file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + */ + public abstract void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary); + + /** + * Implemented to provide the means by which file bytes are sent and appended + * @param fileName the name of the file to send + * @param bytes to bytes of the file to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + * @param byteStreamHandlerId indicates which byte stream handler to receive the bytes with + */ + public abstract void sendAppendFile(String fileName, byte[] bytes, int size, boolean binary, String byteStreamHandlerId); + + /** + * Implemented to provide the means by which classes are sent + * across the comm channel. + * @param className the name of the class to send + */ + public abstract void sendClass(String className); + + /** + * 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 indicates which class byte stream handler to receive the class with + */ + public abstract void sendClass(String className, String classByteStreamHandlerId); + + + /** + * Runs the specified class on the remote system + */ + public abstract void sendClassInstance(IRemoteClassInstance runnable, String classByteStreamHandlerId); + + + /** + * Causes the current thread to wait until this class request has been + * fulfilled. + */ + public synchronized void waitForInput() + { + if (_commands.size() == 0 && _classesToSend.size() == 0) + { + super.waitForInput(); + } + } + + /** + * Implemented to provide the means by which classes are requested + * across the comm channel. + * @param className the name of the class to request + */ + public abstract void requestClass(String className); + + public abstract void sendKeepAliveConfirmation(); + + public abstract void sendKeepAliveRequest(); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DE.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DE.java new file mode 100644 index 00000000000..53e341c1b4f --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DE.java @@ -0,0 +1,225 @@ +/******************************************************************************** + * 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; + +/** + * DE is a container of DataElement constants. These constants + * are used to identify DataElement attributes. + * + *
  • + * Attributes beginning with "P_" indicate property attribute identifiers. + *
  • + *
  • + * Attributes beginning with "T_" indicate DataElement type attributes. + *
  • + *
  • + * Attributes beginning with "A_" indicate DataElement indexs into attributes. + *
  • + * + */ +public class DE +{ + + + /* + * The nested data (children) property identifier of a 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 DataElements. + * DataElements 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 DataElements and for communicating commands + * to miners (tools). + * + *

    + * Every 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. + *

    + * + */ +public final class DataStore +{ + + + private DataStoreAttributes _dataStoreAttributes; + + private RemoteClassLoader _remoteLoader; + + private DataElement _root; + private DataElement _descriptorRoot; + private DataElement _logRoot; + private DataElement _hostRoot; + private DataElement _minerRoot; + private DataElement _tempRoot; + private DataElement _dummy; + private DataElement _externalRoot; + private DataElement _status; + + private DataElement _ticket; + private String _remoteIP; + private DataStoreSchema _dataStoreSchema; + private CommandHandler _commandHandler; + private UpdateHandler _updateHandler; + + private IByteConverter _byteConverter; + private ByteStreamHandlerRegistry _byteStreamHandlerRegistry; + private ClassByteStreamHandlerRegistry _classbyteStreamHandlerRegistry; + + private DomainNotifier _domainNotifier; + + private ArrayList _loaders; + private ArrayList _minersLocations; + private ArrayList _localClassLoaders; + private HashMap _dataStorePreferences; + + private ISSLProperties _sslProperties; + + private boolean _autoRefresh; + + private boolean _isConnected; + private boolean _logTimes; + private int _timeout; + + private HashMap _hashMap; + private HashMap _objDescriptorMap; + private HashMap _cmdDescriptorMap; + private HashMap _relDescriptorMap; + + private ArrayList _recycled; + + private Random _random; + private int _initialSize; + + private File _traceFileHandle; + private RandomAccessFile _traceFile; + private boolean _tracingOn; + + private ArrayList _waitingStatuses = null; + + private String _userPreferencesDirectory = null; + + private HashMap _classReqRepository; + private File _cacheJar; + public static final String REMOTE_CLASS_CACHE_JARFILE_NAME = "rmt_classloader_cache"; + public static final String JARFILE_EXTENSION = ".jar"; + + private int _serverVersion; + private int _serverMinor; + + private List _lastCreatedElements; + + /** + * Creates a new 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 DataElements + */ + 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 DataElements + */ + 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 + * DataElements 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 + * DataElements 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 DataElements + * + * @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 DataElements 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 DataElements 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 DataElements 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 DataElements 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 DataElements 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 DataElements + * + * @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 DataElements. + * + * @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;i 0) + { + newJarOutput.write(buf, 0, numRead); + numRead = source.read(buf); + } + + newJarOutput.closeEntry(); + source.close(); + } + catch (IOException e) + { + System.out.println("Class caching failed. Could not recopy entry from old jar. Cleaning..."); + try { newJarOutput.close(); } catch (IOException ee) { } + if (!newJarFile.delete()) System.out.println("Couldn't erase new jarfile!"); + } + } + + // add the new class file + JarEntry newEntry = new JarEntry(className.replace('.', '/') + ".class"); + newEntry.setCompressedSize(-1); + + try + { + newJarOutput.putNextEntry(newEntry); + newJarOutput.write(bytes, 0, size); + newJarOutput.closeEntry(); + newJarOutput.close(); + } + catch (IOException e) + { + System.out.println("Class caching failed. Could not cache new class into new jar. Cleaning..."); + try { newJarOutput.close(); } catch (IOException ee) { } + if (!newJarFile.delete()) System.out.println("Couldn't erase new jarfile!"); + } + + // get rid of the old jar file + try { oldJarFile.close(); } catch (IOException ee) { } + if (!_cacheJar.delete()) System.out.println("Could not delete old cache jar."); + if (!newJarFile.renameTo(_cacheJar)) System.out.println("Could not rename new cache jar."); + + System.out.println(className + " cached in " + _cacheJar.getAbsolutePath()); + } + + protected JarOutputStream createNewCacheJar(File newJar) throws IOException + { + newJar.createNewFile(); + JarOutputStream dest = new JarOutputStream( + new FileOutputStream(newJar)); + dest.setMethod(ZipOutputStream.DEFLATED); + return dest; + } + + protected void assignCacheJar() + { + String cacheDirectory = getCacheDirectory(); + File cacheJar = new File(cacheDirectory + REMOTE_CLASS_CACHE_JARFILE_NAME + JARFILE_EXTENSION); + File nextCacheJar = new File(cacheDirectory + REMOTE_CLASS_CACHE_JARFILE_NAME + "_next" + JARFILE_EXTENSION); + if (nextCacheJar.exists()) nextCacheJar.renameTo(cacheJar); + if (!cacheJar.exists()) + { + try + { + JarOutputStream cacheOut = createNewCacheJar(cacheJar); + cacheOut.putNextEntry(new JarEntry("/")); + cacheOut.closeEntry(); + cacheOut.close(); + } + catch (IOException e) + { + e.printStackTrace(); + _cacheJar = null; + return; + } + } + _cacheJar = cacheJar; + } + + protected String getCacheDirectory() + { + String cacheDirectory = getUserPreferencesDirectory(); + if (!cacheDirectory.endsWith(File.separator)) + { + cacheDirectory = cacheDirectory + File.separator; + } + return cacheDirectory; + } + + public File getRemoteClassLoaderCache() + { + return _cacheJar; + } + + public void sendKeepAliveConfirmation() + { + if (isVirtual()) + { + _commandHandler.sendKeepAliveConfirmation(); + } + else + { + _updateHandler.sendKeepAliveConfirmation(); + } + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreAttributes.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreAttributes.java new file mode 100644 index 00000000000..7a641aa6c70 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreAttributes.java @@ -0,0 +1,95 @@ +/******************************************************************************** + * 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; + + + +/** + * This class is used to store attributes that are required + * for configurating a remote connection. + */ +public class DataStoreAttributes +{ + + public static final String DATASTORE_VERSION = "DataStore.8.0.0"; + + public static final int A_PLUGIN_PATH = 0; + public static final int A_ROOT_NAME = 1; + public static final int A_ROOT_PATH = 2; + public static final int A_HOST_NAME = 3; + public static final int A_HOST_PATH = 4; + public static final int A_HOST_PORT = 5; + public static final int A_LOCAL_NAME = 6; + public static final int A_LOCAL_PATH = 7; + public static final int A_LOG_NAME = 8; + public static final int A_LOG_PATH = 9; + public static final int A_SIZE = 10; + + private String _attributes[]; + + /** + * Constructor + */ + public DataStoreAttributes() + { + _attributes = new String[A_SIZE]; + + // root + _attributes[A_ROOT_NAME] = new String("Local"); + _attributes[A_ROOT_PATH] = new String(""); + + // log + _attributes[A_LOG_NAME] = new String("log"); + _attributes[A_LOG_PATH] = new String("log.xml"); + + // host + _attributes[A_HOST_NAME] = new String(""); + _attributes[A_HOST_PATH] = new String(""); + _attributes[A_HOST_PORT] = new String("4033"); + + // local + _attributes[A_LOCAL_NAME] = new String(""); + _attributes[A_LOCAL_PATH] = new String(""); + } + + /** + * Gets an attribute at a specified index + * @param attributeIndex the index of an attribute + * @return the attribute + */ + public String getAttribute(int attributeIndex) + { + return _attributes[attributeIndex]; + } + + /** + * Set an attribute at a specified index + * @param attributeIndex the index of an attribute + */ + public void setAttribute(int attributeIndex, String attribute) + { + _attributes[attributeIndex] = new String(attribute); + if (attributeIndex == A_PLUGIN_PATH) + { + if (_attributes[A_ROOT_PATH].length() == 0) + { + _attributes[A_ROOT_PATH] = attribute; + } + } + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.java new file mode 100644 index 00000000000..181295389f7 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.java @@ -0,0 +1,112 @@ +/******************************************************************************** + * 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 class DataStoreResources +{ + public static String model_Log_Root="Log Root"; + public static String model_Tool_Root="Tool Root"; + public static String model_Set="Set"; + public static String model_Modify="Modify"; + public static String model_timeout="timeout"; + public static String model_data="data"; + public static String model_transient="transient"; + public static String model_all="all"; + public static String model_host="host"; + public static String model_root="root"; + public static String model_descriptors="descriptors"; + public static String model_descriptor_for="descriptor for"; + public static String model_project="Project"; + public static String model_log="log"; + public static String model_deleted="deleted"; + public static String model_status="status"; + public static String model_start="start"; + public static String model_failed="failed"; + public static String model_done="done"; + public static String model_working="working"; + public static String model_progress="progress"; + public static String model_error="error"; + public static String model_warning="warning"; + public static String model_informational="informational"; + public static String model_markers="markers"; + public static String model_invocation="invocation"; + public static String model_pattern="pattern"; + public static String model_input="input"; + public static String model_output="output"; + public static String model_details="details"; + public static String model_contents="contents"; + public static String model_contents_arguments="Contents and Arguments"; + public static String model_parent="parent"; + public static String model_arguments="arguments"; + public static String model_Commands="Commands"; + public static String model_device="device"; + public static String model_directory="directory"; + public static String model_folder="folder"; + public static String model_file="file"; + public static String model_Filesystem_Objects="Filesystem Objects"; + public static String model_Container_Object="Container Object"; + public static String model_Directories="Directories"; + public static String model_Details="Details"; + public static String model_miners="miners"; + public static String model_miner="miner"; + public static String model_state="state"; + public static String model_ticket="ticket"; + public static String model_valid="valid"; + public static String model_invalid="invalid"; + public static String model_abstracted_by="abstracted by"; + public static String model_abstracts="abstracts"; + public static String model_incomplete="incomplete"; + public static String model_Miner_Details="Miner Details"; + public static String model_Hosts="Hosts"; + public static String model_Tools="Tools"; + public static String model_Schema="Schema"; + public static String model_Logged_Commands="Logged Commands"; + public static String model_Cancel="Cancel"; + public static String model_Get_Schema="Get Schema"; + public static String model_Show_Ticket="Show Ticket"; + public static String model_Init_Miners="Init Miners"; + public static String model_Set_Host="Set Host"; + public static String model_Exit="Exit"; + public static String model_Connect_to="Connect to"; + public static String model_Disconnect_from="Disconnect from"; + public static String model_Delete_Connection="Delete Connection"; + public static String model_time="time"; + public static String model_property="property"; + public static String model_start_time="start time"; + public static String model_command_time="command time"; + public static String model_Transient_Objects="Transient Objects"; + public static String model_Data="Data"; + public static String model_No_input="No input"; + public static String model_Open="Open"; + public static String model_Close="Close"; + public static String model_Refresh="Refresh"; + public static String model_Query="Query"; + public static String model_Cancellable="Cancellable"; + + public static String SERIALIZED_TYPE="SERIALIZED"; + public static String CLASS_TYPE="CLASS"; + public static String REQUEST_CLASS_TYPE="REQUEST_CLASS"; + public static String DEFAULT_CLASSBYTESTREAMHANDLER="default"; + public static String FILE_TYPE="FILE"; + public static String DOCUMENT_TYPE="DOCUMENT"; + public static String DEFAULT_BYTESTREAMHANDLER="default"; + public static String TRUE="true"; + public static String FALSE="false"; + public static String DELETED="deleted"; + public static String KEEPALIVE_TYPE="KEEPALIVE"; + public static String KEEPALIVECONFIRM_TYPE="CONFIRMKEEPALIVE"; +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.properties b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.properties new file mode 100644 index 00000000000..1a58d45947c --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreResources.properties @@ -0,0 +1,102 @@ +################################################################################ +# 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. +################################################################################ + +# NLS_MESSAGEFORMAT_NONE + +# This file contains the DataStore resources. English. + +# model types +model.Log_Root=Log Root +model.Tool_Root=Tool Root +model.Set=Set +model.Modify=Modify +model.timeout=timeout +model.data=data +model.transient=transient +model.all=all +model.host=host +model.root=root +model.descriptors=descriptors +model.descriptor_for=descriptor for +model.project=Project +model.log=log +model.deleted=deleted +model.status=status +model.start=start +model.failed=failed +model.done=done +model.working=working +model.progress=progress +model.error=error +model.warning=warning +model.informational=informational +model.markers=markers +model.invocation=invocation +model.pattern=pattern +model.input=input +model.output=output +model.details=details +model.contents=contents +model.contents&arguments=Contents and Arguments +model.parent=parent +model.arguments=arguments +model.Commands=Commands +model.device=device +model.directory=directory +model.folder=folder +model.file=file +model.Filesystem_Objects=Filesystem Objects +model.Container_Object=Container Object +model.Directories=Directories +model.Details=Details +model.miners=miners +model.miner=miner +model.state=state +model.ticket=ticket +model.valid=valid +model.invalid=invalid +model.abstracted_by=abstracted by +model.abstracts=abstracts +model.incomplete=incomplete +model.Miner_Details=Miner Details +model.Hosts=Hosts +model.Details=Details +model.Tools=Tools +model.Schema=Schema +model.Logged_Commands=Logged Commands +model.Cancel=Cancel +model.Get_Schema=Get Schema +model.Show_Ticket=Show Ticket +model.Init_Miners=Init Miners +model.Set_Host=Set Host +model.Exit=Exit +model.Connect_to=Connect to +model.Disconnect_from=Disconnect from +model.Delete_Connection=Delete Connection +model.time=time +model.property=property +model.start_time=start time +model.command_time=command time +model.start=start +model.transient=transient +model.Transient_Objects=Transient Objects +model.Data=Data +model.No_input=No input +model.Open=Open +model.Close=Close +model.Refresh=Refresh +model.Query=Query +model.Cancellable=Cancellable \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreSchema.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreSchema.java new file mode 100644 index 00000000000..6fc2e34f21c --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStoreSchema.java @@ -0,0 +1,342 @@ +/******************************************************************************** + * 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; + + +/** + * This class is used for defining the base DataStore schema. All + * miner schemas are derived from the schema defined here. This class + * provides getters for quickly getting at commonly used schema descriptors. + */ +public class DataStoreSchema +{ + + + private DataStore _dataStore; + private DataElement _abstractedBy; + private DataElement _abstracts; + private DataElement _contents; + private DataElement _container; + private DataElement _attributes; + + private DataElement _objectDescriptor; + private DataElement _commandDescriptor; + private DataElement _relationDescriptor; + + private DataElement _abstractObjectDescriptor; + private DataElement _abstractCommandDescriptor; + private DataElement _abstractRelationDescriptor; + + + public static final String C_VALIDATE_TICKET = "C_VALIDATE_TICKET"; + public static final String C_SET = "C_SET"; + public static final String C_MODIFY = "C_MODIFY"; + public static final String C_SET_HOST = "C_SET_HOST"; + public static final String C_SCHEMA = "C_SCHEMA"; + public static final String C_SET_PREFERENCE = "C_SET_PREFERENCE"; + public static final String C_ADD_MINERS = "C_ADD_MINERS"; + public static final String C_ACTIVATE_MINER = "C_ACTIVATE_MINER"; + public static final String C_INIT_MINERS = "C_INIT_MINERS"; + public static final String C_OPEN = "C_OPEN"; + public static final String C_CANCEL = "C_CANCEL"; + public static final String C_SEND_INPUT = "C_SEND_INPUT"; + public static final String C_QUERY = "C_QUERY"; + public static final String C_REFRESH = "C_REFRESH"; + public static final String C_EXIT = "C_EXIT"; + public static final String C_CLOSE = "C_CLOSE"; + public static final String C_NOTIFICATION = "C_NOTIFICATION"; + public static final String C_QUERY_INSTALL = "C_QUERY_INSTALL"; + public static final String C_QUERY_CLIENT_IP = "C_QUERY_CLIENT_IP"; + public static final String C_QUERY_JVM = "C_QUERY_JVM"; + + + /** + * Constructor + * @param dataStore the associated DataStore + */ + public DataStoreSchema(DataStore dataStore) + { + _dataStore = dataStore; + } + + /** + * Returns the abstracted by relationship descriptor + * @return the descriptor + */ + public DataElement getAbstractedByRelation() + { + return _abstractedBy; + } + + /** + * Returns the abstracts relationship descriptor + * @return the descriptor + */ + public DataElement getAbstractsRelation() + { + return _abstracts; + } + + /** + * Returns the contents relationship descriptor + * @return the descriptor + */ + public DataElement getContentsRelation() + { + return _contents; + } + + /** + * Returns the attributes relationship descriptor + * @return the descriptor + */ + public DataElement getAttributesRelation() + { + return _attributes; + } + + /** + * Returns the container base object descriptor + * @return the descriptor + */ + public DataElement getContainerType() + { + return _container; + } + + /** + * Returns the base object descriptor + * @return the descriptor + */ + public DataElement getObjectDescriptor() + { + return _objectDescriptor; + } + + + /** + * Returns the base command descriptor + * @return the descriptor + */ + public DataElement getCommandDescriptor() + { + return _commandDescriptor; + } + + /** + * Returns the base relation descriptor + * @return the descriptor + */ + public DataElement getRelationDescriptor() + { + return _relationDescriptor; + } + + + /** + * Returns the base object descriptor + * @return the descriptor + */ + public DataElement getAbstractObjectDescriptor() + { + return _abstractObjectDescriptor; + } + + + /** + * Returns the base command descriptor + * @return the descriptor + */ + public DataElement getAbstractCommandDescriptor() + { + return _abstractCommandDescriptor; + } + + /** + * Returns the base relation descriptor + * @return the descriptor + */ + public DataElement getAbstractRelationDescriptor() + { + return _abstractRelationDescriptor; + } + + + + /** + * This method is called when the DataStore is initialized. It sets + * up the base DataStore schema. + * @param schemaRoot the root object of the DataStore schema + */ + public void extendSchema(DataElement schemaRoot) + { + // miner-specific descriptors are defined in the miners when they extend the schema + + // these first elements are the most fundamental + DataElement uiCmdD = _dataStore.createObject(schemaRoot, DE.T_UI_COMMAND_DESCRIPTOR, DE.T_UI_COMMAND_DESCRIPTOR); + + _commandDescriptor = _dataStore.createCommandDescriptor(schemaRoot, DE.T_COMMAND_DESCRIPTOR); + _objectDescriptor = _dataStore.createObjectDescriptor(schemaRoot, DE.T_OBJECT_DESCRIPTOR); + _relationDescriptor = _dataStore.createRelationDescriptor(schemaRoot, DE.T_RELATION_DESCRIPTOR); + + _abstractObjectDescriptor = _dataStore.createAbstractObjectDescriptor(schemaRoot, DE.T_ABSTRACT_OBJECT_DESCRIPTOR); + _abstractCommandDescriptor = _dataStore.createAbstractCommandDescriptor(schemaRoot, DE.T_ABSTRACT_COMMAND_DESCRIPTOR); + _abstractRelationDescriptor = _dataStore.createAbstractRelationDescriptor(schemaRoot, DE.T_ABSTRACT_RELATION_DESCRIPTOR); + + // cancellable command base descriptor + DataElement cancellable = _dataStore.createAbstractObjectDescriptor(schemaRoot, DataStoreResources.model_Cancellable); + + DataElement rootD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_root); + + DataElement hostD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_host); + + DataElement logD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_log); + DataElement statusD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_status); + + DataElement deletedD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_deleted); + + // misc + DataElement allD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_all); + + DataElement invokeD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_invocation); + DataElement patternD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_pattern); + + DataElement inputD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_input); + DataElement outputD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_output); + + // types of relationships + _contents = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_contents); + _contents.setDepth(100); + + DataElement descriptorForD = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_descriptor_for); + descriptorForD.setDepth(1); + + DataElement parentD = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_parent); + parentD.setDepth(1); + + _attributes = _dataStore.createRelationDescriptor(schemaRoot, "attributes"); + _attributes.setDepth(0); + + DataElement argsD = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_arguments); + _abstracts = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_abstracts); + + _abstractedBy = _dataStore.createRelationDescriptor(schemaRoot, DataStoreResources.model_abstracted_by); + + DataElement caRelations = _dataStore.createAbstractRelationDescriptor(schemaRoot, DataStoreResources.model_contents_arguments); + _dataStore.createReference(caRelations, _contents, _contents); + _dataStore.createReference(caRelations, argsD, _contents); + + _dataStore.createReference(_objectDescriptor, _contents, _contents); + _dataStore.createReference(_objectDescriptor, parentD, _contents); + _dataStore.createReference(_objectDescriptor, _abstracts, _contents); + _dataStore.createReference(_objectDescriptor, _abstractedBy, _contents); + + _dataStore.createReference(_abstractObjectDescriptor, _contents, _contents); + _dataStore.createReference(_abstractObjectDescriptor, parentD, _contents); + _dataStore.createReference(_abstractObjectDescriptor, _abstracts, _contents); + _dataStore.createReference(_abstractObjectDescriptor, _abstractedBy, _contents); + + _dataStore.createReference(statusD, _contents, _contents); + + _dataStore.createReference(_commandDescriptor, allD, _contents); + _dataStore.createReference(_commandDescriptor, caRelations, _contents); + _dataStore.createReference(_commandDescriptor, argsD, _contents); + _dataStore.createReference(_commandDescriptor, _contents, _contents); + + DataElement logDetails = _dataStore.createAbstractObjectDescriptor(logD, DataStoreResources.model_Commands); + _dataStore.createReference(logDetails, _commandDescriptor, _contents); + _dataStore.createReference(logDetails, allD, _contents); + _dataStore.createReference(logD, caRelations, _contents); + _dataStore.createReference(logD, _contents, _contents); + + //Base Container Object + _container = _dataStore.createAbstractObjectDescriptor(schemaRoot, DataStoreResources.model_Container_Object); + _dataStore.createCommandDescriptor(_container, DataStoreResources.model_Query, "*", C_QUERY, false); + _dataStore.createReference(_container, _contents, _contents); + + // file objects + DataElement fileD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_file); + DataElement dirD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_directory); + + DataElement fsObject = _dataStore.createAbstractObjectDescriptor(schemaRoot, DataStoreResources.model_Filesystem_Objects); + + + _dataStore.createReference(_container, fsObject, _abstracts, _abstractedBy); + + _dataStore.createReference(fileD, fsObject, _abstracts, _abstractedBy); + _dataStore.createReference(fsObject, dirD, _abstracts, _abstractedBy); + + _dataStore.createReference(fsObject, fileD, _contents); + _dataStore.createReference(fsObject, dirD, _contents); + _dataStore.createReference(fsObject, fsObject, _contents); + + _dataStore.createReference(dirD, fileD, _contents); + _dataStore.createReference(dirD, dirD, _contents); + + // miner descriptors + DataElement minersD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_miners); + DataElement minerD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_miner); + DataElement dataD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_data); + DataElement transientD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_transient); + DataElement stateD = _dataStore.createObjectDescriptor(schemaRoot, DataStoreResources.model_state); + // containers + _dataStore.createReference(_container, rootD, _abstracts, _abstractedBy); + _dataStore.createReference(_container, hostD, _abstracts, _abstractedBy); + _dataStore.createReference(_container, logD, _abstracts, _abstractedBy); + _dataStore.createReference(_container, minersD, _abstracts, _abstractedBy); + _dataStore.createReference(_container, minerD, _abstracts, _abstractedBy); + _dataStore.createReference(_container, dataD, _abstracts, _abstractedBy); + + + + // basic commands + _dataStore.createCommandDescriptor(cancellable, DataStoreResources.model_Cancel, "*", C_CANCEL); + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Set, "-", C_SET, false); + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Set_Host, "-", C_SET_HOST, false); + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Init_Miners, "*", C_INIT_MINERS, false); + _dataStore.createCommandDescriptor(rootD, "Add Miners", "-", C_ADD_MINERS, false); + _dataStore.createCommandDescriptor(rootD, "Activate Miner", "-", C_ACTIVATE_MINER, false); + _dataStore.createCommandDescriptor(rootD, "Set Preference", "-", C_SET_PREFERENCE, false); + + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Show_Ticket, "-", C_VALIDATE_TICKET, false); + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Get_Schema, "*", C_SCHEMA, false); + _dataStore.createCommandDescriptor(rootD, DataStoreResources.model_Exit, "*", C_EXIT, false); + _dataStore.createCommandDescriptor(rootD, "Query Install", "*", C_QUERY_INSTALL, false); + _dataStore.createCommandDescriptor(rootD, "Query Client IP", "*", C_QUERY_CLIENT_IP, false); + _dataStore.createCommandDescriptor(rootD, "Query JVM", "*", C_QUERY_JVM, false); + + _dataStore.createCommandDescriptor(rootD, "Notification", "*", C_NOTIFICATION, false); + _dataStore.createCommandDescriptor(rootD, "Send Input", "*", C_SEND_INPUT, false); + + + // both ends have this base schema, so mark each descriptor as updated + for (int i = 0; i < schemaRoot.getNestedSize(); i++) + { + DataElement descriptor = schemaRoot.get(i); + descriptor.setUpdated(true); + + for (int j = 0; j < descriptor.getNestedSize(); j++) + { + DataElement subDescriptor = descriptor.get(j); + subDescriptor.setUpdated(true); + } + + schemaRoot.setUpdated(true); + } + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultByteConverter.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultByteConverter.java new file mode 100644 index 00000000000..06db93b94b8 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultByteConverter.java @@ -0,0 +1,91 @@ +/******************************************************************************** + * Copyright (c) 2004, 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.File; +import java.io.UnsupportedEncodingException; + +/** + * @author dmcknigh + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class DefaultByteConverter implements IByteConverter +{ + private String _clientEncoding = DE.ENCODING_UTF_8; + private String _hostEncoding = System.getProperty("file.encoding"); + public void setContext(File file) + { + } + + public void setHostEncoding(String hostEncoding) + { + _hostEncoding = hostEncoding; + } + + public void setClientEncoding(String clientEncoding) + { + _clientEncoding = clientEncoding; + } + + public byte[] convertHostBytesToClientBytes(byte[] buffer, int offset, int length) + { + byte[] convertedBytes =null; + try + { + convertedBytes = (new String(buffer, offset, length, _hostEncoding)).getBytes(_clientEncoding); + } + catch (UnsupportedEncodingException e) + { + try + { + convertedBytes = (new String(buffer, offset, length)).getBytes(_clientEncoding); + } + catch (UnsupportedEncodingException e2) + { + return buffer; + } + } + + return convertedBytes; + } + + public byte[] convertClientBytesToHostBytes(byte[] buffer, int offset, int length) + { + byte[] convertedBytes = null; + + try + { + convertedBytes = (new String(buffer, offset, length, _clientEncoding)).getBytes(_hostEncoding); + } + catch (UnsupportedEncodingException e) + { + try + { + convertedBytes = (new String(buffer, offset, length)).getBytes(_hostEncoding); + } + catch (UnsupportedEncodingException e2) + { + return buffer; + } + } + + return convertedBytes; + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/Handler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/Handler.java new file mode 100644 index 00000000000..2bd3383a134 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/Handler.java @@ -0,0 +1,161 @@ +/******************************************************************************** + * 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; + +/** + * The Handler class is the base class for the threaded mechanisms in + * the DataStore. This is a thread that periodically does some activity. + * The frequency of handling can be configured. + */ +public abstract class Handler extends Thread +{ + + + protected int _waitIncrement; + protected DataStore _dataStore; + private boolean _keepRunning; + + /** + * Constructor + */ + public Handler() + { + _keepRunning = true; + _waitIncrement = 100; + } + + /** + * Sets the time interval to wait between handling + * @param value the wait interval + */ + public void setWaitTime(int value) + { + _waitIncrement = value; + } + + /** + * Returns the time interval to wait between handling + * @return the wait interval + */ + public int getWaitTime() + { + return _waitIncrement; + } + + /** + * Sets the associated DataStore + * @param dataStore + */ + public void setDataStore(DataStore dataStore) + { + _dataStore = dataStore; + } + + /** + * Indicates whether the handler is finished or not + * @return whether the handler is finished or not + */ + public boolean isFinished() + { + return !_keepRunning; + } + + /** + * Finish handling + */ + public void finish() + { + if (_keepRunning) + { + + _waitIncrement = 0; + _keepRunning = false; + + /* causes hang + try + { + interrupt(); + join(); + } + catch (InterruptedException e) + { + System.out.println(e); + } + */ + handle(); + } + } + + /** + * Implemented to provide the periodic activity to be done in a handler. + * This method is called between wait intervals by the handler thread. + */ + public abstract void handle(); + + /** + * Runs the handler loop in a thread. + */ + public void run() + { + while (_keepRunning) + { + /* + try + { + Thread.sleep(_waitIncrement); + Thread.yield(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + finish(); + return; + } + */ + waitForInput(); + + handle(); + } + } + + /** + * Causes the current thread to wait until this class request has been + * fulfilled. + */ + public synchronized void waitForInput() + { + try + { + wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + finish(); + return; + } + } + + /** + * Causes all threads waiting for this class request to be filled + * to wake up. + */ + public synchronized void notifyInput() + { + notifyAll(); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteConverter.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteConverter.java new file mode 100644 index 00000000000..3f5ce86167a --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteConverter.java @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2004, 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.File; + +/** + * Interface for converting between host bytes and client bytes + */ +public interface IByteConverter +{ + public void setContext(File file); + public byte[] convertHostBytesToClientBytes(byte[] buffer, int offset, int length); + public byte[] convertClientBytesToHostBytes(byte[] buffer, int offset, int length); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteStreamHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteStreamHandler.java new file mode 100644 index 00000000000..cf7a31d4f24 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IByteStreamHandler.java @@ -0,0 +1,59 @@ +/******************************************************************************** + * 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; + +/** + *

    + * 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 extendSchema 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; + + +/** + *

    + * Abtract class for handling updates. A 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. + *

    + *

    + * The UpdateHandler is the means by which the DataStore sends information or files from the remote tools to the client. + *

    + */ +public abstract class UpdateHandler extends Handler +{ + + + protected ArrayList _dataObjects; + protected ArrayList _classesToSend; + + /** + * Constructor + */ + public UpdateHandler() + { + _dataObjects = new ArrayList(); + _classesToSend = new ArrayList(); + } + + /** + * Periodically called on the handler thread to sends data updates. + */ + public void handle() + { + if (!_dataObjects.isEmpty() || !_classesToSend.isEmpty()) + { + sendUpdates(); + } + } + + protected void clean(DataElement object) + { + if (_dataObjects.size() == 0) + { + clean(object, 2); + } + } + + protected synchronized void clean(DataElement object, int depth) + { + + if ((depth > 0) && (object != null) && object.getNestedSize() > 0) + { + List deletedList = _dataStore.findDeleted(object); + + for (int i = 0; i < deletedList.size(); i++) + { + DataElement child = (DataElement) deletedList.get(i); + if (child != null && child.isDeleted()) + { + DataElement parent = child.getParent(); + child.clear(); + if (parent != null) + { + parent.removeNestedData(child); + } + _dataStore.addToRecycled(child); + } + } + + deletedList.clear(); + } + + + } + + /** + * Adds a set of data objects to the update queue + * @param objects a set of objects to get updated + */ + public void update(ArrayList objects) + { + for (int i = 0; i < objects.size(); i++) + { + update((DataElement) objects.get(i)); + } + } + + /** + * Adds an object to the update queue + * @param object an object to get updated + */ + public void update(DataElement object) + { + update(object, false); + } + + /** + * Adds an object to the update queue + * @param object an object to get updated + * @param immediate true indicates that this object should be first in the queue + */ + public void update(DataElement object, boolean immediate) + { + synchronized (_dataObjects) + { + if (immediate) + { + _dataObjects.add(0, object); + handle(); + } + else + { + if (!_dataObjects.contains(object)) + { + _dataObjects.add(object); + } + else + { + + if (_dataStore != null && object != null) + { + if (object.getType().equals(DataStoreResources.model_status)) + { + if (object.getName().equals(DataStoreResources.model_done)) + { + //DKM + // move to the back of the queue + // this is done so that if status that was already queued changed to done in between + // requests, and had not yet been transferred over comm layer, the completed status + // object does not come back to client (as "done") before the results of a query + _dataObjects.remove(object); + _dataObjects.add(object); + } + } + } + } + } + notifyInput(); + } + } + + /** + * Causes the current thread to wait until this class request has been + * fulfilled. + */ + public synchronized void waitForInput() + { + if (_dataObjects.size() == 0 && _classesToSend.size() == 0) + { + super.waitForInput(); + } + } + + /** + * Implemented to provide the means by which updates on the queue are sent. + */ + public abstract void sendUpdates(); + + + /** + * Implemented to provide the means by which files are sent + * @param path the path of the file to send + * @param bytes the bytes to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + */ + public abstract void updateFile(String path, byte[] bytes, int size, boolean binary); + + /** + * Implemented to provide the means by which files are sent and appended + * @param path the path of the file to send + * @param bytes the bytes to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + */ + public abstract void updateAppendFile(String path, byte[] bytes, int size, boolean binary); + + /** + * Implemented to provide the means by which files are sent + * @param path the path of the file to send + * @param bytes the bytes to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes + */ + public abstract void updateFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId); + + /** + * Implemented to provide the means by which files are sent and appended + * @param path the path of the file to send + * @param bytes the bytes to send + * @param size the number of bytes to send + * @param binary indicates whether to send the bytes as binary or text + * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes + */ + public abstract void updateAppendFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId); + + /** + * Implemented to provide the means by which classes are requested + * across the comm channel. + * @param className the name of the class to request + */ + public abstract void requestClass(String className); + + /** + * Implemented to provide the means by which keepalive requests are sent + * across the comm channel. + */ + public abstract void sendKeepAliveRequest(); + + /** + * Impleted to provide the means by which a class on the host is updated on the client + * @param runnable + * @param deserializebyteStreamHandlerId + */ + public abstract void updateClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId); + + /** + * Implemented to provide the means by which classes are sent + * across the comm channel. + * @param className the name of the class to send + */ + public abstract void sendClass(String className); + + /** + * 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 indicates which class byte stream handler to receive the class with + */ + public abstract void sendClass(String className, String classByteStreamHandlerId); + + /** + * Implemented to provide the means by which keepalive confirmations are sent + * across the comm channel. + */ + public abstract void sendKeepAliveConfirmation(); + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ConnectionEstablisher.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ConnectionEstablisher.java new file mode 100644 index 00000000000..4407afd5b6d --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/ConnectionEstablisher.java @@ -0,0 +1,433 @@ +/******************************************************************************** + * 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.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.BindException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; + +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.ISSLProperties; +import org.eclipse.dstore.core.util.ExternalLoader; +import org.eclipse.dstore.core.util.Sender; +import org.eclipse.dstore.core.util.ssl.DStoreSSLContext; + +/** + * ConnectionEstablisher is responsible for managing the server DataStore and + * facilitating the communication between client and server DataStores. + * + */ +public class ConnectionEstablisher +{ + + + private ServerSocket _serverSocket; + private static boolean _continue; + + private ArrayList _receivers; + + private ServerCommandHandler _commandHandler; + private ServerUpdateHandler _updateHandler; + + private ServerAttributes _serverAttributes = new ServerAttributes(); + private DataStore _dataStore; + + private int _maxConnections; + private int _timeout; + + + /** + * Creates the default ConnectionEstablisher. Communication occurs + * on a default port, there is no timeout and no ticket is required + * for a client to work with the DataStore. + * + */ + public ConnectionEstablisher() + { + String port = _serverAttributes.getAttribute(DataStoreAttributes.A_HOST_PORT); + setup(port, null, null); + } + + /** + * Creates a ConnectionEstablisher. Communication occurs + * on the specified port, there is no timeout and no ticket is required + * for a client to work with the DataStore. + * + * @param port the number of the socket port + */ + public ConnectionEstablisher(String port) + { + setup(port, null, null); + } + + /** + * Creates a ConnectionEstablisher. Communication occurs + * on the specified port, a timeout value indicates the idle wait + * time before shutting down, and no ticket is required + * for a client to work with the DataStore. + * + * @param port the number of the socket port + * @param timeout the idle duration to wait before shutting down + */ + public ConnectionEstablisher(String port, String timeout) + { + setup(port, timeout, null); + } + + /** + * Creates a ConnectionEstablisher. Communication occurs + * on the specified port, a timeout value indicates the idle wait + * time before shutting down, and ticket specified the required + * ticket for a client to present in order to work with the DataStore. + * + * @param port the number of the socket port + * @param timeout the idle duration to wait before shutting down + * @param ticket validation id required by the client to access the DataStore + */ + public ConnectionEstablisher(String port, String timeout, String ticket) + { + setup(port, timeout, ticket); + } + + + /** + * Starts the run loop for the ConnectionEstablisher. + */ + public void start() + { + run(); + } + + + + /** + * Returns the DataStore. + * + * @return the DataStore + */ + public DataStore getDataStore() + { + return _dataStore; + } + + /** + * Tells the connection establisher to clean up and shutdown + */ + public void finished(ServerReceiver receiver) + { + _updateHandler.removeSenderWith(receiver.socket()); + _receivers.remove(receiver); + //if (_receivers.size() == 0) + { + _continue = false; + _commandHandler.finish(); + _updateHandler.finish(); + _dataStore.finish(); + System.out.println(ServerReturnCodes.RC_FINISHED); + System.exit(0); + } + } + + private void waitForConnections() + { + while (_continue == true) + { + try + { + Socket newSocket = _serverSocket.accept(); + if (_dataStore.usingSSL()) + { + + // wait for connection + SSLSocket sslSocket = (SSLSocket)newSocket; + sslSocket.setUseClientMode(false); + sslSocket.setNeedClientAuth(false); + SSLSession session = sslSocket.getSession(); + + if (session == null) + { + System.out.println("handshake failed"); + sslSocket.close(); + return; + } + } + + doHandShake(newSocket); + newSocket.setKeepAlive(true); + + ServerReceiver receiver = new ServerReceiver(newSocket, this); + Sender sender = new Sender(newSocket, _dataStore); + + // add this connection to list of elements + _receivers.add(receiver); + _updateHandler.addSender(sender); + + receiver.start(); + + if (_receivers.size() == 1) + { + _updateHandler.start(); + _commandHandler.start(); + } + + if (_receivers.size() == _maxConnections) + { + _continue = false; + _serverSocket.close(); + + } + } + catch (IOException ioe) + { + System.err.println(ServerReturnCodes.RC_CONNECTION_ERROR); + System.err.println("Server: error initializing socket: " + ioe); + _continue = false; + } + } + } + + + + + private ServerSocket createSocket(String portStr) throws UnknownHostException + { + ServerSocket serverSocket = null; + SSLContext sslContext = null; + // port + int port = 0; + + if (_dataStore.usingSSL()) + { + String keyStoreFileName = _dataStore.getKeyStoreLocation(); + String keyStorePassword = _dataStore.getKeyStorePassword(); + + try + { + sslContext = DStoreSSLContext.getServerSSLContext(keyStoreFileName, keyStorePassword); + } + catch (Exception e) + { + + } + } + + // determine if portStr is a port range or just a port + String[] range = portStr.split("-"); + if (range.length == 2) + { + int lPort = 0; + int hPort = 0; + try + { + lPort = Integer.parseInt(range[0]); + hPort = Integer.parseInt(range[1]); + } + catch (Exception e) + { + } + + for (int i = lPort; i < hPort; i++) + { + // create server socket from port + try + { + if (_dataStore.usingSSL()) + { + try + { + serverSocket = sslContext.getServerSocketFactory().createServerSocket(i); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + else + { + serverSocket = new ServerSocket(i); + } + } + catch (Exception e) + { + _dataStore.trace(e); + } + if (serverSocket != null && serverSocket.getLocalPort() > 0) + { + return serverSocket; + } + } + } + else + { + port = Integer.parseInt(portStr); + + + // create server socket from port + if (_dataStore.usingSSL()) + { + try + { + serverSocket = sslContext.getServerSocketFactory().createServerSocket(port); + } + catch (Exception e) + { + _dataStore.trace(e); + } + } + else + { + try + { + serverSocket = new ServerSocket(port); + } + catch (Exception e) + { + _dataStore.trace(e); + } + } + } + return serverSocket; + } + + /** + * Create the DataStore and initializes it's handlers and communications. + * + * @param portStr the number of the socket port + * @param timeoutStr the idle duration to wait before shutting down + * @param ticketStr validation id required by the client to access the DataStore + */ + private void setup(String portStr, String timeoutStr, String ticketStr) + { + _maxConnections = 1; + + + ArrayList loaders = new ArrayList(); + loaders.add(new ExternalLoader(getClass().getClassLoader(), "*")); + _commandHandler = new ServerCommandHandler(loaders); + _updateHandler = new ServerUpdateHandler(); + + String pluginPath = System.getProperty("A_PLUGIN_PATH"); + ISSLProperties sslProperties = new ServerSSLProperties(); + + _dataStore = new DataStore(_serverAttributes, _commandHandler, _updateHandler, null); + _dataStore.setSSLProperties(sslProperties); + + DataElement ticket = _dataStore.getTicket(); + ticket.setAttribute(DE.A_NAME, ticketStr); + + _updateHandler.setDataStore(_dataStore); + _commandHandler.setDataStore(_dataStore); + + _receivers = new ArrayList(); + _continue = true; + + try + { + + _serverSocket = createSocket(portStr); + if (_serverSocket == null) + { + System.err.println(ServerReturnCodes.RC_BIND_ERROR); + _continue = false; + } + else + { + // timeout + if (timeoutStr != null) + { + _timeout = Integer.parseInt(timeoutStr); + } + else + { + _timeout = 120000; + } + + if (_timeout > 0) + { + _serverSocket.setSoTimeout(_timeout); + } + + System.err.println(ServerReturnCodes.RC_SUCCESS); + System.err.println(_serverSocket.getLocalPort()); + try + { + System.err.println("Server running on: " + InetAddress.getLocalHost().getHostName()); + } + catch (UnknownHostException e) + { + // keep running + } + } + } + catch (UnknownHostException e) + { + System.err.println(ServerReturnCodes.RC_UNKNOWN_HOST_ERROR); + _continue = false; + } + catch (BindException e) + { + System.err.println(ServerReturnCodes.RC_BIND_ERROR); + _continue = false; + } + catch (IOException e) + { + System.err.println(ServerReturnCodes.RC_GENERAL_IO_ERROR); + _continue = false; + } + catch (SecurityException e) + { + System.err.println(ServerReturnCodes.RC_SECURITY_ERROR); + _continue = false; + } + } + + private void run() + { + waitForConnections(); + } + + private void doHandShake(Socket socket) + { + try + { + BufferedWriter bwriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), DE.ENCODING_UTF_8)); + PrintWriter writer = new PrintWriter(bwriter); + + writer.println(DataStoreAttributes.DATASTORE_VERSION); + writer.flush(); + } + catch (IOException e) + { + System.out.println(e); + } + + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/MinerLoader.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/MinerLoader.java new file mode 100644 index 00000000000..cf6b9747095 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/server/MinerLoader.java @@ -0,0 +1,419 @@ +/******************************************************************************** + * 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.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; + +import org.eclipse.dstore.core.java.RemoteClassLoader; +import org.eclipse.dstore.core.miners.miner.Miner; +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.ISchemaExtender; +import org.eclipse.dstore.core.model.ISchemaRegistry; +import org.eclipse.dstore.core.util.ExternalLoader; + +/** + * MinerLoader is an implementation of 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 ExternalLoaders 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 ExternalLoaders 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; + +/** + *

    + * 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. + *

    + */ +public class XMLgenerator +{ + + private int _state; + + private StringBuffer _document; + + private int _indent; + private Stack _tagStack; + + private PrintStream _fileWriter; + private BufferedWriter _dataWriter; + + private int _bufferSize; + private boolean _generateBuffer; + private boolean _ignoreDeleted; + + private DataStore _dataStore; + + public static final int EMPTY = 0; + public static final int OPEN = 1; + public static final int CLOSE = 2; + public static final int BODY = 3; + + /** + * Constructor + * @param dataStore the associated DataStore + */ + public XMLgenerator(DataStore dataStore) + { + _dataStore = dataStore; + _state = EMPTY; + _bufferSize = 100000; + + _document = new StringBuffer(_bufferSize); + + _indent = 0; + _generateBuffer = true; + _ignoreDeleted = false; + _tagStack = new Stack(); + } + + /** + * Indicate whether DataElements marked as deleted should be sent. + * @param flag whether deleted elements should be sent + */ + public void setIgnoreDeleted(boolean flag) + { + _ignoreDeleted = flag; + } + + /** + * Sets the file writer used for file transfer + * @param writer the file writer used for file transfer + */ + public void setFileWriter(PrintStream writer) + { + _fileWriter = writer; + } + + /** + * Sets the data writer used for XML transfer + * @param writer the data writer used for XML transfer + */ + public void setDataWriter(BufferedWriter writer) + { + _dataWriter = writer; + } + + /** + * Set the buffer size + * @param size of the buffer used for transmitting packets + */ + public void setBufferSize(int size) + { + _bufferSize = size; + } + + /** + * Indicate whether the buffer attribute of each DataElement should be + * transferred + * @param flag whether the buffer should be transferred + */ + public void setGenerateBuffer(boolean flag) + { + _generateBuffer = flag; + } + + private void append(char c) + { + _document.append(c); + } + + private void append(String buffer) + { + _document.append(buffer); + } + + private void append(StringBuffer buffer) + { + _document.append(buffer); + } + + private void nextLine() + { + if (_dataWriter != null) + { + _document.append('\n'); + + int length = _document.length(); + if (length > _bufferSize) + { + flushData(); + } + } + } + + /** + * Send all buffered data through the pipe. + */ + public void flushData() + { + if (_document.length() > 0 && _dataWriter != null) + { + try + { + _dataWriter.write(_document.toString(), 0, _document.length()); + _dataWriter.write('\n'); + _dataWriter.flush(); + _document.setLength(0); + } + catch (Exception e) + { + _dataStore.trace(e); + _dataWriter = null; + } + } + } + + private void indent() + { + for (int i = 0; i < _indent; i++) + { + append(' '); + } + } + + private void startTag(String name) + { + if (_state == OPEN) + { + append('>'); + _indent++; + } + if (_state == CLOSE) + { + _indent--; + } + if (_state == BODY) + { + nextLine(); + } + indent(); + if (_document == null) + { + append('<'); + append(name); + } + else + { + append('<'); + append(name); + } + _tagStack.push(name); + _state = OPEN; + } + + private void endTag(String name) + { + String top = (String) _tagStack.pop(); + if (_state == CLOSE) + { + } + else if (_state == OPEN) + { + if (top == name) + { + append("/>"); + if (_tagStack.empty()) + { + _state = CLOSE; + } + else + { + _state = BODY; + } + } + } + else if (_state == BODY) + { + if (top == name) + { + nextLine(); + _indent--; + indent(); + append("'); + if (_tagStack.empty()) + { + _state = CLOSE; + } + } + } + } + + private void addAttribute(String name, String value) + { + if (_state != OPEN) + { + } + + StringBuffer niceValue = null; + if (value != null) + { + niceValue = prepareStringForXML(value); + + append(' '); + append(name); + append("=\""); + append(niceValue); + append('"'); + } + else + { + append(' '); + append(name); + append("=\"\""); + } + + } + + private void addFile(byte[] bytes, int size, boolean binary) + { + if (_state == OPEN) + { + append('>'); + + _indent++; + _state = BODY; + } + if (_state == BODY) + { + flushData(); + + // send everything across + if (binary) + { + _fileWriter.write(bytes, 0, size); + _fileWriter.flush(); + } + else + { + try + { + _dataWriter.write(new String(bytes), 0, size); + _dataWriter.flush(); + } + catch (IOException e) + { + _dataStore.trace(e); + } + } + } + else if (_state == EMPTY) + { + } + else if (_state == CLOSE) + { + } + } + + private void addData(StringBuffer data) + { + if (_state == OPEN) + { + append('>'); + + _indent++; + _state = BODY; + } + if (_state == BODY) + { + if (_generateBuffer && data != null && (data.length() > 0)) + { + StringBuffer text = prepareStringForXML(data); + if (text != null && text.length() > 0) + { + nextLine(); + indent(); + append(""); + nextLine(); + indent(); + append(text.toString()); + nextLine(); + indent(); + append(""); + } + } + else + { + append(""); + } + } + else if (_state == EMPTY) + { + } + else if (_state == CLOSE) + { + } + } + + /** + * Returns the current serialized document + * @return the current document + */ + public StringBuffer document() + { + return _document; + } + + /** + * Clears the current serlized document + */ + public void empty() + { + _indent = 0; + _document.delete(0, _document.length()); + } + + /** + * Converts special characters to appropriate representation in XML + * @param input buffer to convert + * @return the converted buffer + */ + public static StringBuffer prepareStringForXML(StringBuffer input) + { + StringBuffer output = new StringBuffer(); + + for (int idx = 0; idx < input.length(); idx++) + { + char currChar = input.charAt(idx); + switch (currChar) + { + case '&' : + output.append(XMLparser.STR_AMP); + break; + case '"' : + output.append(XMLparser.STR_QUOTE); + break; + case '\'' : + output.append(XMLparser.STR_APOS); + break; + case '<' : + output.append(XMLparser.STR_LT); + break; + case '>' : + output.append(XMLparser.STR_GT); + break; + case ';' : + output.append(XMLparser.STR_SEMI); + break; + default : + output.append(currChar); + break; + } + } + + return output; + } + + /** + * Converts special characters to appropriate representation in XML + * @param input buffer to convert + * @return the converted buffer + */ + public static StringBuffer prepareStringForXML(String input) + { + StringBuffer output = new StringBuffer(); + + for (int idx = 0; idx < input.length(); idx++) + { + char currChar = input.charAt(idx); + switch (currChar) + { + case '&' : + output.append(XMLparser.STR_AMP); + break; + case '"' : + output.append(XMLparser.STR_QUOTE); + break; + case '\'' : + output.append(XMLparser.STR_APOS); + break; + case '<' : + output.append(XMLparser.STR_LT); + break; + case '>' : + output.append(XMLparser.STR_GT); + break; + case ';' : + output.append(XMLparser.STR_SEMI); + break; + default : + output.append(currChar); + break; + } + } + + return output; + } + + /** + * Generate an tags for a file transfer and send bytes over the pipe. + * + * @param object the element representing the file transfer + * @param bytes the bytes to send + * @param size the number of bytes to send + * @param isAppend indicates whether bytes should be appended or not to a file on the other end of the pipe + * @param binary indicates whether the bytes should be sent as binary or text + */ + public synchronized void generate(DataElement object, byte[] bytes, int size, boolean isAppend, boolean binary) + { + String tagType = XMLparser.STR_FILE; + if (isAppend) + { + tagType += ".Append"; + } + if (binary) + { + tagType += ".Binary"; + } + + if (object != null) + { + startTag(tagType); + addAttribute(DE.P_TYPE, object.getAttribute(DE.A_TYPE)); + addAttribute(DE.P_ID, object.getAttribute(DE.A_ID)); + addAttribute(DE.P_NAME, object.getAttribute(DE.A_NAME)); + addAttribute(DE.P_VALUE, object.getAttribute(DE.A_VALUE)); + addAttribute(DE.P_SOURCE, object.getAttribute(DE.A_SOURCE)); + addAttribute(DE.P_SOURCE_LOCATION, object.getAttribute(DE.A_SOURCE_LOCATION)); + + if (object.isReference()) + { + addAttribute(DE.P_ISREF, DataStoreResources.TRUE); + } + else + { + addAttribute(DE.P_ISREF, DataStoreResources.FALSE); + } + + addAttribute(DE.P_DEPTH, "" + size); + addFile(bytes, size, binary); + + endTag(tagType); + } + } + + /** + * Generate tags for class transfer and send bytes over the pipe. + * + * @param object the element representing the class transfer + * @param bytes the bytes to send + * @param size the number of bytes to send + */ + public synchronized void generate(DataElement object, byte[] bytes, int size) + { + String tagType = XMLparser.STR_CLASS; + + if (object != null) + { + startTag(tagType); + addAttribute(DE.P_TYPE, object.getAttribute(DE.A_TYPE)); + addAttribute(DE.P_ID, object.getAttribute(DE.A_ID)); + addAttribute(DE.P_NAME, object.getAttribute(DE.A_NAME)); + addAttribute(DE.P_VALUE, object.getAttribute(DE.A_VALUE)); + addAttribute(DE.P_SOURCE, object.getAttribute(DE.A_SOURCE)); + addAttribute(DE.P_SOURCE_LOCATION, object.getAttribute(DE.A_SOURCE_LOCATION)); + if (object.isReference()) + { + addAttribute(DE.P_ISREF, "true"); + } + else + { + addAttribute(DE.P_ISREF, "false"); + } + + addAttribute(DE.P_DEPTH, "" + size); + addFile(bytes, size, true); + + endTag(tagType); + } + } + + /** + * Serializes and sends a DataStore tree through the pipe + * + * @param object the root of the DataStore tree to send + * @param depth the depth of the tree to send + */ + public void generate(DataElement object, int depth) + { + if ((object != null) && (depth >= 0)) + { + String tagType = XMLparser.STR_DATAELEMENT; + + if (object.isUpdated() && !object.isPendingTransfer() && !_generateBuffer) + { + } + else + { + if (object.isDeleted() && _ignoreDeleted) + { + } + else + { + object.setPendingTransfer(false); + + startTag(tagType); + addAttribute(DE.P_TYPE, object.getAttribute(DE.A_TYPE)); + addAttribute(DE.P_ID, object.getAttribute(DE.A_ID)); + addAttribute(DE.P_NAME, object.getAttribute(DE.A_NAME)); + addAttribute(DE.P_VALUE, object.getAttribute(DE.A_VALUE)); + addAttribute(DE.P_SOURCE, object.getAttribute(DE.A_SOURCE)); + addAttribute(DE.P_SOURCE_LOCATION, object.getAttribute(DE.A_SOURCE_LOCATION)); + + if (object.isReference()) + { + addAttribute(DE.P_ISREF, "true"); + } + else + { + addAttribute(DE.P_ISREF, "false"); + } + + addAttribute(DE.P_DEPTH, "" + object.depth()); + addData(object.getBuffer()); + object.setUpdated(true); + + if (!object.isReference() && depth >= 0) + { + for (int i = 0; i < object.getNestedSize(); i++) + { + generate(object.get(i), depth - 1); + } + } + + // end generation + endTag(tagType); + } + } + } + } + + public void generateClassRequest(DataElement object) + { + String tagType = XMLparser.STR_REQUEST_CLASS; + if (object != null) + { + startTag(tagType); + addAttribute(DE.P_TYPE, object.getAttribute(DE.A_TYPE)); + addAttribute(DE.P_ID, object.getAttribute(DE.A_ID)); + addAttribute(DE.P_NAME, object.getAttribute(DE.A_NAME)); + addAttribute(DE.P_VALUE, object.getAttribute(DE.A_VALUE)); + addAttribute(DE.P_SOURCE, object.getAttribute(DE.A_SOURCE)); + addAttribute(DE.P_SOURCE_LOCATION, object.getAttribute(DE.A_SOURCE_LOCATION)); + + if (object.isReference()) + { + addAttribute(DE.P_ISREF, "true"); + } + else + { + addAttribute(DE.P_ISREF, "false"); + } + _state = BODY; + endTag(tagType); + } + + } + + public void generateSerializedObject(DataElement object, IRemoteClassInstance runnable) + { + String tagType = XMLparser.STR_SERIALIZED; + if (object != null) + { + startTag(tagType); + addAttribute(DE.P_TYPE, object.getAttribute(DE.A_TYPE)); + addAttribute(DE.P_ID, object.getAttribute(DE.A_ID)); + addAttribute(DE.P_NAME, object.getAttribute(DE.A_NAME)); + addAttribute(DE.P_VALUE, object.getAttribute(DE.A_VALUE)); + addAttribute(DE.P_SOURCE, object.getAttribute(DE.A_SOURCE)); + addAttribute(DE.P_SOURCE_LOCATION, object.getAttribute(DE.A_SOURCE_LOCATION)); + + if (object.isReference()) + { + addAttribute(DE.P_ISREF, "true"); + } + else + { + addAttribute(DE.P_ISREF, "false"); + } + + try + { + PipedInputStream pin = new PipedInputStream(); + PipedOutputStream pout = new PipedOutputStream(pin); + ObjectOutputStream outStream = new ObjectOutputStream(pout); + outStream.writeObject(runnable); + + + int size = pin.available(); + byte[] bytes = new byte[size]; + int nRead = pin.read(bytes, 0, size); + addAttribute(DE.P_DEPTH, "" + nRead); + addFile(bytes, nRead, true); + + outStream.close(); + pin.close(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + endTag(tagType); + } + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLparser.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLparser.java new file mode 100644 index 00000000000..ac1e486de61 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/util/XMLparser.java @@ -0,0 +1,984 @@ +/******************************************************************************** + * 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.io.InterruptedIOException; +import java.net.Socket; +import java.net.SocketException; +import java.util.Stack; + +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 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 ByteStreamHandler to be saved on disk. + *

    + */ +public class XMLparser +{ + + public static final int IO_SOCKET_READ_TIMEOUT = 3600000; + public static final long KEEPALIVE_RESPONSE_TIMEOUT = 60000; + + private DataStore _dataStore; + private DataElement _rootDataElement; + private Stack _tagStack; + private Stack _objStack; + + private boolean _isFile; + private boolean _isClass; + private boolean _isRequestClass; + private boolean _isKeepAlive; + private boolean _isKeepAliveConfirm; + private boolean _isSerialized; + + private String _tagType; + + private byte[] _byteBuffer; + private byte[] _fileByteBuffer; + private int _maxBuffer; + + private boolean _panic = false; + private Throwable _panicException = null; + + private boolean _isKeepAliveCompatible = false; + private boolean _firstTime = true; + + private KeepAliveRequestThread _kart = null; + private KeepAliveRequestThread _initialKart = null; + + public static String STR_DATAELEMENT = "DataElement"; + + public static String STR_BUFFER_START = ""; + public static String STR_BUFFER_END = ""; + public static String STR_BUFFER = "Buffer"; + + public static String STR_STATUS = "status"; + public static String STR_STATUS_DONE = "done"; + public static String STR_STATUS_ALMOST_DONE = "almost done"; + + public static String STR_FILE = "File"; + public static String STR_CLASS = "Class"; + public static String STR_REQUEST_CLASS= "RequestClass"; + public static String STR_SERIALIZED = "Serialized"; + + public static String STR_AMP = "&"; + public static String STR_QUOTE = """; + public static String STR_APOS = "'"; + public static String STR_LT = "<"; + public static String STR_GT = ">"; + public static String STR_SEMI = ";"; + + + /** + * Constructor + * @param dataStore the associated DataStore + */ + public XMLparser(DataStore dataStore) + { + _dataStore = dataStore; + _tagStack = new Stack(); + _objStack = new Stack(); + _maxBuffer = 100000; + _byteBuffer = new byte[_maxBuffer]; + } + + /** + * Read a file from the pipe + * @param reader the pipe reader + * @param size the number of bytes to read + * @param path the path of the file where the received bytes should be inserted + */ + public void readFile(BufferedInputStream reader, int size, String path, String byteStreamHandlerId) + { + + Runtime rt = Runtime.getRuntime(); + //long totalMem = rt.totalMemory(); + long freeMem = rt.freeMemory(); + + if (size * 100 > freeMem) + { + rt.gc(); + } + + if (_fileByteBuffer == null || _fileByteBuffer.length < size) + { + try + { + _fileByteBuffer = new byte[size]; + } + catch (OutOfMemoryError e) + { + System.exit(-1); + } + } + + int written = 0; + +// // hack to deal with platform inconsistencies +// // only needed on the server side +// if (!_dataStore.isVirtual()) +// { +// try +// { +// synchronized (reader) +// { +// int first = reader.read(); +// +// if (first != 10) { +// written = 1; +// buffer[0] = (byte) first; +// } +// else { +// System.out.println("First byte is 10!"); +// } +// } +// } +// catch (IOException e) +// { +// _dataStore.trace(e); +// } +// } + + while (written < size) + { + try + { + int read = reader.read(_fileByteBuffer, written, size - written); + written += read; + } + catch (SocketException se) + { + // DKM- socket exception means connection is gone + // need bail now! + _dataStore.trace(se); + handlePanic(se); + return; + } + catch (IOException e) + { + _dataStore.trace(e); + handlePanic(e); + } + catch (Error err) + { + System.out.println("error!"); + handlePanic(err); + } + } + + if (_tagType.startsWith("File.Append")) + { + boolean binary = _tagType.equals("File.Append.Binary"); + _dataStore.appendToFile(path, _fileByteBuffer, size, binary, byteStreamHandlerId); + } + else + { + boolean binary = _tagType.equals("File.Binary"); + _dataStore.saveFile(path, _fileByteBuffer, size, binary, byteStreamHandlerId); + } + } + + public boolean readInstance(BufferedInputStream reader, int size, String classbyteStreamHandlerId) + { + byte[] buffer = new byte[size]; + int written = 0; + + while (written < size) + { + try + { + int read = reader.read(buffer, written, size - written); + written += read; + } + catch (SocketException se) + { + // DKM- socket exception means connection is gone + // need bail now! + _dataStore.trace(se); + handlePanic(se); + return false; + } + catch (IOException e) + { + _dataStore.trace(e); + handlePanic(e); + return false; + } + } + _dataStore.saveClassInstance(buffer, size, classbyteStreamHandlerId); + return true; + } + + /** + * Read a class file from the pipe + * @param reader the pipe reader + * @param size the number of bytes to read + * @param className the name of the class defined by the byte array. + * @param classbyteStreamHandlerId the name of the classByteStreamHandler that will receive the bytes of the file. + * @return whether the operation is successful + */ + public boolean readClass(BufferedInputStream reader, int size, String className, String classbyteStreamHandlerId) + { + byte[] buffer = new byte[size]; + int written = 0; + + while (written < size) + { + try + { + int read = reader.read(buffer, written, size - written); + written += read; + } + catch (SocketException se) + { + // DKM- socket exception means connection is gone + // need bail now! + _dataStore.trace(se); + handlePanic(se); + return false; + } + catch (IOException e) + { + _dataStore.trace(e); + handlePanic(e); + return false; + } + } + _dataStore.saveClass(className, buffer, size, classbyteStreamHandlerId); + return true; + } + + /** + * Reads a line from the pipe + * + * @param reader the pipe reader + * @return the line received + */ + public String readLine(BufferedInputStream reader, Socket socket) + { + boolean done = false; + int offset = 0; + + try + { + boolean inquotes = false; + while (!done) + { + + if (_firstTime) + { + _initialKart = new KeepAliveRequestThread(KEEPALIVE_RESPONSE_TIMEOUT, _dataStore); + _firstTime = false; + _initialKart.start(); + continue; + } + else if (_initialKart != null && !_initialKart.isAlive()) + { + if (!_initialKart.failed()) + { + _isKeepAliveCompatible = true; + _initialKart = null; + } + else + { + _isKeepAliveCompatible = false; + _initialKart = null; + } + } + + int in = -1; + + if (_isKeepAliveCompatible) + { + socket.setSoTimeout(IO_SOCKET_READ_TIMEOUT); + try + { + in = reader.read(); + } + catch (InterruptedIOException e) + { + if ((_kart != null) && _kart.failed()) + { + done = true; + handlePanic(new Exception("KeepAlive request to client wasnt answered in time.")); + continue; + } + else + { + _kart = new KeepAliveRequestThread(KEEPALIVE_RESPONSE_TIMEOUT, _dataStore); + _kart.start(); + continue; + } + } + } + else + { + in = reader.read(); + } + + if (in == -1) + { + done = true; + Exception e = new Exception("The connection to the server has been lost."); + handlePanic(e); + } + else + { + if (in <= 0) + { + done = true; + } + else + { + if (_kart != null) _kart.interrupt(); + } + byte aByte = (byte) in; + switch (aByte) + { + case '"': + inquotes = !inquotes; + break; + case '\n': + case '\r': + case '\0': + if (!inquotes) + done = true; + break; + default: + break; + } + + if (offset >= _maxBuffer) + { + done = true; + } + + _byteBuffer[offset] = aByte; + offset++; + } + } + } + catch (IOException e) + { + _dataStore.trace(e); + done = true; + + handlePanic(e); + + return null; + } + + if (offset > 0) + { + String result = null; + try + { + result = new String(_byteBuffer, 0, offset, DE.ENCODING_UTF_8); + } + catch (IOException e) + { + _dataStore.trace(e); + } + return result; + } + else + { + return null; + } + } + + /** + * Called if an exception occurs during reading of the pipe + * @param e the Exception + */ + private void handlePanic(Throwable e) + { + _panic = true; + _panicException = e; + } + + /** + * Returns the communications exception if one occurred + * @return a exception + */ + public Throwable getPanicException() + { + return _panicException; + } + + /** + * This method gets called to receive data from the pipe. It deserializes + * DataStore XML documents, creating the appropriate DataElements in appropriate + * places in the DataStore tree. If files are being transmitted it creates + * the appropriate files using the DataStore 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("'); + _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 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.dstore.extra/.cvsignore b/rse/plugins/org.eclipse.dstore.extra/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.dstore.extra/.project b/rse/plugins/org.eclipse.dstore.extra/.project new file mode 100644 index 00000000000..ceed1c764fc --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/.project @@ -0,0 +1,28 @@ + + + org.eclipse.dstore.extra + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.dstore.extra/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.dstore.extra/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..37f39ad3fb5 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.dstore.extra +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.dstore.extra.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.views +Eclipse-LazyStart: true +Export-Package: org.eclipse.dstore.extra.internal.extra +Bundle-Vendor: Eclipse.org +Bundle-ClassPath: dstore_extra.jar diff --git a/rse/plugins/org.eclipse.dstore.extra/about.html b/rse/plugins/org.eclipse.dstore.extra/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.extra/build.properties b/rse/plugins/org.eclipse.dstore.extra/build.properties new file mode 100644 index 00000000000..a39331fe9db --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/build.properties @@ -0,0 +1,10 @@ +bin.includes = about.html,\ + META-INF/,\ + plugin.properties,\ + dstore_extra.jar +src.includes = META-INF/,\ + about.html,\ + plugin.properties +jars.compile.order = dstore_extra.jar +source.dstore_extra.jar = src/ +output.dstore_extra.jar = bin/ diff --git a/rse/plugins/org.eclipse.dstore.extra/plugin.properties b/rse/plugins/org.eclipse.dstore.extra/plugin.properties new file mode 100644 index 00000000000..811c3349f67 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/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 Platform Support \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java new file mode 100644 index 00000000000..468f168cdfa --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java @@ -0,0 +1,57 @@ +/******************************************************************************** + * 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.extra.internal.extra; + + + +public class DataElementActionFilter +{ + + + private static String _type = "type"; + private static DataElementActionFilter _instance; + + public static DataElementActionFilter getInstance() + { + if (_instance == null) + _instance = new DataElementActionFilter(); + return _instance; + } + + /** + * @see IActionFilter#testAttribute(Object, String, String) + */ + public boolean testAttribute(Object target, String name, String value) + { + if (name.equals(_type)) + { + IDataElement le = (IDataElement)target; + if (le.getType().equals(value) || le.isOfType(value)) + { + return true; + } + } + + return false; + } + + public static boolean matches(Class aClass) + { + return false; + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DesktopElement.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DesktopElement.java new file mode 100644 index 00000000000..46e160dff92 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DesktopElement.java @@ -0,0 +1,32 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public class DesktopElement +{ + + + public static boolean matches(Class aClass) + { + return false; + } + + public static Object getPlatformAdapter(Object obj, Class aClass) + { + return null; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DomainEvent.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DomainEvent.java new file mode 100644 index 00000000000..2fdab06f842 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DomainEvent.java @@ -0,0 +1,101 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +import java.util.List; + +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/server/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java new file mode 100644 index 00000000000..1d35a5687b3 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/DomainNotifier.java @@ -0,0 +1,53 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public class DomainNotifier implements IDomainNotifier +{ + + + public DomainNotifier() + { + } + + public void enable(boolean on) + { + } + + public boolean isEnabled() + { + return false; + } + + public void addDomainListener(IDomainListener listener) + { + } + + + public void fireDomainChanged(DomainEvent event) + { + } + + public boolean hasDomainListener(IDomainListener listener) + { + return false; + } + + public void removeDomainListener(IDomainListener listener) + { + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDataElement.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDataElement.java new file mode 100644 index 00000000000..ef71bdb6edd --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDataElement.java @@ -0,0 +1,35 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +import java.util.List; + +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/server/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java new file mode 100644 index 00000000000..f028b4b0665 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDesktopElement.java @@ -0,0 +1,23 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public interface IDesktopElement +{ + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDomainListener.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDomainListener.java new file mode 100644 index 00000000000..9b69661ee04 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDomainListener.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.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/server/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.java new file mode 100644 index 00000000000..34b21150cce --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IDomainNotifier.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.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/server/org/eclipse/dstore/extra/internal/extra/IElement.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IElement.java new file mode 100644 index 00000000000..1e186a3a5db --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IElement.java @@ -0,0 +1,24 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public interface IElement +{ + + + public Object getElementProperty(Object key); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IPropertySource.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IPropertySource.java new file mode 100644 index 00000000000..f26d96aa58c --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/IPropertySource.java @@ -0,0 +1,23 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public interface IPropertySource +{ + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/PropertySource.java b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/PropertySource.java new file mode 100644 index 00000000000..99179f127e1 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/server/org/eclipse/dstore/extra/internal/extra/PropertySource.java @@ -0,0 +1,31 @@ +/******************************************************************************** + * 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.extra.internal.extra; + +public class PropertySource +{ + + + public PropertySource(IDataElement element) + { + } + + public static boolean matches(Class key) + { + return false; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/serverruntime/.cvsignore b/rse/plugins/org.eclipse.dstore.extra/serverruntime/.cvsignore new file mode 100644 index 00000000000..2053777fa08 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/serverruntime/.cvsignore @@ -0,0 +1 @@ +dstore_extra_server.jar diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/Activator.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/Activator.java new file mode 100644 index 00000000000..3ae7a9ade7e --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/Activator.java @@ -0,0 +1,70 @@ +/******************************************************************************** + * 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.extra; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.dstore.extra", path); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java new file mode 100644 index 00000000000..650e0c6f8e1 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.extra/src/org/eclipse/dstore/extra/internal/extra/DataElementActionFilter.java @@ -0,0 +1,87 @@ +/******************************************************************************** + * 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 class DataElementActionFilter implements org.eclipse.ui.IActionFilter { + + + // constants to be used by Eclipse Filtering and Enablement Support. + private static String _type = "type"; + private static String _name = "name"; + private static DataElementActionFilter _instance; + + public static DataElementActionFilter getInstance() { + if (_instance == null) + _instance = new DataElementActionFilter(); + return _instance; + } + + /** + * Supports Eclipse filtering and enablement. + * eg: + * + * + * + * + * + * + * + * + * + * + * + * + * + * 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 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/.cvsignore b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/.project b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.project new file mode 100644 index 00000000000..96589beabdd --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.connectorservice.dstore + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.connectorservice.dstore/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..ac209d92391 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.connectorservice.dstore +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.rse.connectorservice.dstore.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.rse.services, + org.eclipse.rse.services.dstore, + org.eclipse.dstore.core, + org.eclipse.dstore.extra, + org.eclipse.rse.ui +Eclipse-LazyStart: true +Export-Package: org.eclipse.rse.connectorservice.dstore, + org.eclipse.rse.connectorservice.dstore.util +Bundle-Vendor: Eclipse.org +Bundle-ClassPath: dstore_connector_service.jar diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/about.html b/rse/plugins/org.eclipse.rse.connectorservice.dstore/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.rse.connectorservice.dstore/build.properties b/rse/plugins/org.eclipse.rse.connectorservice.dstore/build.properties new file mode 100644 index 00000000000..6972fc9aabe --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/build.properties @@ -0,0 +1,10 @@ +bin.includes = META-INF/,\ + about.html,\ + plugin.properties,\ + dstore_connector_service.jar +src.includes = META-INF/,\ + about.html,\ + plugin.properties +source.dstore_connector_service.jar = src/ +jars.compile.order = dstore_connector_service.jar +output.dstore_connector_service.jar = bin/ diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/plugin.properties b/rse/plugins/org.eclipse.rse.connectorservice.dstore/plugin.properties new file mode 100644 index 00000000000..92c2e030acb --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/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 Connector Service \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/Activator.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/Activator.java new file mode 100644 index 00000000000..417fad38a8e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/Activator.java @@ -0,0 +1,67 @@ +/******************************************************************************** + * 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.dstore; + +import org.eclipse.rse.core.SystemBasePlugin; +import org.osgi.framework.BundleContext; + + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends SystemBasePlugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + + + protected void initializeImageRegistry() + { + // TODO Auto-generated method stub + + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.java new file mode 100644 index 00000000000..99c4c4d96f7 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.java @@ -0,0 +1,32 @@ +/******************************************************************************** + * 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.dstore; + +import org.eclipse.osgi.util.NLS; + +public class ConnectorServiceResources extends NLS +{ + private static String BUNDLE_NAME = "org.eclipse.rse.connectorservice.dstore.ConnectorServiceResources";//$NON-NLS-1$ + + public static String DStore_ConnectorService_Label; + public static String DStore_ConnectorService_Description; + + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, ConnectorServiceResources.class); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.properties b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.properties new file mode 100644 index 00000000000..6d39a835ea2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/ConnectorServiceResources.properties @@ -0,0 +1,20 @@ +################################################################################ +# 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. +################################################################################ + + + +DStore_ConnectorService_Label=DStore Connector Service +DStore_ConnectorService_Description=The DStore Connector Service uses RSE's DataStore protocol to connect to the host. You must have a DataStore daemon or server running on the remote machine. \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java new file mode 100644 index 00000000000..128fbfc1af6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java @@ -0,0 +1,1089 @@ +/******************************************************************************** + * 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.File; +import java.io.IOException; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.Vector; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.eclipse.dstore.core.client.ClientConnection; +import org.eclipse.dstore.core.client.ClientSSLProperties; +import org.eclipse.dstore.core.client.ConnectionStatus; +import org.eclipse.dstore.core.java.IRemoteClassInstance; +import org.eclipse.dstore.core.java.RemoteClassLoader; +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.IDataStoreProvider; +import org.eclipse.dstore.core.model.ISSLProperties; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.rse.connectorservice.dstore.util.ConnectionStatusListener; +import org.eclipse.rse.connectorservice.dstore.util.StatusMonitor; +import org.eclipse.rse.connectorservice.dstore.util.StatusMonitorFactory; +import org.eclipse.rse.core.ISystemTypes; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemPlugin; +import org.eclipse.rse.core.comm.ISystemKeystoreProvider; +import org.eclipse.rse.core.comm.SystemKeystoreProviderManager; +import org.eclipse.rse.core.subsystems.AbstractConnectorService; +import org.eclipse.rse.core.subsystems.CommunicationsEvent; +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.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ServerLaunchType; +import org.eclipse.rse.core.subsystems.SubSystem; +import org.eclipse.rse.dstore.universal.miners.environment.EnvironmentMiner; +import org.eclipse.rse.model.IHost; +import org.eclipse.rse.model.SystemSignonInformation; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.SystemPropertyResources; +import org.eclipse.rse.ui.actions.DisplaySystemMessageAction; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.osgi.framework.Bundle; +/** + * System class required by the remote systems framework. + * This represents the live connection at tool runtime. + *

    + * 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: + *

      + *
    • os.name + *
    • os.version + *
    • user.home + *
    • temp.dir + *
    + * @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. + *

    + * 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 128) + return (byte )(i - 256); + return (byte)i; + } + + } + return (byte)0; + } + private void logMessage (String message) { + if (logInfo) + SystemBasePlugin.logError("RexecDstoreServer :" + message); + } + + public void setSocketTimeoutValue(int value) + { + _socketTimeoutValue = value; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ConnectionStatusListener.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ConnectionStatusListener.java new file mode 100644 index 00000000000..f55df492669 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ConnectionStatusListener.java @@ -0,0 +1,272 @@ +/******************************************************************************** + * 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.util; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.dstore.core.model.DataElement; +import org.eclipse.dstore.extra.internal.extra.DomainEvent; +import org.eclipse.dstore.extra.internal.extra.IDomainListener; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemPlugin; +import org.eclipse.rse.core.subsystems.IConnectorService; +import org.eclipse.rse.core.subsystems.SubSystemConfiguration; +import org.eclipse.rse.model.ISystemRegistry; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +public class ConnectionStatusListener implements IDomainListener, IRunnableWithProgress +{ + + + protected DataElement _dataStoreStatus; + protected IConnectorService _connection; + protected boolean _connectionDown = false; + + /** + * @param status The status element for the DataStore handling this connection. + */ + public ConnectionStatusListener(DataElement status, IConnectorService connection) + { + _dataStoreStatus = status; + _connection = connection; + } + + protected Shell internalGetShell() + { + Shell activeShell = SystemBasePlugin.getActiveWorkbenchShell(); + if (activeShell != null) + { + return activeShell; + } + + IWorkbenchWindow window = null; + try + { + window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + } + catch (Exception e) + { + return null; + } + if (window == null) + { + + IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + if (windows != null && windows.length > 0) + { + return windows[0].getShell(); + } + + } + else + { + return window.getShell(); + } + + return null; + } + + /** + * The handleConnectionDown method is invoked if the network connection between the + * client and server goes down while connected. Currently this method displays + * an error to the user and the subsytem is disconnected. + */ + protected void handleConnectionDown() + { + Display.getDefault().asyncExec(new ConnectionDown(this)); + } + + class ConnectionDown implements Runnable + { + private ConnectionStatusListener _listener; + public ConnectionDown(ConnectionStatusListener listener) + { + _listener = listener; + } + + public void run() + { + Shell shell = getShell(); + _connectionDown = true; + SystemMessage msg = SystemPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_UNKNOWNHOST); + msg.makeSubstitution(_connection.getPrimarySubSystem().getHost().getAliasName()); + SystemMessageDialog dialog = new SystemMessageDialog(internalGetShell(), msg); + dialog.open(); + try + { + IRunnableContext runnableContext = getRunnableContext(getShell()); + runnableContext.run(false,true,_listener); // inthread, cancellable, IRunnableWithProgress + _connection.reset(); + ISystemRegistry sr = SystemPlugin.getDefault().getSystemRegistry(); + sr.connectedStatusChange(_connection.getPrimarySubSystem(), false, true, true); + } + catch (InterruptedException exc) // user cancelled + { + if (shell != null) + showDisconnectCancelledMessage(shell, _connection.getHostName(), _connection.getPort()); + } + catch (java.lang.reflect.InvocationTargetException invokeExc) // unexpected error + { + Exception exc = (Exception)invokeExc.getTargetException(); + if (shell != null) + showDisconnectErrorMessage(shell, _connection.getHostName(), _connection.getPort(), exc); + } + catch (Exception e) + { + SystemBasePlugin.logError("ConnectionStatusListener: Error disconnecting", e); + } + } + } + + /** + * @see IDomainListener#listeningTo(DomainEvent) + */ + public boolean listeningTo(DomainEvent event) + { + if (_dataStoreStatus == event.getParent()) + { + return true; + } + return false; + } + + /** + * @see IDomainListener#domainChanged(DomainEvent) + */ + public void domainChanged(DomainEvent event) + { + if (!_dataStoreStatus.getName().equals("okay")) + { + handleConnectionDown(); + } + } + + /** + * @see IDomainListener#getShell() + */ + public Shell getShell() + { + return internalGetShell(); + } + + /** + * Callback method for the ISystem to determine if the connection is down. This is + * called by the disconnect method to determine if we can do saves or not. + */ + public boolean isConnectionDown() + { + return _connectionDown; + } + + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException + { + String message = null; + message = SubSystemConfiguration.getDisconnectingMessage(_connection.getHostName(), _connection.getPort()); + monitor.beginTask(message, IProgressMonitor.UNKNOWN); + try + { + _connection.disconnect(); + } + catch(Exception exc) + { + if (exc instanceof java.lang.reflect.InvocationTargetException) + throw (java.lang.reflect.InvocationTargetException)exc; + if (exc instanceof java.lang.InterruptedException) + throw (java.lang.InterruptedException)exc; + throw new java.lang.reflect.InvocationTargetException(exc); + } + finally + { + monitor.done(); + } + } + /** + * Get the progress monitor dialog for this operation. We try to + * use one for all phases of a single operation, such as connecting + * and resolving. + */ + protected IRunnableContext getRunnableContext(Shell rshell) + { + Shell shell = getShell(); + // for other cases, use statusbar + IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow(); + if (win != null) + { + Shell winShell = SystemPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(); + if (winShell != null && !winShell.isDisposed() && winShell.isVisible()) + { + SystemBasePlugin.logInfo("Using active workbench window as runnable context"); + shell = winShell; + return win; + } + else + { + win = null; + } + } + + if (shell == null || shell.isDisposed() || !shell.isVisible()) + { + SystemBasePlugin.logInfo("Using progress monitor dialog with given shell as parent"); + shell = rshell; + } + + + IRunnableContext dlg = new ProgressMonitorDialog(rshell); + return dlg; + } + + /** + * Show an error message when the disconnection fails. + * Shows a common message by default. + * Overridable. + */ + protected void showDisconnectErrorMessage(Shell shell, String hostName, int port, Exception exc) + { + //SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR,shell,SystemPlugin.getResourceBundle(), + // ISystemMessages.MSG_DISCONNECT_FAILED, + // hostName, exc.getMessage()); + //SystemPlugin.logError("Disconnect failed",exc); // temporary + SystemMessageDialog msgDlg = new SystemMessageDialog(shell, + SystemPlugin.getPluginMessage(ISystemMessages.MSG_DISCONNECT_FAILED).makeSubstitution(hostName,exc)); + msgDlg.setException(exc); + msgDlg.open(); + } + /** + * Show an error message when the user cancels the disconnection. + * Shows a common message by default. + * Overridable. + */ + protected void showDisconnectCancelledMessage(Shell shell, String hostName, int port) + { + //SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR, shell, SystemPlugin.getResourceBundle(), + // ISystemMessages.MSG_DISCONNECT_CANCELLED, hostName); + SystemMessageDialog msgDlg = new SystemMessageDialog(shell, + SystemPlugin.getPluginMessage(ISystemMessages.MSG_DISCONNECT_CANCELLED).makeSubstitution(hostName)); + msgDlg.open(); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnostic.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnostic.java new file mode 100644 index 00000000000..7738e6d6442 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnostic.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.rse.connectorservice.dstore.util; + +import org.eclipse.rse.core.subsystems.IConnectorService; + +/** + * An interface for ICommunicationsDiagnostic class + */ +public interface ICommunicationsDiagnostic extends Runnable { + + + + public static final int CANCEL_WAIT_REQUESTED = 1; + + + /** + * Setup for the diagnostic + * + * @param + * String id: assign an ID for this diagnostic instance + * boolean quiet: true if user to be prompted for a dialog + * String server: the host network name + * ISystem system: the connection to be investigated + * String str1, str2, str3: optional strings + */ + public void setUp(String id, boolean quiet, String server, IConnectorService system, String str1, String str2, String str3); + + /** + * Log an error in the .log file + * + * @param + * String text: message text to be logged + */ + public void logError(String text); + + /** + * Check if network is down + * @param None + * @return true or false + * + */ + public boolean isNetworkDown(); + + /** + * Check if host server is still active + * @param None + * @return true or false + */ + public boolean isServerActive(); + + /** + * Dispaly a message dialog + * + * @param + * int id: message to be displayed. + */ + public void displayMessage(String id); + + /** + * diagnosticStatus + * + * @return status + */ + public int diagnosticStatus(); + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnosticFactory.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnosticFactory.java new file mode 100644 index 00000000000..3bc4c334c64 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/ICommunicationsDiagnosticFactory.java @@ -0,0 +1,29 @@ +/******************************************************************************** + * 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.dstore.util; + +/** + * Factory for creating ICommunicationsDiagnostic instances. + */ +public interface ICommunicationsDiagnosticFactory +{ + + /** + * Factory method for creating instances + */ + public ICommunicationsDiagnostic createInstance(); +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitor.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitor.java new file mode 100644 index 00000000000..c1f5a3ac65c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/util/StatusMonitor.java @@ -0,0 +1,456 @@ +/******************************************************************************** + * 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.util; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +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.extra.internal.extra.DomainEvent; +import org.eclipse.dstore.extra.internal.extra.IDomainListener; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemPlugin; +import org.eclipse.rse.core.subsystems.CommunicationsEvent; +import org.eclipse.rse.core.subsystems.ICommunicationsListener; +import org.eclipse.rse.core.subsystems.IConnectorService; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + + +/* + * This utility class can be used to monitor the status of one more more status DataElements. + * Only one instanceof of this class is required per DataStore for use in monitoring statuses. + * This is intended to be used in place of StatusChangeListeners + * + * *

    + * The following is one example of the use of the StatusMonitor. The code: + *

    + *    		DataElement status = dataStore.command(dsCmd, args, deObj);
    + *
    + *			StatusMonitor smon = StatusMonitorFactory.getInstance().getStatusMonitorFor(getSystem(), ds);
    + *			smon.waitForUpdate(status, monitor);
    + * 
    + */ +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 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 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/.cvsignore b/rse/plugins/org.eclipse.rse.connectorservice.local/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/.project b/rse/plugins/org.eclipse.rse.connectorservice.local/.project new file mode 100644 index 00000000000..323499d479a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.connectorservice.local + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.connectorservice.local/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..7a4a2cc1b87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.connectorservice.local +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.rse.connectorservice.local.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.rse.services, + org.eclipse.rse.ui +Eclipse-LazyStart: true +Export-Package: org.eclipse.rse.connectorservice.local +Bundle-Vendor: Eclipse.org +Bundle-ClassPath: local_connector_service.jar diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/about.html b/rse/plugins/org.eclipse.rse.connectorservice.local/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.rse.connectorservice.local/build.properties b/rse/plugins/org.eclipse.rse.connectorservice.local/build.properties new file mode 100644 index 00000000000..9730f3af1ca --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/build.properties @@ -0,0 +1,10 @@ +bin.includes = META-INF/,\ + about.html,\ + plugin.properties,\ + local_connector_service.jar +src.includes = META-INF/,\ + about.html,\ + plugin.properties +source.local_connector_service.jar = src/ +jars.compile.order = local_connector_service.jar +output.local_connector_service.jar = bin/ diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/plugin.properties b/rse/plugins/org.eclipse.rse.connectorservice.local/plugin.properties new file mode 100644 index 00000000000..1edaf33afe1 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/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 Local Connector Service \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/Activator.java b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/Activator.java new file mode 100644 index 00000000000..e82041db18f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/Activator.java @@ -0,0 +1,70 @@ +/******************************************************************************** + * 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.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.rse.connectorservice.local", path); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.java b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.java new file mode 100644 index 00000000000..9aa495b4f1d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.java @@ -0,0 +1,32 @@ +/******************************************************************************** + * 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.osgi.util.NLS; + +public class ConnectorServiceResources extends NLS +{ + private static String BUNDLE_NAME = "org.eclipse.rse.connectorservice.local.ConnectorServiceResources";//$NON-NLS-1$ + + public static String Local_ConnectorService_Label; + public static String Local_ConnectorService_Description; + + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, ConnectorServiceResources.class); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.properties b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.properties new file mode 100644 index 00000000000..d34ca28997f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ConnectorServiceResources.properties @@ -0,0 +1,20 @@ +################################################################################ +# 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. +################################################################################ + + + +Local_ConnectorService_Label=Local Connector Service +Local_ConnectorService_Description=The Local Connector Service uses the Java API to connect to the local host. \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ILocalSubSystem.java b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ILocalSubSystem.java new file mode 100644 index 00000000000..7034a17e34a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/ILocalSubSystem.java @@ -0,0 +1,25 @@ +/******************************************************************************** + * 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.local; + +/** + * This is the interface all our subsystems in a local connection implement. + */ +public interface ILocalSubSystem +{ + String copyright = "(c) Copyright IBM Corporation 2001, 2003. "; //$NON-NLS-1$ +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorService.java b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorService.java new file mode 100644 index 00000000000..6a6e57af05e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.connectorservice.local/src/org/eclipse/rse/connectorservice/local/LocalConnectorService.java @@ -0,0 +1,120 @@ +/******************************************************************************** + * 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.local; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.rse.core.subsystems.AbstractConnectorService; +import org.eclipse.rse.core.subsystems.CommunicationsEvent; +import org.eclipse.rse.model.IHost; + +/** + * System class required by the remote systems framework. + * This represents the live connection at tool runtime. + * Since we don't really have such a thing for local files, this + * is pretty well empty. + */ +public class LocalConnectorService extends AbstractConnectorService +{ + + /** + * Constructor when we don't have a subsystem yet. + * Call setSubSystem after. + */ + public LocalConnectorService(IHost host) + { + super(ConnectorServiceResources.Local_ConnectorService_Label, ConnectorServiceResources.Local_ConnectorService_Description, host, 0); + } + + + + /** + * @see org.eclipse.rse.core.subsystems.AbstractConnectorService#disconnect() + */ + public void disconnect() throws Exception + { + fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT); + + // Fire comm event to signal state changed + notifyDisconnection(); + } + + /** + * @see org.eclipse.rse.core.subsystems.IConnectorService#connect(IProgressMonitor) + */ + protected void internalConnect(IProgressMonitor monitor) throws Exception + { + } + + /** + * @see org.eclipse.rse.core.subsystems.IConnectorService#isConnected() + */ + public boolean isConnected() + { + return true; + } + + /** + * Return the version, release, modification of the operating system. + *

    + * 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 @@ + + + + + + diff --git a/rse/plugins/org.eclipse.rse.core/.project b/rse/plugins/org.eclipse.rse.core/.project new file mode 100644 index 00000000000..c2582431cd8 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.core/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..f16e8e25366 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.core; singleton:=true +Bundle-Version: 1.0.0 +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.rse.services, + org.eclipse.rse.logging, + org.eclipse.core.resources, + org.eclipse.jface.text, + org.eclipse.ui.views, + org.eclipse.ui.forms, + org.eclipse.ui.ide, + org.eclipse.debug.ui, + org.eclipse.ui.workbench.texteditor +Eclipse-LazyStart: false +Bundle-Vendor: Eclipse.org diff --git a/rse/plugins/org.eclipse.rse.core/about.html b/rse/plugins/org.eclipse.rse.core/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.core/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.rse.core/about.properties b/rse/plugins/org.eclipse.rse.core/about.properties new file mode 100644 index 00000000000..4dcb5746577 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.core/about.properties @@ -0,0 +1,25 @@ +############################################################################### +# 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 +############################################################################### +# about.properties +# contains externalized strings for about.ini +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# fill-ins are supplied by about.mappings +# This file should be translated. +# +# Do not translate any values surrounded by {} + +blurb=Remote System Explorer Core\n\ +\n\ +Version: {featureVersion}\n\ +Build id: {0}\n\ +\n\ +(c) Copyright Eclipse contributors and others 2000, 2006. All rights reserved.\n\ +Visit http://www.eclipse.org/dsdp/tm/ diff --git a/rse/plugins/org.eclipse.rse.core/plugin.properties b/rse/plugins/org.eclipse.rse.core/plugin.properties new file mode 100644 index 00000000000..3596ca495da --- /dev/null +++ b/rse/plugins/org.eclipse.rse.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 Core \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/.classpath b/rse/plugins/org.eclipse.rse.dstore.security/.classpath new file mode 100644 index 00000000000..751c8f2e504 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.dstore.security/.cvsignore b/rse/plugins/org.eclipse.rse.dstore.security/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.dstore.security/.project b/rse/plugins/org.eclipse.rse.dstore.security/.project new file mode 100644 index 00000000000..a26f8a7e3c2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.dstore.security + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.dstore.security/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.dstore.security/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..b628dd42a89 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.dstore.security; singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.rse.dstore.security.UniversalSecurityPlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.rse.services, + org.eclipse.dstore.core, + org.eclipse.core.resources, + org.eclipse.rse.subsystems.files.dstore, + org.eclipse.rse.subsystems.shells.dstore, + org.eclipse.rse.subsystems.processes.dstore, + org.eclipse.rse.subsystems.files.core, + org.eclipse.rse.subsystems.processes.core, + org.eclipse.rse.subsystems.shells.core, + org.eclipse.rse.ui +Eclipse-LazyStart: true +Bundle-Vendor: Eclipse.org +Bundle-ClassPath: dstore_security.jar diff --git a/rse/plugins/org.eclipse.rse.dstore.security/about.html b/rse/plugins/org.eclipse.rse.dstore.security/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.rse.dstore.security/build.properties b/rse/plugins/org.eclipse.rse.dstore.security/build.properties new file mode 100644 index 00000000000..cf6a1d30ded --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/build.properties @@ -0,0 +1,18 @@ +bin.includes = about.html,\ + icons/,\ + plugin.properties,\ + plugin.xml,\ + dstore_security.jar,\ + schema/,\ + about.htm,\ + about.mappings,\ + about.properties,\ + about.ini,\ + META-INF/ +source.dstore_security.jar = src/ +output.dstore_security.jar = bin/ +src.includes = META-INF/,\ + about.html,\ + icons/,\ + plugin.properties,\ + plugin.xml diff --git a/rse/plugins/org.eclipse.rse.dstore.security/icons/full/obj16/certif_file.gif b/rse/plugins/org.eclipse.rse.dstore.security/icons/full/obj16/certif_file.gif new file mode 100644 index 00000000000..7d2dbe47704 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.dstore.security/icons/full/obj16/certif_file.gif differ diff --git a/rse/plugins/org.eclipse.rse.dstore.security/icons/full/wizban/import_cert_wiz.gif b/rse/plugins/org.eclipse.rse.dstore.security/icons/full/wizban/import_cert_wiz.gif new file mode 100644 index 00000000000..528a05b5c80 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.dstore.security/icons/full/wizban/import_cert_wiz.gif differ diff --git a/rse/plugins/org.eclipse.rse.dstore.security/plugin.properties b/rse/plugins/org.eclipse.rse.dstore.security/plugin.properties new file mode 100644 index 00000000000..4481bef6266 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/plugin.properties @@ -0,0 +1,23 @@ +################################################################################ +# 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. +################################################################################ + +# NLS_MESSAGEFORMAT_VAR + +plugin.name = RSE Dstore SSL Support + +KeystoreProviderName = Universal Keystore Provider +PreferencePage.SSL = SSL +PropertyPage.ServerConnectionSecurity = Server Connection Security \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/plugin.xml b/rse/plugins/org.eclipse.rse.dstore.security/plugin.xml new file mode 100644 index 00000000000..2e506962a1a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/plugin.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/ImageRegistry.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/ImageRegistry.java new file mode 100644 index 00000000000..5253cd2ee61 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/ImageRegistry.java @@ -0,0 +1,159 @@ +/******************************************************************************** + * 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.dstore.security; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; + +public class ImageRegistry { + + private static URL fgIconBaseURL= null; + + static { + try { + fgIconBaseURL= new URL(UniversalSecurityPlugin.getDefault().getBundle().getEntry("/"), "icons/full/" ); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (MalformedURLException e) { + UniversalSecurityPlugin.getDefault().log(e); + } + } + + /* + * Set of predefined Image Descriptors. + * the following String are all $NON-NLS-1$ + */ + public static final String T_OBJ = "obj16"; //$NON-NLS-1$ + public static final String T_WIZBAN = "wizban"; //$NON-NLS-1$ + + public static final String IMG_CERTIF_FILE = "certif_file.gif"; + public static final String IMG_WZ_IMPORT_CERTIF = "import_cert_wiz.gif";//"newjprj_wiz.gif";//$NON-NLS-1$ + + public static final ImageDescriptor DESC_IMG_CERTIF_FILE = createManaged(T_OBJ,IMG_CERTIF_FILE); + public static final ImageDescriptor DESC_IMG_WZ_IMPORT_CERTIF = createManaged(T_WIZBAN,IMG_WZ_IMPORT_CERTIF); + + protected static HashMap _images; + protected static HashMap _imageDescriptors; + + public static Image getImage(String name) + { + return (Image)_images.get(name); + } + + + /** + * Insert the method's description here. + * Creation date: (2/16/2001 4:57:29 PM) + * @return com.ibm.jface.resource.ImageDescriptor + * @param name java.lang.String + */ + public static ImageDescriptor getImageDescriptor(String name) { + + return (ImageDescriptor) _imageDescriptors.get(name); + } + + private static ImageDescriptor createManaged(String prefix, String name) { + try { + ImageDescriptor result = + ImageDescriptor.createFromURL(makeIconFileURL(prefix, name)); + + if (_images == null || _imageDescriptors == null) { + _images = new HashMap(); + _imageDescriptors = new HashMap(); + } + + _imageDescriptors.put(name, result); + _images.put(name, result.createImage()); + return result; + + } catch (MalformedURLException e) { + return ImageDescriptor.getMissingImageDescriptor(); + } + } + + public static void setImageDescriptors( + IAction action, + String type, + String relPath) { + try { + ImageDescriptor id = + ImageDescriptor.createFromURL(makeIconFileURL("d" + type, relPath)); + //$NON-NLS-1$ + if (id != null) { + action.setDisabledImageDescriptor(id); + } + } catch (MalformedURLException e) { + } + + try { + ImageDescriptor id = + ImageDescriptor.createFromURL(makeIconFileURL("c" + type, relPath));//$NON-NLS-1$ + if (id != null) { + action.setHoverImageDescriptor(id); + } + } catch (MalformedURLException e) { + } + + action.setImageDescriptor(create("e" + type, relPath)); //$NON-NLS-1$ + } + + private static URL makeIconFileURL(String prefix, String name) + throws MalformedURLException { + if (fgIconBaseURL == null) + throw new MalformedURLException(); + + StringBuffer buffer; + if (prefix != null) { + buffer = new StringBuffer(prefix); + buffer.append('/'); + buffer.append(name); + } else { + buffer = new StringBuffer(name); + } + return new URL(fgIconBaseURL, buffer.toString()); + } + + private static ImageDescriptor create(String prefix, String name) { + try { + return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name)); + } catch (MalformedURLException e) { + return ImageDescriptor.getMissingImageDescriptor(); + } + } + + public static void shutdown() { + if (_images == null) + return; + + for (Iterator e = _images.values().iterator(); e.hasNext();) { + Object next = e.next(); + if (next instanceof Image && !((Image) next).isDisposed()) { + ((Image) next).dispose(); + } + } + + _images.clear(); + _images = null; + _imageDescriptors.clear(); + _imageDescriptors = null; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalKeystoreProvider.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalKeystoreProvider.java new file mode 100644 index 00000000000..8df369f3889 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalKeystoreProvider.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.rse.dstore.security; + + +import java.util.List; + +import org.eclipse.rse.core.comm.ISystemKeystoreProvider; +import org.eclipse.rse.dstore.security.wizards.SystemImportCertAction; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + + +public class UniversalKeystoreProvider implements ISystemKeystoreProvider +{ + public class ImportCertificateRunnable implements Runnable + { + private List _certificates; + private ISystemKeystoreProvider _provider; + private boolean _wasCancelled = false; + + public ImportCertificateRunnable(ISystemKeystoreProvider provider, List certs) + { + _certificates = certs; + _provider = provider; + } + + public boolean wasCancelled() + { + return _wasCancelled; + } + + public void run() + { + Shell shell = Display.getDefault().getActiveShell(); + SystemImportCertAction importAction = new SystemImportCertAction(_provider, _certificates); + importAction.run(); + _wasCancelled = importAction.wasCancelled(); + } + } + + public String getKeyStorePassword() + { + return UniversalSecurityPlugin.getKeyStorePassword(); + } + + public String getKeyStorePath() + { + return UniversalSecurityPlugin.getKeyStoreLocation(); + } + + public boolean importCertificates(List certs) + { + Display display = Display.getDefault(); + ImportCertificateRunnable impRun = new ImportCertificateRunnable(this, certs); + display.syncExec(impRun); + + return !impRun.wasCancelled(); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityPlugin.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityPlugin.java new file mode 100644 index 00000000000..9a2ea6d1b4f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityPlugin.java @@ -0,0 +1,117 @@ +/******************************************************************************** + * 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.dstore.security; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +public class UniversalSecurityPlugin extends AbstractUIPlugin +{ + private final static String KEYSTORE = "dstorekeystore.dat"; + private static UniversalSecurityPlugin inst; + private static ResourceBundle aResourceBundle; + public static final String PLUGIN_ID = "org.eclipse.rse.dstore.security"; //$NON-NLS-1$ + + public UniversalSecurityPlugin() { + if (inst == null) + inst = this; + } + + public static UniversalSecurityPlugin getDefault() { + return inst; + } + + public static String getPluginId() { + return PLUGIN_ID; + } + + public static ResourceBundle getResourceBundle() { + if(aResourceBundle == null) + { + try { + aResourceBundle = Platform.getResourceBundle(Platform.getBundle(PLUGIN_ID)); + } catch (Exception e) { + aResourceBundle = null; + } + } + return aResourceBundle; + } + + public static String getString(String key) { + try { + return getResourceBundle().getString(key); + } catch (MissingResourceException e) { + return key; + } + } + + + + public static String getKeyStoreLocation() { + + return Platform.getPluginStateLocation(inst).append(KEYSTORE).toOSString(); + } + + public static String getKeyStorePassword() + { + return "dstore"; + } + + public static String getWorkspaceName(){ + IPath workspace = Platform.getLocation(); + int nr = workspace.segmentCount(); + String workspaceName = workspaceName = workspace.segment(nr - 1); + return workspaceName; + } + + /* (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + + super.stop(context); + + savePluginPreferences(); + ImageRegistry.shutdown(); + } + + public static Shell getActiveWorkbenchShell() { + return getActiveWorkbenchWindow().getShell(); + } + public static IWorkbenchWindow getActiveWorkbenchWindow() { + return getDefault().getWorkbench().getActiveWorkbenchWindow(); + } + + public void log(IStatus status) { + getLog().log(status); + } + + public void log(Throwable e) { + log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, "Error", e)); //$NON-NLS-1$ + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.java new file mode 100644 index 00000000000..b6e4c645e11 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.java @@ -0,0 +1,95 @@ +/******************************************************************************** + * 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.dstore.security; + + +import org.eclipse.osgi.util.NLS; + + + +public class UniversalSecurityProperties extends NLS +{ + private static String BUNDLE_NAME = "org.eclipse.rse.dstore.security.UniversalSecurityProperties";//$NON-NLS-1$ + + + public static String RESID_SECURITY_CERTIFICATE_PROP_TITLE; + public static String RESID_SECURITY_VALIDITY_PERIOD; + public static String RESID_SECURITY_SERIAL_NUMBER_LBL ; + public static String RESID_SECURITY_CERTIF_VERSION_LBL; + public static String RESID_SECURITY_PROP_ALIAS_LBL; + public static String RESID_SECURITY_ISSUED_TO_LBL; + public static String RESID_SECURITY_ISSUED_BY_LBL; + public static String RESID_SECURITY_VALIDITY_LBL; + public static String RESID_SECURITY_SIGALG_LBL; + public static String RESID_SECURITY_ALGORITHM_LBL; + public static String RESID_SECURITY_SIGNATURE_LBL; + public static String RESID_SECURITY_SUBJECT_LBL; + public static String RESID_SECURITY_KEY_LBL; + public static String RESID_SECURITY_PUBLIC_KEY_LBL; + public static String RESID_SECURITY_KEY_ENTRY; + public static String RESID_SECURITY_ADD_CERT_DLG_TITLE; + public static String RESID_SECURITY_RENAME_CERT_DLG_TITLE; + public static String RESID_SECURITY_CERTIFICATE_ALIAS; + public static String RESID_SECURITY_SEC_MSG; + public static String RESID_SECURITY_TRUSTED_CERTIFICATE; + public static String RESID_SECURITY_CERTIFICATE_FILE; + public static String RESID_SECURITY_BROWSE; + public static String RESID_SECURITY_ADD_LBL; + public static String RESID_SECURITY_REMOVE_LBL; + public static String RESID_SECURITY_RENAME_LBL; + public static String RESID_SECURITY_PREF_ALIAS_NAME;; + public static String RESID_SECURITY_PREF_ISSUED_TO;; + public static String RESID_SECURITY_PREF_ISSUED_FROM;; + public static String RESID_SECURITY_PREF_EXPIRES;; + + public static String RESID_SECURITY_KEY_IO_ERROR_; + public static String RESID_SECURITY_KEY_LOAD_ERROR_; + public static String RESID_SECURITY_ALGORITHM_ERROR_; + public static String RESID_SECURITY_KEY_MANAG_ERROR_; + public static String RESID_SECURITY_KEY_STORE_ERROR_; + public static String RESID_SECURITY_UNREC_KEY_ERROR_; + public static String RESID_SECURITY_PWD_REQ_INFO_; + public static String RESID_SECURITY_LOGIN_FAILED_INFO_; + public static String RESID_SECURITY_KEYSTORE_SAVE_ERROR_; + public static String RESID_SECURITY_IO_SAVE_ERROR_; + public static String RESID_SECURITY_CERTIFICATE_STORE_ERROR_; + public static String RESID_SECURITY_UNINIT_KEYSTORE_ERROR_; + public static String RESID_SECURITY_INITIALIZE_ERROR_; + public static String RESID_SECURITY_SECURITY_PROVIDER_ERROR_; + public static String RESID_SECURITY_LOAD_KEYSTORE_ERROR_; + public static String RESID_SECURITY_CERTIFICATE_EXC_; + public static String RESID_SECURITY_LOAD_IO_EXC_; + public static String RESID_SECURITY_CERTIFICATE_LOAD_EXC_; + public static String RESID_SECURITY_PREF_SEC_DESCRIPTION; + public static String RESID_SECURITY_PROPERTIES_LBL; + + public static String RESID_SECURITY_TRUST_WIZ_ALIAS_TITLE; + public static String RESID_SECURITY_TRUST_WIZ_ALIAS_DESC; + + public static String RESID_SECURITY_TRUST_WIZ_CERTIFICATE_TITLE; + public static String RESID_SECURITY_TRUST_WIZ_CERTIFICATE_DESC; + + public static String RESID_SECURITY_TRUST_IMPORT_CERTIFICATE_WIZARD; + public static String RESID_SECURITY_CERTIFICATE_INFORMATION; + + static + { + // load message values from bundle file + initializeMessages(BUNDLE_NAME, UniversalSecurityProperties.class); + } + +}; \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.properties b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.properties new file mode 100644 index 00000000000..3ba530ae370 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/UniversalSecurityProperties.properties @@ -0,0 +1,78 @@ +################################################################################ +# 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. +################################################################################ + +# NLS_MESSAGEFORMAT_NONE + + RESID_SECURITY_CERTIFICATE_PROP_TITLE = Certificate Properties + RESID_SECURITY_VALIDITY_PERIOD = Valid from %1 to %2 + RESID_SECURITY_SERIAL_NUMBER_LBL = Serial number: + RESID_SECURITY_CERTIF_VERSION_LBL = Version: + RESID_SECURITY_PROP_ALIAS_LBL = Alias Name: + RESID_SECURITY_ISSUED_TO_LBL = Issued To: + RESID_SECURITY_ISSUED_BY_LBL = Issued By: + RESID_SECURITY_VALIDITY_LBL = Validity: + RESID_SECURITY_SIGALG_LBL = Signature Algorithm: + RESID_SECURITY_ALGORITHM_LBL = Algorithm: + RESID_SECURITY_SIGNATURE_LBL = Signature: + RESID_SECURITY_SUBJECT_LBL = Subject: + RESID_SECURITY_KEY_LBL = Key: + RESID_SECURITY_PUBLIC_KEY_LBL = Public key: + RESID_SECURITY_KEY_ENTRY = Key + RESID_SECURITY_ADD_CERT_DLG_TITLE = Add Certificate + RESID_SECURITY_RENAME_CERT_DLG_TITLE = Rename Certificate + RESID_SECURITY_CERTIFICATE_ALIAS = Alias Name: + RESID_SECURITY_SEC_MSG = Security Message + RESID_SECURITY_TRUSTED_CERTIFICATE = Trusted Certificate + RESID_SECURITY_CERTIFICATE_FILE = Security Certificate File: + RESID_SECURITY_BROWSE = Browse... + RESID_SECURITY_ADD_LBL = Add... + RESID_SECURITY_REMOVE_LBL = Remove + RESID_SECURITY_RENAME_LBL = Rename... + RESID_SECURITY_PREF_ALIAS_NAME = Alias + RESID_SECURITY_PREF_ISSUED_TO = Issued To + RESID_SECURITY_PREF_ISSUED_FROM = Issued By + RESID_SECURITY_PREF_EXPIRES = Expiration Date + + RESID_SECURITY_KEY_IO_ERROR_ = File not found \n%1. + RESID_SECURITY_KEY_LOAD_ERROR_ = One or more certificates in the\n%1\nkey store could not be loaded. + RESID_SECURITY_ALGORITHM_ERROR_ = The algorithm used to check the integrity of the key store\n%1\ncannot be found. + RESID_SECURITY_KEY_MANAG_ERROR_ = Key management exception, for operations dealing with key management in\n%1. + RESID_SECURITY_KEY_STORE_ERROR_ = Key store exception, for operations dealing with key store in\n%1. + RESID_SECURITY_UNREC_KEY_ERROR_ = Unrecoverable key exception for operations dealing with key store in\n%1. + RESID_SECURITY_PWD_REQ_INFO_ = This is a secure connection, password authentication is required. + RESID_SECURITY_LOGIN_FAILED_INFO_ = Login failed, password authentication is required. + RESID_SECURITY_KEYSTORE_SAVE_ERROR_ = Unable to persist key store. + RESID_SECURITY_IO_SAVE_ERROR_ = A input-output exception occurred while saving key store \n%1. + RESID_SECURITY_CERTIFICATE_STORE_ERROR_ = One or more certificates in the\n%1\nkey store could not be stored. + RESID_SECURITY_UNINIT_KEYSTORE_ERROR_ = Keystore %1 \nhas not been initialized. + RESID_SECURITY_INITIALIZE_ERROR_ = Unable to initialize key store \n%1. + RESID_SECURITY_SECURITY_PROVIDER_ERROR_ = Requested security provider not available. + RESID_SECURITY_LOAD_KEYSTORE_ERROR_ = Failed to load key store. + RESID_SECURITY_CERTIFICATE_EXC_ = A certificate exception occurred while loading the file\n%1 + RESID_SECURITY_LOAD_IO_EXC_ = A input-output exception occurred while loading the file\n%1 + RESID_SECURITY_CERTIFICATE_LOAD_EXC_ = Unable to load certificate. + RESID_SECURITY_PREF_SEC_DESCRIPTION = Create, remove or edit Security Certificate definitions. + RESID_SECURITY_PROPERTIES_LBL = Properties... + + RESID_SECURITY_TRUST_WIZ_CERTIFICATE_TITLE = Untrusted Certificate + RESID_SECURITY_TRUST_WIZ_CERTIFICATE_DESC = An untrusted certificate has been received from host.\n If you want to start trusting this certificate, continue to the next page. + + RESID_SECURITY_TRUST_WIZ_ALIAS_TITLE = Certificate Alias + RESID_SECURITY_TRUST_WIZ_ALIAS_DESC = Specify an alias to use when referencing the new certificate. + + RESID_SECURITY_TRUST_IMPORT_CERTIFICATE_WIZARD = Import Host Certificate + RESID_SECURITY_CERTIFICATE_INFORMATION = Certificate Information: + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertPropertiesDialog.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertPropertiesDialog.java new file mode 100644 index 00000000000..45337440bbe --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertPropertiesDialog.java @@ -0,0 +1,56 @@ +/******************************************************************************** + * 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.dstore.security.preference; + + +import org.eclipse.rse.dstore.security.UniversalSecurityPlugin; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.dstore.security.widgets.CertificatePropertiesForm; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + + + + +public class CertPropertiesDialog extends SystemPromptDialog +{ + private Object _cert; + + public CertPropertiesDialog(Shell parentShell, Object cert) + { + super(parentShell, UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_CERTIFICATE_PROP_TITLE)); + _cert = cert; + } + + + + public Control getInitialFocusControl() + { + return getOkButton(); + } + + protected Control createInner(Composite parent) + { + CertificatePropertiesForm form = new CertificatePropertiesForm(getShell(), _cert, true); + return form.createContents(parent); + } + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableContentProvider.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableContentProvider.java new file mode 100644 index 00000000000..39615349769 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableContentProvider.java @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2004, 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.preference; +import java.util.ArrayList; + +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class CertTableContentProvider implements IStructuredContentProvider { + /** + * @see IStructuredContentProvider#getElements(Object) + */ + public Object[] getElements(Object element) { + if (element instanceof ArrayList) + return ((ArrayList)element).toArray(); + + return new Object[0]; + } + /** + * @see IContentProvider#dispose() + */ + public void dispose() { + } + /** + * @see IContentProvider#inputChanged(Viewer, Object, Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableLabelProvider.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableLabelProvider.java new file mode 100644 index 00000000000..4c186f9dc94 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableLabelProvider.java @@ -0,0 +1,96 @@ +/******************************************************************************** + * 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.dstore.security.preference; + + + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + + + +public class CertTableLabelProvider + extends LabelProvider + implements ITableLabelProvider + { + + public Image getColumnImage(Object element, int columnIndex) + { + if (columnIndex == 0) + { + if (element instanceof Element) + { + return ((Element)element).getImage(); + } + } + return null; + } + /** + * @see ITableLabelProvider#getColumnText(Object, int) + */ + public String getColumnText(Object element, int columnIndex) + { + if (element instanceof Element) + { + X509CertificateElement myTableElement = (X509CertificateElement) element; + + switch (columnIndex) + { + case 0: // alias + return myTableElement.getAlias(); + case 1: // issued to + { + String name = myTableElement.getSubjectName(); + if (name == null || name.length() == 0) + { + name = myTableElement.getSubjectUnit(); + if (name == null || name.length() == 0) + { + name = myTableElement.getSubjectOrg(); + } + } + return name; + } + case 2: // issuer + { + String name = myTableElement.getIssuerName(); + if (name == null || name.length() == 0) + { + name = myTableElement.getIssuerUnit(); + if (name == null || name.length() == 0) + { + name = myTableElement.getIssuerOrg(); + } + } + + return name; + } + case 3: // expires + return myTableElement.getNotAfter(); + + default: + break; + } + } + return ""; + } + + + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableSorter.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableSorter.java new file mode 100644 index 00000000000..52b1135de8c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/CertTableSorter.java @@ -0,0 +1,193 @@ +/******************************************************************************** + * 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.dstore.security.preference; + + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.TableColumn; + +public class CertTableSorter +extends ViewerSorter +{ + private final static String ASC_SYMBOL = "^"; + private final static String DESC_SYMBOL = "."; + + private TableViewer tableViewer; + private int currentColumn; + private boolean asc; + private boolean addDirectionSymbol; + + private SelectionListener headerListener; + + public CertTableSorter(TableViewer tableViewer, int defaultColumn, boolean asc, boolean addDirectionSymbol, boolean addHeaderListener) + { + this.tableViewer = tableViewer; + this.addDirectionSymbol = addDirectionSymbol; + + setSort(defaultColumn, asc); + + tableViewer.setSorter(this); + if(addHeaderListener) + addColumnHeaderListeners(); + } + + public static void setTableSorter(TableViewer tableViewer, int defaultColumn, boolean asc) + { + new CertTableSorter(tableViewer, defaultColumn, asc, false, true); + } + + private void initializeHeaderListener() + { + headerListener = new SelectionListener() + { + public void widgetDefaultSelected(SelectionEvent e) + { + } + + public void widgetSelected(SelectionEvent e) + { + String text = null; + + if(currentColumn >= 0) + { + TableColumn currentTableColumn = (TableColumn)tableViewer.getTable().getColumn(currentColumn); + if(addDirectionSymbol && (currentTableColumn != null)) + { + text = currentTableColumn.getText(); + if((text != null) && (text.startsWith(ASC_SYMBOL) || text.startsWith(DESC_SYMBOL))) + { + text = text.substring(1); + currentTableColumn.setText(text); + } + } + } + + TableColumn tableColumn = (TableColumn)e.widget; + text = tableColumn.getText(); + + int index = tableViewer.getTable().indexOf(tableColumn); + if(index == currentColumn) + { + asc = !asc; + } + else + { + asc = true; + currentColumn = index; + } + + if(addDirectionSymbol && (text != null)) + { + if(asc) + text = ASC_SYMBOL + text; + else + text = DESC_SYMBOL + text; + + tableColumn.setText(text); + } + + tableViewer.getTable().setRedraw(false); + tableViewer.refresh(); + tableViewer.getTable().setRedraw(true); + } + }; + } + + public void addColumnHeaderListeners() + { + for(int i=0, length=tableViewer.getTable().getColumnCount(); i 0) + { + Iterator i = elem.iterator(); + while (i.hasNext()) + { + try + { + Element current = (Element) i.next(); + _keyStore.deleteEntry(current.getAlias()); + _tableItems.remove(current); + } + catch (KeyStoreException e) + { + } + } + + _viewer.refresh(); + } + + } + else if (event.widget == _renameButton) + { + IStructuredSelection elem = (IStructuredSelection) _viewer + .getSelection(); + if (elem.size() == 1) + { + Element sel = (Element) elem.getFirstElement(); + RenameCertDialog dlg = new RenameCertDialog(this, getShell(), + sel.getAlias()); + dlg.open(); + + if (dlg.getReturnCode() == Window.OK) + { + try + { + DStoreKeyStore.addCertificateToKeyStore( + UniversalSecurityPreferencePage.this._keyStore, + (Certificate) sel.getCert(), dlg.getNewAlias()); + _keyStore.deleteEntry(sel.getAlias()); + sel.setAlias(dlg.getNewAlias()); + _viewer.refresh(); + } + catch (KeyStoreException e) + { + } + } + } + + } + else if (event.widget == _propertiesButton) + { + IStructuredSelection elem = (IStructuredSelection) _viewer + .getSelection(); + if (elem.size() == 1) + { + Element sel = (Element) elem.getFirstElement(); + CertPropertiesDialog dlg = null; + if (sel instanceof X509CertificateElement) + { + dlg = new X509CertificatePropertiesDialog(getShell(), (X509CertificateElement)sel); + } + else + { + dlg = new KeyPropertiesDialog(getShell(), (KeyElement)sel); + } + + dlg.open(); + + } + + } + + boolean sel = _viewer.getSelection().isEmpty(); + _renameButton.setEnabled(!sel); + _removeButton.setEnabled(!sel); + _propertiesButton.setEnabled(!sel); + } + + public void widgetSelected(SelectionEvent e) + { + // TODO Auto-generated method stub + boolean sel = _viewer.getSelection().isEmpty(); + _renameButton.setEnabled(!sel); + _removeButton.setEnabled(!sel); + _propertiesButton.setEnabled(!sel); + } + + public void widgetDefaultSelected(SelectionEvent e) + { + widgetSelected(e); + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificateElement.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificateElement.java new file mode 100644 index 00000000000..fefda619998 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificateElement.java @@ -0,0 +1,215 @@ +/******************************************************************************** + * 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.dstore.security.preference; + + +import java.security.cert.X509Certificate; +import java.util.Date; + + +public class X509CertificateElement extends Element +{ + public static int CERT_NAME = 0; + public static int CERT_UNIT = 1; + public static int CERT_ORGANIZATION = 2; + public static int CERT_CITY = 3; + public static int CERT_PROVINCE = 4; + public static int CERT_COUNTRY = 5; + + + private X509Certificate _cert; + public X509CertificateElement(String alias, String value, X509Certificate cert) + { + super(alias, value); + _cert = cert; + } + + public String getType() + { + return _cert.getType(); + } + + public String getVersion() + { + return "V." + _cert.getVersion(); + } + + private String[] parse(String full) + { + StringBuffer result = new StringBuffer(); + char[] chars = full.toCharArray(); + boolean inQuotes = false; + for (int i = 0; i < chars.length; i++) + { + char c = chars[i]; + if (c == '\"') + { + inQuotes = !inQuotes; + } + else + { + if (c == ',') + { + if (!inQuotes) + { + c = ';'; + } + } + } + result.append(c); + } + return result.toString().split(";"); + } + + private String extract(String full, int index) + { + String[] pairs = parse(full); + String match = pairs[index].split("=")[1]; + return match; + } + + + public String getIssuerDN() + { + String full = _cert.getIssuerDN().getName(); + return full; + } + + public String getIssuerName() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_NAME); + } + + public String getIssuerUnit() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_UNIT); + } + + public String getIssuerOrg() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_ORGANIZATION); + } + + public String getIssuerCity() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_CITY); + } + + public String getIssuerProvince() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_PROVINCE); + } + + public String getIssuerCountry() + { + String full = _cert.getIssuerDN().getName(); + return extract(full, CERT_COUNTRY); + } + + public String getSubjectDN() + { + String full = _cert.getSubjectDN().getName(); + return full; + } + + public String getSubjectName() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_NAME); + } + + public String getSubjectUnit() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_UNIT); + } + + public String getSubjectOrg() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_ORGANIZATION); + } + + public String getSubjectCity() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_CITY); + } + + public String getSubjectProvince() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_PROVINCE); + } + + public String getSubjectCountry() + { + String full = _cert.getSubjectDN().getName(); + return extract(full, CERT_COUNTRY); + } + + + + + + public String getNotBefore() + { + return _cert.getNotBefore().toString(); + } + + public String getNotAfter() + { + return _cert.getNotAfter().toString(); + } + + public String getExpirationDate() + { + Date date = _cert.getNotAfter(); + return date.toString(); + } + + + public String getSigAlgName() + { + return _cert.getSigAlgName(); + } + + public String getSerialNumber() + { + return _cert.getSerialNumber().toString(); + } + + public String getAlgorithm() + { + return _cert.getPublicKey().getAlgorithm(); + } + + public String getFormat() + { + return _cert.getPublicKey().getFormat(); + } + + public Object getCert() + { + return _cert; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificatePropertiesDialog.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificatePropertiesDialog.java new file mode 100644 index 00000000000..09f197b3190 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/preference/X509CertificatePropertiesDialog.java @@ -0,0 +1,28 @@ +/******************************************************************************** + * 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.dstore.security.preference; + +import org.eclipse.swt.widgets.Shell; + +public class X509CertificatePropertiesDialog extends CertPropertiesDialog +{ + public X509CertificatePropertiesDialog(Shell parentShell, X509CertificateElement element) + { + super(parentShell, element.getCert()); + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/GridUtil.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/GridUtil.java new file mode 100644 index 00000000000..d8721e3098d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/GridUtil.java @@ -0,0 +1,68 @@ +/******************************************************************************** + * 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.dstore.security.util; + +import org.eclipse.swt.layout.GridData; + +/** + * A utility class to create convenient grid data objects. + */ +public class GridUtil +{ + /** + * GridUtil constructor comment. + */ + public GridUtil() + { + super(); + } + + /** + * Creates a grid data object that occupies vertical and horizontal space. + */ + static public GridData createFill() + { + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.FILL; + gd.grabExcessHorizontalSpace = true; + gd.verticalAlignment = GridData.FILL; + gd.grabExcessVerticalSpace = true; + return gd; + } + + /** + * Creates a grid data object that occupies horizontal space. + */ + static public GridData createHorizontalFill() + { + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.FILL; + gd.grabExcessHorizontalSpace = true; + return gd; + } + + /** + * Creates a grid data object that occupies vertical space. + */ + static public GridData createVerticalFill() + { + GridData gd = new GridData(); + gd.verticalAlignment = GridData.FILL; + gd.grabExcessVerticalSpace = true; + return gd; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/StringModifier.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/StringModifier.java new file mode 100644 index 00000000000..17d122552a6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/util/StringModifier.java @@ -0,0 +1,52 @@ +/******************************************************************************** + * 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.dstore.security.util; +/** + * This class provides static methods for some of the + * very used IString operations + */ + +public class StringModifier +{ + // change all occurrences of oldPat to newPat + public static String change(String in, String oldPat, String newPat) + { + if (oldPat.length() == 0) + return in; + if (oldPat.length() == 1 && newPat.length() == 1) + return in.replace(oldPat.charAt(0), newPat.charAt(0)); + + int lastIndex = 0; + int newIndex = 0; + StringBuffer newString = new StringBuffer(); + for(;;) + { + newIndex = in.indexOf(oldPat, lastIndex); + if (newIndex != -1) + { + newString.append(in.substring(lastIndex, newIndex) + newPat); + lastIndex = newIndex + oldPat.length(); + } + else + { + newString.append(in.substring(lastIndex)); + break; + } + } + return newString.toString(); + } + } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificateForm.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificateForm.java new file mode 100644 index 00000000000..eea23f9863f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificateForm.java @@ -0,0 +1,185 @@ +/******************************************************************************** + * 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.dstore.security.widgets; + +import java.io.File; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.ArrayList; + +import org.eclipse.dstore.core.util.ssl.DStoreKeyStore; +import org.eclipse.rse.dstore.security.UniversalSecurityPlugin; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.dstore.security.util.GridUtil; +import org.eclipse.rse.ui.SystemBaseForm; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +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.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + + +public class CertificateForm extends SystemBaseForm +{ + private Text _pathField; + private Text _aliasField; + private String _aliasStr; + private String _pathStr; + private ArrayList listenerList; + + private Button _browseButton; + public Shell _shell; + + public CertificateForm(Shell shell, ISystemMessageLine msgLine) + { + super(shell, msgLine); + listenerList = new ArrayList(); + _shell = shell; + } + + public Control getInitialFocusControl() + { + return _pathField; + } + + public Control createContents(Composite c){ + + GridData data; + Composite nameGroup = new Composite(c, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + data = GridUtil.createFill(); + data.widthHint = 400; + nameGroup.setLayoutData(data); + nameGroup.setLayout(layout); + + Label lblPath = new Label(nameGroup, SWT.NONE); + lblPath.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_CERTIFICATE_FILE)); + _pathField = new Text(nameGroup, SWT.BORDER); + _pathField.setLayoutData(GridUtil.createHorizontalFill()); + _pathField.setText(""); + + _browseButton = new Button(nameGroup, SWT.PUSH); + _browseButton.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_BROWSE)); + + _browseButton.addListener(SWT.Selection, this); + + Label lblName = new Label(nameGroup, SWT.NONE); + lblName.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_CERTIFICATE_ALIAS)); + _aliasField = new Text(nameGroup, SWT.BORDER); + _aliasField.setText(""); + + _aliasField.setLayoutData(GridUtil.createHorizontalFill()); + + _aliasField.addListener(SWT.Modify, this); + _pathField.addListener(SWT.Modify, this); + + return _pathField; + + } + + /** + * Handle all events and enablements for widgets in this dialog + * + * @param event Event + */ + public void handleEvent(Event event) { + + if(event.widget == _browseButton){ + showFileDialog(); + NotifyListeners(event); + } + if(event.widget==_aliasField || event.widget==_pathField){ + //setButtonState(); + _pathStr = _pathField.getText(); + _aliasStr = _aliasField.getText(); + NotifyListeners(event); + } + + } + + public void NotifyListeners(Event event){ + for(int i=0;i0 && _pathField.getText().trim().length()>0); + } + + private void showFileDialog(){ + String currentSource = _pathField.getText(); + + FileDialog dlg = new FileDialog(_shell, SWT.OPEN); + + dlg.setFileName(currentSource); + dlg.setFilterExtensions(new String[]{"*.cer", "*.*"}); + + String source = dlg.open(); + + if(source!=null) + { + _pathField.setText(source); + File f = new File(source); + String alias = f.getName(); + int dotIndex = alias.indexOf('.'); + if (dotIndex > 0) + { + alias = alias.substring(0, dotIndex); + } + _aliasField.setText(alias); + } + + } + + public Certificate loadCertificate(KeyStore ks) throws IOException, CertificateException, KeyStoreException { + + + Certificate fCertificate = DStoreKeyStore.loadCertificate(getPath()); + DStoreKeyStore.addCertificateToKeyStore(ks, fCertificate, getAliasName()); + return fCertificate; + + } + + public void registerListener(Listener listener){ + listenerList.add(listener); + + } + public String getAliasName() + { + return _aliasStr; + } + + public String getPath() + { + return _pathStr; + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificatePropertiesForm.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificatePropertiesForm.java new file mode 100644 index 00000000000..b030a5cba9d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/widgets/CertificatePropertiesForm.java @@ -0,0 +1,291 @@ +/******************************************************************************** + * 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.dstore.security.widgets; + +import java.security.Key; +import java.security.cert.X509Certificate; +import java.text.DateFormat; + +import org.eclipse.rse.dstore.security.UniversalSecurityPlugin; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.dstore.security.util.GridUtil; +import org.eclipse.rse.dstore.security.util.StringModifier; +import org.eclipse.rse.ui.SystemBaseForm; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class CertificatePropertiesForm extends SystemBaseForm +{ + private Object _certificate; + private String _alias; + private boolean _advanced; + + public CertificatePropertiesForm(Shell shell, Object certificate, String alias) + { + this(shell, certificate, alias, false); + } + + public CertificatePropertiesForm(Shell shell, Object certificate) + { + this(shell, certificate, false); + } + + public CertificatePropertiesForm(Shell shell, Object certificate, String alias, boolean advanced) + { + super(shell, null); + _certificate = certificate; + _alias = alias; + _advanced = advanced; + } + + public CertificatePropertiesForm(Shell shell, Object certificate, boolean advanced) + { + this(shell, certificate, null, advanced); + } + + + public Control createContents(Composite parent) + { + if (_advanced) + { + return createAdvancedContents(parent); + } + else + { + return createSimpleContents(parent); + } + } + + public Control createSimpleContents(Composite parent) + { + Composite content = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + GridData data = GridUtil.createFill(); + data.widthHint = 450; + //data.heightHint = 300; + layout.numColumns = 2; + content.setLayout(layout); + content.setLayoutData(data); + + if (_alias != null) + { + Label lblAlias = new Label(content, SWT.NONE); + lblAlias.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_PROP_ALIAS_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblAlias.setLayoutData(data); + + Label lblAliasValue = new Label(content, SWT.NONE); + lblAliasValue.setText(_alias); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblAliasValue.setLayoutData(data); + } + + Label lblVersion = new Label(content, SWT.NONE); + lblVersion.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_CERTIF_VERSION_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblVersion.setLayoutData(data); + + Label lblVersionValue = new Label(content, SWT.NONE); + + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblVersionValue.setLayoutData(data); + + Label lblIssuedTo = new Label(content, SWT.NONE); + lblIssuedTo.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ISSUED_TO_LBL)); + data = new GridData(); + data.verticalAlignment = GridData.BEGINNING; + data.horizontalIndent = 5; + lblIssuedTo.setLayoutData(data); + + Text lblIssuedToValue = new Text(content, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP) ; + data = new GridData(GridData.FILL_HORIZONTAL); + data.heightHint = 60; + data.horizontalIndent = 5; + lblIssuedToValue.setLayoutData(data); + + Label lblIssuedBy = new Label(content, SWT.NONE); + lblIssuedBy.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ISSUED_BY_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + data.verticalAlignment = GridData.BEGINNING; + lblIssuedBy.setLayoutData(data); + + Text lblIssuedByValue = new Text(content, SWT.BORDER |SWT.READ_ONLY | SWT.WRAP); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + data.heightHint = 60; + lblIssuedByValue.setLayoutData(data); + + Label lblValidity = new Label(content, SWT.NONE); + lblValidity.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_VALIDITY_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblValidity.setLayoutData(data); + + Label lblValidityValue = new Label(content, SWT.NONE); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblValidityValue.setLayoutData(data); + + Label lblAlgorithm = new Label(content, SWT.NONE); + lblAlgorithm.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ALGORITHM_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblAlgorithm.setLayoutData(data); + + Label lblAlgorithmValue = new Label(content, SWT.NONE); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblAlgorithmValue.setLayoutData(data); + + if(_certificate instanceof X509Certificate){ + lblVersionValue.setText(((X509Certificate)_certificate).getType() + " V."+((X509Certificate)_certificate).getVersion()); + lblIssuedToValue.setText(((X509Certificate)_certificate).getSubjectDN().getName()); + lblIssuedByValue.setText(((X509Certificate)_certificate).getIssuerDN().getName()); + DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); + + String validity = UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_VALIDITY_PERIOD); + validity = StringModifier.change(validity,"%1", df.format(((X509Certificate)_certificate).getNotBefore())); + validity = StringModifier.change(validity,"%2", df.format(((X509Certificate)_certificate).getNotAfter())); + + lblValidityValue.setText(validity); + lblAlgorithmValue.setText(((X509Certificate)_certificate).getSigAlgName()); + }else if(_certificate instanceof Key){ + lblVersionValue.setText(((Key)_certificate).getFormat()); + lblAlgorithmValue.setText(((Key)_certificate).getAlgorithm()); + } + + return content; + } + + + public Control createAdvancedContents(Composite parent) + { + Composite content = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + GridData data = GridUtil.createFill(); + data.widthHint = 450; + //data.heightHint = 300; + layout.numColumns = 2; + content.setLayout(layout); + content.setLayoutData(data); + + if (_alias != null) + { + Label lblAlias = new Label(content, SWT.NONE); + lblAlias.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_PROP_ALIAS_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblAlias.setLayoutData(data); + + Label lblAliasValue = new Label(content, SWT.NONE); + lblAliasValue.setText(_alias); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblAliasValue.setLayoutData(data); + } + + Label lblVersion = new Label(content, SWT.NONE); + lblVersion.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_CERTIF_VERSION_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblVersion.setLayoutData(data); + + Label lblVersionValue = new Label(content, SWT.NONE); + + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblVersionValue.setLayoutData(data); + + Label lblIssuedTo = new Label(content, SWT.NONE); + lblIssuedTo.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ISSUED_TO_LBL)); + data = new GridData(); + data.verticalAlignment = GridData.BEGINNING; + data.horizontalIndent = 5; + lblIssuedTo.setLayoutData(data); + + Text lblIssuedToValue = new Text(content, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP) ; + data = new GridData(GridData.FILL_HORIZONTAL); + data.heightHint = 60; + data.horizontalIndent = 5; + lblIssuedToValue.setLayoutData(data); + + Label lblIssuedBy = new Label(content, SWT.NONE); + lblIssuedBy.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ISSUED_BY_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + data.verticalAlignment = GridData.BEGINNING; + lblIssuedBy.setLayoutData(data); + + Text lblIssuedByValue = new Text(content, SWT.BORDER |SWT.READ_ONLY | SWT.WRAP); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + data.heightHint = 60; + lblIssuedByValue.setLayoutData(data); + + Label lblValidity = new Label(content, SWT.NONE); + lblValidity.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_VALIDITY_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblValidity.setLayoutData(data); + + Label lblValidityValue = new Label(content, SWT.NONE); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblValidityValue.setLayoutData(data); + + Label lblAlgorithm = new Label(content, SWT.NONE); + lblAlgorithm.setText(UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_ALGORITHM_LBL)); + data = new GridData(); + data.horizontalIndent = 5; + lblAlgorithm.setLayoutData(data); + + Label lblAlgorithmValue = new Label(content, SWT.NONE); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalIndent = 5; + lblAlgorithmValue.setLayoutData(data); + + if(_certificate instanceof X509Certificate){ + lblVersionValue.setText(((X509Certificate)_certificate).getType() + " V."+((X509Certificate)_certificate).getVersion()); + lblIssuedToValue.setText(((X509Certificate)_certificate).getSubjectDN().getName()); + lblIssuedByValue.setText(((X509Certificate)_certificate).getIssuerDN().getName()); + DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); + + String validity = UniversalSecurityPlugin.getString(UniversalSecurityProperties.RESID_SECURITY_VALIDITY_PERIOD); + validity = StringModifier.change(validity,"%1", df.format(((X509Certificate)_certificate).getNotBefore())); + validity = StringModifier.change(validity,"%2", df.format(((X509Certificate)_certificate).getNotAfter())); + + lblValidityValue.setText(validity); + lblAlgorithmValue.setText(((X509Certificate)_certificate).getSigAlgName()); + }else if(_certificate instanceof Key){ + lblVersionValue.setText(((Key)_certificate).getFormat()); + lblAlgorithmValue.setText(((Key)_certificate).getAlgorithm()); + } + + return content; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/NewCertTableLabelProvider.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/NewCertTableLabelProvider.java new file mode 100644 index 00000000000..590acc72509 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/NewCertTableLabelProvider.java @@ -0,0 +1,96 @@ +/******************************************************************************** + * 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.dstore.security.wizards; + + + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.rse.dstore.security.preference.Element; +import org.eclipse.rse.dstore.security.preference.X509CertificateElement; +import org.eclipse.swt.graphics.Image; + + + +public class NewCertTableLabelProvider + extends LabelProvider + implements ITableLabelProvider + { + + public Image getColumnImage(Object element, int columnIndex) + { + if (columnIndex == 0) + { + if (element instanceof Element) + { + return ((Element)element).getImage(); + } + } + return null; + } + /** + * @see ITableLabelProvider#getColumnText(Object, int) + */ + public String getColumnText(Object element, int columnIndex) + { + if (element instanceof Element) + { + X509CertificateElement myTableElement = (X509CertificateElement) element; + + switch (columnIndex) + { + case 0: // issued to + { + String name = myTableElement.getSubjectName(); + if (name == null || name.length() == 0) + { + name = myTableElement.getSubjectUnit(); + if (name == null || name.length() == 0) + { + name = myTableElement.getSubjectOrg(); + } + } + return name; + } + case 1: // issuer + { + String name = myTableElement.getIssuerName(); + if (name == null || name.length() == 0) + { + name = myTableElement.getIssuerUnit(); + if (name == null || name.length() == 0) + { + name = myTableElement.getIssuerOrg(); + } + } + + return name; + } + case 2: // expires + return myTableElement.getNotAfter(); + + default: + break; + } + } + return ""; + } + + + + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertAction.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertAction.java new file mode 100644 index 00000000000..b7c14fb4b76 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertAction.java @@ -0,0 +1,50 @@ +/******************************************************************************** + * 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.dstore.security.wizards; + +import java.util.List; + +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.rse.core.comm.ISystemKeystoreProvider; +import org.eclipse.rse.dstore.security.ImageRegistry; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.ui.actions.SystemBaseWizardAction; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class SystemImportCertAction extends SystemBaseWizardAction + { + private List _certificates; + private ISystemKeystoreProvider _provider; + public SystemImportCertAction(ISystemKeystoreProvider provider, List certs) + { + super(UniversalSecurityProperties.RESID_SECURITY_TRUST_IMPORT_CERTIFICATE_WIZARD, + ImageRegistry.getImageDescriptor(ImageRegistry.IMG_CERTIF_FILE), + Display.getDefault().getActiveShell() + ); + _certificates = certs; + _provider = provider; + } + + public IWizard createWizard() + { + Shell shell = Display.getDefault().getActiveShell(); + SystemImportCertWizard importWiz = new SystemImportCertWizard(_provider); + importWiz.setInputObject(_certificates); + return importWiz; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizard.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizard.java new file mode 100644 index 00000000000..8e69f15151c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizard.java @@ -0,0 +1,148 @@ +/******************************************************************************** + * 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.dstore.security.wizards; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.List; + +import org.eclipse.dstore.core.util.ssl.DStoreKeyStore; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemPlugin; +import org.eclipse.rse.core.comm.ISystemKeystoreProvider; +import org.eclipse.rse.dstore.security.ImageRegistry; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.wizards.AbstractSystemWizard; + +public class SystemImportCertWizard + extends AbstractSystemWizard + implements ISystemMessages +{ + + private SystemImportCertWizardMainPage _mainPage; + private SystemImportCertWizardAliasPage _aliasPage; + private ISystemKeystoreProvider _provider; + + + /** + * Constructor + */ + public SystemImportCertWizard(ISystemKeystoreProvider provider) + { + super(UniversalSecurityProperties.RESID_SECURITY_TRUST_IMPORT_CERTIFICATE_WIZARD, + ImageRegistry.getImageDescriptor(ImageRegistry.IMG_WZ_IMPORT_CERTIF)); + _provider = provider; + } + + /** + * Creates the wizard pages. + * This method is an override from the parent Wizard class. + */ + public void addPages() + { + try { + _mainPage = createMainPage(); + addPage((WizardPage)_mainPage); + + _aliasPage = createAliasPage(); + addPage((WizardPage)_aliasPage); + //super.addPages(); + } catch (Exception exc) + { + SystemBasePlugin.logError("New File: Error in createPages: ",exc); + } + } + + /** + * Creates the wizard's main page. + * This method is an override from the parent class. + */ + protected SystemImportCertWizardMainPage createMainPage() + { + SystemMessage errMsg = null; + + _mainPage = new SystemImportCertWizardMainPage(this, getCertificates()); + if (errMsg != null) + _mainPage.setErrorMessage(errMsg); + return _mainPage; + } + + /** + * Creates the wizard's main page. + * This method is an override from the parent class. + */ + protected SystemImportCertWizardAliasPage createAliasPage() + { + SystemMessage errMsg = null; + + _aliasPage = new SystemImportCertWizardAliasPage(this, getCertificates()); + if (errMsg != null) + _aliasPage.setErrorMessage(errMsg); + return _aliasPage; + } + + /** + * 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() + { + boolean ok = false; + if (_aliasPage.performFinish()) + { + List certs = getCertificates(); + for (int i = 0; i < certs.size(); i++) + { + X509Certificate cert = (X509Certificate)certs.get(i); + if (cert != null) + { + String alias = _aliasPage.getAlias(); + + try + { + KeyStore ks = DStoreKeyStore.getKeyStore(_provider.getKeyStorePath(), _provider.getKeyStorePassword()); + DStoreKeyStore.addCertificateToKeyStore(ks, cert, alias); + DStoreKeyStore.persistKeyStore(ks, _provider.getKeyStorePath(), _provider.getKeyStorePassword()); + ok = true; + } + catch (Exception e) + { + e.printStackTrace(); + ok = false; + } + } + } + } + return ok; + } + + + public List getCertificates() + { + return (List)getInputObject(); + } + + + +} // end class \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardAliasPage.java b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardAliasPage.java new file mode 100644 index 00000000000..034368d4c10 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.dstore.security/src/org/eclipse/rse/dstore/security/wizards/SystemImportCertWizardAliasPage.java @@ -0,0 +1,175 @@ +/******************************************************************************** + * 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.wizard.Wizard; +import org.eclipse.rse.dstore.security.UniversalSecurityProperties; +import org.eclipse.rse.dstore.security.preference.X509CertificateElement; +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.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + + +public class SystemImportCertWizardAliasPage + extends AbstractSystemWizardPage + implements ISystemMessages +{ + + + protected SystemMessage errorMessage; + protected ISystemValidator nameValidator; + protected ISystemMessageLine msgLine; + + private Text _alias; + /** + * Constructor. + */ + public SystemImportCertWizardAliasPage(Wizard wizard, List certs) + { + super(wizard, "SpecifyAlias", + UniversalSecurityProperties.RESID_SECURITY_TRUST_WIZ_ALIAS_TITLE, + UniversalSecurityProperties.RESID_SECURITY_TRUST_WIZ_ALIAS_DESC); + } + + /** + * 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 content = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + GridData data = new GridData(GridData.FILL_BOTH); + layout.numColumns = 3; + content.setLayout(layout); + content.setLayoutData(data); + + SystemWidgetHelpers.createLabel(content, UniversalSecurityProperties.RESID_SECURITY_CERTIFICATE_ALIAS); + _alias = SystemWidgetHelpers.createTextField(content, null); + _alias.addModifyListener( + new ModifyListener() + { + public void modifyText(ModifyEvent e) + { + validateNameInput(); + } + } + ); + return _alias; + } + + + 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 _alias; + } + + /** + * Init values using input data + */ + protected void initializeInput() + { + } + + /** + * This hook method is called whenever the text changes in the input field. + * The default implementation delegates the request to an 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 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/.cvsignore b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/.project b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.project new file mode 100644 index 00000000000..e6bafed58fb --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.eclipse.filesystem + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.eclipse.filesystem/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..ddd8cafcec9 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.eclipse.filesystem; singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.rse.eclipse.filesystem.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.filesystem, + org.eclipse.rse.subsystems.files.core, + org.eclipse.rse.services, + org.eclipse.rse.files.ui, + org.eclipse.core.resources, + org.eclipse.rse.ui +Eclipse-LazyStart: true +Bundle-Vendor: Eclipse.org diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/about.html b/rse/plugins/org.eclipse.rse.eclipse.filesystem/about.html new file mode 100644 index 00000000000..6f6b96c4c87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/about.html @@ -0,0 +1,22 @@ + + + +About + + + +

    About This Content

    + +

    February 24, 2005

    +

    License

    + +

    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.rse.eclipse.filesystem/build.properties b/rse/plugins/org.eclipse.rse.eclipse.filesystem/build.properties new file mode 100644 index 00000000000..fca1546c3c5 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/build.properties @@ -0,0 +1,12 @@ +bin.includes = META-INF/,\ + plugin.xml,\ + about.html,\ + plugin.properties,\ + rse_filesystem.jar +src.includes = META-INF/,\ + about.html,\ + plugin.properties,\ + plugin.xml +jars.compile.order = rse_filesystem.jar +source.rse_filesystem.jar = src/ +output.rse_filesystem.jar = bin/ diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.properties b/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.properties new file mode 100644 index 00000000000..0e25d533969 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.properties @@ -0,0 +1,19 @@ +################################################################################ +# 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. +################################################################################ + +# NLS_MESSAGEFORMAT_VAR + +plugin.name = RSE EFS Support diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.xml b/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.xml new file mode 100644 index 00000000000..d2ac2d6161a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/plugin.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/Activator.java b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/Activator.java new file mode 100644 index 00000000000..9ed61f85d16 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/Activator.java @@ -0,0 +1,72 @@ +/******************************************************************************** + * 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.eclipse.filesystem; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + * + * @return the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.rse.eclipse.filesystem", path); + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/FileStoreConversionUtility.java b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/FileStoreConversionUtility.java new file mode 100644 index 00000000000..0fbfb73c187 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/FileStoreConversionUtility.java @@ -0,0 +1,41 @@ +/******************************************************************************** + * 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.eclipse.filesystem; + + + +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; + + +public class FileStoreConversionUtility +{ + public static IFileStore convert(IFileStore parent, IRemoteFile remoteFile) + { + return new RSEFileStoreRemoteFileWrapper(parent, remoteFile); + } + + public static IFileStore[] convert(IFileStore parent, IRemoteFile[] remoteFiles) + { + IFileStore[] converted = new IFileStore[remoteFiles.length]; + for (int i = 0; i < remoteFiles.length; i++) + { + converted[i] = convert(parent, remoteFiles[i]); + } + return converted; + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileStoreRemoteFileWrapper.java b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileStoreRemoteFileWrapper.java new file mode 100644 index 00000000000..d149d07a367 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileStoreRemoteFileWrapper.java @@ -0,0 +1,130 @@ +/******************************************************************************** + * 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.eclipse.filesystem; + +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.filesystem.provider.FileInfo; +import org.eclipse.core.filesystem.provider.FileStore; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.rse.core.subsystems.RemoteChildrenContentsType; +import org.eclipse.rse.files.ui.resources.UniversalFileTransferUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; + + +public class RSEFileStoreRemoteFileWrapper extends FileStore implements IFileStore +{ + private IRemoteFile _remoteFile; + private IFileStore _parent; + public RSEFileStoreRemoteFileWrapper(IFileStore parent, IRemoteFile remoteFile) + { + _remoteFile = remoteFile; + _parent = parent; + } + public String[] childNames(int options, IProgressMonitor monitor) + { + String[] names; + if (!_remoteFile.isStale() && _remoteFile.hasContents(RemoteChildrenContentsType.getInstance())) + { + Object[] children = _remoteFile.getContents(RemoteChildrenContentsType.getInstance()); + names = new String[children.length]; + + for (int i = 0; i < children.length; i++) + { + names[i] = ((IRemoteFile)children[i]).getName(); + } + } + else + { + IRemoteFile[] children = _remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(_remoteFile); + names = new String[children.length]; + for (int i = 0; i < children.length; i++) + { + names[i] = ((IRemoteFile)children[i]).getName(); + } + } + return names; + } + + public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException + { + FileInfo info = new FileInfo(getName()); + info.setExists(true); + info.setLastModified(_remoteFile.getLastModified()); + boolean isDir = _remoteFile.isDirectory(); + info.setDirectory(isDir); + if (!isDir) + { + info.setLength(_remoteFile.getLength()); + } + + info.setName(getName()); + return info; + } + public IFileStore getChild(String name) + { + if (!_remoteFile.isStale() && _remoteFile.hasContents(RemoteChildrenContentsType.getInstance(), name)) + { + Object[] children = _remoteFile.getContents(RemoteChildrenContentsType.getInstance(), name); + if (children != null && children.length > 0) + { + return FileStoreConversionUtility.convert(_parent, (IRemoteFile)children[0]); + } + } + else + { + IRemoteFile[] children = _remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(_remoteFile, name); + if (children != null && children.length > 0) + { + return FileStoreConversionUtility.convert(_parent, children[0]); + } + } + return null; + } + public String getName() + { + return _remoteFile.getName(); + } + public IFileStore getParent() + { + return _parent; + } + public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException + { + IFile file = UniversalFileTransferUtility.copyRemoteFileToWorkspace(_remoteFile, monitor); + return file.getContents(); + } + + public URI toURI() + { + try + { + return new URI("rse", _remoteFile.getAbsolutePath(), null); //$NON-NLS-1$ + } + catch (URISyntaxException e) + { + throw new RuntimeException(e); + } + } + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileSystem.java b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileSystem.java new file mode 100644 index 00000000000..11cfca09676 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.eclipse.filesystem/src/org/eclipse/rse/eclipse/filesystem/RSEFileSystem.java @@ -0,0 +1,80 @@ +/******************************************************************************** + * 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.eclipse.filesystem; + +import java.net.URI; + +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.filesystem.provider.FileSystem; +import org.eclipse.rse.core.SystemPlugin; +import org.eclipse.rse.model.IHost; +import org.eclipse.rse.model.ISystemRegistry; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; + +public class RSEFileSystem extends FileSystem +{ + + public boolean canDelete() + { + return true; + } + + public boolean canWrite() + { + return true; + } + + private IHost getConnectionFor(String hostName) + { + ISystemRegistry sr = SystemPlugin.getTheSystemRegistry(); + IHost[] connections = sr.getHosts(); + for (int i = 0; i < connections.length; i++) + { + IHost con = connections[i]; + if (con.getHostName().equalsIgnoreCase(hostName)) + { + return con; + } + } + return null; + } + + public IFileStore getStore(URI uri) + { + try + { + String path = uri.getPath(); + String hostName = uri.getHost(); + IHost con = getConnectionFor(hostName); + if (con != null) + { + IRemoteFileSubSystem fs = RemoteFileUtility.getFileSubSystem(con); + if (fs != null) + { + return FileStoreConversionUtility.convert(null, fs.getRemoteFileObject(path)); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + +} \ No newline at end of file