Author: cziegeler
Date: Tue Jun 23 16:03:06 2009
New Revision: 787739
URL: http://svn.apache.org/viewvc?rev=787739&view=rev
Log:
SLING-1018 : Remove dependency to declarative service. Use activator instead.
Some code cleanup.
Added:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
(with props)
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/InstallResultCode.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiController.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiResourceProcessor.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessor.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/ConfigResourceProcessor.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/InstallableDataWrapper.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTaskExecutor.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiResourceTask.java
sling/trunk/contrib/extensions/jcrinstall/osgi/src/test/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessorTest.java
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/InstallResultCode.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/InstallResultCode.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/InstallResultCode.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/InstallResultCode.java
Tue Jun 23 16:03:06 2009
@@ -19,13 +19,13 @@
package org.apache.sling.osgi.installer;
/** Result codes for resource installation operations */
-public class InstallResultCode {
+public enum InstallResultCode {
/** Result code for installOrUpdate: resource was ignored */
- public static final int IGNORED = 0;
+ IGNORED,
/** Result code for installOrUpdate: resource was installed */
- public static final int INSTALLED = 1;
-
+ INSTALLED,
+
/** Result code for installOrUpdate: resource was updated */
- public static final int UPDATED = 2;
+ UPDATED;
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiController.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiController.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiController.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiController.java
Tue Jun 23 16:03:06 2009
@@ -21,19 +21,18 @@
import java.io.IOException;
import java.util.Set;
-/** jcrinstall component that installs/updates/removes
+/** jcrinstall component that installs/updates/removes
* OSGi resources (bundles, deployment packages, configs)
* in the OSGi framework.
*/
public interface OsgiController {
-
- /** Schedule installation or update of supplied resource
+
+ /** Schedule installation or update of supplied resource
* @param uri Unique identifier for the resource
* @param data The data to install
- * @return one of the {...@link InstallResultCode} result codes.
*/
void scheduleInstallOrUpdate(String uri, InstallableData data) throws
IOException, JcrInstallException;
-
+
/** Schedule uninstallation of resource that was installed via given uri.
* Might be called several times for the same URI - needless calls should
* be ignored.
@@ -42,21 +41,21 @@
* removed after calling this method
*/
void scheduleUninstall(String uri) throws IOException, JcrInstallException;
-
- /** Return the list of uri for resources that have been installed
+
+ /** Return the list of uri for resources that have been installed
* by this controller.
*/
Set<String> getInstalledUris();
-
+
/** Get the lastModified value for given uri, assuming the resource pointed
* to by that uri was installed.
* @return -1 if we don't have info for given uri
*/
String getDigest(String uri);
-
+
/** Optionally set ResourceOverrideRules */
void setResourceOverrideRules(ResourceOverrideRules r);
-
+
/** Do the actual installs/uninistalls which were scheduled by the other
methods */
void executeScheduledOperations() throws Exception;
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiResourceProcessor.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiResourceProcessor.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiResourceProcessor.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiResourceProcessor.java
Tue Jun 23 16:03:06 2009
@@ -25,19 +25,19 @@
* that is bundles, deployment packages, configs, etc.
*/
public interface OsgiResourceProcessor {
-
+
/** True if this processor can process the given data */
boolean canProcess(String uri, InstallableData data);
-
- /** Install or update supplied resource
+
+ /** Install or update supplied resource
* @param uri Unique identifier for the resource
* @param attributes metadata stored by the OsgiController, can be used to
* store additional information
* @param data The data to install
- * @return one of the {...@link InstallResultCode} result codes.
+ * @return one of the {...@link InstallResultCode} result codes.
*/
- int installOrUpdate(String uri, Map<String, Object> attributes,
InstallableData data) throws Exception;
-
+ InstallResultCode installOrUpdate(String uri, Map<String, Object>
attributes, InstallableData data) throws Exception;
+
/** Uninstall the resource that was installed via given uri. Calling this
with an uri
* that is not installed is not an error.
* @param uri Unique identifier for the resource
@@ -45,12 +45,12 @@
* removed after calling this method
*/
void uninstall(String uri, Map<String, Object> attributes) throws
Exception;
-
+
/** Process our installer queue, if needed, for example by trying
* to start outstanding bundles.
*/
void processResourceQueue() throws Exception;
-
+
/**
* Called to cleanup the resource processor when it is not needed anymore.
*/
Added:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java?rev=787739&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
(added)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
Tue Jun 23 16:03:06 2009
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.osgi.installer.impl;
+
+import java.util.Hashtable;
+
+import org.apache.sling.osgi.installer.OsgiController;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+
+ private static String PACKAGE_ADMIN_NAME = PackageAdmin.class.getName();
+ private static String START_LEVEL_NAME = StartLevel.class.getName();
+ private static String LOG_SERVICE_NAME = LogService.class.getName();
+
+ private ServiceTracker startLevelTracker;
+
+ private ServiceTracker packageAdminTracker;
+
+ private ServiceTracker logServiceTracker;
+
+ private OsgiControllerImpl service;
+
+ private ServiceRegistration serviceReg;
+
+ /**
+ * @see
org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ this.startLevelTracker = new ServiceTracker(context, START_LEVEL_NAME,
null);
+ this.packageAdminTracker = new ServiceTracker(context,
PACKAGE_ADMIN_NAME, null);
+ this.logServiceTracker = new ServiceTracker(context, LOG_SERVICE_NAME,
null);
+ this.startLevelTracker.open();
+ this.packageAdminTracker.open();
+ this.logServiceTracker.open();
+
+ // register service
+ final Hashtable<String, String> props = new Hashtable<String,
String>();
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Install
Controller Service");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ this.service = new OsgiControllerImpl(context,
+ (PackageAdmin)this.packageAdminTracker.getService(),
+ (StartLevel)this.startLevelTracker.getService(),
+ (LogService)this.logServiceTracker.getService());
+ serviceReg = context.registerService(new String[]
{OsgiController.class.getName()}, service, props);
+ }
+
+ /**
+ * @see
org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ if ( this.serviceReg != null ) {
+ this.serviceReg.unregister();
+ this.serviceReg = null;
+ }
+ if ( this.service != null ) {
+ this.service.deactivate();
+ this.service = null;
+ }
+ if ( this.startLevelTracker != null ) {
+ this.startLevelTracker.close();
+ this.startLevelTracker = null;
+ }
+ if ( this.packageAdminTracker != null ) {
+ this.packageAdminTracker.close();
+ this.packageAdminTracker = null;
+ }
+ if ( this.logServiceTracker != null ) {
+ this.logServiceTracker.close();
+ this.logServiceTracker = null;
+ }
+ }
+}
Propchange:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessor.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessor.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessor.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessor.java
Tue Jun 23 16:03:06 2009
@@ -18,9 +18,6 @@
*/
package org.apache.sling.osgi.installer.impl;
-import static org.apache.sling.osgi.installer.InstallResultCode.IGNORED;
-import static org.apache.sling.osgi.installer.InstallResultCode.UPDATED;
-import static org.apache.sling.osgi.installer.InstallResultCode.INSTALLED;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -33,6 +30,7 @@
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
+import org.apache.sling.osgi.installer.InstallResultCode;
import org.apache.sling.osgi.installer.InstallableData;
import org.apache.sling.osgi.installer.OsgiResourceProcessor;
import org.osgi.framework.Bundle;
@@ -55,7 +53,7 @@
/** {...@link Storage} key for the bundle ID */
public static final String KEY_BUNDLE_ID = "bundle.id";
-
+
/** Max time allowed to refresh packages (TODO configurable??) */
public static final int MAX_REFRESH_PACKAGES_WAIT_SECONDS = 30;
@@ -72,7 +70,7 @@
* them in the next round.
*/
private final Set<Long> activeBundles;
-
+
/**
* The list of bundles which have been updated or installed and which need
* to be started in the next round. Bundles from this list, which fail
@@ -80,7 +78,7 @@
* started in the next round.
*/
private final List<Long> installedBundles;
-
+
/**
* Flag set by {...@link #installOrUpdate(String, Map, InputStream)} of a
* bundle has been updated and by {...@link #uninstall(String, Map)} if a
@@ -89,10 +87,10 @@
* @see #processResourceQueue()
*/
private boolean needsRefresh;
-
+
/** Flag used to avoid reentrant {...@link @startBundles()} calls */
private boolean startingBundles;
-
+
private final Logger log = LoggerFactory.getLogger(this.getClass());
BundleResourceProcessor(BundleContext ctx, PackageAdmin packageAdmin,
StartLevel startLevel) {
@@ -118,7 +116,7 @@
* the PackageAdmin.refreshPackages has finished its work of refreshing
* the packages. When packages have been refreshed all bundles which are
* expected to be active (those active before refreshing the packages and
- * newly installed or updated bundles) are started.
+ * newly installed or updated bundles) are started.
*/
public void frameworkEvent(FrameworkEvent event) {
if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
@@ -130,24 +128,22 @@
// ---------- OsgiResourceProcessor
/**
- * @throws BundleException
- * @see
org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#installOrUpdate(java.lang.String,
- * java.util.Map, java.io.InputStream)
+ * @see
org.apache.sling.osgi.installer.OsgiResourceProcessor#installOrUpdate(java.lang.String,
java.util.Map, org.apache.sling.osgi.installer.InstallableData)
*/
- public int installOrUpdate(String uri, Map<String, Object> attributes,
+ public InstallResultCode installOrUpdate(String uri, Map<String, Object>
attributes,
InstallableData installableData) throws BundleException,
IOException {
-
+
// Check that we have bundle data and manifest
InputStream data = installableData.adaptTo(InputStream.class);
if(data == null) {
throw new IOException("InstallableData does not adapt to an
InputStream: " + uri);
}
-
+
final Manifest m = getManifest(installableData);
if(m == null) {
throw new IOException("Manifest not found for
InstallableData " + uri);
}
-
+
// Update if we already have a bundle id, else install
Bundle b;
boolean updated;
@@ -166,18 +162,18 @@
if (b == null) {
b = getMatchingBundle(m);
}
-
+
// If the bundle (or one with the same symbolic name) is
// already installed, ignore the new one if it's a lower
// version
- if(b != null && m!= null) {
+ if (b != null ) {
final Version installedVersion = new
Version((String)(b.getHeaders().get(Constants.BUNDLE_VERSION)));
final Version newBundleVersion = new
Version(m.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
if
(newBundleVersion.compareTo(installedVersion) <= 0) {
log.debug(
"Ignore update of bundle {} from {} as the
installed version is equal or higher.",
b.getSymbolicName(), uri);
- return IGNORED;
+ return InstallResultCode.IGNORED;
}
}
@@ -219,12 +215,11 @@
installedBundles.add(b.getBundleId());
}
- return updated ? UPDATED : INSTALLED;
+ return updated ? InstallResultCode.UPDATED :
InstallResultCode.INSTALLED;
}
/**
- * @see
org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#uninstall(java.lang.String,
- * java.util.Map)
+ * @see
org.apache.sling.osgi.installer.OsgiResourceProcessor#uninstall(java.lang.String,
java.util.Map)
*/
public void uninstall(String uri, Map<String, Object> attributes)
throws BundleException {
@@ -250,12 +245,12 @@
}
/**
- * @see
org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#canProcess(java.lang.String)
+ * @see
org.apache.sling.osgi.installer.OsgiResourceProcessor#canProcess(java.lang.String,
org.apache.sling.osgi.installer.InstallableData)
*/
public boolean canProcess(String uri, InstallableData data) {
return uri.endsWith(BUNDLE_EXTENSION);
}
-
+
/** Execute a PackageAdmin.refreshPackages call and wait for the
corresponding
* framework event. Used to execute this call "synchronously" to make
things
* more sequential when installing/updating/removing bundles.
@@ -264,13 +259,13 @@
final int targetEventCount = packageRefreshEventsCount + 1;
final long start = System.currentTimeMillis();
final long timeout = System.currentTimeMillis() +
MAX_REFRESH_PACKAGES_WAIT_SECONDS * 1000L;
-
+
// It seems like (at least with Felix 1.0.4) we won't get a
FrameworkEvent.PACKAGES_REFRESHED
// if one happened very recently and there's nothing to refresh
packageAdmin.refreshPackages(bundles);
while(true) {
if(System.currentTimeMillis() > timeout) {
- log.warn("No FrameworkEvent.PACKAGES_REFRESHED event received
within {} seconds after refresh",
+ log.warn("No FrameworkEvent.PACKAGES_REFRESHED event received
within {} seconds after refresh",
MAX_REFRESH_PACKAGES_WAIT_SECONDS);
break;
}
@@ -296,10 +291,10 @@
*/
public void processResourceQueue() {
if (needsRefresh) {
-
+
// reset the flag
needsRefresh = false;
-
+
// gather bundles currently active
for (Bundle bundle : ctx.getBundles()) {
if (bundle.getState() == Bundle.ACTIVE) {
@@ -309,10 +304,10 @@
}
}
- log.debug("Processing resource queue in REFRESH mode, {} active
bundles found, refreshing packages",
+ log.debug("Processing resource queue in REFRESH mode, {} active
bundles found, refreshing packages",
activeBundles.size());
refreshPackagesSynchronously(null);
-
+
} else {
startBundles();
}
@@ -328,7 +323,7 @@
* <p>
* This method gets its own input stream from the installable data object
* and closes it after haing read the manifest file.
- *
+ *
* @param installableData The installable data providing the bundle jar
file
* from the input stream.
* @return The installed bundle with the same symbolic name as the bundle
@@ -349,7 +344,7 @@
}
}
}
-
+
return null;
}
@@ -360,7 +355,7 @@
if (ins == null) {
return null;
}
-
+
JarInputStream jis = null;
try {
jis = new JarInputStream(ins);
@@ -384,7 +379,7 @@
}
}
}
-
+
return result;
}
@@ -411,23 +406,23 @@
}
}
}
-
+
/**
* Starts all bundles whose bundle ID is contained in the
* <code>bundleCollection</code>. If a bundle fails to start, its bundle
* ID is added to the list of active bundles again for the bundle to
* be started next time the packages are refreshed or the resource queue is
* processed.
- *
+ *
* @param bundleIdCollection The IDs of bundles to be started.
*/
private void startBundles(Collection<Long> bundleIdCollection, String
collectionName) {
-
+
if(bundleIdCollection.size() > 0) {
- log.debug("startBundles({}): {} bundles to process",
+ log.debug("startBundles({}): {} bundles to process",
collectionName, bundleIdCollection.size());
}
-
+
// get the bundle ids and remove them from the collection
Long[] bundleIds;
synchronized (bundleIdCollection) {
@@ -448,7 +443,7 @@
final long delta = System.currentTimeMillis() - start;
log.info("bundle.start() call took {} msec for bundle {}",
delta, bundle.getSymbolicName());
} catch (BundleException be) {
- log.info("Failed to start Bundle "
+ log.info("Failed to start Bundle "
+ bundle.getSymbolicName() + "/" + bundle.getBundleId()
+ ", rescheduling for start"
,be);
@@ -461,7 +456,7 @@
}
}
}
-
+
if(startupFailed.size() > 0) {
log.info("Finished starting {} bundles, failed: {}", toStart + " "
+ collectionName, startupFailed);
} else {
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/ConfigResourceProcessor.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/ConfigResourceProcessor.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/ConfigResourceProcessor.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/ConfigResourceProcessor.java
Tue Jun 23 16:03:06 2009
@@ -18,14 +18,12 @@
*/
package org.apache.sling.osgi.installer.impl;
-import static org.apache.sling.osgi.installer.InstallResultCode.INSTALLED;
-import static org.apache.sling.osgi.installer.InstallResultCode.UPDATED;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Map;
+import org.apache.sling.osgi.installer.InstallResultCode;
import org.apache.sling.osgi.installer.InstallableData;
import org.apache.sling.osgi.installer.JcrInstallException;
import org.apache.sling.osgi.installer.OsgiControllerServices;
@@ -45,47 +43,45 @@
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final DictionaryReader reader = new DictionaryReader();
private final OsgiControllerServices serviceProxy;
-
+
ConfigResourceProcessor(OsgiControllerServices sp) {
serviceProxy = sp;
}
-
+
public void dispose() {
// nothing to do
}
-
+
public boolean canProcess(String uri, InstallableData data) {
- final boolean isDict = data == null ? false :
data.adaptTo(Dictionary.class) != null;
+ final boolean isDict = data == null ? false :
data.adaptTo(Dictionary.class) != null;
return uri.endsWith(CONFIG_EXTENSION) || isDict;
}
@SuppressWarnings("unchecked")
- public int installOrUpdate(String uri, Map<String, Object> attributes,
+ public InstallResultCode installOrUpdate(String uri, Map<String, Object>
attributes,
InstallableData installableData) throws Exception {
-
+
// Convert data to a configuration Dictionary
Dictionary dict = installableData.adaptTo(Dictionary.class);
if(dict == null) {
InputStream data = installableData.adaptTo(InputStream.class);
- if(data == null) {
+ if (data == null) {
throw new IOException("InstallableData does not adapt
to an InputStream: " + uri);
}
try {
dict = reader.load(data);
} finally {
- if(data != null) {
- data.close();
- }
+ data.close();
}
}
-
- if(dict == null) {
+
+ if (dict == null) {
throw new JcrInstallException("Null Dictionary for uri=" + uri);
}
-
+
// Add pseudo-properties
dict.put(CONFIG_PATH_KEY, uri);
-
+
// Get pids from node name
final ConfigurationPid pid = new ConfigurationPid(uri);
log.debug("{} created for uri {}", pid, uri);
@@ -95,20 +91,20 @@
}
// get or create configuration
- int result = UPDATED;
+ InstallResultCode result = InstallResultCode.UPDATED;
Configuration config = getConfiguration(pid, false);
if(config == null) {
- result = INSTALLED;
+ result = InstallResultCode.INSTALLED;
config = getConfiguration(pid, true);
}
if (config.getBundleLocation() != null) {
config.setBundleLocation(null);
}
config.update(dict);
- log.info("Configuration {} {}", config.getPid(), (result == UPDATED ?
"updated" : "created"));
+ log.info("Configuration {} {}", config.getPid(), (result ==
InstallResultCode.UPDATED ? "updated" : "created"));
return result;
}
-
+
public void processResourceQueue() throws Exception {
// TODO might need to retry installing configs, as
// we do for bundles
@@ -126,16 +122,16 @@
}
/** Get or create configuration */
- Configuration getConfiguration(ConfigurationPid cp, boolean
createIfNeeded)
- throws IOException, InvalidSyntaxException, MissingServiceException
+ Configuration getConfiguration(ConfigurationPid cp, boolean createIfNeeded)
+ throws IOException, InvalidSyntaxException, MissingServiceException
{
final ConfigurationAdmin configurationAdmin =
serviceProxy.getConfigurationAdmin();
if(configurationAdmin == null) {
throw new MissingServiceException(ConfigurationAdmin.class);
}
-
+
Configuration result = null;
-
+
if (cp.getFactoryPid() == null) {
result = configurationAdmin.getConfiguration(cp.getConfigPid(),
null);
} else {
@@ -143,7 +139,7 @@
"(|(" + ALIAS_KEY
+ "=" + cp.getFactoryPid() + ")(.alias_factory_pid=" +
cp.getFactoryPid()
+ "))");
-
+
if (configs == null || configs.length == 0) {
if(createIfNeeded) {
result =
configurationAdmin.createFactoryConfiguration(cp.getConfigPid(), null);
@@ -152,7 +148,7 @@
result = configs[0];
}
}
-
+
return result;
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/InstallableDataWrapper.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/InstallableDataWrapper.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/InstallableDataWrapper.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/InstallableDataWrapper.java
Tue Jun 23 16:03:06 2009
@@ -32,21 +32,21 @@
/** Wraps InstallableData instances that provide an InputStream
* so that their data comes from our BundleContext's storage.
- *
+ *
* Needed as InstallableData will be provided by a separate bundle,
* with InputStreams that might not be available anymore once
* the data is actually installed, for example if that data comes
* from a JCR repository that's deactivated due to bundle updates.
*/
class InstallableDataWrapper implements InstallableData {
-
+
private InstallableData wrapped;
private final File dataFile;
private static int fileCounter;
-
+
InstallableDataWrapper(InstallableData d, BundleContext bc) throws
IOException {
wrapped = d;
-
+
// If d adapts to an input stream, save its content in
// our BundleContext storage
final InputStream is = wrapped.adaptTo(InputStream.class);
@@ -60,7 +60,7 @@
filename += "." + (++fileCounter);
}
dataFile = bc.getDataFile(filename);
-
+
os = new BufferedOutputStream(new
FileOutputStream(dataFile));
final byte[] buffer = new byte[16384];
int count = 0;
@@ -80,7 +80,7 @@
public int getBundleStartLevel() {
return wrapped.getBundleStartLevel();
}
-
+
/** Adapt the underlying data to the provided type.
* @return null if cannot be adapted */
@SuppressWarnings("unchecked")
@@ -92,15 +92,14 @@
} catch(IOException ioe) {
throw new IllegalStateException("Unable to open
data file " + dataFile.getAbsolutePath());
}
- } else {
- return wrapped.adaptTo(type);
- }
+ }
+ return wrapped.adaptTo(type);
}
public String getDigest() {
return wrapped.getDigest();
}
-
+
void cleanup() {
if(dataFile != null) {
dataFile.delete();
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
Tue Jun 23 16:03:06 2009
@@ -31,33 +31,24 @@
import org.apache.sling.osgi.installer.OsgiResourceProcessor;
import org.apache.sling.osgi.installer.ResourceOverrideRules;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.component.ComponentContext;
import org.osgi.service.log.LogService;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
-/** OsgiController service
+/**
+ * OsgiController service
*
- * @scr.service
- * @scr.component
- * immediate="true"
- * metatype="no"
- * @scr.property
- * name="service.description"
- * value="Sling jcrinstall OsgiController Service"
- * @scr.property
- * name="service.vendor"
- * value="The Apache Software Foundation"
-*/
-public class OsgiControllerImpl implements OsgiController,
SynchronousBundleListener, OsgiControllerServices, OsgiControllerTask.Context {
-
- private BundleContext bundleContext;
- private Storage storage;
- private OsgiResourceProcessorList processors;
+ */
+public class OsgiControllerImpl
+ implements OsgiController,
+ OsgiControllerServices,
+ OsgiControllerTask.Context {
+
+ private final BundleContext bundleContext;
+ private final Storage storage;
+ private final OsgiResourceProcessorList processors;
private ResourceOverrideRules roRules;
private final List<OsgiControllerTask> tasks = new
LinkedList<OsgiControllerTask>();
private final OsgiControllerTaskExecutor executor = new
OsgiControllerTaskExecutor();
@@ -67,52 +58,49 @@
/** Storage key: digest of an InstallableData */
public static final String KEY_DIGEST = "data.digest";
- /** @scr.reference */
- private PackageAdmin packageAdmin;
+ private final PackageAdmin packageAdmin;
+
+ protected final StartLevel startLevel;
+
+ protected final LogService logService;
- /** @scr.reference */
- protected StartLevel startLevel;
-
- /** @scr.reference */
- protected LogService logService;
-
/** Default value for getLastModified() */
public static final long LAST_MODIFIED_NOT_FOUND = -1;
- protected void activate(ComponentContext context) throws IOException {
- bundleContext = context.getBundleContext();
- processors = new OsgiResourceProcessorList(context.getBundleContext(),
packageAdmin, startLevel, this);
- storage = new
Storage(context.getBundleContext().getDataFile(STORAGE_FILENAME));
- }
+ public OsgiControllerImpl(final BundleContext bc,
+ final PackageAdmin pa,
+ final StartLevel sl,
+ final LogService ls)
+ throws IOException {
+ this.bundleContext = bc;
+ this.packageAdmin = pa;
+ this.startLevel = sl;
+ this.logService = ls;
+ processors = new OsgiResourceProcessorList(bc, packageAdmin,
startLevel, this);
+ storage = new Storage(bc.getDataFile(STORAGE_FILENAME));
+ }
+
+ public void deactivate() {
+ try {
+ storage.saveToFile();
+ } catch(IOException ioe) {
+ if (logService != null) {
+ logService.log(LogService.LOG_WARNING, "IOException in
Storage.saveToFile()", ioe);
+ }
+ }
- protected void deactivate(ComponentContext oldContext) {
- if(logService != null) {
- logService.log(LogService.LOG_WARNING,
- OsgiController.class.getName()
- + " service deactivated - this warning can be
ignored if system is shutting down");
- }
-
- bundleContext = null;
- if(storage != null) {
- try {
- storage.saveToFile();
- } catch(IOException ioe) {
- if(logService != null) {
- logService.log(LogService.LOG_WARNING, "IOException in
Storage.saveToFile()", ioe);
- }
- }
+ for (OsgiResourceProcessor processor : processors) {
+ processor.dispose();
}
-
- if (processors != null) {
- for (OsgiResourceProcessor processor : processors) {
- processor.dispose();
- }
+
+ if(logService != null) {
+ logService.log(LogService.LOG_WARNING,
+ OsgiController.class.getName()
+ + " service deactivated - this warning can be ignored if
system is shutting down");
}
-
- storage = null;
- processors = null;
+
}
-
+
public void scheduleInstallOrUpdate(String uri, InstallableData data)
throws IOException, JcrInstallException {
synchronized (tasks) {
tasks.add(new OsgiResourceTask(uri, data, bundleContext));
@@ -146,14 +134,9 @@
return "jcrinstall://" + uri;
}
- /** Schedule our next scan sooner if anything happens to bundles */
- public void bundleChanged(BundleEvent e) {
- //loopDelay = 0;
- }
-
/** {...@inheritdoc} */
public void executeScheduledOperations() throws Exception {
-
+
// Ready to work?
if(processors == null) {
if(logService != null) {
@@ -161,31 +144,33 @@
}
return;
}
-
+
// Anything to do?
if(tasks.isEmpty()) {
return;
}
-
+
synchronized (tasks) {
// Add tasks for our processors to execute their own operations,
// after our own tasks are executed
for(OsgiResourceProcessor p : processors) {
tasks.add(new ResourceQueueTask(p));
}
-
+
// Now execute all our tasks in a separate thread
if(logService != null) {
- logService.log(LogService.LOG_DEBUG, "Executing " +
tasks.size() + " queued tasks");
+ logService.log(LogService.LOG_INFO, "Executing " +
tasks.size() + " queued tasks");
}
final long start = System.currentTimeMillis();
-
+
// execute returns the list of tasks that could not be executed
but should be retried later
// and those have been removed from the tasks list
- tasks.addAll(executor.execute(tasks, this));
-
+ final List<OsgiControllerTask> remainingTasks =
executor.execute(tasks, this);
+ tasks.clear();
+ tasks.addAll(remainingTasks);
+
if(logService != null) {
- logService.log(LogService.LOG_DEBUG,
+ logService.log(LogService.LOG_INFO,
"Done executing queued tasks (" +
(System.currentTimeMillis() - start) + " msec)");
}
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTaskExecutor.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTaskExecutor.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTaskExecutor.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTaskExecutor.java
Tue Jun 23 16:03:06 2009
@@ -29,32 +29,34 @@
class OsgiControllerTaskExecutor {
private final Logger log = LoggerFactory.getLogger(this.getClass());
static int counter;
-
+
/** Execute the given tasks in a new thread, return when done */
- List<OsgiControllerTask >execute(final List<OsgiControllerTask> tasks,
final OsgiControllerTask.Context context)
- throws InterruptedException {
- final List<OsgiControllerTask> remainingTasks = new
LinkedList<OsgiControllerTask>();
+ List<OsgiControllerTask >execute(final List<OsgiControllerTask> tasks,
final OsgiControllerTask.Context context) {
+ final List<OsgiControllerTask> remainingTasks = new
LinkedList<OsgiControllerTask>();
final String threadName = getClass().getSimpleName() + " #" +
(++counter);
- final Thread executor = new Thread(threadName) {
- @Override
- public void run() {
- while(!tasks.isEmpty()) {
- final OsgiControllerTask t =
tasks.remove(0);
- try {
- t.execute(context);
- log.debug("Task execution
successful: " + t);
- } catch(MissingServiceException mse) {
- log.info("Task execution
deferred due to " + mse + ", task=" + t);
- remainingTasks.add(t);
- } catch(Exception e) {
- log.warn("Task execution
failed: " + t, e);
- }
+ final String oldThreadName = Thread.currentThread().getName();
+ Thread.currentThread().setName(threadName);
+ try {
+ log.info("Starting controller task executor.");
+ while(!tasks.isEmpty()) {
+ final OsgiControllerTask t = tasks.remove(0);
+ try {
+ log.info("Executing task: " + t);
+ t.execute(context);
+ log.info("Task execution successful: "
+ t);
+ } catch(MissingServiceException mse) {
+ log.info("Task execution deferred due
to " + mse + ", task=" + t);
+ remainingTasks.add(t);
+ } catch(Throwable e) {
+ log.warn("Task execution failed: " + t,
e);
+ remainingTasks.add(t);
}
}
- };
- executor.setDaemon(true);
- executor.start();
- executor.join();
+ log.info("Finishing controller task executor.");
+ } finally {
+ Thread.currentThread().setName(oldThreadName);
+ }
+
return remainingTasks;
}
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiResourceTask.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiResourceTask.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiResourceTask.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiResourceTask.java
Tue Jun 23 16:03:06 2009
@@ -33,27 +33,27 @@
* by the OsgiController worker thread.
*/
class OsgiResourceTask implements OsgiControllerTask {
-
+
private final String uri;
private final InstallableData data;
-
+
private static final Logger log =
LoggerFactory.getLogger(OsgiResourceTask.class);
/** Create a task that will install, update or uninstall a resource.
* @param data if not null, operation is install or update, else uninstall
*/
OsgiResourceTask(
- String uri,
+ String uri,
InstallableData data,
BundleContext bc) throws IOException
{
this.uri = uri;
this.data = (data == null ? null : new
InstallableDataWrapper(data, bc));
}
-
+
@Override
public String toString() {
- return
+ return
getClass().getSimpleName()
+ ", "
+ (isInstallOrUpdate() ? "install/update" : "uninstall")
@@ -62,7 +62,7 @@
;
}
-
+
public void execute(OsgiControllerTask.Context context) throws
Exception {
// TODO Auto-generated method stub
if(isInstallOrUpdate()) {
@@ -70,7 +70,7 @@
} else {
executeUninstall(context);
}
-
+
// Cleanup InstallableDataWrapper
if(data instanceof InstallableDataWrapper) {
((InstallableDataWrapper)data).cleanup();
@@ -82,6 +82,7 @@
}
private void executeUninstall(OsgiControllerTask.Context context)
throws Exception {
+ log.info("Execute uninstall " + this);
// If a corresponding higher priority resource is installed, ignore
this request
if(context.getResourceOverrideRules() != null) {
for(String r :
context.getResourceOverrideRules().getHigherPriorityResources(uri)) {
@@ -92,18 +93,19 @@
}
}
}
-
+
// let each processor try to uninstall, one of them
// should know how that handle uri
for(OsgiResourceProcessor p : context.getProcessors()) {
- p.uninstall(uri, context.getStorage().getMap(uri));
+ p.uninstall(uri, context.getStorage().getMap(uri));
}
-
+
context.getStorage().remove(uri);
context.getStorage().saveToFile();
}
private void executeInstallOrUpdate(OsgiControllerTask.Context context)
throws Exception {
+ log.info("Execute install or update " + this);
// If a corresponding higher priority resource is already installed,
ignore this one
if(context.getResourceOverrideRules() != null) {
for(String r :
context.getResourceOverrideRules().getHigherPriorityResources(uri)) {
@@ -114,7 +116,7 @@
}
}
}
-
+
// If a corresponding lower priority resource is installed, uninstall
it first
if(context.getResourceOverrideRules() != null) {
for(String r :
context.getResourceOverrideRules().getLowerPriorityResources(uri)) {
@@ -125,7 +127,7 @@
}
}
}
-
+
// let suitable OsgiResourceProcessor process install
final OsgiResourceProcessor p =
context.getProcessors().getProcessor(uri, data);
if (p != null) {
@@ -136,6 +138,5 @@
context.getStorage().saveToFile();
}
return;
-
}
}
Modified:
sling/trunk/contrib/extensions/jcrinstall/osgi/src/test/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessorTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/test/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessorTest.java?rev=787739&r1=787738&r2=787739&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/jcrinstall/osgi/src/test/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessorTest.java
(original)
+++
sling/trunk/contrib/extensions/jcrinstall/osgi/src/test/java/org/apache/sling/osgi/installer/impl/BundleResourceProcessorTest.java
Tue Jun 23 16:03:06 2009
@@ -62,15 +62,14 @@
}
@org.junit.Test public void testNothing() {
-
+
}
-
+
/** Disabled for now - too complex, gets in the way of osgiworker changes
*/
public void TODO_DISABLED_testInstall() throws Exception {
- final OsgiControllerImpl c = new OsgiControllerImpl();
final BundleContext bc = mockery.mock(BundleContext.class);
- Utilities.setField(c, "bundleContext", bc);
+ final OsgiControllerImpl c = new OsgiControllerImpl(bc, null, null,
null);
final PackageAdmin pa = mockery.mock(PackageAdmin.class);
final TestStorage s = new TestStorage(Utilities.getTestFile());
Utilities.setStorage(c, s);
@@ -102,7 +101,7 @@
will(returnValue(getDataFile()));
one(bc).installBundle(
-
with(equal(OsgiControllerImpl.getResourceLocation(uri))),
+
with(equal(OsgiControllerImpl.getResourceLocation(uri))),
with(any(InputStream.class)));
inSequence(sequence);
will(returnValue(b));
@@ -113,7 +112,7 @@
one(b).stop();
inSequence(sequence);
-
+
one(b).update(with(any(InputStream.class)));
inSequence(sequence);
@@ -128,8 +127,8 @@
proc.add(p);
Utilities.setField(c, "processors", proc);
assertFalse("Before install, uri must not be in list",
c.getInstalledUris().contains(uri));
-
- // Need to send framework events to p
+
+ // Need to send framework events to p
// TODO: this test is getting too complicated... ;-)
class FEThread extends Thread {
boolean active = true;
@@ -149,7 +148,7 @@
}
};
FEThread t = new FEThread();
-
+
// do the actual testing
c.scheduleInstallOrUpdate(uri, data);
c.executeScheduledOperations();
@@ -175,7 +174,7 @@
mockery.assertIsSatisfied();
t.active = false;
}
-
+
static File getDataFile() throws IOException {
return
File.createTempFile(BundleResourceProcessor.class.getSimpleName() +
(++counter),".tmp");
}