ReferenceAggregatorImpl.java 5.17 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferenceCardinality
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.Resource
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.references.impl;

import com.adobe.granite.references.Reference;
import com.adobe.granite.references.ReferenceAggregator;
import com.adobe.granite.references.ReferenceList;
import com.adobe.granite.references.ReferenceProvider;
import com.adobe.granite.references.impl.ReferenceListImpl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
@org.apache.felix.scr.annotations.Reference(name="referenceProvider", bind="bindReferenceProvider", unbind="unbindReferenceProvider", referenceInterface=ReferenceProvider.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC)
public class ReferenceAggregatorImpl
implements ReferenceAggregator {
    private final Logger log = LoggerFactory.getLogger(ReferenceAggregatorImpl.class);
    private final Map<String, ReferenceProvider> providerCache = new ConcurrentHashMap<String, ReferenceProvider>(10);
    private final Set<String> typeCache = Collections.newSetFromMap(new ConcurrentHashMap(10));

    @Override
    public ReferenceList createReferenceList(Resource resource) {
        return this.createReferenceList(resource, null);
    }

    @Override
    public /* varargs */ ReferenceList createReferenceList(Resource resource, String ... types) {
        if (resource == null) {
            throw new IllegalArgumentException("Reference list's resource must not be null");
        }
        List typesToConsider = types != null ? Arrays.asList(types) : Collections.emptyList();
        boolean noTypeRestriction = typesToConsider.isEmpty();
        ArrayList<Reference> references = new ArrayList<Reference>();
        long start = System.currentTimeMillis();
        for (ReferenceProvider provider : this.providerCache.values()) {
            if (!noTypeRestriction && !typesToConsider.contains(provider.getType())) continue;
            try {
                long providerStart = System.currentTimeMillis();
                List<Reference> providerReferences = provider.getReferences(resource);
                this.log.debug(">> Provider [{}] got [{}] reference(s) in [{}]ms", new Object[]{provider.getClass().getName(), providerReferences.size(), System.currentTimeMillis() - providerStart});
                references.addAll(providerReferences);
            }
            catch (Exception e) {
                this.log.error("Exception thrown by " + provider.getClass().getName(), (Throwable)e);
            }
        }
        this.log.debug("Got [{}] total reference(s) in [{}ms]", (Object)references.size(), (Object)(System.currentTimeMillis() - start));
        return new ReferenceListImpl(resource, references);
    }

    @Override
    public Set<String> getTypes() {
        return Collections.unmodifiableSet(this.typeCache);
    }

    @Activate
    protected void activate() {
    }

    protected void bindReferenceProvider(ReferenceProvider newProvider, Map<String, Object> config) {
        String className = newProvider.getClass().getName();
        ReferenceProvider provider = this.providerCache.get(className);
        if (provider == null) {
            this.providerCache.put(className, newProvider);
            this.typeCache.add(newProvider.getType());
            this.log.info("Bound new reference provider [{}]. Got [{}] providers.", (Object)className, (Object)this.providerCache.size());
        } else {
            this.log.error("Cannot bind new provider: provider with same class [{}] already present.", (Object)className);
        }
    }

    protected void unbindReferenceProvider(ReferenceProvider provider, Map<String, Object> config) {
        String className = provider.getClass().getName();
        this.providerCache.remove(className);
        String providerReferenceType = provider.getType();
        boolean keepType = false;
        for (ReferenceProvider cachedProvider : this.providerCache.values()) {
            if (!providerReferenceType.equals(cachedProvider.getType())) continue;
            keepType = true;
            break;
        }
        if (!keepType) {
            this.typeCache.remove(providerReferenceType);
        }
        this.log.info("Removed reference provider [{}]. Got [{}] providers.", (Object)className, (Object)this.providerCache.size());
    }
}