Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jubula.app.autrun/src/org/eclipse/jubula/app/autrun/AutRunner.java2
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/AutAgent.java73
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/IRestartAutHandler.java6
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutAutRun.java12
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutConfiguration.java11
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/AbstractStartToolkitAut.java163
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartHtmlAutServerCommand.java6
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartJavaFXAutServerCommand.java10
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartRcpAutServerCommand.java5
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwingAutServerCommand.java14
-rw-r--r--org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwtAutServerCommand.java2
-rw-r--r--org.eclipse.jubula.communication/src/org/eclipse/jubula/communication/internal/message/ConnectToClientMessage.java19
-rw-r--r--org.eclipse.jubula.feature.rc/feature.xml2
-rw-r--r--org.eclipse.jubula.feature/feature.xml7
-rw-r--r--org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AUTServer.java134
-rw-r--r--org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AutServerLauncher.java4
-rw-r--r--org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/adaptable/AdapterFactoryRegistry.java117
-rw-r--r--org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/commands/ConnectToClientCommand.java3
-rw-r--r--org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/constants/CommandConstants.java2
-rw-r--r--org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/utils/ClassPathHacker.java116
20 files changed, 529 insertions, 179 deletions
diff --git a/org.eclipse.jubula.app.autrun/src/org/eclipse/jubula/app/autrun/AutRunner.java b/org.eclipse.jubula.app.autrun/src/org/eclipse/jubula/app/autrun/AutRunner.java
index 4a547a4b4..431ff99e3 100644
--- a/org.eclipse.jubula.app.autrun/src/org/eclipse/jubula/app/autrun/AutRunner.java
+++ b/org.eclipse.jubula.app.autrun/src/org/eclipse/jubula/app/autrun/AutRunner.java
@@ -127,6 +127,7 @@ public class AutRunner {
/** the address for the AUT Agent */
private InetSocketAddress m_agentAddr;
+
/**
* Constructor
@@ -188,6 +189,7 @@ public class AutRunner {
writer.println(
m_autConfiguration.get(AutConfigConstants.AUT_NAME));
+ writer.println(m_startAut.getClass().getName());
Thread agentConnectionThread = new AgentConnectionWatcher(
AGENT_CONNECTION_THREAD_NAME, writer, agentSocket, reader);
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/AutAgent.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/AutAgent.java
index 70a2bc4ca..1f61f613b 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/AutAgent.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/AutAgent.java
@@ -21,12 +21,16 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.eclipse.jubula.autagent.commands.AbstractStartToolkitAut;
+import org.eclipse.jubula.autagent.commands.IStartAut;
import org.eclipse.jubula.communication.internal.Communicator;
import org.eclipse.jubula.communication.internal.IConnectionInitializer;
import org.eclipse.jubula.communication.internal.connection.ConnectionState;
@@ -37,6 +41,7 @@ import org.eclipse.jubula.communication.internal.message.Message;
import org.eclipse.jubula.communication.internal.message.PrepareForShutdownMessage;
import org.eclipse.jubula.communication.internal.message.StartAUTServerMessage;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
+import org.eclipse.jubula.tools.internal.constants.CommandConstants;
import org.eclipse.jubula.tools.internal.constants.EnvConstants;
import org.eclipse.jubula.tools.internal.exception.CommunicationException;
import org.eclipse.jubula.tools.internal.exception.JBVersionException;
@@ -44,6 +49,7 @@ import org.eclipse.jubula.tools.internal.registration.AutIdentifier;
import org.eclipse.jubula.tools.internal.utils.IsAliveThread;
import org.eclipse.jubula.tools.internal.utils.StringParsing;
import org.eclipse.jubula.tools.internal.utils.TimeUtil;
+import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -168,14 +174,17 @@ public class AutAgent {
@SuppressWarnings("synthetic-access")
public void run() {
try {
- String infoLine = reader.readLine();
- if (infoLine != null
- && infoLine.length() > 0) {
-
- AutIdentifier autId =
- new AutIdentifier(infoLine);
+ String autID = reader.readLine();
+ String toolkit = reader.readLine();
+ if (autID != null
+ && autID.length() > 0
+ && toolkit != null
+ && toolkit.length() > 0) {
+
+ AutIdentifier autId = new AutIdentifier(autID);
m_autIdToRestartHandler.put(autId,
- new RestartAutAutRun(autId, socket, reader));
+ new RestartAutAutRun(
+ autId, socket, reader, toolkit));
}
} catch (IOException ioe) {
// Error occurred while constructing the stream
@@ -668,9 +677,8 @@ public class AutAgent {
* was successfully received and processed.
*/
public ConnectToAutResponseMessage sendConnectToClientMessage(
- AutIdentifier autId, String clientHostName,
- int clientPort) {
-
+ AutIdentifier autId, String clientHostName, int clientPort) {
+
synchronized (m_auts) {
Communicator autSocket = m_auts.get(autId);
if (autSocket == null) {
@@ -680,9 +688,48 @@ public class AutAgent {
}
try {
- autSocket.send(
- new ConnectToClientMessage(clientHostName, clientPort));
- } catch (CommunicationException ce) {
+ Map<String, String> fragmentMap = new HashMap<>();
+ //Create fragment classpath for on demand fragment loading
+ synchronized (m_autIdToRestartHandler) {
+ //Determine toolkit of the AUT
+ String startClass = m_autIdToRestartHandler.get(autId)
+ .getAUTStartClass();
+ Class autServerClass = Class.forName(startClass);
+ AbstractStartToolkitAut autStarter =
+ (AbstractStartToolkitAut) autServerClass
+ .newInstance();
+ String rcBundleID = autStarter.getRcBundleId();
+ //Only for Java Toolkits
+ if (rcBundleID.equals(CommandConstants.RC_JAVAFX_BUNDLE_ID)
+ || rcBundleID.equals(
+ CommandConstants.RC_SWING_BUNDLE_ID)
+ || rcBundleID.equals(
+ CommandConstants.RC_SWT_BUNDLE_ID)) {
+ List<Bundle> fragments = new ArrayList<Bundle>();
+ fragments = AbstractStartToolkitAut
+ .getFragmentsForBundleId(rcBundleID);
+
+ for (Bundle bundle : fragments) {
+ StringBuilder pathBuilder = new StringBuilder();
+ for (String entry : AbstractStartToolkitAut
+ .getPathforBundle(bundle)) {
+ pathBuilder.append(entry).append(
+ IStartAut.PATH_SEPARATOR);
+ }
+ if (pathBuilder.length() > 0) {
+ fragmentMap.put(pathBuilder.substring(
+ 0,
+ pathBuilder.lastIndexOf
+ (IStartAut.PATH_SEPARATOR)),
+ bundle.getSymbolicName());
+ }
+ }
+ }
+ }
+ autSocket.send(new ConnectToClientMessage(clientHostName,
+ clientPort, fragmentMap));
+ } catch (CommunicationException | ClassNotFoundException
+ | InstantiationException | IllegalAccessException ce) {
return new ConnectToAutResponseMessage(
ce.getLocalizedMessage());
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/IRestartAutHandler.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/IRestartAutHandler.java
index 97d1192c3..d7bf085d8 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/IRestartAutHandler.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/IRestartAutHandler.java
@@ -27,4 +27,10 @@ public interface IRestartAutHandler {
* 0) or whether the AUT should terminate by itself (timeout > 0)
*/
public void restartAut(AutAgent agent, int timeout);
+
+ /**
+ * Get the class which was used to start the AUT
+ * @return the class name of the class
+ */
+ public String getAUTStartClass();
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutAutRun.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutAutRun.java
index 6c961f91f..a96f0010f 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutAutRun.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutAutRun.java
@@ -41,6 +41,9 @@ public class RestartAutAutRun implements IRestartAutHandler {
/** reader used for communicating with autrun */
private BufferedReader m_socketReader;
+
+ /** the class which was used to start the AUT **/
+ private String m_autStartClass;
/**
* Constructor
@@ -48,13 +51,15 @@ public class RestartAutAutRun implements IRestartAutHandler {
* @param autId The ID of the started AUT.
* @param socket The socket used for communicating with autrun.
* @param reader Reader for the given socket.
+ * @param startClass the class which was used to start the AUT
*/
public RestartAutAutRun(AutIdentifier autId, Socket socket,
- BufferedReader reader) {
+ BufferedReader reader, String startClass) {
m_autId = autId;
m_autrunSocket = socket;
m_socketReader = reader;
+ m_autStartClass = startClass;
}
/**
@@ -78,4 +83,9 @@ public class RestartAutAutRun implements IRestartAutHandler {
}
+ @Override
+ public String getAUTStartClass() {
+ return m_autStartClass;
+ }
+
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutConfiguration.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutConfiguration.java
index 4af931404..358b45969 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutConfiguration.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/agent/RestartAutConfiguration.java
@@ -49,4 +49,15 @@ public class RestartAutConfiguration implements IRestartAutHandler {
startCommand.setMessage(m_startAutMessage);
startCommand.execute();
}
+
+ @Override
+ public String getAUTStartClass() {
+ String autToolkit = m_startAutMessage.getAutToolKit();
+ String toolkitName = autToolkit.substring(
+ autToolkit.lastIndexOf('.') + 1,
+ autToolkit.lastIndexOf("ToolkitPlugin")); //$NON-NLS-1$
+ String className = "org.eclipse.jubula.autagent.commands.Start" //$NON-NLS-1$
+ + toolkitName + "AutServerCommand"; //$NON-NLS-1$
+ return className;
+ }
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/AbstractStartToolkitAut.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/AbstractStartToolkitAut.java
index 29b593ec0..fd486aa0a 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/AbstractStartToolkitAut.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/AbstractStartToolkitAut.java
@@ -285,66 +285,64 @@ public abstract class AbstractStartToolkitAut implements IStartAut {
* </ul>
* an empty array will be returned.
*/
- public static String[] getClasspathEntriesForBundleId(String bundleId) {
- Bundle mainBundle = Platform.getBundle(bundleId);
- List<Bundle> bundleAndFragmentList = new ArrayList<Bundle>();
- if (mainBundle == null) {
- mainBundle = bundleLookupWithInactive(bundleId);
- if (mainBundle == null) {
- log.error("No bundle found for ID '" + bundleId + "'."); //$NON-NLS-1$//$NON-NLS-2$
- return new String[0];
- }
- }
-
- bundleAndFragmentList.add(mainBundle);
- Bundle[] mainBundleFragments = Platform.getFragments(mainBundle);
- if (mainBundleFragments == null) {
- bundleAndFragmentList.addAll(
- fragmentLookupWithInactive(mainBundle));
- } else {
- for (Bundle fragment : mainBundleFragments) {
- bundleAndFragmentList.add(fragment);
- }
- }
+ private static String[] getClasspathEntriesForBundleId(String bundleId) {
+ Bundle mainBundle = getBundleForID(bundleId);
+ ArrayList<Bundle> bundleAndFragmentList = new ArrayList<>();
+ bundleAndFragmentList.add(mainBundle);
+ bundleAndFragmentList.addAll(getFragmentsForBundleId(bundleId));
List<String> classpathEntries = new ArrayList<String>();
for (Bundle bundle : bundleAndFragmentList) {
- try {
- File bundleFile = FileLocator.getBundleFile(bundle);
- if (bundleFile.isFile()) {
- // bundle file is not a directory, so we assume it's a JAR file
- classpathEntries.add(bundleFile.getAbsolutePath());
- // since the classloader cannot handle nested JARs, we need to extract
- // all known nested JARs and add them to the classpath
- try {
- // assuming that it's a JAR/ZIP file
- File[] createdFiles = ZipUtil.unzipTempJars(bundleFile);
- for (int i = 0; i < createdFiles.length; i++) {
- classpathEntries.add(createdFiles[i].
- getAbsolutePath());
- }
- } catch (IOException e) {
- log.error("An error occurred while trying to extract nested JARs from " + bundleId, e); //$NON-NLS-1$
+ classpathEntries.addAll(getPathforBundle(bundle));
+ }
+ return classpathEntries.toArray(new String[classpathEntries.size()]);
+ }
+
+ /**
+ * Determines the file-system path to the jar for the given bundle and also
+ * for nested jars within this jar
+ *
+ * @param bundle the bundle to get the path for
+ * @return A list containing the path to the jar, or several paths if the
+ * jar contained nested jars
+ */
+ public static List<String> getPathforBundle(Bundle bundle) {
+ List<String> path = new ArrayList<String>();
+ try {
+ File bundleFile = FileLocator.getBundleFile(bundle);
+ if (bundleFile.isFile()) {
+ // bundle file is not a directory, so we assume it's a JAR file
+ path.add(bundleFile.getAbsolutePath());
+ // since the classloader cannot handle nested JARs, we need to extract
+ // all known nested JARs and add them to the classpath
+ try {
+ // assuming that it's a JAR/ZIP file
+ File[] createdFiles = ZipUtil.unzipTempJars(bundleFile);
+ for (int i = 0; i < createdFiles.length; i++) {
+ path.add(createdFiles[i].
+ getAbsolutePath());
}
- } else {
- Enumeration<URL> e = bundle.findEntries(
- "/", "*.jar", true); //$NON-NLS-1$//$NON-NLS-2$
- if (e != null) {
- while (e.hasMoreElements()) {
- URL jarUrl = e.nextElement();
- File jarFile =
- new File(bundleFile + jarUrl.getFile());
- if (!isJarFileWithManifestAttr(
- jarFile, SOURCE_BUNDLE_MANIFEST_ATTR)) {
- classpathEntries.add(jarFile.getAbsolutePath());
- }
+ } catch (IOException e) {
+ log.error("An error occurred while trying to extract nested JARs from " + bundle.getSymbolicName(), e); //$NON-NLS-1$
+ }
+ } else {
+ Enumeration<URL> e = bundle.findEntries(
+ "/", "*.jar", true); //$NON-NLS-1$//$NON-NLS-2$
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ URL jarUrl = e.nextElement();
+ File jarFile =
+ new File(bundleFile + jarUrl.getFile());
+ if (!isJarFileWithManifestAttr(
+ jarFile, SOURCE_BUNDLE_MANIFEST_ATTR)) {
+ path.add(jarFile.getAbsolutePath());
}
}
}
- } catch (IOException ioe) {
- log.error("Bundle with ID '" + bundleId + "' could not be resolved to a file.", ioe); //$NON-NLS-1$//$NON-NLS-2$
}
+ } catch (IOException ioe) {
+ log.error("Bundle with ID '" + bundle.getSymbolicName() + "' could not be resolved to a file.", ioe); //$NON-NLS-1$//$NON-NLS-2$
}
- return classpathEntries.toArray(new String[classpathEntries.size()]);
+ return path;
}
/**
@@ -410,6 +408,25 @@ public abstract class AbstractStartToolkitAut implements IStartAut {
}
/**
+ * Looks for the bundle with the given ID and the highest Version. This
+ * search also includes non active bundles.
+ *
+ * @param bundleId
+ * the bundle ID to look for
+ * @return the bundle
+ */
+ public static Bundle getBundleForID(String bundleId) {
+ Bundle bundle = Platform.getBundle(bundleId);
+ if (bundle == null) {
+ bundle = bundleLookupWithInactive(bundleId);
+ if (bundle == null) {
+ log.error("No bundle found for ID '" + bundleId + "'."); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ return bundle;
+ }
+
+ /**
*
* @param file The file to check.
* @param manifestAttr The name of the Manifest Attribute to check for.
@@ -463,8 +480,18 @@ public abstract class AbstractStartToolkitAut implements IStartAut {
* an empty String will be returned.
*/
public static String getClasspathForBundleId(String bundleId) {
+ String[] classPath = getClasspathEntriesForBundleId(bundleId);
+ return createClassPath(classPath);
+ }
+
+ /**
+ * Creates a class path sting for a given string array
+ * @param classPath the array
+ * @return a the class path in the same order as the array
+ */
+ protected static String createClassPath(String[] classPath) {
StringBuilder pathBuilder = new StringBuilder();
- for (String entry : getClasspathEntriesForBundleId(bundleId)) {
+ for (String entry : classPath) {
pathBuilder.append(entry).append(PATH_SEPARATOR);
}
@@ -492,4 +519,34 @@ public abstract class AbstractStartToolkitAut implements IStartAut {
cmds.add("-Djava.compiler=NONE"); //$NON-NLS-1$
}
}
+
+ /**
+ * Return the bundle id of the RC bundle
+ * @return the bundle name
+ */
+ public abstract String getRcBundleId();
+
+ /**
+ * Finds fragments for the given bundle in the running Platform. If no
+ * active fragments are found, e.g. when jre version is below the minimum
+ * BREE of a bundle, we are also adding non-active (installed) fragments.
+ *
+ * @param rcBundleId the bundle name
+ * @return the fragments which have been found
+ */
+ public static List<Bundle> getFragmentsForBundleId(String rcBundleId) {
+ Bundle fragmentHost = getBundleForID(rcBundleId);
+ ArrayList<Bundle> fragments = new ArrayList<Bundle>();
+
+ Bundle[] f = Platform.getFragments(fragmentHost);
+ if (f == null) {
+ fragments.addAll(
+ fragmentLookupWithInactive(fragmentHost));
+ } else {
+ for (Bundle fragment : f) {
+ fragments.add(fragment);
+ }
+ }
+ return fragments;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartHtmlAutServerCommand.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartHtmlAutServerCommand.java
index 3c8227589..7f4068750 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartHtmlAutServerCommand.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartHtmlAutServerCommand.java
@@ -153,5 +153,11 @@ public class StartHtmlAutServerCommand extends AbstractStartPseudoJavaAUT {
}
return browserString;
+ }
+
+
+ @Override
+ public String getRcBundleId() {
+ return CommandConstants.RC_HTML_BUNDLE_ID;
}
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartJavaFXAutServerCommand.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartJavaFXAutServerCommand.java
index 898204730..8550d235d 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartJavaFXAutServerCommand.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartJavaFXAutServerCommand.java
@@ -18,6 +18,7 @@ import java.util.Vector;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
import org.eclipse.jubula.tools.internal.constants.CommandConstants;
import org.eclipse.jubula.tools.internal.utils.MonitoringUtil;
+import org.osgi.framework.Bundle;
/**
* @author BREDEX GmbH
@@ -75,7 +76,7 @@ public class StartJavaFXAutServerCommand extends AbstractStartJavaAutServer {
/**
* {@inheritDoc}
*/
- protected String getRcBundleId() {
+ public String getRcBundleId() {
return CommandConstants.RC_JAVAFX_BUNDLE_ID;
}
@@ -97,7 +98,12 @@ public class StartJavaFXAutServerCommand extends AbstractStartJavaAutServer {
* @return the class path corresponding to the receiver's RC bundle.
*/
protected String getRcBundleClassPath() {
- return AbstractStartToolkitAut.getClasspathForBundleId(getRcBundleId());
+ Bundle rcBundle = AbstractStartToolkitAut
+ .getBundleForID(getRcBundleId());
+ List<String> classList = AbstractStartToolkitAut
+ .getPathforBundle(rcBundle);
+ return AbstractStartToolkitAut.createClassPath(classList
+ .toArray(new String[classList.size()]));
}
@Override
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartRcpAutServerCommand.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartRcpAutServerCommand.java
index 6d8806c47..39d228bf1 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartRcpAutServerCommand.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartRcpAutServerCommand.java
@@ -254,5 +254,10 @@ public class StartRcpAutServerCommand extends AbstractStartJavaAut {
return props;
}
+
+ @Override
+ public String getRcBundleId() {
+ return CommandConstants.RC_RCP_BUNDLE_ID;
+ }
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwingAutServerCommand.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwingAutServerCommand.java
index 3915aa570..097b26446 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwingAutServerCommand.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwingAutServerCommand.java
@@ -18,6 +18,7 @@ import java.util.Vector;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
import org.eclipse.jubula.tools.internal.constants.CommandConstants;
import org.eclipse.jubula.tools.internal.utils.MonitoringUtil;
+import org.osgi.framework.Bundle;
/**
@@ -79,20 +80,25 @@ public class StartSwingAutServerCommand extends AbstractStartJavaAutServer {
return super.createEnvArray(parameters, isAgentSet);
}
-
+
/**
*
* @return the class path corresponding to the receiver's RC bundle.
*/
protected String getRcBundleClassPath() {
- return AbstractStartToolkitAut.getClasspathForBundleId(getRcBundleId());
+ Bundle rcBundle = AbstractStartToolkitAut
+ .getBundleForID(getRcBundleId());
+ List<String> classList = AbstractStartToolkitAut
+ .getPathforBundle(rcBundle);
+ return AbstractStartToolkitAut.createClassPath(classList
+ .toArray(new String[classList.size()]));
}
-
+
/**
*
* @return the ID of the receiver's RC bundle.
*/
- protected String getRcBundleId() {
+ public String getRcBundleId() {
return CommandConstants.RC_SWING_BUNDLE_ID;
}
diff --git a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwtAutServerCommand.java b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwtAutServerCommand.java
index f16707d09..b09e69456 100644
--- a/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwtAutServerCommand.java
+++ b/org.eclipse.jubula.autagent/src/org/eclipse/jubula/autagent/commands/StartSwtAutServerCommand.java
@@ -82,7 +82,7 @@ public class StartSwtAutServerCommand extends StartSwingAutServerCommand {
*
* {@inheritDoc}
*/
- protected String getRcBundleId() {
+ public String getRcBundleId() {
return CommandConstants.RC_SWT_BUNDLE_ID;
}
diff --git a/org.eclipse.jubula.communication/src/org/eclipse/jubula/communication/internal/message/ConnectToClientMessage.java b/org.eclipse.jubula.communication/src/org/eclipse/jubula/communication/internal/message/ConnectToClientMessage.java
index c152d98a4..12827f996 100644
--- a/org.eclipse.jubula.communication/src/org/eclipse/jubula/communication/internal/message/ConnectToClientMessage.java
+++ b/org.eclipse.jubula.communication/src/org/eclipse/jubula/communication/internal/message/ConnectToClientMessage.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.jubula.communication.internal.message;
+import java.util.Map;
+
import org.eclipse.jubula.tools.internal.constants.CommandConstants;
/**
@@ -26,6 +28,9 @@ public class ConnectToClientMessage extends Message {
/** the port number on which the client is listening */
private int m_clientPort;
+
+ /** Key: path to fragment jar. Value: fragment name*/
+ private Map<String, String> m_fragments;
/**
* Default constructor for transportation layer. Don't use for normal
@@ -44,10 +49,14 @@ public class ConnectToClientMessage extends Message {
* The host name at which the client is listening.
* @param clientPort
* The port number on which the client is listening.
+ * @param fragments
+ * Map of fragments which should be loaded by the AUT
*/
- public ConnectToClientMessage(String clientHostName, int clientPort) {
+ public ConnectToClientMessage(String clientHostName, int clientPort,
+ Map<String, String> fragments) {
m_clientHostName = clientHostName;
m_clientPort = clientPort;
+ m_fragments = fragments;
}
/** {@inheritDoc} */
@@ -64,4 +73,12 @@ public class ConnectToClientMessage extends Message {
public int getClientPort() {
return m_clientPort;
}
+
+ /**
+ *
+ * @return Key: path to fragment jar. Value: fragment name
+ */
+ public Map<String, String> getFragments() {
+ return m_fragments;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jubula.feature.rc/feature.xml b/org.eclipse.jubula.feature.rc/feature.xml
index 8b7c06c88..c72a99a52 100644
--- a/org.eclipse.jubula.feature.rc/feature.xml
+++ b/org.eclipse.jubula.feature.rc/feature.xml
@@ -40,6 +40,8 @@ BREDEX GmbH - initial API and implementation and/or initial documentation
<plugin id="org.eclipse.jubula.rc.swing.source" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.eclipse.jubula.rc.javafx" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.eclipse.jubula.rc.javafx.source" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
+ <plugin id="org.eclipse.jubula.rc.javafx.j8u40" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
+ <plugin id="org.eclipse.jubula.rc.javafx.j8u40.source" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.eclipse.jubula.rc.swt" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.eclipse.jubula.rc.swt.source" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.eclipse.jubula.tools" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
diff --git a/org.eclipse.jubula.feature/feature.xml b/org.eclipse.jubula.feature/feature.xml
index 5ba14d110..38b47ca98 100644
--- a/org.eclipse.jubula.feature/feature.xml
+++ b/org.eclipse.jubula.feature/feature.xml
@@ -422,6 +422,13 @@ BREDEX GmbH - initial API and implementation and/or initial documentation
install-size="0"
version="0.0.0"
unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jubula.rc.javafx.j8u40"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
<plugin
id="org.eclipse.jubula.rc.swt"
diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AUTServer.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AUTServer.java
index 1fb678bcb..8e3be5d28 100644
--- a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AUTServer.java
+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AUTServer.java
@@ -9,16 +9,22 @@
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.rc.common;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.jubula.communication.internal.Communicator;
import org.eclipse.jubula.communication.internal.listener.ICommunicationErrorListener;
@@ -27,6 +33,7 @@ import org.eclipse.jubula.communication.internal.message.AUTStartMessage;
import org.eclipse.jubula.communication.internal.message.ChangeAUTModeMessage;
import org.eclipse.jubula.communication.internal.message.Message;
import org.eclipse.jubula.rc.common.adaptable.AdapterFactoryRegistry;
+import org.eclipse.jubula.rc.common.adaptable.IAdapterFactory;
import org.eclipse.jubula.rc.common.commands.AUTStartCommand;
import org.eclipse.jubula.rc.common.commands.ChangeAUTModeCommand;
import org.eclipse.jubula.rc.common.driver.IRobot;
@@ -44,6 +51,7 @@ import org.eclipse.jubula.tools.internal.exception.CommunicationException;
import org.eclipse.jubula.tools.internal.exception.JBVersionException;
import org.eclipse.jubula.tools.internal.objects.IComponentIdentifier;
import org.eclipse.jubula.tools.internal.registration.AutIdentifier;
+import org.eclipse.jubula.tools.internal.utils.ClassPathHacker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -475,18 +483,21 @@ public abstract class AUTServer {
* <li>AUT Agent and AUT</li>
* </ul>
*
- * @param clientHostName
- * Host name to use for connecting to the client.
- * @param clientPort
- * Port number to use for connecting to the client.
+ * @param clientHostName Host name to use for connecting to the client.
+ * @param clientPort Port number to use for connecting to the client.
+ * @param fragments Key: path to fragment jar. Value: fragment name
*
* @throws UnknownHostException
* if no IP address can be found for <code>clientHostName</code>
* .
*/
- public void initClientCommunication(String clientHostName, int clientPort)
- throws UnknownHostException {
-
+ public void initClientCommunication(String clientHostName, int clientPort,
+ Map<String, String> fragments)
+ throws UnknownHostException {
+ List<String> errors = new ArrayList<String>();
+ if (!fragments.isEmpty()) {
+ errors = loadExtensions(fragments);
+ }
if (log.isDebugEnabled()) {
log.debug("initializing communication"); //$NON-NLS-1$
}
@@ -496,7 +507,114 @@ public abstract class AUTServer {
createCommunicator(new InetSocketAddress(clientAddress, clientPort));
connectToITE();
}
-
+
+ /**
+ * Uses the class loader of the AUT server to load the extensions which are
+ * in the map
+ *
+ * @param fragments Key: path to fragment jar. Value: fragment name
+ * @return List containing error messages. A message should contain the name
+ * of the fragment which was affected by the error and therefore not
+ * loaded
+ */
+ protected List<String> loadExtensions(Map<String, String> fragments) {
+ Map<URL, String> jars = new HashMap<URL, String>();
+ ArrayList<String> errors = new ArrayList<String>();
+ for (String classpath : fragments.keySet()) {
+ try {
+ String[] path = classpath
+ .split(AutServerLauncher.PATH_SEPARATOR);
+ // Splitting up the classpath of each fragment because it might
+ // contain several jars
+ for (String p : path) {
+ URL url = new File(p).toURI().toURL();
+ jars.put(url, fragments.get(classpath));
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+ URL[] urls = jars.keySet().toArray(new URL[jars.keySet().size()]);
+ List<URL> notLoaded = addURLsToClassloader(urls);
+ for (URL url : notLoaded) {
+ errors.add(jars.get(url));
+ }
+ String path = AdapterFactoryRegistry.EXT_ADAPTER_PACKAGE_NAME.replace(
+ '.', '/');
+ Enumeration<URL> extensionsFactories = null;
+ try {
+ extensionsFactories =
+ this.getClass().getClassLoader().getResources(path);
+ } catch (IOException e) {
+ log.error("Loading classloader resources failed: " + e); //$NON-NLS-1$
+ }
+ while (extensionsFactories != null
+ && extensionsFactories.hasMoreElements()) {
+ URL url = extensionsFactories.nextElement();
+ try {
+ List<Class> classes = ClassPathHacker.findClassesInJar(url,
+ AdapterFactoryRegistry.EXT_ADAPTER_PACKAGE_NAME,
+ this.getClass().getClassLoader());
+ for (Class<?> c : classes) {
+ if (IAdapterFactory.class.isAssignableFrom(c)) {
+ IAdapterFactory fac = (IAdapterFactory) c.newInstance();
+ if (!AdapterFactoryRegistry.getInstance()
+ .isRegistered(fac)) {
+ AdapterFactoryRegistry.getInstance()
+ .registerFactory(fac);
+ }
+ }
+ }
+ } catch (IOException e) {
+ try {
+ errors.add(jars.remove(new URL(url.getPath().split("!")[0]))); //$NON-NLS-1$
+ } catch (MalformedURLException e1) {
+ log.error("Creating error message failed: " + e1); //$NON-NLS-1$
+ }
+ log.error("Loading class failed: " + e); //$NON-NLS-1$
+ } catch (ReflectiveOperationException e) {
+ try {
+ errors.add(jars.remove(new URL(url.getPath().split("!")[0]))); //$NON-NLS-1$
+ } catch (MalformedURLException e1) {
+ log.error("Creating error message failed: " + e1); //$NON-NLS-1$
+ }
+ log.error("Loading class failed: " + e); //$NON-NLS-1$
+ } catch (NoClassDefFoundError e) {
+ try {
+ errors.add(jars.remove(new URL(url.getPath().split("!")[0]))); //$NON-NLS-1$
+ } catch (MalformedURLException e1) {
+ log.error("Creating error message failed: " + e1); //$NON-NLS-1$
+ }
+ log.error("Loading class failed: " + e); //$NON-NLS-1$
+ }
+ }
+ return errors;
+ }
+
+ /**
+ * Adds the given urls to the AUT Server class loader
+ * @param urls the urls to add
+ * @return list of urls which could not be added
+ */
+ private List<URL> addURLsToClassloader(URL[] urls) {
+ List<URL> notLoaded = new ArrayList<URL>();
+ for (URL u : urls) {
+ try {
+ ClassPathHacker.addURL(u, this.getClass().getClassLoader());
+ } catch (IOException e) {
+ log.error("Could not add url: " + e); //$NON-NLS-1$
+ notLoaded.add(u);
+ } catch (ReflectiveOperationException e) {
+ log.error("Could not add url: " + e); //$NON-NLS-1$
+ notLoaded.add(u);
+ } catch (NoClassDefFoundError e) {
+ log.error("Could not add url: " + e); //$NON-NLS-1$
+ notLoaded.add(u);
+ }
+ }
+ return notLoaded;
+ }
+
/**
* connect the ITE (integrated testing environment)
*/
diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AutServerLauncher.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AutServerLauncher.java
index df8063677..ff71ff700 100644
--- a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AutServerLauncher.java
+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/AutServerLauncher.java
@@ -26,6 +26,10 @@ import org.eclipse.jubula.tools.internal.constants.AUTServerExitConstants;
* @created 10.11.2005
*/
public class AutServerLauncher {
+
+ /** <code>PATH_SEPARATOR</code> */
+ public static final String PATH_SEPARATOR = System.getProperty("path.separator"); //$NON-NLS-1$
+
/**
* name for environment variable that should be set if old/classic class
* loading should be used
diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/adaptable/AdapterFactoryRegistry.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/adaptable/AdapterFactoryRegistry.java
index d37d60b40..f2b0dc818 100644
--- a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/adaptable/AdapterFactoryRegistry.java
+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/adaptable/AdapterFactoryRegistry.java
@@ -10,12 +10,8 @@
*******************************************************************************/
package org.eclipse.jubula.rc.common.adaptable;
-import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
import java.net.URL;
-import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -24,11 +20,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
import org.eclipse.jubula.rc.common.classloader.DefaultUrlLocator;
import org.eclipse.jubula.rc.common.classloader.IUrlLocator;
+import org.eclipse.jubula.tools.internal.utils.ClassPathHacker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +35,7 @@ public class AdapterFactoryRegistry {
public static final String ADAPTER_PACKAGE_NAME = "org.eclipse.jubula.rc.common.adapter"; //$NON-NLS-1$
/** the name of the package to search for extension adapters */
- private static final String EXT_ADAPTER_PACKAGE_NAME = "org.eclipse.jubula.ext.rc.common.adapter"; //$NON-NLS-1$
+ public static final String EXT_ADAPTER_PACKAGE_NAME = "org.eclipse.jubula.ext.rc.common.adapter"; //$NON-NLS-1$
/** the logger */
private static Logger log = LoggerFactory
@@ -266,105 +261,37 @@ public class AdapterFactoryRegistry {
List<Class> classes = new ArrayList<Class>();
for (int i = 0; i < dirs.size(); i++) {
if (dirs.get(i).toString().startsWith("jar:")) { //$NON-NLS-1$
- classes.addAll(findClassesInJar(dirs.get(i), packageName));
+ classes.addAll(ClassPathHacker.
+ findClassesInJar(dirs.get(i), packageName,
+ classLoader));
} else {
- classes.addAll(findClasses(dirs.get(i), packageName));
+ classes.addAll(ClassPathHacker.findClasses(
+ dirs.get(i), packageName));
}
}
return castListToClassArray(classes);
}
-
/**
- * Recursive method used to find all classes in a given directory and
- * subdirectories.
- *
- * @param directoryUrl
- * The base directory
- * @param packageName
- * The package name for classes found inside the base directory
- * @return The classes
- * @throws ClassNotFoundException
+ * Checks if the given factory is already registered
+ * @param factory the factory to check
+ * @return true if the factory is already registered, false otherwise
*/
- private static List<Class> findClasses(URL directoryUrl, String packageName)
- throws ClassNotFoundException {
- List<Class> classes = new ArrayList<Class>();
- File directory = new File(directoryUrl.getFile());
- if (!directory.exists()) {
- return classes;
- }
- File[] files = directory.listFiles();
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- String fileName = file.getName();
- if (file.isDirectory()) {
- try {
- classes.addAll(findClasses(file.toURI().toURL(),
- packageName + '.' + fileName));
- } catch (MalformedURLException e) {
- log.error(e.getLocalizedMessage(), e);
- }
- } else if (fileName.endsWith(".class")) { //$NON-NLS-1$
- classes.add(Class.forName(packageName + '.'
- + fileName.substring(0, fileName.length() - 6)));
- }
- }
- return classes;
- }
-
- /**
- * method to find all classes in a given jar
- *
- * @param resource
- * The URL to the jar file
- * @param pkgname
- * The package name for classes found inside the base directory
- * @return The classes
- */
- private static List<Class> findClassesInJar(URL resource, String pkgname) {
- String relPath = pkgname.replace('.', '/');
- String path = resource.getPath()
- .replaceFirst("[.]jar[!].*", ".jar") //$NON-NLS-1$ //$NON-NLS-2$
- .replaceFirst("file:", ""); //$NON-NLS-1$ //$NON-NLS-2$
- try {
- path = URLDecoder.decode(path, "utf-8"); //$NON-NLS-1$
- } catch (UnsupportedEncodingException uee) {
- log.error(uee.getLocalizedMessage(), uee);
- }
- List<Class> classes = new ArrayList<Class>();
- JarFile jarFile = null;
- try {
- jarFile = new JarFile(path);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- String entryName = entry.getName();
- String className = null;
- if (entryName.endsWith(".class") //$NON-NLS-1$
- && entryName.startsWith(relPath)) {
- className = entryName.replace('/', '.').replace('\\', '.')
- .replaceAll(".class", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
- if (className != null) {
- try {
- classes.add(Class.forName(className));
- } catch (ClassNotFoundException cnfe) {
- log.error(cnfe.getLocalizedMessage(), cnfe);
- }
- }
- }
+ public boolean isRegistered(IAdapterFactory factory) {
+ Class[] supportedClasses = factory.getSupportedClasses();
+ for (int i = 0; i < supportedClasses.length; i++) {
+ final Class supportedClass = supportedClasses[i];
+ Collection<IAdapterFactory> registeredFactories = m_registrationMap
+ .get(supportedClass);
+ if (registeredFactories == null) {
+ return false;
}
- } catch (IOException ioe) {
- log.warn(ioe.getLocalizedMessage(), ioe);
- } finally {
- if (jarFile != null) {
- try {
- jarFile.close();
- } catch (IOException e) {
- log.error(e.getLocalizedMessage(), e);
+ for (IAdapterFactory iAdapterFactory : registeredFactories) {
+ if (iAdapterFactory.getClass().equals(factory.getClass())) {
+ return true;
}
}
}
- return classes;
+ return false;
}
} \ No newline at end of file
diff --git a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/commands/ConnectToClientCommand.java b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/commands/ConnectToClientCommand.java
index 6ddcee8d6..25256315e 100644
--- a/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/commands/ConnectToClientCommand.java
+++ b/org.eclipse.jubula.rc.common/src/org/eclipse/jubula/rc/common/commands/ConnectToClientCommand.java
@@ -40,7 +40,8 @@ public class ConnectToClientCommand implements ICommand {
try {
AUTServer.getInstance().initClientCommunication(
m_message.getClientHostName(),
- m_message.getClientPort());
+ m_message.getClientPort(),
+ m_message.getFragments());
} catch (UnknownHostException uhe) {
LOG.error("Error while attempting to connect to client.", uhe); //$NON-NLS-1$
}
diff --git a/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/constants/CommandConstants.java b/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/constants/CommandConstants.java
index 9dd05eed0..1ff695ab8 100644
--- a/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/constants/CommandConstants.java
+++ b/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/constants/CommandConstants.java
@@ -90,6 +90,8 @@ public abstract class CommandConstants {
public static final String RC_SWING_BUNDLE_ID = "org.eclipse.jubula.rc.swing"; //$NON-NLS-1$
/** ID of the SWT RC bundle */
public static final String RC_SWT_BUNDLE_ID = "org.eclipse.jubula.rc.swt"; //$NON-NLS-1$
+ /** ID of the RCP RC bundle */
+ public static final String RC_RCP_BUNDLE_ID = "org.eclipse.jubula.rc.rcp.swt"; //$NON-NLS-1$
/** ID of the HTML RC bundle */
public static final String RC_HTML_BUNDLE_ID = "com.bredexsw.jubula.rc.html"; //$NON-NLS-1$
/** ID of the Win RC bundle */
diff --git a/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/utils/ClassPathHacker.java b/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/utils/ClassPathHacker.java
index d1a65da83..d97266893 100644
--- a/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/utils/ClassPathHacker.java
+++ b/org.eclipse.jubula.tools/src/org/eclipse/jubula/tools/internal/utils/ClassPathHacker.java
@@ -14,8 +14,15 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
/**
* Class to edit classpath in runtime
@@ -78,4 +85,113 @@ public class ClassPathHacker {
}
}
+
+ /**
+ * Add URL to given Classloader
+ *
+ * @param u
+ * URL
+ * @param classLoader
+ * the Classloader
+ * @throws IOException
+ * Error
+ * @throws SecurityException
+ * @throws NoSuchMethodException
+ * @throws InvocationTargetException
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ */
+ public static void addURL(URL u, ClassLoader classLoader)
+ throws IOException, NoSuchMethodException, SecurityException,
+ IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException {
+ Class sysclass = URLClassLoader.class;
+ Method method = sysclass.getDeclaredMethod("addURL", PARAMETERS); //$NON-NLS-1$
+ method.setAccessible(true);
+ method.invoke(classLoader, new Object[] { u });
+ }
+
+ /**
+ * Recursive method used to find all classes in a given directory and
+ * subdirectories.
+ *
+ * @param directoryUrl
+ * The base directory
+ * @param packageName
+ * The package name for classes found inside the base directory
+ * @return The classes
+ * @throws ClassNotFoundException
+ * @throws MalformedURLException
+ */
+ public static List<Class> findClasses(URL directoryUrl, String packageName)
+ throws ClassNotFoundException, MalformedURLException {
+ List<Class> classes = new ArrayList<Class>();
+ File directory = new File(directoryUrl.getFile());
+ if (!directory.exists()) {
+ return classes;
+ }
+ File[] files = directory.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ String fileName = file.getName();
+ if (file.isDirectory()) {
+ classes.addAll(findClasses(file.toURI().toURL(),
+ packageName + '.' + fileName));
+ } else if (fileName.endsWith(".class")) { //$NON-NLS-1$
+ classes.add(Class.forName(packageName + '.'
+ + fileName.substring(0, fileName.length() - 6)));
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * method to find all classes in a given jar
+ *
+ * @param resource
+ * The URL to the jar file
+ * @param pkgname
+ * The package name for classes found inside the base directory
+ * @param classLoader
+ * the Classloader which should be used
+ * @return The classes
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ public static List<Class> findClassesInJar(URL resource, String pkgname,
+ ClassLoader classLoader)
+ throws IOException, ClassNotFoundException {
+ String relPath = pkgname.replace('.', '/');
+ String path = resource.getPath()
+ .replaceFirst("[.]jar[!].*", ".jar") //$NON-NLS-1$ //$NON-NLS-2$
+ .replaceFirst("file:", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ path = URLDecoder.decode(path, "utf-8"); //$NON-NLS-1$
+ List<Class> classes = new ArrayList<Class>();
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(path);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String entryName = entry.getName();
+ String className = null;
+ if (entryName.endsWith(".class") //$NON-NLS-1$
+ && entryName.startsWith(relPath)) {
+ className = entryName.replace('/', '.').replace('\\', '.')
+ .replaceAll(".class", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if (className != null) {
+ classes.add(Class.forName(
+ className, true, classLoader));
+ }
+ }
+ }
+ } finally {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+ return classes;
+ }
}

Back to the top