ServiceTrackerImpl.java 8.63 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  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.References
 *  org.osgi.framework.ServiceReference
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.notification.impl;

import com.day.cq.wcm.notification.Channel;
import com.day.cq.wcm.notification.Subscription;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.References;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0, componentAbstract=1)
@References(value={@Reference(name="channel", referenceInterface=Channel.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC), @Reference(name="subscription", referenceInterface=Subscription.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC)})
public abstract class ServiceTrackerImpl {
    protected final Logger logger;
    private static final String PROPERTY_TYPE = "type";
    private final Map<String, Channel> channels;
    private final Map<String, String> channelsByName;
    private final Map<String, Subscription> subscriptions;
    private final Map<String, String> subscriptionsByName;
    protected ComponentContext context;
    protected final Map<String, ServiceDesc> unhandledServices;

    public ServiceTrackerImpl() {
        this.logger = LoggerFactory.getLogger(this.getClass());
        this.channels = new HashMap<String, Channel>();
        this.channelsByName = new HashMap<String, String>();
        this.subscriptions = new HashMap<String, Subscription>();
        this.subscriptionsByName = new HashMap<String, String>();
        this.unhandledServices = new HashMap<String, ServiceDesc>();
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void activate(ComponentContext context) {
        ArrayList<ServiceDesc> refs;
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            this.context = context;
            refs = new ArrayList<ServiceDesc>(this.unhandledServices.values());
            this.unhandledServices.clear();
        }
        for (ServiceDesc ref : refs) {
            this.register(ref.type, ref.ref);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void deactivate(ComponentContext context) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            this.context = null;
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void bindChannel(ServiceReference ref) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            if (this.context == null) {
                ServiceDesc desc = new ServiceDesc();
                desc.type = ServiceDescType.CHANNEL;
                desc.ref = ref;
                this.unhandledServices.put((String)ref.getProperty("service.pid"), desc);
            } else {
                this.register(ServiceDescType.CHANNEL, ref);
            }
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void bindSubscription(ServiceReference ref) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            if (this.context == null) {
                ServiceDesc desc = new ServiceDesc();
                desc.type = ServiceDescType.SUBSCRIPTION;
                desc.ref = ref;
                this.unhandledServices.put((String)ref.getProperty("service.pid"), desc);
            } else {
                this.register(ServiceDescType.SUBSCRIPTION, ref);
            }
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void unbindChannel(ServiceReference ref) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            this.unregister(ServiceDescType.CHANNEL, ref);
            this.unhandledServices.remove(ref.getProperty("service.pid"));
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void unbindSubscription(ServiceReference ref) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            this.unregister(ServiceDescType.SUBSCRIPTION, ref);
            this.unhandledServices.remove(ref.getProperty("service.pid"));
        }
    }

    protected void register(ServiceDescType type, ServiceReference ref) {
        String key = (String)ref.getProperty("service.pid");
        String name = (String)ref.getProperty("type");
        if (name == null) {
            this.logger.error("Service " + (Object)ref + " is missing required property " + "type");
            return;
        }
        Object service = null;
        switch (type) {
            case CHANNEL: {
                service = this.context.locateService(type.getName(), ref);
                if (service == null) break;
                this.channels.put(key, (Channel)service);
                this.channelsByName.put(name, key);
                break;
            }
            case SUBSCRIPTION: {
                service = this.context.locateService(type.getName(), ref);
                if (service == null) break;
                this.subscriptions.put(key, (Subscription)service);
                this.subscriptionsByName.put(name, key);
            }
        }
        if (service != null) {
            this.logger.debug("Registering service {} : {}", (Object)key, service);
        } else {
            this.logger.error("Unable to register service {} for {}.", (Object)key, (Object)ref);
        }
    }

    protected void unregister(ServiceDescType type, ServiceReference ref) {
        String key = (String)ref.getProperty("service.pid");
        String name = (String)ref.getProperty("type");
        if (name == null) {
            return;
        }
        switch (type) {
            case CHANNEL: {
                this.channels.remove(key);
                if (!key.equals(this.channelsByName.get(name))) break;
                this.channelsByName.remove(name);
                break;
            }
            case SUBSCRIPTION: {
                this.subscriptions.remove(key);
                if (!key.equals(this.subscriptionsByName.get(name))) break;
                this.subscriptionsByName.remove(name);
            }
        }
        this.logger.debug("Unregistering service {}.", (Object)key);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public Channel getChannel(String name) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            String serviceId = this.channelsByName.get(name);
            if (serviceId != null) {
                return this.channels.get(serviceId);
            }
            return null;
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public Subscription getSubscription(String name) {
        Map<String, ServiceDesc> map = this.unhandledServices;
        synchronized (map) {
            String serviceId = this.subscriptionsByName.get(name);
            if (serviceId != null) {
                return this.subscriptions.get(serviceId);
            }
            return null;
        }
    }

    protected Set<String> getSubscriptionNames() {
        return this.subscriptionsByName.keySet();
    }

    protected static enum ServiceDescType {
        CHANNEL("channel"),
        SUBSCRIPTION("subscription");
        
        private final String name;

        private ServiceDescType(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }
    }

    protected static final class ServiceDesc {
        public ServiceDescType type;
        public ServiceReference ref;

        protected ServiceDesc() {
        }
    }

}