Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIkuo Yamasaki2007-01-26 18:14:29 -0500
committerIkuo Yamasaki2007-01-26 18:14:29 -0500
commita3934720b8b359f8141aab35f4189e5bb487db67 (patch)
treead647b92ad742dd2a3c7619602f4f2441c6f1c96
parentfb51ba1d3ffc9417ffb6501e4f0c13f6bf2dc031 (diff)
downloadrt.equinox.p2-a3934720b8b359f8141aab35f4189e5bb487db67.tar.gz
rt.equinox.p2-a3934720b8b359f8141aab35f4189e5bb487db67.tar.xz
rt.equinox.p2-a3934720b8b359f8141aab35f4189e5bb487db67.zip
Initial commit of the framework admin service
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/.classpath8
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/.project28
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/META-INF/MANIFEST.MF13
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/build.properties4
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/doc/readme.txt31
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/Configurator.java74
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/ConfiguratorManipulator.java71
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundleInfo.java159
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundlesState.java142
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/ConfigData.java197
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdmin.java104
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdminRuntimeException.java51
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/LauncherData.java190
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/Manipulator.java196
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/SimpleBundlesState.java338
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/Utils.java486
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorConstants.java23
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorUtils.java251
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/test/org/eclipse/incubator/configurator/util/UtilsTest.java122
19 files changed, 2488 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/.classpath b/bundles/org.eclipse.equinox.frameworkadmin/.classpath
new file mode 100644
index 000000000..61c682532
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="test"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/.project b/bundles/org.eclipse.equinox.frameworkadmin/.project
new file mode 100644
index 000000000..908721184
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.frameworkadmin</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.frameworkadmin/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..478b0cf63
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: FrameworkAdmin Service IF
+Bundle-SymbolicName: org.eclipse.equinox.frameworkadmin
+Bundle-Version: 1.0.0
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Import-Package: org.osgi.framework;version="1.3.0",
+ org.osgi.service.startlevel;version="1.0.0"
+Export-Package: org.eclipse.equinox.configurator,
+ org.eclipse.equinox.frameworkadmin,
+ org.eclipse.equinox.internal.frameworkadmin.utils,
+ org.eclipse.equinox.internal.simpleconfigurator.utils
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/build.properties b/bundles/org.eclipse.equinox.frameworkadmin/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/doc/readme.txt b/bundles/org.eclipse.equinox.frameworkadmin/doc/readme.txt
new file mode 100644
index 000000000..a153dfab1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/doc/readme.txt
@@ -0,0 +1,31 @@
+2006/12/18
+
+This bundle contains API related with FwHandler.
+
+-------------------------
+* Packages
+- org.eclipse.core.fwhandler: contains APIs for handling framework (hereafter shortened as fw)
+ without Configurator.
+
+- org.eclipse.core.configurator: contains APIs related with configurator which configures bundle's lifecycle on a fw.
+
+- org.eclipse.core.fwhandler.configurator: contains APIs for handling fw with Configurator.
+
+-------------------------
+* Developers are recommended to read the comments (or JavaDocs) in the following order.
+
+1. FwHandlerAdmin in org.eclipse.core.fwhandler.
+2. Other APIs in org.eclipse.core.fwhandler.
+3. Configurator in org.eclipse.core.configurator.
+4. ConfiguratorManipilatorAdmin and ConfiguratorManipilator in org.eclipse.core.configurator.
+5. APIs in org.eclipse.core.fwhandler.configurator
+
+-------------------------
+* Other remarks
+
+Examples of implementation of FwHandlerAdmin are "org.eclipse.core.fwhandler.equinox" bundle
+ and "org.eclipse.core.fwhandler.kf" bundle.
+An example of implementation of Configurator is "org.eclipse.core.simpleConfigurator" bundle.
+An example of implementation of ConfiguratorManipulatorAdmin is "org.eclipse.core.fwhandler.simpleConfigurator.manipulator" bundle.
+
+An example using FwHandlerAdmin is "org.eclipse.core.fwhandler.examples" bundle.
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/Configurator.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/Configurator.java
new file mode 100644
index 000000000..ff452a045
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/Configurator.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.configurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.equinox.frameworkadmin.BundleInfo;
+
+/**
+ * The implementation of this interface will be registered into a service registry
+ * by a Configurator Bundle.
+ *
+ * The client bundle can apply configuration which can be interpreted by refering
+ * the specified location to the current running OSGi environment. In addition,
+ * the client can expect bundle state in advance .
+ *
+ * TODO: this interface might not be required to be defined.
+ *
+ *
+ * **********************************************
+ * Current Definition of Configurator Bundle:
+ *
+ * Configurator Bundle will do the followinig operation at its startup.
+ *
+ * 1. Create a Configurator object.
+ * 2. Register it as a service to the service registry.
+ * 3. Get where to read for knowing what kinds of bundles in its implementation dependend way.
+ * 4. Call {@link Configurator#applyConfiguration(URL)} with the URL.
+ *
+ * At its stopping, the service registered will be unregistered.
+ *
+ * @see ConfiguratorManipulator
+ *
+ */
+public interface Configurator {
+
+ /**
+ * Apply configuration read from the specified url to the OSGi
+ * environment currently running.
+ *
+ * @param url URL to be read.
+ * @throws IOException - If reading information from the specified url fails.
+ */
+ void applyConfiguration(URL url) throws IOException;
+
+
+ /**
+ * Return expected bundle states (as an array of BundleInfo)
+ * as if {@link Configurator#applyConfiguration(URL)} with an argument of the specified
+ * url will be called now.
+ *
+ * If there are no ManipulatorAdmin services which create a Manipulator initialized according to
+ * the running fw state, null will be returned.
+ *
+ * This method can be used to check what kinds of bundles will be
+ * installed on the system in advance to calling {@link Configurator#applyConfiguration(URL)}.
+ *
+ * @param url URL to be referred.
+ * @return Array of BundleInfo representing the expected state. null
+ * if there are no ManipulatorAdmin services which create a Manipulator initialized according to
+ * the running fw state.
+ * @throws IOException - If reading information from the specified url fails.
+ */
+ BundleInfo[] getExpectedStateRuntime(URL url) throws IOException;
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/ConfiguratorManipulator.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/ConfiguratorManipulator.java
new file mode 100644
index 000000000..358b2afc0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/configurator/ConfiguratorManipulator.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.configurator;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.equinox.frameworkadmin.*;
+
+/**
+ *
+ * This interface provides methods that enable client bundles to
+ * manipulate the corresponding ConfiguratorBundle.
+ *
+ * @see Configurator
+ */
+
+public interface ConfiguratorManipulator {
+ String SERVICE_PROP_KEY_CONFIGURATOR_BUNDLESYMBOLICNAME = "org.eclipse.equinox.configurator.BundleSymbolicName";
+
+ /**
+ * Save configuration for the corresponding Configurator Bundle so that
+ * Bundles kept by the specified {@link Manipulator} would be installed after completion of a launch.
+ * The location of a configuration file is determined by the parameters set to the Manipulator object
+ * and it depends on the corresponding ConfiguratorBundle implementation.
+ *
+ * While some parameters of the {@link Manipulator} object will be modified (for setting info about the
+ * location the ConfiguratorBundle would be able to refer in a future launch),
+ * the Bundles kept by the {@link Manipulator} object should not be modified.
+ *
+ * Instead, it will return BundleInfo[] to be managed not by the ConfiguratorBundle.
+ * These values are supposed to be saved into fw config files.
+ *
+ * If backup flag is true, a file have existed already under the same name
+ * will be renamed into another name as a backup.
+ *
+ * We assume that the implementation of {@link Manipulator#save(boolean)} will call this method.
+ *
+ * @return array of BundleInfo to be saved as installing bundles in fw config files.
+ * @param Manipulator {@link Manipulator} object which contains the bundles to be installed finally.
+ * @param backup if files exists at the location to save, it will be copied as a backup.
+ * @throws IOException - If fail to save configuration for the corresponding Configurator Bundle.
+ */
+ BundleInfo[] save(Manipulator Manipulator, boolean backup) throws IOException;
+
+ /**
+ * Update bundles kept by the specified {@link Manipulator} object into installed bundles
+ * if {@link FrameworkAdmin#launch(Manipulator, File)} with the specified
+ * {@link Manipulator} is called taking the corresponding ConfiguratorBundle behaivior into account.
+ *
+ * If there is no corresponding ConfiguratorBundle in Manipulator.getConfigData().getBundles(),
+ * just return.
+ *
+ * The BundleInfo[] of the specified Manipulator object will be modified.
+ *
+ * This method is assumed to be called from {@link Manipulator#load()}.
+ *
+ * @param Manipulator {@link Manipulator} object to be used and updated.
+ * @throws IOException - If fail to read configuration for the corresponding Configurator Bundle.
+ */
+ void updateBundles(Manipulator Manipulator) throws IOException;
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundleInfo.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundleInfo.java
new file mode 100644
index 000000000..363b31847
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundleInfo.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.frameworkadmin;
+
+/**
+ * This object represents information of a bundle.
+ *
+ */
+public class BundleInfo {
+ public static final int NO_LEVEL = -1;
+
+ private String symbolicName = null;
+ private String version = null;
+ private String location;
+ private boolean markedAsStarted = false;
+ private int startLevel = NO_LEVEL;
+ private boolean resolved = false;
+
+ // private Dictionary manifest;
+
+ public BundleInfo() {
+ }
+
+ public BundleInfo(String location) {
+ this.location = location.trim();
+ }
+
+ public BundleInfo(String location, boolean started) {
+ this.location = location.trim();
+ this.markedAsStarted = started;
+ }
+
+ public BundleInfo(String location, int startLevel) {
+ this.location = location.trim();
+ this.startLevel = startLevel;
+ }
+
+ public BundleInfo(String location, int startLevel, boolean started) {
+ this.location = location.trim();
+ this.startLevel = startLevel;
+ this.markedAsStarted = started;
+ }
+
+ public BundleInfo(String symbolic, String version, String location, int startLevel, boolean started) {
+ this.symbolicName = symbolic;
+ this.version = version;
+ this.location = location.trim();
+ this.markedAsStarted = started;
+ this.startLevel = startLevel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object toCompare) {
+ if (toCompare instanceof BundleInfo) {
+ BundleInfo info = (BundleInfo) toCompare;
+ //if (info.symbolicName.equals(symbolicName) && info.version.equals(version) && (info.url == null || url == null ? true : info.url.equals(url)))
+ if (info.symbolicName != null && info.version != null && symbolicName != null && version != null) {
+ if (info.symbolicName.equals(symbolicName) && info.version.equals(version) && (info.location == null || location == null ? true : info.location.equals(location)))
+ return true;
+ } else {
+ return (info.location == null || location == null ? false : info.location.equals(location));
+ }
+ }
+ return false;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public int getStartLevel() {
+ return startLevel;
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int result = symbolicName == null ? 0 : symbolicName.hashCode();
+ result = result + (version == null ? 0 : version.hashCode());
+ result = result + (location == null ? 0 : location.hashCode());
+ return result;
+ }
+
+ public boolean isMarkedAsStarted() {
+ return markedAsStarted;
+ }
+
+ public boolean isResolved() {
+ return resolved;
+ }
+
+ public void setLocation(String location) {
+ this.location = location.trim();
+ }
+
+ public void setMarkedAsStarted(boolean markedAsStarted) {
+ this.markedAsStarted = markedAsStarted;
+ }
+
+ public void setResolved(boolean resolved) {
+ this.resolved = resolved;
+ }
+
+ public void setStartLevel(int level) {
+ this.startLevel = level;
+ }
+
+ public void setSymbolicName(String symbolicName) {
+ this.symbolicName = symbolicName;
+ }
+
+ public void setVersion(String vertion) {
+ this.version = vertion;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("BundleInfo("); //$NON-NLS-1$
+ if (symbolicName != null)
+ buffer.append(symbolicName);
+ buffer.append(", ");
+ if (version != null)
+ buffer.append(version);
+ buffer.append(", ");
+ buffer.append("location=");
+ buffer.append(location);
+ buffer.append(", startLevel="); //$NON-NLS-1$
+ buffer.append(startLevel);
+ buffer.append(", toBeStarted=");
+ buffer.append(markedAsStarted);
+ buffer.append(", resolved=");
+ buffer.append(resolved);
+ // buffer.append(',').append(manifest == null ? "no manifest" : "manifest available");
+ buffer.append(')');
+ return buffer.toString();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundlesState.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundlesState.java
new file mode 100644
index 000000000..c72c116d0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/BundlesState.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.frameworkadmin;
+
+/**
+ * This API is used for expecting bundles state virtually.
+ *
+ * This object is instantiated by {@link Manipulator#getBundlesState()}.
+ * At its instantiation, state of the bundles will be created in this object
+ * according to the parameters which the calling {@link Manipulator} object has.
+ * For its creation, information in the fw persistent data will be taken into account.
+ *
+ * Modification of this object after its instantiation never affects the parameters
+ * in the calling {@link Manipulator} object.
+ *
+ * XXX Implementation of Simple ConfiguratorManipulator needs the functions.
+ *
+ * @see Manipulator
+ */
+public interface BundlesState {
+
+ /** Return expected bundles state currently kept in this object.
+ *
+ * The implementation of this method will try to resolve the state
+ * if resolving a state is supported.
+ *
+ * @return bundle array of BundleInfo currently composed in this object.
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created the parent {@link Manipulator} is unregistered.
+ */
+ BundleInfo[] getExpectedState() throws FrameworkAdminRuntimeException;
+
+ /**
+ * Return required bundles to be resolve the specified bInfo
+ * under the state currently composed.
+ *
+ * The implementation of this method will try to resolve the state
+ * if resolving a state is supported.
+ *
+ * @param bInfo bundleinfo whose prerequisite bundles will be searched.
+ * @return bundle array of BundleInfos required for the specified bInfo to be resolved.
+ */
+ BundleInfo[] getPrerequisteBundles(BundleInfo bInfo);
+
+ /**
+ * Return a bundle to be used as a framework under the state currently composed.
+ * @return a bundle to be used as a framework under the state currently composed.
+ */
+ public BundleInfo getSystemBundle();
+
+ /**
+ * Return bundles which are fragment bundles of the framework under the state currently composed.
+ * @return array of BundleInfos which are fragment bundles of the framework.
+ */
+ public BundleInfo[] getSystemFragmentedBundles();
+
+ /**
+ * Return array of Strings which tells the unsatisfied constaints
+ * to resolve the specified bInfo under the state currently composed.
+ *
+ * If this implementation doesn't support resolving state,
+ * FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION}
+ * will be thrown.
+ *
+ * XXX this method is prepared mainly for debugging.
+ *
+ * @param bInfo
+ * @return array of Strings which tells the unsatisfied constaints.
+ * @throws FrameworkAdminRuntimeException if this implementation doesn't support resolving state, FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION} will be thrown.
+ */
+ public String[] getUnsatisfiedConstraints(BundleInfo bInfo) throws FrameworkAdminRuntimeException;
+
+ /**
+ * Install the specified bInfo as a installed bundle to the current state virtually.
+ * Note that resolve this bundle is not done in this implementation.
+ *
+ * @param bInfo BundleInfo to be installed
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created the parent {@link Manipulator} is unregistered.
+ */
+ void installBundle(BundleInfo bInfo) throws FrameworkAdminRuntimeException;
+
+ /**
+ * Return true if this implementation supports full functions,
+ * such as resolving bundles and .
+ * Otherwise false will be returend.
+ * @return true if this implementation supports resolving state. Otherwise false.
+ */
+ boolean isFullySupported();
+
+ /**
+ * Return true if the state currently composed is resolved after the last change of the state.
+ * Otherwise false.
+ *
+ * If this implementation doesn't support resolving state,
+ * FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION}
+ * will be thrown.
+ *
+ * @return true if the state currently composed is resolved after the last change of the state. Otherwise false.
+ * @throws FrameworkAdminRuntimeException if this implementation doesn't support resolving state, FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION} will be thrown.
+ */
+ public boolean isResolved() throws FrameworkAdminRuntimeException;
+
+ /**
+ * Return true if the specified bundle is resolved.
+ * Otherwise false.
+ *
+ * If this implementation doesn't support resolving state,
+ * FwLauncherException with a cause of {@value FwLauncherException#UNSUPPORTED_OPERATION}
+ * will be thrown.
+ *
+ * @return true if the specified bundle is resolved. Otherwise false.
+ * @throws FrameworkAdminRuntimeException if this implementation doesn't support resolving state, FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION} will be thrown.
+ */
+ public boolean isResolved(BundleInfo bInfo) throws FrameworkAdminRuntimeException;
+
+ /**
+ * Resolves the constraints contained in this state.
+ *
+ * If this implementation doesn't support resolving state,
+ * FrameworkAdminRuntimeException with a cause of {@value FrameworkAdminRuntimeException#UNSUPPORTED_OPERATION}
+ * will be thrown.
+ *
+ * @param incremental a flag controlling whether resolution should be incremental
+ * @throws FrameworkAdminRuntimeException
+ */
+ void resolve(boolean increment) throws FrameworkAdminRuntimeException;
+
+ /**
+ * Uninstall the specified bInfo from the current state virtually.
+ *
+ * @param bInfo BundleInfo to be uninstalled
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created the parent {@link Manipulator} is unregistered.
+ */
+ void uninstallBundle(BundleInfo bInfo) throws FrameworkAdminRuntimeException;;
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/ConfigData.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/ConfigData.java
new file mode 100644
index 000000000..15165371c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/ConfigData.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.frameworkadmin;
+
+import java.util.*;
+
+/**
+ * This object is instantiated by {@link Manipulator#getConfigData()};
+ * The class that keeps some parameters of the {@link Manipulator}
+ * created this object. The manipulating of the parameters will affect
+ * the {@link Manipulator}.
+ *
+ * @see Manipulator
+ */
+public class ConfigData {
+
+ private static Properties appendProperties(Properties to, Properties from) {
+ if (from != null) {
+ if (to == null)
+ to = new Properties();
+ // printoutProperties(System.out, "to", to);
+ // printoutProperties(System.out, "from", from);
+
+ for (Enumeration enumeration = from.keys(); enumeration.hasMoreElements();) {
+ String key = (String) enumeration.nextElement();
+ to.setProperty(key, from.getProperty(key));
+ }
+ }
+ // printoutProperties(System.out, "to", to);
+ return to;
+ }
+
+ final private String fwName;
+ final private String fwVersion;
+ final private String launcherName;
+ final private String launcherVersion;
+ private int beginningFwStartLevel = BundleInfo.NO_LEVEL;
+ private int initialBundleStartLevel = BundleInfo.NO_LEVEL;
+ // List of BundleInfo
+ private List bundlesList = new LinkedList();
+ private Properties fwIndependentProps = new Properties();
+
+ private Properties fwDependentProps = new Properties();
+
+ public ConfigData(String fwName, String fwVersion, String launcherName, String launcherVersion) {
+ this.fwName = fwName;
+ this.fwVersion = fwVersion;
+ this.launcherName = launcherName;
+ this.launcherVersion = launcherVersion;
+ this.initialize();
+ }
+
+ public void addBundle(BundleInfo bundleInfo) {
+ this.bundlesList.add(bundleInfo);
+ }
+
+ public int getBeginingFwStartLevel() {
+ return this.beginningFwStartLevel;
+ }
+
+ public BundleInfo[] getBundles() {
+ if (bundlesList.size() == 0)
+ return new BundleInfo[0];
+ BundleInfo[] ret = new BundleInfo[bundlesList.size()];
+ bundlesList.toArray(ret);
+ return ret;
+ }
+
+ public String getFwDependentProp(String key) {
+ return fwDependentProps.getProperty(key);
+ }
+
+ public Properties getFwDependentProps() {
+ Properties ret = new Properties();
+ appendProperties(ret, fwDependentProps);
+ return ret;
+ }
+
+ public String getFwIndependentProp(String key) {
+ return fwIndependentProps.getProperty(key);
+ }
+
+ public Properties getFwIndependentProps() {
+ Properties ret = new Properties();
+ appendProperties(ret, fwIndependentProps);
+ return ret;
+ }
+
+ public String getFwName() {
+ return this.fwName;
+ }
+
+ public String getFwVersion() {
+ return this.fwVersion;
+ }
+
+ public int getInitialBundleStartLevel() {
+ return this.initialBundleStartLevel;
+ }
+
+ public String getLauncherName() {
+ return launcherName;
+ }
+
+ public String getLauncherVersion() {
+ return launcherVersion;
+ }
+
+ public void initialize() {
+ this.beginningFwStartLevel = BundleInfo.NO_LEVEL;
+ this.initialBundleStartLevel = BundleInfo.NO_LEVEL;
+ this.bundlesList.clear();
+ this.fwIndependentProps.clear();
+ this.fwDependentProps.clear();
+ }
+
+ public void removeBundle(BundleInfo bundleInfo) {
+ this.bundlesList.remove(bundleInfo);
+ }
+
+ public void setBeginningFwStartLevel(int startLevel) {
+ this.beginningFwStartLevel = startLevel;
+ }
+
+ public void setBundles(BundleInfo[] bundleInfos) {
+ this.bundlesList.clear();
+ if (bundleInfos != null)
+ for (int i = 0; i < bundleInfos.length; i++)
+ bundlesList.add(bundleInfos[i]);
+ }
+
+ public void setFwDependentProp(String key, String value) {
+ this.fwDependentProps.setProperty(key, value);
+ }
+
+ public void setFwDependentProps(Properties props) {
+ this.fwDependentProps.clear();
+ appendProperties(fwDependentProps, props);
+ }
+
+ public void setFwIndependentProp(String key, String value) {
+ this.fwIndependentProps.setProperty(key, value);
+ }
+
+ public void setFwIndependentProps(Properties props) {
+ this.fwIndependentProps.clear();
+ appendProperties(fwIndependentProps, props);
+ }
+
+ public void setInitialBundleStartLevel(int startLevel) {
+ this.initialBundleStartLevel = startLevel;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Class:" + this.getClass().getName() + "\n");
+ sb.append("============Independent===============\n");
+ sb.append("fwName=" + this.fwName + "\n");
+ sb.append("fwVersion=" + this.fwVersion + "\n");
+ sb.append("launcherName=" + this.launcherName + "\n");
+ sb.append("launcherVersion=" + this.launcherVersion + "\n");
+ sb.append("beginningFwStartLevel=" + this.beginningFwStartLevel + "\n");
+ sb.append("initialBundleStartLevel=" + this.initialBundleStartLevel + "\n");
+ if (this.bundlesList.size() == 0)
+ sb.append("bundlesList=null\n");
+ else {
+ sb.append("bundlesList=\n");
+ for (int i = 0; i < this.bundlesList.size(); i++)
+ sb.append("\tbundlesList[" + i + "]=" + bundlesList.get(i).toString() + "\n");
+ }
+
+ sb.append("============ Fw Independent Props ===============\n");
+ sb.append("fwIndependentProps=");
+ if (fwIndependentProps.size() > 0)
+ sb.append("\n" + fwIndependentProps.toString() + "\n");
+ else
+ sb.append("null\n");
+ sb.append("============ Fw Dependent Props ===============\n");
+ sb.append("fwDependentProps=");
+ if (fwDependentProps.size() > 0)
+ sb.append("\n" + fwDependentProps.toString() + "\n");
+ else
+ sb.append("null\n");
+
+ return sb.toString();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdmin.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdmin.java
new file mode 100644
index 000000000..25b03a5ef
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdmin.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.frameworkadmin;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * The implementation of this API will be registered to the service
+ * registry as an OSGi service.
+ *
+ * *****************************************************************
+ * 1. For developers who implement bundles that register this service.
+ *
+ * At the registration, the following
+ * service properties must be set for client to search the FrameworkAdmin object
+ * which will create BundlesState / ConfigData / LauncherData objects.
+ *
+ * {@link FrameworkAdmin#SERVICE_PROP_KEY_FW_NAME}: String; name of the framework
+ * {@link FrameworkAdmin#SERVICE_PROP_KEY_FW_VERSION}: String; version of the framework
+ * {@link FrameworkAdmin#SERVICE_PROP_KEY_LAUNCHER_NAME}: String; name of the launcher
+ * {@link FrameworkAdmin#SERVICE_PROP_KEY_LAUNCHER_VERSION}: String; version of the launcher
+ *
+ * Bundles register this service will check if the currently runnning system can be manipulated by
+ * this FrameworkAdmin. If yes and this implementation can create an initialized Manipulator object
+ * according to the running fw and launcher, add the service property keyed by
+ *
+ * {@link FrameworkAdmin#SERVICE_PROP_KEY_RUNNING_SYSTEM_FLAG}: String; if "true", this service that will be returned by getRunningManipulator() is fully initialized so as to represent the state of running system.
+ *
+ * It is recommended to implement Manipulator objects created by calling methods of this interface
+ * so that they cannot be used after this service is unregistered.
+ *
+ * *****************************************************************
+ * 2. For developers who implement client bundles that use this service.
+ *
+ * A client bundle of this service can get new Manipulator object
+ * by calling its method.
+ *
+ * A client bundle can search among services registered in a service registry
+ * and can get the desired FrameworkAdmin service object so that the bundle
+ * can get the desired {@link Manipulator} object for desired framework type with version and launcher type with version.
+ *
+ * Especially, in order for a client bundle to manipulate the {@link Manipulator} object of the running fw and laucher,
+ * filtering (FrameworkAdmin#SERVICE_PROP_KEY_RUNNING_FW_FLAG=true) is used.
+ *
+ * As generally speaking about OSGi service, the client bundle should track this service state.
+ * If unregistered, it should stop using any of objects that it got by this service and
+ * release all of them. If it continues to use them, {@link FrameworkAdminRuntimeException} might
+ * be thrown.
+ *
+ */
+public interface FrameworkAdmin {
+
+ String SERVICE_PROP_KEY_FW_NAME = "org.eclipse.equinox.frameworkhandler.framework.name";
+ String SERVICE_PROP_KEY_FW_VERSION = "org.eclipse.equinox.frameworkhandler.framework.version";
+
+ String SERVICE_PROP_KEY_LAUNCHER_NAME = "org.eclipse.equinox.frameworkhandler.launcher.name";
+ String SERVICE_PROP_KEY_LAUNCHER_VERSION = "org.eclipse.equinox.frameworkhandler.launcher.version";
+ String SERVICE_PROP_KEY_RUNNING_SYSTEM_FLAG = "org.eclipse.equinox.frameworkhandler.runningfwflag";
+
+ /**
+ * Create new instance of {@link Manipulator} and return it.
+ *
+ * @return new instance of Manipulator.
+ */
+ Manipulator getManipulator();
+
+ /**
+ * Create new instance of {@link Manipulator} for running system
+ * and return it. The instance must be initialized fully according to the
+ * running environment. If this implementation cannot provide it, return null.
+ *
+ * @return new instance of Manipulator.
+ */
+ Manipulator getRunningManipulator();
+
+ /**
+ * Launch a framework instance under the specified current working directory.
+ *
+ *
+ * @param manipulator {@link Manipulator} object to be launched.
+ * @param cwd current working directory to be used for launching.
+ * @return process
+ * @throws IllegalArgumentException if specified arguments are null.
+ * @throws IOException if any error relate with IO occurs
+ * @throws FrameworkAdminRuntimeException if the FrameworkAdmin service object
+ * that created the specified Manipulator object is unregistered.
+ */
+ Process launch(Manipulator manipulator, File cwd) throws IllegalArgumentException, IOException, FrameworkAdminRuntimeException;
+
+ /**
+ *
+ * @return true if this object is active. false otherwise.
+ */
+ boolean isActive();
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdminRuntimeException.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdminRuntimeException.java
new file mode 100644
index 000000000..7a0ae863c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/FrameworkAdminRuntimeException.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.frameworkadmin;
+
+public class FrameworkAdminRuntimeException extends RuntimeException {
+
+ private static final long serialVersionUID = -2292498677000772317L;
+ public static final String FRAMEWORKADMIN_UNAVAILABLE = "FrameworkAdmin service created this object is not available any more";
+ public static final String UNSUPPORTED_OPERATION = "This implementation doesn't support this method.";
+
+ private final String reason;
+
+ /**
+ * @param message
+ */
+ public FrameworkAdminRuntimeException(String message, String reason) {
+ super(message);
+ this.reason = reason;
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public FrameworkAdminRuntimeException(String message, Throwable cause, String reason) {
+ super(message, cause);
+ this.reason = reason;
+ }
+
+ /**
+ * @param cause
+ */
+ public FrameworkAdminRuntimeException(Throwable cause, String reason) {
+ super(cause);
+ this.reason = reason;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/LauncherData.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/LauncherData.java
new file mode 100644
index 000000000..92f15fcdf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/LauncherData.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.frameworkadmin;
+
+import java.io.File;
+
+/**
+ * This object is instantiated by {@link Manipulator#getLauncherData()};
+ * The class that keeps some parameters of the {@link Manipulator}
+ * created this object. The manipulating of the parameters will affect
+ * the {@link Manipulator}.
+ *
+ *
+ * @see Manipulator
+ */
+public class LauncherData {
+ private static final String[] NULL_STRINGS = new String[0];
+ private File fwPersistentDataLocation = null;
+ private File jvm = null;
+ private String[] jvmArgs;
+ private boolean clean;
+ private File fwConfigLocation;
+ private File homeLocation = null;
+ private File fwJar = null;
+
+ private File launcher = null;
+ private File launcherConfigLocation = null;
+
+ private String fwName;
+ private String fwVersion;
+ private String launcherName;
+ private String launcherVersion;
+
+ public LauncherData(String fwName, String fwVersion, String launcherName, String launcherVersion) {
+ this.fwName = fwName;
+ this.fwVersion = fwVersion;
+ this.launcherName = launcherName;
+ this.launcherVersion = launcherVersion;
+ this.initialize();
+ }
+
+ public void addJvmArgs(String[] args) {
+ if (args == null) {
+ jvmArgs = NULL_STRINGS;
+ return;
+ }
+ if (jvmArgs.length == 0)
+ this.setJvmArgs(args);
+ String[] newArgs = new String[jvmArgs.length + args.length];
+ System.arraycopy(jvmArgs, 0, newArgs, 0, jvmArgs.length);
+ System.arraycopy(args, 0, newArgs, jvmArgs.length, args.length);
+ jvmArgs = newArgs;
+ }
+
+ public File getFwConfigLocation() {
+ return fwConfigLocation;
+ }
+
+ public File getFwJar() {
+ return fwJar;
+ }
+
+ public String getFwName() {
+ return fwName;
+ }
+
+ public File getFwPersistentDataLocation() {
+ return fwPersistentDataLocation;
+ }
+
+ public String getFwVersion() {
+ return fwVersion;
+ }
+
+ public File getHome() {
+ return homeLocation;
+ }
+
+ public File getJvm() {
+ return jvm;
+ }
+
+ public String[] getJvmArgs() {
+ return jvmArgs;
+ }
+
+ public File getLauncher() {
+ return launcher;
+ }
+
+ public File getLauncherConfigLocation() {
+ return launcherConfigLocation;
+ }
+
+ public String getLauncherName() {
+ return launcherName;
+ }
+
+ public String getLauncherVersion() {
+ return launcherVersion;
+ }
+
+ public void initialize() {
+ fwPersistentDataLocation = null;
+ jvm = null;
+ jvmArgs = NULL_STRINGS;
+ clean = false;
+ fwConfigLocation = null;
+ fwJar = null;
+ launcher = null;
+ }
+
+ public boolean isClean() {
+ return clean;
+ }
+
+ public void setFwConfigLocation(File fwConfigLocation) {
+ this.fwConfigLocation = fwConfigLocation;
+ }
+
+ public void setFwJar(File fwJar) {
+ this.fwJar = fwJar;
+ }
+
+ public void setFwPersistentDataLocation(File fwPersistentDataLocation, boolean clean) {
+ this.fwPersistentDataLocation = fwPersistentDataLocation;
+ this.clean = clean;
+ }
+
+ public void setHomeLocation(File homeLocation) {
+ this.homeLocation = homeLocation;
+ }
+
+ public void setJvm(File file) {
+ this.jvm = file;
+ }
+
+ public void setJvmArgs(String[] args) {
+ if (args == null) {
+ jvmArgs = NULL_STRINGS;
+ return;
+ }
+ String[] jvmArgs = new String[args.length];
+ System.arraycopy(args, 0, jvmArgs, 0, args.length);
+ }
+
+ public void setLauncher(File launcherFile) {
+ launcher = launcherFile;
+ }
+
+ public void setLauncherConfigLocation(File launcherConfigLocation) {
+ this.launcherConfigLocation = launcherConfigLocation;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Class:" + this.getClass().getName() + "\n");
+ sb.append("fwName=" + this.fwName + "\n");
+ sb.append("fwVersion=" + this.fwVersion + "\n");
+ sb.append("launcherName=" + this.launcherName + "\n");
+ sb.append("launcherVersion=" + this.launcherVersion + "\n");
+
+ sb.append("jvm=" + this.jvm + "\n");
+ if (this.jvmArgs.length == 0)
+ sb.append("jvmArgs = null\n");
+ else {
+ sb.append("jvmArgs=\n");
+ for (int i = 0; i < this.jvmArgs.length; i++)
+ sb.append("\tjvmArgs[" + i + "]=" + jvmArgs[i] + "\n");
+ }
+
+ sb.append("fwConfigLocation=" + this.fwConfigLocation + "\n");
+ sb.append("fwJar=" + this.fwJar + "\n");
+ sb.append("fwPersistentDataLocation=" + this.fwPersistentDataLocation + "\n");
+ sb.append("homeLocation=" + this.homeLocation + "\n");
+ sb.append("launcher=" + this.launcher + "\n");
+ sb.append("launcherConfigLocation=" + this.launcherConfigLocation + "\n");
+ sb.append("clean=" + this.isClean() + "\n");
+
+ return sb.toString();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/Manipulator.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/Manipulator.java
new file mode 100644
index 000000000..bdc120056
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/frameworkadmin/Manipulator.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.frameworkadmin;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.equinox.configurator.ConfiguratorManipulator;
+
+/**
+ * An object implementing this interface will be gotten by calling
+ * {@link FrameworkAdmin#getManipulator()}.
+ *
+ * The object plays main roles for handling a framwork, such as configuring a framework
+ * and launching.
+ *
+ * The typical usecases of this method:
+ *
+ * Usecase 1: set parameters, check the expected state, save them into configuration files, and launch.
+ * A. create a {@link Manipulator} object from a {@link FrameworkAdmin}.
+ * B. set parameters to the {@link Manipulator} object.
+ * C. getExpectedState() and check what bundle state will be realized.
+ * If it is not same as you desire, repeat B and C until it becomes as you desire.
+ * D. save parameters into configuration files by {@link Manipulator#save(boolean)}.
+ * E. launch the framework by {@link FrameworkAdmin#launch(Manipulator, File)}.
+ *
+ * Usecase 2: set parameters required for loading, load parameters from configuration files,
+ * check the expected state, and launch.
+ * A. create a {@link Manipulator} object from a {@link FrameworkAdmin}.
+ * B. set parameters about launcher or fw config file to the {@link Manipulator} object.
+ * C. load parameters from configuration files by {@link Manipulator#load()};
+ * D. getExpectedState() and check what bundle state will be realized.
+ * E. launch the framework by {@link FrameworkAdmin#launch(Manipulator, File)}.
+ * @see FrameworkAdmin
+ * @see ConfigData
+ * @see LauncherData
+ */
+
+public interface Manipulator {
+
+ /**
+ * Return the newly created BundldsState object,
+ * according to the parameters set to this object "in memory".
+ *
+ * None of launcher config file, framework config file and configurator config file
+ * will be read by this method. However, the fw persistent data location should be
+ * taken into consideration. In other words, this method will return
+ * the expected {@link BundlesState} object assuming that the current parameters were saved and
+ * {@link FrameworkAdmin#launch(Manipulator, File)} with an argument of this object
+ * were called. (It would read the fw persistent data location if required).
+ *
+ * This method should not modify the parameters in this {@link Manipulator} object.
+ *
+ * @return fw bundle state object created according to he current parameters set.
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created this object is unregistered or this implementation doesn't support this method.
+ */
+ BundlesState getBundlesState() throws FrameworkAdminRuntimeException;
+
+ /**
+ * The reference of {@link ConfigData} object representing configuration information related with framework settings will be returned.
+ * Remind that manipulating returned object will affect this Manipulator behaivior.
+ *
+ * @return ConfigData object representing configuration information related with framework setting
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created this object is unregistered or this implementation doesn't support this method.
+ * @see ConfigData
+ */
+ ConfigData getConfigData() throws FrameworkAdminRuntimeException;
+
+ /**
+ * Return the expected BundldInfo array representing state of bundles,
+ * according to the parameters set to this object "in memory".
+ *
+ * None of launcher config file, framework config file and configurator config file
+ * will be read by this method. However, the fw persistent data location should be
+ * taken into consideration. In other words, this method will return
+ * the expected bundles state assuming that the current parameters were saved and
+ * {@link FrameworkAdmin#launch(Manipulator, File)} with an argument of this object
+ * were called. (It would read the fw persistent data location if required).
+ *
+ * Returned BundleInfos must have resolved flag set.
+ * This method should not modify the parameters in this {@link Manipulator} object.
+ *
+ * cf. getConfigData().getBundles() will return array of BundleInfo too.
+ * However the resolved flag of returned BundleInfos might not be reliable.
+ *
+ * This method is equivalent to calling getBundlesState().getExpectedState().
+ *
+ * @return array of BundleInfo representing expected state of all bundles installed.
+ * @throws IllegalArgumentException - If either of fwJar or cwd doesn't exist.
+ * @throws IOException - If reading fw configuration file or reading persitently recorded information
+ * of fw fails.
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created this object is unregistered or this implementation doesn't support this method.
+ */
+ BundleInfo[] getExpectedState() throws IllegalStateException, IOException, FrameworkAdminRuntimeException;
+
+ /**
+ * The reference of {@link LauncherData} object representing configuration information
+ * related with launcher settings will be returned.
+ * Remember that manipulating returned object will affect this Manipulator object behaivior.
+ *
+ * @return LauncherData object representing configuration information related with launcher setting
+ * @throws FrameworkAdminRuntimeException - If the ManipulatorAdmin service created this object is unregistered or this implementation doesn't support this method.
+ * @see LauncherData
+ */
+ LauncherData getLauncherData() throws FrameworkAdminRuntimeException;
+
+ /**
+ * Initialize all information that this object keeps at that time.
+ */
+ void initialize();
+
+ /**
+ * load configs from appropriate config files,
+ * including launcher config file, fw config file, and configurator config files,
+ * whose locations are determined by the current setting. In addition,
+ * the fw persistent data location should be taken into consideration.
+ *
+ * The following procedure contains the matters of implementation detail.
+ * However, it is an example how it works.
+ *
+ * 1. if launcher object is set, corresponding launcher config file will be read.
+ * According to the information retrieved, setting of this object will be updated.
+ * including fw config file.
+ *
+ * 2. If fw config file is not specified, IllegalStateException will be thrown.
+ * Otherwise, the information will be retrieved from the fw config file.
+ *
+ * 3. If any ConfiguratorBundle is included in the bundle list,
+ * read appropriate configurator config file by
+ * {@link ConfiguratorManipulator#updateBundles(Manipulator)},
+ * which will update the parameter about installed bundles in its
+ * {@link Manipulator#getConfigData()} object.
+ *
+ * Most old parameters will be updated by this method call.
+ *
+ * @throws IOException - If reading info from configuration files fails.
+ * @throws IllegalStateException - If config files cannot be determined.
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created this object is unregistered or this implementation doesn't support this method.
+ */
+ void load() throws IllegalStateException, IOException, FrameworkAdminRuntimeException;
+
+ /**
+ * Save parameters that this object keeps at that time into appropriate config files,
+ * which include launcher config file, fw config file, and configurator config files
+ * (if required and implementation of this object supports), according to the current setting and situation.
+ *
+ * The followins procedure contains the matters of implementation detail.
+ * However, it is an example how it works.
+ *
+ * 1. if a launcher file is set,
+ * the parameters to be saved into a LauncherConfigFile will be saved into the default LauncherConfigFile
+ * that is determined by the location of the launcher file.
+ *
+ *
+ * 2. if there are any {@link ConfiguratorManipulator} objects available whose corresponding ConfiguratorBundle
+ * is set to be started, choose the ConfiguratorBudnle that starts the first among them and go to next step.
+ * Otherwise, save the BundleInfo[] set to this object into a FwConfigFile that is determined
+ * by the parameters set.
+ *
+ * 3. call {@link ConfiguratorManipulator#save(Manipulator, boolean)} of
+ * the ConfiguratorManipulator that can manipulate the chosen ConfiguratorBudnle.
+ * This method will save configs for ConfiguratorBundle to read appropriately
+ * and return BundleInfo[] to be saved in the FwConfigFile, which is determined by the parameters set.
+ *
+ * 4. Save the rerurned BundleInfo[] in the FwConfigFile, which is determined by the parameters set.
+ *
+ * @param backup - if true, keep old file by renaming if exists.
+ * @throws IOException - If writing info into configuration files fails.
+ * @throws FrameworkAdminRuntimeException - If the {@link FrameworkAdmin} service created this object is unregistered or this implementation doesn't support this method.
+ */
+ void save(boolean backup) throws IOException, FrameworkAdminRuntimeException;
+
+ /**
+ * Copy all information the specified {@link ConfigData} contains into this object.
+ * All of old settings will be initialized and replaced.
+ *
+ * @param configData fw config data to be set to this object.
+ */
+ void setConfigData(ConfigData configData);
+
+ /**
+ * Copy all information the specified {@link LauncherData} contains into this object.
+ * All of old settings will be initialized and replaced.
+ *
+ * @param launcherData launcher config data to be set to this object.
+ */
+ void setLauncherData(LauncherData launcherData);
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/SimpleBundlesState.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/SimpleBundlesState.java
new file mode 100644
index 000000000..b97007808
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/SimpleBundlesState.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.frameworkadmin.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.*;
+
+import org.eclipse.equinox.frameworkadmin.*;
+
+import org.eclipse.equinox.internal.frameworkadmin.utils.Utils;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * This implementation of BundlesState doesn't support any of
+ * - resolving bundles,
+ * - retrieving fw persistent data.
+ *
+ * This implementation can be used for those cases.
+ *
+ */
+/**
+ * @author iyamasak
+ *
+ */
+public class SimpleBundlesState implements BundlesState {
+ public static final BundleInfo[] NULL_BUNDLEINFOS = new BundleInfo[0];
+ /**
+ * Check if the specified FrameworkAdmin is available.
+ *
+ * @param fwAdmin
+ * @throws FrameworkAdminRuntimeException
+ */
+ public static void checkAvailability(FrameworkAdmin fwAdmin) throws FrameworkAdminRuntimeException {
+ if (!fwAdmin.isActive())
+ throw new FrameworkAdminRuntimeException("FrameworkAdmin creates this object is no more available.", FrameworkAdminRuntimeException.FRAMEWORKADMIN_UNAVAILABLE);
+ }
+ /**
+ *
+ * @param launcherData
+ * @return File of fwJar to be used.
+ * @throws IOException
+ */
+ static File getFwJar(LauncherData launcherData) {
+ if (launcherData.getFwJar() != null)
+ return launcherData.getFwJar();
+ return null;
+ }
+ private final String systemBundleSymbolicName;
+
+ private final String systemBundleName;
+
+ private final String systemBundleVendor;
+ BundleContext context = null;
+ List bundleInfosList = new LinkedList();
+
+ FrameworkAdmin fwAdmin = null;
+
+ Manipulator manipulator = null;
+
+ /**
+ * If the manifest of the target fw implementation has Constants.BUNDLE_SYMBOLICNAME header,
+ * this constructor should be used.
+ *
+ * @param context
+ * @param ManipulatorAdmin
+ * @param Manipulator
+ * @param systemBundleSymbolicName
+ */
+ public SimpleBundlesState(BundleContext context, FrameworkAdmin ManipulatorAdmin, Manipulator Manipulator, String systemBundleSymbolicName) {
+ super();
+ this.context = context;
+ this.fwAdmin = ManipulatorAdmin;
+ // copy Manipulator object for avoiding modifying the parameters of the Manipulator.
+ this.manipulator = ManipulatorAdmin.getManipulator();
+ this.manipulator.setConfigData(Manipulator.getConfigData());
+ this.manipulator.setLauncherData(Manipulator.getLauncherData());
+ this.systemBundleSymbolicName = systemBundleSymbolicName;
+ this.systemBundleName = null;
+ this.systemBundleVendor = null;
+ initialize();
+ }
+
+ /**
+ * If the manifest of the target fw implementation has not Constants.BUNDLE_SYMBOLICNAME header
+ * but , Constants.BUNDLE_NAME and BUNDLE_VERSION,
+ * this constructor should be used.
+ *
+ * @param context
+ * @param ManipulatorAdmin
+ * @param Manipulator
+ * @param systemBundleName
+ * @param systemBundleVender
+ */
+ public SimpleBundlesState(BundleContext context, FrameworkAdmin ManipulatorAdmin, Manipulator Manipulator, String systemBundleName, String systemBundleVender) {
+ super();
+ this.context = context;
+ this.fwAdmin = ManipulatorAdmin;
+ // copy Manipulator object for avoiding modifying the parameters of the Manipulator.
+ this.manipulator = ManipulatorAdmin.getManipulator();
+ this.manipulator.setConfigData(Manipulator.getConfigData());
+ this.manipulator.setLauncherData(Manipulator.getLauncherData());
+ this.systemBundleSymbolicName = null;
+ this.systemBundleName = systemBundleName;
+ this.systemBundleVendor = systemBundleVender;
+ initialize();
+ }
+
+ public BundleInfo[] getExpectedState() throws FrameworkAdminRuntimeException {
+ if (!fwAdmin.isActive())
+ throw new FrameworkAdminRuntimeException("FrameworkAdmin creates this object is no more available.", FrameworkAdminRuntimeException.FRAMEWORKADMIN_UNAVAILABLE);
+ return Utils.getBundleInfosFromList(this.bundleInfosList);
+ }
+
+ /*
+ * Just return required bundles.
+ *
+ * @see org.eclipse.equinox.frameworkadmin.BundlesState#getPrerequisteBundles(org.eclipse.equinox.frameworkadmin.BundleInfo)
+ */
+ public BundleInfo[] getPrerequisteBundles(BundleInfo bInfo) {
+ String location = bInfo.getLocation();
+ final String requiredBundles = Utils.getManifestMainAttributes(location, Constants.REQUIRE_BUNDLE);
+ if (requiredBundles == null)
+ return new BundleInfo[] {this.getSystemBundle()};
+
+ String[] clauses = Utils.getClauses(requiredBundles);
+ List list = new LinkedList();
+ for (int i = 0; i < clauses.length; i++)
+ list.add(Utils.getPathFromClause(clauses[i]));
+
+ List ret = new LinkedList();
+ ret.add(this.getSystemBundle());
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ BundleInfo currentBInfo = (BundleInfo) ite.next();
+ String currentLocation = currentBInfo.getLocation();
+ String currentSymbolicName = Utils.getManifestMainAttributes(currentLocation, Constants.BUNDLE_SYMBOLICNAME);
+ if (currentSymbolicName == null)
+ continue;
+ currentSymbolicName = Utils.getPathFromClause(currentSymbolicName);
+ for (Iterator ite2 = list.iterator(); ite2.hasNext();) {
+ String symbolicName = (String) ite2.next();
+ if (symbolicName.equals(currentSymbolicName)) {
+ ret.add(currentBInfo);
+ break;
+ }
+ }
+ }
+ return Utils.getBundleInfosFromList(ret);
+ }
+
+ public BundleInfo getSystemBundle() {
+ if (this.systemBundleSymbolicName == null) {
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ BundleInfo bInfo = (BundleInfo) ite.next();
+ // if (bInfo.getStartLevel() != 1)
+ // return null;;
+ String location = bInfo.getLocation();
+ String bundleName = Utils.getManifestMainAttributes(location, Constants.BUNDLE_NAME);
+ if (systemBundleName.equals(bundleName)) {
+ String bundleVendor = Utils.getManifestMainAttributes(location, Constants.BUNDLE_VENDOR);
+ if (systemBundleVendor.equals(bundleVendor))
+ return bInfo;
+ }
+ }
+ return null;
+ }
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ BundleInfo bInfo = (BundleInfo) ite.next();
+ String location = bInfo.getLocation();
+ String symbolicName = Utils.getManifestMainAttributes(location, Constants.BUNDLE_SYMBOLICNAME);
+ symbolicName = Utils.getPathFromClause(symbolicName);
+ if (this.systemBundleSymbolicName.equals(symbolicName))
+ return bInfo;
+ }
+ return null;
+ }
+
+ public BundleInfo[] getSystemFragmentedBundles() {
+ BundleInfo systemBInfo = this.getSystemBundle();
+ if (systemBInfo == null)
+ return NULL_BUNDLEINFOS;
+
+ List list = new LinkedList();
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ BundleInfo bInfo = (BundleInfo) ite.next();
+ String location = bInfo.getLocation();
+ String manifestVersion = Utils.getManifestMainAttributes(location, Constants.BUNDLE_MANIFESTVERSION);
+ if (manifestVersion == null)
+ continue;
+ if (manifestVersion.equals("1") || manifestVersion.equals("1.0"))
+ continue;
+
+ String fragmentHost = Utils.getManifestMainAttributes(location, Constants.FRAGMENT_HOST);
+ if (fragmentHost == null)
+ continue;
+ int index = fragmentHost.indexOf(";");
+ if (index == -1)
+ continue;
+ String symbolicName = fragmentHost.substring(0, index).trim();
+ String parameter = fragmentHost.substring(index + 1).trim();
+ // TODO What to do ,in case of alias name of system bundle is not used ?
+ if (symbolicName.equals(Constants.SYSTEM_BUNDLE_SYMBOLICNAME))
+ if (parameter.equals(Constants.EXTENSION_DIRECTIVE + ":=" + Constants.EXTENSION_FRAMEWORK)) {
+ list.add(location);
+ break;
+ }
+ }
+ return Utils.getBundleInfosFromList(list);
+ }
+
+ public String[] getUnsatisfiedConstraints(BundleInfo bInfo) throws FrameworkAdminRuntimeException {
+ throw new FrameworkAdminRuntimeException("getUnsatisfiedConstraints(BundleInfo bInfo) is not supported in this implementation", FrameworkAdminRuntimeException.UNSUPPORTED_OPERATION);
+ }
+
+ private void initialize() {
+ this.bundleInfosList.clear();
+ LauncherData launcherData = manipulator.getLauncherData();
+ ConfigData configData = manipulator.getConfigData();
+ File fwJar = getFwJar(launcherData);;
+
+ if (fwJar == null)
+ throw new IllegalStateException("launcherData.getLauncherConfigFile() == null && fwJar is not set.");
+ // No fw persistent data location is taken into consideration.
+
+ BundleInfo[] bInfos = configData.getBundles();
+ for (int j = 0; j < bInfos.length; j++)
+ this.installBundle(bInfos[j]);
+
+ if (getSystemBundle() == null) {
+ try {
+ BundleInfo sysBInfo = new BundleInfo(launcherData.getFwJar().toURL().toExternalForm(), 0, true);
+ this.installBundle(sysBInfo);
+
+ } catch (MalformedURLException e) {
+ // Nothign to do because never happens.
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void installBundle(BundleInfo bInfo) throws FrameworkAdminRuntimeException {
+
+ String newLocation = bInfo.getLocation();
+ Dictionary newManifest = Utils.getOSGiManifest(newLocation);
+ String newSymbolicName = (String) newManifest.get(Constants.BUNDLE_SYMBOLICNAME);
+ String newVersion = (String) newManifest.get(Constants.BUNDLE_VERSION);
+ //System.out.println("> currentInstalledBundles.length=" + currentInstalledBundles.length);
+ boolean found = false;
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ BundleInfo currentBInfo = (BundleInfo) ite.next();
+ String location = currentBInfo.getLocation();
+ if (newLocation.equals(location)) {
+ found = true;
+ break;
+ }
+ Dictionary manifest = Utils.getOSGiManifest(location);
+ String symbolicName = (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME);
+ String version = (String) manifest.get(Constants.BUNDLE_VERSION);
+ if (newSymbolicName != null && newVersion != null)
+ if (newSymbolicName.equals(symbolicName) && newVersion.equals(version)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ this.bundleInfosList.add(bInfo);
+ }
+ }
+
+ // public String toString() {
+ // if (state == null)
+ // return null;
+ // StringBuffer sb = new StringBuffer();
+ // BundleDescription[] bundleDescriptions = state.getBundles();
+ // for (int i = 0; i < bundleDescriptions.length; i++) {
+ // sb.append(bundleDescriptions[i].getBundleId() + ":");
+ // sb.append(bundleDescriptions[i].toString() + "(");
+ // sb.append(bundleDescriptions[i].isResolved() + ")");
+ // String[] ees = bundleDescriptions[i].getExecutionEnvironments();
+ // for (int j = 0; j < ees.length; j++)
+ // sb.append(ees[j] + " ");
+ // sb.append("\n");
+ // }
+ // sb.append("PlatformProperties:\n");
+ // Dictionary[] dics = state.getPlatformProperties();
+ // for (int i = 0; i < dics.length; i++) {
+ // for (Enumeration enum = dics[i].keys(); enum.hasMoreElements();) {
+ // String key = (String) enum.nextElement();
+ // String value = (String) dics[i].get(key);
+ // sb.append(" (" + key + "," + value + ")\n");
+ // }
+ // }
+ // sb.append("\n");
+ // return sb.toString();
+ // }
+
+ public boolean isFullySupported() {
+ return false;
+ }
+
+ public boolean isResolved() throws FrameworkAdminRuntimeException {
+ throw new FrameworkAdminRuntimeException("isResolved() is not supported in this implementation", FrameworkAdminRuntimeException.UNSUPPORTED_OPERATION);
+ }
+
+ public boolean isResolved(BundleInfo bInfo) throws FrameworkAdminRuntimeException {
+ throw new FrameworkAdminRuntimeException("isResolved(BundleInfo bInfo) is not supported in this implementation", FrameworkAdminRuntimeException.UNSUPPORTED_OPERATION);
+ }
+
+ public void resolve(boolean increment) throws FrameworkAdminRuntimeException {
+ throw new FrameworkAdminRuntimeException("resolve(boolean increment) is not supported in this implementation", FrameworkAdminRuntimeException.UNSUPPORTED_OPERATION);
+ }
+
+ public void uninstallBundle(BundleInfo bInfo) throws FrameworkAdminRuntimeException {
+ String targetLocation = bInfo.getLocation();
+ int index = -1;
+ for (Iterator ite = this.bundleInfosList.iterator(); ite.hasNext();) {
+ index++;
+ BundleInfo currentBInfo = (BundleInfo) ite.next();
+ String location = currentBInfo.getLocation();
+ if (targetLocation.equals(location)) {
+ break;
+ }
+ }
+ if (index != -1)
+ this.bundleInfosList.remove(index);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/Utils.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/Utils.java
new file mode 100644
index 000000000..aaa4efc97
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/frameworkadmin/utils/Utils.java
@@ -0,0 +1,486 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.frameworkadmin.utils;
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.eclipse.equinox.frameworkadmin.BundleInfo;
+
+public class Utils {
+ private final static String PATH_SEP = "/";
+
+ /**
+ * Overwrite all properties of from to the properties of to. Return the result of to.
+ *
+ * @param to Properties whose keys and values of other Properties will be appended to.
+ * @param from Properties whose keys and values will be set to the other properties.
+ * @return Properties as a result of this method.
+ */
+ public static Properties appendProperties(Properties to, Properties from) {
+ if (from != null) {
+ if (to == null)
+ to = new Properties();
+ // printoutProperties(System.out, "to", to);
+ // printoutProperties(System.out, "from", from);
+
+ for (Enumeration enumeration = from.keys(); enumeration.hasMoreElements();) {
+ String key = (String) enumeration.nextElement();
+ to.setProperty(key, from.getProperty(key));
+ }
+ }
+ // printoutProperties(System.out, "to", to);
+ return to;
+ }
+
+ public static void checkAbsoluteDir(File file, String dirName) throws IllegalArgumentException {
+ if (file == null)
+ throw new IllegalArgumentException(dirName + " is null");
+ if (!file.isAbsolute())
+ throw new IllegalArgumentException(dirName + " is not absolute path. file=" + file.getAbsolutePath());
+ if (!file.isDirectory())
+ throw new IllegalArgumentException(dirName + " is not directory. file=" + file.getAbsolutePath());
+ }
+
+ public static void checkAbsoluteFile(File file, String dirName) {//throws ManipulatorException {
+ if (file == null)
+ throw new IllegalArgumentException(dirName + " is null");
+ if (!file.isAbsolute())
+ throw new IllegalArgumentException(dirName + " is not absolute path. file=" + file.getAbsolutePath());
+ if (file.isDirectory())
+ throw new IllegalArgumentException(dirName + " is not file but directory");
+ }
+
+ public static URL checkFullUrl(URL url, String urlName) throws IllegalArgumentException {//throws ManipulatorException {
+ if (url == null)
+ throw new IllegalArgumentException(urlName + " is null");
+ if (!url.getProtocol().endsWith("file"))
+ return url;
+ File file = new File(url.getFile());
+ if (!file.isAbsolute())
+ throw new IllegalArgumentException(urlName + "(" + url + ") does not have absolute path");
+ if (file.getAbsolutePath().startsWith(PATH_SEP))
+ return url;
+ try {
+ return getUrl("file", null, PATH_SEP + file.getAbsolutePath());
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException(urlName + "(" + "file:" + PATH_SEP + file.getAbsolutePath() + ") is not fully quallified", e);
+ }
+ }
+
+ public static void createParentDir(File file) throws IOException {
+ // try {
+ createParentDir(file, new Stack());
+ // } catch (IOException e) {
+ // throw new IOException("Fail to createParentDir(" + file.getAbsolutePath() + ")", e);
+ //Fs }
+ }
+
+ private static void createParentDir(File file, Stack stack) throws IOException {
+ // file.getParent()
+ //
+ // URL url = getUrl("file",null,file.getAbsolutePath());
+ // StringTokenizer tokenizer = new StringTokenizer(url.getFile(),"/");
+ //
+
+ File parent = file.getParentFile();
+ if (parent.exists()) {
+ while (!stack.empty()) {
+ File child = (File) stack.pop();
+ if (!child.mkdir())
+ throw new IOException("Fail to mkdir of " + child.toString());
+ }
+ return;
+ }
+ stack.push(parent);
+ createParentDir(parent, stack);
+ }
+
+ public static void deleteDir(File file) throws IOException {
+ if (file.isFile()) {
+ if (!file.delete())
+ throw new IOException("Fail to delete File(" + file.getAbsolutePath() + ")");
+ return;
+ }
+ File[] children = file.listFiles();
+ for (int i = 0; i < children.length; i++) {
+ deleteDir(children[i]);
+ }
+ if (!file.delete())
+ throw new IOException("Fail to delete Dir(" + file.getAbsolutePath() + ")");
+ return;
+ }
+
+ /**
+ * First, it replaces File.seperator of relativePath to "/".
+ * If relativePath is in URL format, return its URL.
+ * Otherwise, create absolute URL based on the baseUrl.
+ *
+ * @param relativePath
+ * @param baseUrl
+ * @return URL
+ * @throws MalformedURLException
+ */
+ public static URL formatUrl(String relativePath, URL baseUrl) throws MalformedURLException {//throws ManipulatorException {
+ relativePath = Utils.replaceAll(relativePath, File.separator, "/");
+ URL url = null;
+ try {
+ url = new URL(relativePath);
+ if (url.getProtocol().equals("file"))
+ if (!(new File(url.getFile())).isAbsolute())
+ url = getUrlInFull(relativePath, baseUrl);
+ return url;
+ } catch (MalformedURLException e) {
+ return getUrlInFull(relativePath, baseUrl);
+ }
+ }
+
+ public static BundleInfo[] getBundleInfosFromList(List list) {
+ if (list == null)
+ return new BundleInfo[0];
+ BundleInfo[] ret = new BundleInfo[list.size()];
+ list.toArray(ret);
+ return ret;
+ }
+
+ public static String getPathFromClause(String clause) {
+ if (clause == null)
+ return null;
+ if (clause.indexOf(";") != -1)
+ clause = clause.substring(0, clause.indexOf(";"));
+ return clause.trim();
+ }
+
+ public static String[] getClauses(String header) {
+ StringTokenizer token = new StringTokenizer(header, ",");
+ List list = new LinkedList();
+ while (token.hasMoreTokens()) {
+ list.add(token.nextToken());
+ }
+ String[] ret = new String[list.size()];
+ list.toArray(ret);
+ return ret;
+ }
+
+ public static String[] getClausesManifestMainAttributes(String location, String name) {
+ return getClauses(getManifestMainAttributes(location, name));
+ }
+
+ public static String getManifestMainAttributes(String location, String name) {
+ try {
+ URL url = new URL("jar:" + location + "!/");
+ JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
+ Manifest manifest = jarConnection.getManifest();
+ Attributes attributes = manifest.getMainAttributes();
+ String value = attributes.getValue(name);
+ return value == null ? null : value.trim();
+ } catch (MalformedURLException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static Dictionary getOSGiManifest(String location) {
+ try {
+ URL url = new URL("jar:" + location + "!/");
+ JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
+ Manifest manifest = jarConnection.getManifest();
+ Attributes attributes = manifest.getMainAttributes();
+ // Set set = attributes.keySet();
+ Hashtable table = new Hashtable();
+ for (java.util.Iterator ite = attributes.keySet().iterator(); ite.hasNext();) {
+ // Object obj = ite.next();
+ //System.out.println(obj.getClass().getName());
+
+ String key = (String) ite.next().toString();
+ // While table contains non OSGiManifest, it doesn't matter.
+ table.put(key, attributes.getValue(key));
+ // System.out.println("key=" + key + " value=" + value);
+ }
+ // System.out.println("");
+ return table;
+ } catch (MalformedURLException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String getRelativePath(File target, File from) {
+
+ String targetPath = Utils.replaceAll(target.getAbsolutePath(), File.separator, PATH_SEP);
+ String fromPath = Utils.replaceAll(from.getAbsolutePath(), File.separator, PATH_SEP);
+
+ String[] targetTokens = Utils.getTokens(targetPath, PATH_SEP);
+ String[] fromTokens = Utils.getTokens(fromPath, PATH_SEP);
+ int index = -1;
+ for (int i = 0; i < fromTokens.length; i++)
+ if (fromTokens[i].equals(targetTokens[i]))
+ index = i;
+ else
+ break;
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = index + 1; i < fromTokens.length; i++)
+ sb.append(".." + PATH_SEP);
+
+ for (int i = index + 1; i < targetTokens.length; i++)
+ if (i != targetTokens.length - 1)
+ sb.append(targetTokens[i] + PATH_SEP);
+ else
+ sb.append(targetTokens[i]);
+ return sb.toString();
+ }
+
+ public static String getRelativePath(URL target, URL from) throws IllegalArgumentException {
+
+ if (!target.getProtocol().equals(from.getProtocol()))
+ throw new IllegalArgumentException("Protocols of target(=" + target + ") and from(=" + from + ") does NOT equal");
+
+ if (target.getHost() != null && target.getHost().length() != 0) {
+ //System.out.println("target.getHost()=" + target.getHost());
+ if (from.getHost() != null && from.getHost().length() != 0) {
+ if (!target.getHost().equals(from.getHost()))
+ throw new IllegalArgumentException("Hosts of target(=" + target + ") and from(=" + from + ") does NOT equal");
+ if (target.getPort() != (from.getPort()))
+ throw new IllegalArgumentException("Ports of target(=" + target + ") and from(=" + from + ") does NOT equal");
+ } else
+ throw new IllegalArgumentException("While Host of target(=" + target + ") is set, Host of from is null.target.getHost()=" + target.getHost());
+ } else if (from.getHost() != null && from.getHost().length() != 0)
+ throw new IllegalArgumentException("While Host of from(=" + from + ") is set, Host of target is null");
+
+ String targetPath = target.getFile();
+ String fromPath = from.getFile();
+
+ String[] targetTokens = Utils.getTokens(targetPath, PATH_SEP);
+ String[] fromTokens = Utils.getTokens(fromPath, PATH_SEP);
+ int index = -1;
+ for (int i = 0; i < fromTokens.length; i++)
+ if (fromTokens[i].equals(targetTokens[i]))
+ index = i;
+ else
+ break;
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = index + 1; i < fromTokens.length; i++)
+ sb.append(".." + PATH_SEP);
+
+ for (int i = index + 1; i < targetTokens.length; i++)
+ if (i != targetTokens.length - 1)
+ sb.append(targetTokens[i] + PATH_SEP);
+ else
+ sb.append(targetTokens[i]);
+ return sb.toString();
+ }
+
+ /**
+ * This method will be called for create a backup file.
+ *
+ * @param file target file
+ * @return File backup file whose filename consists of "hogehoge.yyyyMMddHHmmss.ext" or
+ * "hogehoge.yyyyMMddHHmmss".
+ */
+ public static File getSimpleDataFormattedFile(File file) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
+ String date = df.format(new Date());
+ String filename = file.getName();
+ int index = filename.lastIndexOf(".");
+ if (index != -1)
+ filename = filename.substring(0, index) + "." + date + "." + filename.substring(index + 1);
+ else
+ filename = filename + "." + date;
+ File dest = new File(file.getParentFile(), filename);
+ return dest;
+ }
+
+ // public static URL getAbsoluteUrl(String relativePath, URL baseUrl) throws FwLauncherException {
+ // relativePath = Utils.replaceAll(relativePath, File.separator, "/");
+ // try {
+ // return new URL(baseUrl, relativePath);
+ // } catch (MalformedURLException e) {
+ // throw new FwLauncherException("Absolute URL cannot be created. \nrelativePath=" + relativePath + ",baseUrl=" + baseUrl, e, FwLauncherException.URL_FORMAT_ERROR);
+ // }
+ // }
+
+ // public static void setProperties(Properties to, Properties from, String key) {
+ // if (from != null) {
+ // String value = from.getProperty(key);
+ // if (value != null) {
+ // if (to != null)
+ // to = new Properties();
+ // to.setProperty(key, value);
+ // }
+ // }
+ // }
+
+ // public static int getIntProperties(Properties props, String key) {//throws ManipulatorException {
+ // if (props == null)
+ // throw new IllegalArgumentException("props == null");
+ // String value = null;
+ // try {
+ // value = props.getProperty(key);
+ // return Integer.parseInt(value);
+ // } catch (NumberFormatException nfe) {
+ // throw new ManipulatorException("key=" + key + ",value=" + value, nfe, ManipulatorException.OTHERS);
+ // }
+ // }
+
+ public static String[] getTokens(String msg, String delim) {
+ return getTokens(msg, delim, false);
+ }
+
+ public static String[] getTokens(String msg, String delim, boolean returnDelims) {
+ StringTokenizer targetST = new StringTokenizer(msg, delim, returnDelims);
+ String[] tokens = new String[targetST.countTokens()];
+ ArrayList list = new ArrayList(targetST.countTokens());
+ while (targetST.hasMoreTokens()) {
+ list.add(targetST.nextToken());
+ }
+ list.toArray(tokens);
+ return tokens;
+ }
+
+ public static URL getUrl(String protocol, String host, String file) throws MalformedURLException {// throws ManipulatorException {
+ file = Utils.replaceAll(file, File.separator, "/");
+ return new URL(protocol, host, file);
+ }
+
+ public static URL getUrlInFull(String path, URL from) throws MalformedURLException {//throws ManipulatorException {
+ Utils.checkFullUrl(from, "from");
+ path = Utils.replaceAll(path, File.separator, "/");
+ //System.out.println("from.toExternalForm()=" + from.toExternalForm());
+ String fromSt = Utils.removeLastCh(from.toExternalForm(), '/');
+ //System.out.println("fromSt=" + fromSt);
+ if (path.startsWith("/")) {
+ String fileSt = from.getFile();
+ return new URL(fromSt.substring(0, fromSt.lastIndexOf(fileSt) - 1) + path);
+ }
+ return new URL(fromSt + "/" + path);
+ }
+
+ /**
+ * Just used for debug.
+ *
+ * @param ps printstream
+ * @param name name of properties
+ * @param props properties whose keys and values will be printed out.
+ */
+ public static void printoutProperties(PrintStream ps, String name, Properties props) {
+ if (props == null || props.size() == 0) {
+ ps.println("Props(" + name + ") is empty");
+ return;
+ }
+ ps.println("Props(" + name + ")=");
+ for (Enumeration enumeration = props.keys(); enumeration.hasMoreElements();) {
+ String key = (String) enumeration.nextElement();
+ ps.print("\tkey=" + key);
+ ps.println("\tvalue=" + props.getProperty(key));
+ }
+ }
+
+ public static String removeLastCh(String target, char ch) {
+ while (target.charAt(target.length() - 1) == ch) {
+ target = target.substring(0, target.length() - 1);
+ }
+ return target;
+ }
+
+ public static String replaceAll(String st, String oldSt, String newSt) {
+ int index = -1;
+ while ((index = st.indexOf(oldSt)) != -1) {
+ st = st.substring(0, index) + newSt + st.substring(index + oldSt.length());
+ }
+ return st;
+ }
+
+ public static String shrinkPath(String target) {
+ String targetPath = Utils.replaceAll(target, File.separator, PATH_SEP);
+ String[] targetTokens = Utils.getTokens(targetPath, PATH_SEP);
+ //String[] fromTokens = Utils.getTokens(fromPath, PATH_SEP);
+ for (int i = 0; i < targetTokens.length; i++)
+ if (targetTokens[i].equals("")) {
+ targetTokens[i] = null;
+ } else if (targetTokens[i].equals(".")) {
+ targetTokens[i] = null;
+ } else if (targetTokens[i].equals("..")) {
+ int id = i - 1;
+ while (targetTokens[id] == null) {
+ id--;
+ }
+ targetTokens[id] = null;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ if (targetPath.startsWith(PATH_SEP))
+ sb.append(PATH_SEP);
+ for (int i = 0; i < targetTokens.length; i++)
+ if (targetTokens[i] != null)
+ sb.append(targetTokens[i] + PATH_SEP);
+ String ret = sb.toString();
+ if (!targetPath.endsWith(PATH_SEP))
+ ret = ret.substring(0, ret.lastIndexOf(PATH_SEP));
+ return ret;
+ }
+
+ /**
+ * Sort by increasing order of startlevels.
+ *
+ * @param bInfos array of BundleInfos to be sorted.
+ * @param initialBSL initial bundle start level to be used.
+ * @return sorted array of BundleInfos
+ */
+ public static BundleInfo[] sortBundleInfos(BundleInfo[] bInfos, int initialBSL) {
+ SortedMap bslToList = new TreeMap();
+ for (int i = 0; i < bInfos.length; i++) {
+ Integer sL = Integer.valueOf(bInfos[i].getStartLevel());
+ if (sL.intValue() == BundleInfo.NO_LEVEL)
+ sL = new Integer(initialBSL);
+ List list = (List) bslToList.get(sL);
+ if (list == null) {
+ list = new LinkedList();
+ bslToList.put(sL, list);
+ }
+ list.add(bInfos[i]);
+ }
+
+ // bslToList is sorted by the key (StartLevel).
+ List bundleInfoList = new LinkedList();
+ for (Iterator ite = bslToList.keySet().iterator(); ite.hasNext();) {
+ Integer sL = (Integer) ite.next();
+ List list = (List) bslToList.get(sL);
+ for (Iterator ite2 = list.iterator(); ite2.hasNext();) {
+ BundleInfo bInfo = (BundleInfo) ite2.next();
+ bundleInfoList.add(bInfo);
+ }
+ }
+ return getBundleInfosFromList(bundleInfoList);
+ }
+
+ public static void validateUrl(URL url) {//throws ManipulatorException {
+ try {//test
+ URLConnection connection = url.openConnection();
+ connection.connect();
+ } catch (IOException e) {
+ throw new IllegalArgumentException("URL(" + url + ") cannot be connected.", e);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorConstants.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorConstants.java
new file mode 100644
index 000000000..a67ec9f96
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorConstants.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.simpleconfigurator.utils;
+
+public class SimpleConfiguratorConstants {
+ public static final String PARAMETER_BASEURL = "eclipse.simpleConfigurator.baseUrl";
+ public static final String PROP_KEY_EXCLUSIVE_INSTALLATION = "org.eclipse.equinox.simpleconfigurator.exclusiveInstallation";
+
+ public static final String LAST_CONFIG_STAMP = "last.config.stamps"; //$NON-NLS-1$
+ public static final String CONFIG_LIST = "bundles.txt"; //$NON-NLS-1$
+ public static final String CONFIGURATOR_FOLDER = "simpleConfiguration"; //$NON-NLS-1$
+ public static final String CONFIG_INI = "config.ini"; //$NON-NLS-1$
+ public static final String PROP_KEY_CONFIGURL = "org.eclipse.equinox.simpleconfigurator.configUrl";
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorUtils.java b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorUtils.java
new file mode 100644
index 000000000..5bfddb1ee
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/src/org/eclipse/equinox/internal/simpleconfigurator/utils/SimpleConfiguratorUtils.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.simpleconfigurator.utils;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.equinox.frameworkadmin.BundleInfo;
+import org.eclipse.equinox.internal.frameworkadmin.utils.Utils;
+import org.osgi.framework.*;
+import org.osgi.service.startlevel.StartLevel;
+
+public class SimpleConfiguratorUtils {
+
+ final static boolean DEBUG = false;
+
+ public static final String SERVICE_PROP_VALUE_CONFIGURATOR_SYMBOLICNAME = "org.eclipse.equinox.simpleconfigurator";
+
+ public static boolean checkMatchEclipseJarNaming(String location, final String jarName) {
+ String filename = null;
+ if (location.indexOf(":") == -1)
+ filename = location;
+ else
+ filename = location.substring(location.lastIndexOf(":") + 1);
+
+ if (location.indexOf("/") == -1)
+ filename = location;
+ else
+ filename = location.substring(location.lastIndexOf("/") + 1);
+ // filename must be "jarName"_"version".jar
+ //System.out.println("filename=" + filename);
+ if (!filename.endsWith(".jar"))
+ return false;
+ filename = filename.substring(0, filename.lastIndexOf(".jar"));
+ //System.out.println("filename=" + filename);
+ if (filename.lastIndexOf("_") == -1)
+ return false;
+ filename = filename.substring(0, filename.lastIndexOf("_"));
+ //System.out.println("filename=" + filename);
+ if (filename.indexOf("_") != -1)
+ return false;
+ if (filename.equals(jarName))
+ return true;
+ return false;
+ }
+
+ public static BundleInfo getBundleInfoFromBundle(BundleContext context, StartLevel startLevelService, Bundle bundle) {
+ String symbolicName = bundle.getSymbolicName();
+ Dictionary manifest = context.getBundle().getHeaders();
+ String versionSt = (String) manifest.get(Constants.BUNDLE_VERSION);
+
+ BundleInfo bInfo = new BundleInfo(symbolicName, versionSt, bundle.getLocation(), startLevelService.getBundleStartLevel(bundle), startLevelService.isBundlePersistentlyStarted(bundle));
+ return bInfo;
+ }
+
+ public static String getBundleStateString(Bundle bundle) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(bundle.getLocation());
+ sb.append(" : ");
+ switch (bundle.getState()) {
+ case Bundle.INSTALLED :
+ sb.append("INSTALLED");
+ break;
+ case Bundle.ACTIVE :
+ sb.append("ACTIVE");
+ break;
+ case Bundle.RESOLVED :
+ sb.append("RESOLVED");
+ break;
+ case Bundle.STARTING :
+ sb.append("STARTING");
+ break;
+ case Bundle.STOPPING :
+ sb.append("STOPPING");
+ break;
+ case Bundle.UNINSTALLED :
+ sb.append("UNINSTALLED");
+ break;
+ }
+ return sb.toString();
+ }
+
+ // public static BundleInfo[] mergeCurrentState(BundleContext context, StartLevel startLevelService, List bundleInfoList) throws FwLauncherException {
+ // // if (this.configApplier == null)
+ // // configApplier = new ConfigApplier(context, this);
+ //
+ // List currentList = getInstalledBundleInfosList(context,startLevelService);
+ //
+ // return mergeCurrentState(bundleInfoList, currentList);
+ // }
+
+ public static List getInstalledBundleInfosList(BundleContext context, StartLevel startLevelService) {
+ Bundle[] bundles = context.getBundles();
+ List currentList = new LinkedList();
+
+ for (int i = 0; i < bundles.length; i++) {
+ BundleInfo bInfo = getBundleInfoFromBundle(context, startLevelService, bundles[i]);
+ currentList.add(bInfo);
+ }
+ return currentList;
+ }
+
+ public static String getListSt(List list) {
+ StringBuffer sb = new StringBuffer();
+ for (Iterator ite2 = list.iterator(); ite2.hasNext();) {
+ BundleInfo bInfo = (BundleInfo) ite2.next();
+ sb.append(bInfo.toString() + "\n");
+ }
+ return sb.toString();
+ }
+
+ public static boolean isSystemBundleFragment(BundleContext context, Bundle bundle) {
+ //Bundle[] bundles = context.getBundles();
+ String symbolicNameSystem = context.getBundle(0).getSymbolicName();
+ String fragmentHost = (String) bundle.getHeaders().get(Constants.FRAGMENT_HOST);
+ if (fragmentHost != null) {
+ String symbolic = fragmentHost.substring(0, fragmentHost.indexOf(";")).trim();
+ if (symbolic.equals(symbolicNameSystem))
+ return true;
+ if (symbolic.equals(Constants.SYSTEM_BUNDLE_SYMBOLICNAME))
+ return true;
+ }
+ return false;
+ }
+
+ public static BundleInfo[] mergeState(List addedBundleInfoList, List currentBundleInfoList) {
+ for (Iterator ite = addedBundleInfoList.iterator(); ite.hasNext();) {
+ boolean duplicated = false;
+ BundleInfo bInfo = (BundleInfo) ite.next();
+ for (Iterator currentIte = currentBundleInfoList.iterator(); currentIte.hasNext();) {
+ BundleInfo bInfoCurrent = (BundleInfo) currentIte.next();
+ // int sl = startLevelService.getInitialBundleStartLevel();
+ // if (bInfo.getStartLevel() != BundleInfo.NO_LEVEL)
+ // sl = bInfo.getStartLevel();
+ if (bInfoCurrent.getLocation().equals(bInfo.getLocation())) {
+ bInfoCurrent.setStartLevel(bInfo.getStartLevel());
+ bInfoCurrent.setMarkedAsStarted(bInfo.isMarkedAsStarted());
+ duplicated = true;
+ break;
+ }
+ }
+ if (!duplicated)
+ currentBundleInfoList.add(bInfo);
+ }
+ return Utils.getBundleInfosFromList(currentBundleInfoList);
+ }
+
+ public static List readConfiguration(URL url) throws IOException {
+ List bundles = new ArrayList();
+ try {
+ // System.out.println("readConfiguration(URL url):url()=" + url);
+ // URL configFileUrl = getConfigFileUrl();
+ // URL configFileUrl = Utils.getUrl("file",null,
+ // inputFile.getAbsolutePath());
+ BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()));
+ // BufferedReader r = new BufferedReader(new FileReader(inputFile));
+
+ String line;
+ try {
+ URL baseUrl = new URL(url, "./");
+ while ((line = r.readLine()) != null) {
+ if (line.startsWith("#"))
+ continue;
+ line = line.trim();// symbolicName,version,location,startlevel,expectedState
+ if (line.length() == 0)
+ continue;
+
+ // (expectedState is an integer).
+ //System.out.println("line=" + line);
+ if (line.startsWith(SimpleConfiguratorConstants.PARAMETER_BASEURL + "=")) {
+ String baseUrlSt = line.substring((SimpleConfiguratorConstants.PARAMETER_BASEURL + "=").length());
+ if (!baseUrlSt.endsWith("/"))
+ baseUrlSt += "/";
+ baseUrl = new URL(url, baseUrlSt);
+// if (DEBUG)
+// System.out.println("baseUrl=" + baseUrl);
+ continue;
+ }
+ StringTokenizer tok = new StringTokenizer(line, ",", true);
+ String symbolicName = tok.nextToken();
+ if (symbolicName.equals(","))
+ symbolicName = null;
+ else
+ tok.nextToken(); // ,
+
+ String version = tok.nextToken();
+ if (version.equals(","))
+ version = null;
+ else
+ tok.nextToken(); // ,
+
+ String urlSt = tok.nextToken();
+ if (urlSt.equals(",")) {
+ if (symbolicName != null && version != null)
+ urlSt = symbolicName + "_" + version + ".jar";
+ else
+ urlSt = null;
+ } else
+ tok.nextToken(); // ,
+ try {
+ new URL(urlSt);
+// if (DEBUG)
+// System.out.println("1 urlSt=" + urlSt);
+ } catch (MalformedURLException e) {
+ urlSt = Utils.getUrlInFull(urlSt, baseUrl).toExternalForm();
+// if (DEBUG)
+// System.out.println("2 urlSt=" + urlSt);
+ }
+
+ int sl = Integer.parseInt(tok.nextToken().trim());
+ tok.nextToken(); // ,
+ boolean markedAsStarted = Boolean.parseBoolean(tok.nextToken());
+ // URL urlBundle = null;
+ // try {
+ // urlBundle = new URL(urlSt);
+ // } catch (MalformedURLException e) {
+ // urlBundle = Utils.getFullUrl(urlSt, baseUrl);
+ // }
+
+ BundleInfo bInfo = new BundleInfo(symbolicName, version, urlSt, sl, markedAsStarted);
+ bundles.add(bInfo);
+ // System.out.println("tail line=" + line);
+ }
+ } finally {
+ try {
+ r.close();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ // TODO log something
+ // bundleInfos = NULL_BUNDLEINFOS;
+ }
+ return bundles;
+ // bundleInfos = (BundleInfo[]) bundles.toArray(new
+ // BundleInfo[bundles.size()]);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/test/org/eclipse/incubator/configurator/util/UtilsTest.java b/bundles/org.eclipse.equinox.frameworkadmin/test/org/eclipse/incubator/configurator/util/UtilsTest.java
new file mode 100644
index 000000000..73c542483
--- /dev/null
+++ b/bundles/org.eclipse.equinox.frameworkadmin/test/org/eclipse/incubator/configurator/util/UtilsTest.java
@@ -0,0 +1,122 @@
+///**
+// *
+// */
+//package org.eclipse.incubator.configurator.util;
+//
+//import java.net.MalformedURLException;
+//import java.net.URL;
+//
+//import junit.framework.*;
+//
+//import org.eclipse.equinox.internal.frameworkadmin.utils.*;
+//
+///**
+// * @author iyamasak
+// *
+// */
+//public class UtilsTest extends TestCase {
+//
+// /**
+// * @param name
+// */
+// public UtilsTest(String name) {
+// super(name);
+// }
+//
+// /* (non-Javadoc)
+// * @see junit.framework.TestCase#setUp()
+// */
+// protected void setUp() throws Exception {
+// super.setUp();
+// }
+//
+// /* (non-Javadoc)
+// * @see junit.framework.TestCase#tearDown()
+// */
+// protected void tearDown() throws Exception {
+// super.tearDown();
+// }
+//
+// // /**
+// // * Test method for {@link org.eclipse.configMan.internal.util.Utils#getUrl(java.lang.String, java.lang.String, java.lang.String)}.
+// // */
+// // public void testGetUrl() {
+// // fail("Not yet implemented");
+// // }
+//
+// /**
+// * Test method for {@link Utils#getRelativePath(java.net.URL, java.net.URL)}.
+// */
+// public void testGetRelativePath() {
+// //URL target;
+// //URL from;
+// try {
+// URL target = new URL("http", "www.ntt.co.jp", "dir1/dir2/target.html");
+// URL from = new URL("http", "www.ntt.co.jp", "dir1/dir3/dir4/from.html");
+// String expected = "../../../dir2/target.html";
+// String ret = Utils.getRelativePath(target, from);
+// assertEquals(expected, ret);
+//
+// expected = "../../dir3/dir4/from.html";
+// ret = Utils.getRelativePath(from, target);
+// assertEquals(expected, ret);
+//
+// try {
+// target = new URL("http", "www.ntt.co.jp", "dir1/dir2/target.html");
+// from = new URL("http", "www.ibm.com", "dir1/dir3/dir4/from.html");
+// ret = Utils.getRelativePath(target, from);
+// fail("IllegalArgumentException must be thrown");
+// } catch (IllegalArgumentException e) {
+//
+// }
+// try {
+// target = new URL("file", null, "dir2/target.html");
+// from = new URL("http", "www.ntt.co.jp", "dir1/dir3/dir4/from.html");
+// ret = Utils.getRelativePath(target, from);
+// fail("IllegalArgumentException must be thrown");
+// } catch (IllegalArgumentException e) {
+//
+// }
+// } catch (MalformedURLException e) {
+// e.printStackTrace();
+//
+// }
+//
+// }
+//
+// /**
+// * Test method for {@link Utils#replaceAll(java.lang.String, java.lang.String, java.lang.String)}.
+// */
+// public void testReplaceAll() {
+// String st = "tere/eerere//ty/d";
+// String expected = "tere\\eerere\\\\ty\\d";
+// String oldSt = "/";
+// String newSt = "\\";
+// String ret = Utils.replaceAll(st, oldSt, newSt);
+// assertEquals(expected, ret);
+// }
+//
+// /**
+// * Test method for {@link Utils#getTokens(java.lang.String, java.lang.String)}.
+// */
+// public void testGetTokens() {
+// String st = "/AAAA/BB//CC/D/";
+// String[] expected = {"AAAA", "BB", "CC", "D"};
+// String delim = "/";
+// String[] ret = Utils.getTokens(st, delim);
+// assertEquals("lengths must equal.", ret.length, expected.length);
+// for (int i = 0; i < ret.length; i++)
+// assertEquals("each elements must equal.", expected[i], ret[i]);
+// }
+//
+// /**
+// * Test method for {@link Utils#removeLastCh(String target, char ch)}.
+// */
+// public void testRemoveLastCh() {
+// String target = "ddddaaaaaaaa";
+// String expected = "dddd";
+// char ch = 'a';
+// String ret = Utils.removeLastCh(target, ch);
+// assertEquals(expected, ret);
+// }
+//}

Back to the top