Author: cziegeler
Date: Sat Jan 22 17:12:36 2011
New Revision: 1062205
URL: http://svn.apache.org/viewvc?rev=1062205&view=rev
Log:
SLING-1946 : Transformer should only be invoked once on an untransformed
resource
Modified:
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/RegisteredResourceImpl.java
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
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=1062205&r1=1062204&r2=1062205&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
Sat Jan 22 17:12:36 2011
@@ -47,8 +47,10 @@ import org.apache.sling.installer.api.ta
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -542,30 +544,42 @@ public class OsgiInstallerImpl
private void transformResources() {
boolean changed = false;
- final List<ResourceTransformer> services =
this.transformerTracker.getSortedServices();
+ final List<ServiceReference> serviceRefs =
this.transformerTracker.getSortedServiceReferences();
- if ( services.size() > 0 ) {
+ if ( serviceRefs.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(final ResourceTransformer transformer : services) {
- try {
- final TransformationResult[] result =
transformer.transform(resource);
- if ( logger.isDebugEnabled() ) {
- logger.debug("Invoked transformer {} on {} : {}",
- new Object[] {transformer, resource,
Arrays.toString(result)});
- }
- if ( result != null && result.length > 0 ) {
- this.persistentList.transform(resource, result);
- changed = true;
- index--;
- break;
+ for(final ServiceReference reference : serviceRefs) {
+ final Long id =
(Long)reference.getProperty(Constants.SERVICE_ID);
+ // check if this transformer has already been invoked for
the resource
+ final String transformers =
(String)((RegisteredResourceImpl)resource).getAttribute(ResourceTransformer.class.getName());
+ if ( id == null ||
+ (transformers != null && transformers.contains(":" +
id + ':'))) {
+ continue;
+ }
+ final ResourceTransformer transformer =
(ResourceTransformer) this.transformerTracker.getService(reference);
+ if ( transformer != null ) {
+ try {
+ final TransformationResult[] result =
transformer.transform(resource);
+ final String newTransformers = (transformers ==
null ? ":" + id + ':' : transformers + id + ':');
+
((RegisteredResourceImpl)resource).setAttribute(ResourceTransformer.class.getName(),
newTransformers);
+ if ( logger.isDebugEnabled() ) {
+ logger.debug("Invoked transformer {} on {} :
{}",
+ new Object[] {transformer, resource,
Arrays.toString(result)});
+ }
+ 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);
}
- } catch (final Throwable t) {
- logger.error("Uncaught exception during resource
transformation!", t);
}
}
index++;
@@ -600,7 +614,7 @@ public class OsgiInstallerImpl
eventsCount++;
}
final int t = e.getType();
- if(t == BundleEvent.INSTALLED || t == BundleEvent.RESOLVED || t ==
BundleEvent.STARTED || t == BundleEvent.UPDATED) {
+ if (t == BundleEvent.INSTALLED || t == BundleEvent.RESOLVED || t ==
BundleEvent.STARTED || t == BundleEvent.UPDATED) {
logger.debug("Received BundleEvent that might allow installed
bundles to start, scheduling retries if any");
// TODO - for now we always reschedule regardless if we have
retries
// If the config task factory is only registered when config admin
is available we can relax this again.
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java?rev=1062205&r1=1062204&r2=1062205&view=diff
==============================================================================
---
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java
(original)
+++
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java
Sat Jan 22 17:12:36 2011
@@ -479,6 +479,7 @@ public class RegisteredResourceImpl
this.digest,
this.priority,
this.urlScheme);
+ rr.attributes.putAll(this.attributes);
rr.update(transformationResult);
return rr;
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=1062205&r1=1062204&r2=1062205&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
Sat Jan 22 17:12:36 2011
@@ -38,8 +38,12 @@ public class SortingServiceTracker<T>
private int lastCount = -1;
+ private int lastRefCount = -1;
+
private List<T> sortedServiceCache;
+ private List<ServiceReference> sortedReferences;
+
/**
* Constructor
*/
@@ -56,6 +60,7 @@ public class SortingServiceTracker<T>
@Override
public void removedService(ServiceReference reference, Object service) {
this.sortedServiceCache = null;
+ this.sortedReferences = null;
this.context.ungetService(reference);
}
@@ -65,6 +70,7 @@ public class SortingServiceTracker<T>
@Override
public void modifiedService(ServiceReference reference, Object service) {
this.sortedServiceCache = null;
+ this.sortedReferences = null;
}
/**
@@ -73,15 +79,15 @@ public class SortingServiceTracker<T>
@Override
public Object addingService(ServiceReference reference) {
this.sortedServiceCache = null;
- // new factory has been added, wake up main thread
+ this.sortedReferences = null;
+ // new factory or resource transformer has been added, wake up main
thread
this.listener.wakeUp();
return context.getService(reference);
}
/**
- * Return a sorted array of the services.
+ * Return a sorted list of the services.
*/
- @SuppressWarnings("unchecked")
public List<T> getSortedServices() {
if ( this.sortedServiceCache == null || this.lastCount <
this.getTrackingCount() ) {
this.lastCount = this.getTrackingCount();
@@ -92,6 +98,7 @@ public class SortingServiceTracker<T>
Arrays.sort(references);
this.sortedServiceCache = new ArrayList<T>();
for(int i=0;i<references.length;i++) {
+ @SuppressWarnings("unchecked")
final T service =
(T)this.getService(references[references.length - 1 - i]);
if ( service != null ) {
this.sortedServiceCache.add(service);
@@ -101,4 +108,24 @@ public class SortingServiceTracker<T>
}
return this.sortedServiceCache;
}
+
+ /**
+ * Return a sorted list of the services references.
+ */
+ public List<ServiceReference> getSortedServiceReferences() {
+ if ( this.sortedReferences == null || this.lastRefCount <
this.getTrackingCount() ) {
+ this.lastRefCount = this.getTrackingCount();
+ final ServiceReference[] references = this.getServiceReferences();
+ if ( references == null || references.length == 0 ) {
+ this.sortedReferences = Collections.emptyList();
+ } else {
+ Arrays.sort(references);
+ this.sortedReferences = new ArrayList<ServiceReference>();
+ for(int i=0;i<references.length;i++) {
+ this.sortedReferences.add(references[i]);
+ }
+ }
+ }
+ return this.sortedReferences;
+ }
}