public void addOrUpdate()

in src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java [362:424]


    public void addOrUpdate(final RegisteredResourceImpl r) {
        synchronized ( lock ) {
            LOGGER.debug("Adding new resource: {}", r);
            Collections.sort(this.resources);
            // If an object with same url is already present, replace with the
            // new one which might have different attributes
            boolean first = true;
            boolean add = true;
            final Iterator<RegisteredResourceImpl> taskIter = this.resources.iterator();
            while ( taskIter.hasNext() ) {
                final TaskResource rr = taskIter.next();
                if ( rr.getURL().equals(r.getURL()) ) {
                    if ( RegisteredResourceImpl.isSameResource((RegisteredResourceImpl)rr, r) ) {
                        // this check is questionable. The digest could be the same and
                        // the resource URI might have changed nevertheless
                        if ( !rr.getDigest().equals(r.getDigest()) ) {
                            // same resource but different digest
                            LOGGER.debug("Updating resource due to different digests: {} vs {}", r, rr);

                            // we need to check the resource URI if provided (aka getDataURI())
                            // if different that one needs to be updated
                            // this update only handles the following cases:
                            // 1. existing resource has a resource URI and new resource has a resource URI
                            // 2. existing resource has a file and new resource has a resource URI
                            // It doesn't necessarily handle:
                            // 1. existing resource has a resource URI and new resource has a file
                            // 2. existing resource has a file and new resource has a file
                            ((RegisteredResourceImpl)rr).updateResourceUri(r.getDataURI());

                            LOGGER.debug("Cleanup duplicate resource: {}", r);
                            this.cleanup(r);
                        }
                        // same resource, just ignore the new one
                        add = false;
                    } else {
                        if ( first && rr.getState() == ResourceState.INSTALLED) {
                            // it's not the same, but the first one is installed, so uninstall
                            String message = MessageFormat.format(
                                    "The first resource '{0}' got installed, therefore uninstall this secondary resource in this group",
                                    rr.getEntityId());
                            LOGGER.debug(message);
                            ((RegisteredResourceImpl) rr).setState(ResourceState.UNINSTALL, message);
                        } else {
                            LOGGER.debug("Cleanup obsolete resource: {}", rr);
                            taskIter.remove();
                            this.cleanup(rr);
                        }
                    }
                    break;
                }
                first = false;
            }
            if ( add ) {
                resources.add(r);
                // make sure that in case the newly added resource is not the first one the state is saying why it is in mode install
                Collections.sort(this.resources);
                if (r != resources.get(0)) {
                    // don't change actual state but indicate why resource is not considered for subsequent runs (not on first position)
                    r.setState(ResourceState.INSTALL, "Another resource with the same entity id but a higher version or priority or digest found (in that order, the latter only in case the version is a SNAPSHOT)!");
                }
            }
        }
    }