Author: cziegeler
Date: Fri Jan 21 18:33:01 2011
New Revision: 1061954
URL: http://svn.apache.org/viewvc?rev=1061954&view=rev
Log:
SLING-1943 : Sort services (transformer and factories) by service ranking
before invoking
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/DefaultTransformer.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Util.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SystemBundleUpdateTask.java
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/DefaultTransformer.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/DefaultTransformer.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/DefaultTransformer.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/DefaultTransformer.java
Fri Jan 21 18:33:01 2011
@@ -18,12 +18,8 @@
*/
package org.apache.sling.installer.core.impl;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.tasks.RegisteredResource;
@@ -79,34 +75,23 @@ public class DefaultTransformer
* @return
*/
private TransformationResult[] checkBundle(final RegisteredResource
resource) {
- try {
- final Manifest m = getManifest(resource.getInputStream());
- if (m != null) {
- final String sn =
m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- if (sn != null) {
- final String v =
m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
- if (v != null) {
- final Map<String, Object> attr = new HashMap<String,
Object>();
- attr.put(Constants.BUNDLE_SYMBOLICNAME, sn);
- attr.put(Constants.BUNDLE_VERSION, v.toString());
-
- // check for activation policy
- final String actPolicy =
m.getMainAttributes().getValue(Constants.BUNDLE_ACTIVATIONPOLICY);
- if ( Constants.ACTIVATION_LAZY.equals(actPolicy) ) {
- attr.put(Constants.BUNDLE_ACTIVATIONPOLICY,
actPolicy);
- }
-
- final TransformationResult tr = new
TransformationResult();
- tr.setId(sn);
- tr.setResourceType(InstallableResource.TYPE_BUNDLE);
- tr.setAttributes(attr);
-
- return new TransformationResult[] {tr};
- }
- }
+ final Util.BundleHeaders headers = Util.readBundleHeaders(resource);
+ if ( headers != null ) {
+ final Map<String, Object> attr = new HashMap<String, Object>();
+ attr.put(Constants.BUNDLE_SYMBOLICNAME, headers.symbolicName);
+ attr.put(Constants.BUNDLE_VERSION, headers.version);
+
+ // check for activation policy
+ if ( headers.activationPolicy != null ) {
+ attr.put(Constants.BUNDLE_ACTIVATIONPOLICY,
headers.activationPolicy);
}
- } catch (final IOException ignore) {
- // ignore
+
+ final TransformationResult tr = new TransformationResult();
+ tr.setId(headers.symbolicName);
+ tr.setResourceType(InstallableResource.TYPE_BUNDLE);
+ tr.setAttributes(attr);
+
+ return new TransformationResult[] {tr};
}
return null;
}
@@ -161,38 +146,7 @@ public class DefaultTransformer
return new TransformationResult[] {tr};
}
- /**
- * Read the manifest from supplied input stream, which is closed before
return.
- */
- private Manifest getManifest(final InputStream ins) throws IOException {
- Manifest result = null;
- if ( ins != null ) {
- JarInputStream jis = null;
- try {
- jis = new JarInputStream(ins);
- result= jis.getManifest();
-
- } finally {
-
- // close the jar stream or the inputstream, if the jar
- // stream is set, we don't need to close the input stream
- // since closing the jar stream closes the input stream
- if (jis != null) {
- try {
- jis.close();
- } catch (IOException ignore) {
- }
- } else {
- try {
- ins.close();
- } catch (IOException ignore) {
- }
- }
- }
- }
- return result;
- }
/**
* Compute the extension
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
Fri Jan 21 18:33:01 2011
@@ -446,8 +446,8 @@ public class OsgiInstallerImpl
}
// Walk the list of entities, and create appropriate OSGi tasks for
each group
- final InstallTaskFactory[] services =
this.factoryTracker.getSortedServices();
- if ( services != null && services.length > 0 ) {
+ final List<InstallTaskFactory> services =
this.factoryTracker.getSortedServices();
+ if ( services.size() > 0 ) {
for(final String entityId : this.persistentList.getEntityIds()) {
final EntityResourceList group =
this.persistentList.getEntityResourceList(entityId);
// Check the first resource in each group
@@ -467,12 +467,11 @@ public class OsgiInstallerImpl
/**
* Get the task for the resource.
*/
- private InstallTask getTask(final InstallTaskFactory[] services,
+ private InstallTask getTask(List<InstallTaskFactory> services,
final TaskResourceGroup rrg) {
InstallTask result = null;
- for(int i=0; i<services.length; i++) {
- final InstallTaskFactory factory = services[i];
+ for(final InstallTaskFactory factory : services) {
if ( factory != null ) {
result = factory.createTask(rrg);
if ( result != null ) {
@@ -542,30 +541,26 @@ public class OsgiInstallerImpl
private void transformResources() {
boolean changed = false;
- final ResourceTransformer[] services =
this.transformerTracker.getSortedServices();
+ final List<ResourceTransformer> services =
this.transformerTracker.getSortedServices();
- if ( services != null && services.length > 0 ) {
+ if ( services.size() > 0 ) {
// Walk the list of unknown resources and invoke all transformers
int index = 0;
final List<RegisteredResource> unknownList =
this.persistentList.getUntransformedResources();
while ( index < unknownList.size() ) {
final RegisteredResource resource = unknownList.get(index);
- for(int i=0; i<services.length; i++) {
- final ResourceTransformer transformer = services[i];
- if ( transformer != null ) {
-
- try {
- final TransformationResult[] result =
transformer.transform(resource);
- if ( result != null && result.length > 0 ) {
- this.persistentList.transform(resource,
result);
- changed = true;
- index--;
- break;
- }
- } catch (final Throwable t) {
- logger.error("Uncaught exception during resource
transformation!", t);
+ for(final ResourceTransformer transformer : services) {
+ try {
+ final TransformationResult[] result =
transformer.transform(resource);
+ if ( result != null && result.length > 0 ) {
+ this.persistentList.transform(resource, result);
+ changed = true;
+ index--;
+ break;
}
+ } catch (final Throwable t) {
+ logger.error("Uncaught exception during resource
transformation!", t);
}
}
index++;
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
Fri Jan 21 18:33:01 2011
@@ -18,7 +18,10 @@
*/
package org.apache.sling.installer.core.impl;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -35,7 +38,7 @@ public class SortingServiceTracker<T>
private int lastCount = -1;
- private T[] sortedServiceCache;
+ private List<T> sortedServiceCache;
/**
* Constructor
@@ -79,17 +82,20 @@ public class SortingServiceTracker<T>
* Return a sorted array of the services.
*/
@SuppressWarnings("unchecked")
- public T[] getSortedServices() {
+ public List<T> getSortedServices() {
if ( this.sortedServiceCache == null || this.lastCount <
this.getTrackingCount() ) {
this.lastCount = this.getTrackingCount();
final ServiceReference[] references = this.getServiceReferences();
if ( references == null || references.length == 0 ) {
- this.sortedServiceCache = (T[])new Object[0];
+ this.sortedServiceCache = Collections.emptyList();
} else {
Arrays.sort(references);
- this.sortedServiceCache = (T[])new Object[references.length];
+ this.sortedServiceCache = new ArrayList<T>();
for(int i=0;i<references.length;i++) {
- this.sortedServiceCache[i] =
(T)this.getService(references[references.length - 1 - i]);
+ final T service =
(T)this.getService(references[references.length - 1 - i]);
+ if ( service != null ) {
+ this.sortedServiceCache.add(service);
+ }
}
}
}
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Util.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Util.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Util.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Util.java
Fri Jan 21 18:33:01 2011
@@ -19,11 +19,19 @@
package org.apache.sling.installer.core.impl;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Field;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.sling.installer.api.tasks.RegisteredResource;
+import org.osgi.framework.Constants;
public class Util {
- /** Set a (final) field during deserialization. */
+ /**
+ * Set a (final) field during deserialization.
+ */
public static void setField(final Object obj, final String name, final
Object value)
throws IOException {
try {
@@ -43,4 +51,77 @@ public class Util {
throw (IOException)new IOException().initCause(e);
}
}
+
+ /**
+ * Read the manifest from supplied input stream, which is closed before
return.
+ */
+ private static Manifest getManifest(final RegisteredResource rsrc)
+ throws IOException {
+ final InputStream ins = rsrc.getInputStream();
+
+ Manifest result = null;
+
+ if ( ins != null ) {
+ JarInputStream jis = null;
+ try {
+ jis = new JarInputStream(ins);
+ result= jis.getManifest();
+
+ } finally {
+
+ // close the jar stream or the inputstream, if the jar
+ // stream is set, we don't need to close the input stream
+ // since closing the jar stream closes the input stream
+ if (jis != null) {
+ try {
+ jis.close();
+ } catch (IOException ignore) {
+ }
+ } else {
+ try {
+ ins.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ final static public class BundleHeaders {
+ public String symbolicName;
+ public String version;
+ public String activationPolicy; // optional
+ }
+
+ /**
+ * Read the bundle info from the manifest (if available)
+ */
+ public static BundleHeaders readBundleHeaders(final RegisteredResource
resource) {
+ try {
+ final Manifest m = Util.getManifest(resource);
+ if (m != null) {
+ final String sn =
m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+ if (sn != null) {
+ final String v =
m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+ if (v != null) {
+ final BundleHeaders headers = new BundleHeaders();
+ headers.symbolicName = sn;
+ headers.version = v.toString();
+
+ // check for activation policy
+ final String actPolicy =
m.getMainAttributes().getValue(Constants.BUNDLE_ACTIVATIONPOLICY);
+ if ( Constants.ACTIVATION_LAZY.equals(actPolicy) ) {
+ headers.activationPolicy = actPolicy;
+ }
+
+ return headers;
+ }
+ }
+ }
+ } catch (final IOException ignore) {
+ // ignore
+ }
+ return null;
+ }
}
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
Fri Jan 21 18:33:01 2011
@@ -75,6 +75,7 @@ public class BundleStartTask extends Abs
* Check if the bundle is active.
* This is true if the bundle has the active state or of the bundle
* is in the starting state and has the lazy activation policy.
+ * Or if the bundle is a fragment, it's considered active as well
*/
public static boolean isBundleActive(final Bundle b) {
if ( b.getState() == Bundle.ACTIVE ) {
@@ -83,6 +84,10 @@ public class BundleStartTask extends Abs
if ( b.getState() == Bundle.STARTING && isLazyActivatian(b) ) {
return true;
}
+ /*
+ if ( b.getHeaders().get(Constants.FRAGMENT_HOST) != null ) {
+ return true;
+ }*/
return false;
}
/**
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
Fri Jan 21 18:33:01 2011
@@ -25,6 +25,7 @@ import org.apache.sling.installer.api.ta
import org.apache.sling.installer.api.tasks.TaskResource;
import org.apache.sling.installer.api.tasks.TaskResourceGroup;
import org.apache.sling.installer.core.impl.InternalService;
+import org.apache.sling.installer.core.impl.Util;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
@@ -140,12 +141,25 @@ public class BundleTaskCreator implement
if ( !toActivate.getType().equals(InstallableResource.TYPE_BUNDLE)
) {
return null;
}
- final InstallTask result;
+ // check if symbolic name and version is provided in the attributes
+ if ( toActivate.getAttribute(Constants.BUNDLE_SYMBOLICNAME) == null ) {
+ final Util.BundleHeaders headers =
Util.readBundleHeaders(toActivate);
+ if ( headers == null ) {
+ logger.info("Resource of type bundle {} is not really a bundle
- manifest entries are missing.", toActivate);
+ return new ChangeStateTask(resourceList,
ResourceState.IGNORED);
+ }
+ toActivate.setAttribute(Constants.BUNDLE_SYMBOLICNAME,
headers.symbolicName);
+ toActivate.setAttribute(Constants.BUNDLE_VERSION, headers.version);
+ if ( headers.activationPolicy != null ) {
+ toActivate.setAttribute(Constants.BUNDLE_ACTIVATIONPOLICY,
headers.activationPolicy);
+ }
+ }
final String symbolicName =
(String)toActivate.getAttribute(Constants.BUNDLE_SYMBOLICNAME);
final BundleInfo info = this.getBundleInfo(symbolicName);
// Uninstall
+ final InstallTask result;
if (toActivate.getState() == ResourceState.UNINSTALL) {
// Remove corresponding bundle if present and if we
installed it
if (info != null
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
Fri Jan 21 18:33:01 2011
@@ -79,8 +79,13 @@ public class BundleUpdateTask extends Ab
ctx.log("Updated bundle {} from resource {}", b, getResource());
if (reactivate) {
- this.getResource().setAttribute(BundleTaskCreator.ATTR_START,
"true");
- ctx.addTaskToCurrentCycle(new
BundleStartTask(this.getResourceGroup(), b.getBundleId(), this.creator));
+ // if ( isSystemBundleFragment(b) ) {
+ // this.setFinishedState(ResourceState.INSTALLED);
+ // ctx.addTaskToCurrentCycle(new
SystemBundleUpdateTask(null, creator));
+ // } else {
+
this.getResource().setAttribute(BundleTaskCreator.ATTR_START, "true");
+ ctx.addTaskToCurrentCycle(new
BundleStartTask(this.getResourceGroup(), b.getBundleId(), this.creator));
+ // }
} else {
this.setFinishedState(ResourceState.INSTALLED);
}
@@ -99,4 +104,10 @@ public class BundleUpdateTask extends Ab
return BUNDLE_UPDATE_ORDER + getResource().getEntityId();
}
+ private boolean isSystemBundleFragment(final Bundle installedBundle) {
+ final String fragmentHeader = (String)
installedBundle.getHeaders().get(
+ Constants.FRAGMENT_HOST);
+ return fragmentHeader != null
+ && fragmentHeader.indexOf(Constants.EXTENSION_DIRECTIVE) > 0;
+ }
}
\ No newline at end of file
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SystemBundleUpdateTask.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SystemBundleUpdateTask.java?rev=1061954&r1=1061953&r2=1061954&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SystemBundleUpdateTask.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SystemBundleUpdateTask.java
Fri Jan 21 18:33:01 2011
@@ -44,7 +44,12 @@ public class SystemBundleUpdateTask exte
}
@Override
- public void execute(InstallationContext ctx) {
+ public void execute(final InstallationContext ctx) {
+ // restart system bundle
+ if ( this.getResource() == null ) {
+ this.restartSystemBundleDelayed();
+ return;
+ }
final String symbolicName =
(String)getResource().getAttribute(Constants.BUNDLE_SYMBOLICNAME);
final Bundle b = this.creator.getMatchingBundle(symbolicName);
if (b == null) {
@@ -101,4 +106,30 @@ public class SystemBundleUpdateTask exte
return BUNDLE_UPDATE_ORDER + getResource().getURL();
}
+ private void restartSystemBundleDelayed() {
+ final Bundle systemBundle =
this.creator.getBundleContext().getBundle(0);
+ // sanity check
+ if ( systemBundle == null ) {
+ return;
+ }
+ final Thread t = new Thread(new Runnable() {
+
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ try {
+ Thread.sleep(800);
+ } catch(InterruptedException ignored) {
+ }
+ try {
+ systemBundle.update();
+ } catch (final BundleException be) {
+ getLogger().warn("Unable to refresh system bundle", be);
+ }
+ }
+ });
+ t.setDaemon(true);
+ t.start();
+ }
}
\ No newline at end of file