in src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java [1144:1313]
private void internalResourceAddedOrUpdated(final String resourceType,
final String entityId,
final ResourceData data,
final Dictionary<String, Object> dict,
final Map<String, Object> attributes) {
final String key = resourceType + ':' + entityId;
final boolean persistChange = attributes != null
? Converters.standardConverter().convert(attributes.get(ResourceChangeListener.RESOURCE_PERSIST))
.defaultValue(Boolean.TRUE).to(Boolean.class)
: true;
try {
boolean compactAndSave = false;
boolean done = false;
synchronized ( this.resourcesLock ) {
final EntityResourceList erl = this.persistentList.getEntityResourceList(key);
logger.debug("Added or updated {} : {}", key, erl);
// we first check for update
if ( erl != null && erl.getFirstResource() != null ) {
// check digest for dictionaries
final TaskResource tr = erl.getFirstResource();
if ( dict != null ) {
final String digest = FileDataStore.computeDigest(dict);
if ( tr.getDigest().equals(digest) ) {
if ( tr.getState() == ResourceState.INSTALLED ) {
logger.debug("Resource did not change {}", key);
} else if ( tr.getState() == ResourceState.INSTALL
|| tr.getState() == ResourceState.IGNORED ) {
erl.setForceFinishState(ResourceState.INSTALLED, null);
compactAndSave = true;
}
done = true;
}
}
final UpdateHandler handler;
if ( !done && persistChange ) {
handler = this.findHandler(tr.getScheme());
if ( handler == null ) {
logger.debug("No handler found to handle update of resource with scheme {}", tr.getScheme());
}
} else {
handler = null;
}
if ( !done && handler == null ) {
compactAndSave = this.handleExternalUpdateWithoutWriteBack(erl);
done = true;
}
if ( !done ) {
final InputStream localIS = data.getInputStream();
try {
final UpdateResult result = (localIS == null ? handler.handleUpdate(resourceType, entityId, tr.getURL(), data.getDictionary(), attributes)
: handler.handleUpdate(resourceType, entityId, tr.getURL(), localIS, attributes));
if ( result != null ) {
if ( !result.getURL().equals(tr.getURL()) && !result.getResourceIsMoved() ) {
// resource has been added!
final InternalResource internalResource = new InternalResource(result.getScheme(),
result.getResourceId(),
null,
data.getDictionary(),
(data.getDictionary() != null ? InstallableResource.TYPE_PROPERTIES : InstallableResource.TYPE_FILE),
data.getDigest(result.getURL(), result.getDigest()),
result.getPriority(),
data.getDataFile(),
null);
final RegisteredResource rr = this.persistentList.addOrUpdate(internalResource);
final TransformationResult transRes = new TransformationResult();
// use the old entity id
final int pos = erl.getResourceId().indexOf(':');
transRes.setId(erl.getResourceId().substring(pos + 1));
transRes.setResourceType(resourceType);
if ( attributes != null ) {
transRes.setAttributes(attributes);
}
this.persistentList.transform(rr, new TransformationResult[] {
transRes
});
final EntityResourceList newGroup = this.persistentList.getEntityResourceList(key);
newGroup.setFinishState(ResourceState.INSTALLED, null);
newGroup.compact();
} else {
// resource has been updated or moved
((RegisteredResourceImpl)tr).update(
data.getDataFile(), data.getDictionary(),
data.getDigest(result.getURL(), result.getDigest()),
result.getPriority(),
result.getURL());
erl.setForceFinishState(ResourceState.INSTALLED, null);
}
compactAndSave = true;
} else {
// handler does not persist
compactAndSave = this.handleExternalUpdateWithoutWriteBack(erl);
}
} finally {
if ( localIS != null ) {
// always close the input stream!
try { localIS.close(); } catch (final IOException ignore) {
// ignore
}
}
}
done = true;
}
}
if ( !done && persistChange) {
// create
final List<UpdateHandler> handlerList = this.updateHandlerTracker.getSortedServices();
for(final UpdateHandler handler : handlerList) {
final InputStream localIS = data.getInputStream();
try {
final UpdateResult result = (localIS == null ? handler.handleUpdate(resourceType, entityId, null, data.getDictionary(), attributes)
: handler.handleUpdate(resourceType, entityId, null, localIS, attributes));
if ( result != null ) {
final InternalResource internalResource = new InternalResource(result.getScheme(),
result.getResourceId(),
null,
data.getDictionary(),
(data.getDictionary() != null ? InstallableResource.TYPE_PROPERTIES : InstallableResource.TYPE_FILE),
data.getDigest(result.getURL(), result.getDigest()),
result.getPriority(),
data.getDataFile(),
null);
final RegisteredResource rr = this.persistentList.addOrUpdate(internalResource);
final TransformationResult transRes = new TransformationResult();
transRes.setId(entityId);
transRes.setResourceType(resourceType);
if ( attributes != null ) {
transRes.setAttributes(attributes);
}
this.persistentList.transform(rr, new TransformationResult[] {
transRes
});
final EntityResourceList newGroup = this.persistentList.getEntityResourceList(key);
newGroup.setFinishState(ResourceState.INSTALLED);
newGroup.compact();
compactAndSave = true;
done = true;
break;
}
} finally {
if ( localIS != null ) {
// always close the input stream!
try {
localIS.close();
} catch (final IOException ignore) {
// ignore
}
}
}
}
if ( !done ) {
logger.debug("No handler found to handle creation of resource {}", key);
}
}
if ( compactAndSave ) {
if ( erl != null ) {
erl.compact();
}
this.persistentList.save();
}
}
} catch (final IOException ioe) {
logger.error("Unable to handle resource add or update of " + key, ioe);
}
}