blob: 1ba37437035821a2c8c42396999e03d3bd27ea84 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.distribution.component.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
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.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.distribution.agent.spi.DistributionAgent;
import org.apache.sling.distribution.agent.impl.DistributionRequestAuthorizationStrategy;
import org.apache.sling.distribution.packaging.DistributionPackageBuilder;
import org.apache.sling.distribution.packaging.DistributionPackageExporter;
import org.apache.sling.distribution.packaging.DistributionPackageImporter;
import org.apache.sling.distribution.queue.impl.DistributionQueueProvider;
import org.apache.sling.distribution.queue.impl.DistributionQueueDispatchingStrategy;
import org.apache.sling.distribution.transport.DistributionTransportSecretProvider;
import org.apache.sling.distribution.trigger.DistributionTrigger;
/**
* {@link DistributionComponentProvider} OSGi service.
*/
@Component
@Property(name = "name", value = "default")
@References({
@Reference(name = "distributionAgent", referenceInterface = DistributionAgent.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionPackageImporter", referenceInterface = DistributionPackageImporter.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionPackageExporter", referenceInterface = DistributionPackageExporter.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionQueueProvider", referenceInterface = DistributionQueueProvider.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionQueueDistributionStrategy", referenceInterface = DistributionQueueDispatchingStrategy.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionTransportSecretProvider", referenceInterface = DistributionTransportSecretProvider.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionTrigger", referenceInterface = DistributionTrigger.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionRequestAuthorizationStrategy", referenceInterface = DistributionRequestAuthorizationStrategy.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
@Reference(name = "distributionPackageBuilder", referenceInterface = DistributionPackageBuilder.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
})
@Service(DistributionComponentProvider.class)
public class DefaultDistributionComponentProvider implements DistributionComponentProvider {
private static final String NAME = DistributionComponentConstants.PN_NAME;
private final Map<String, DistributionComponent<DistributionAgent>> distributionAgentMap = new ConcurrentHashMap<String, DistributionComponent<DistributionAgent>>();
private final Map<String, DistributionComponent<DistributionQueueProvider>> distributionQueueProviderMap = new ConcurrentHashMap<String, DistributionComponent<DistributionQueueProvider>>();
private final Map<String, DistributionComponent<DistributionQueueDispatchingStrategy>> distributionQueueDistributionStrategyMap = new ConcurrentHashMap<String, DistributionComponent<DistributionQueueDispatchingStrategy>>();
private final Map<String, DistributionComponent<DistributionTransportSecretProvider>> distributionTransportSecretProviderMap = new ConcurrentHashMap<String, DistributionComponent<DistributionTransportSecretProvider>>();
private final Map<String, DistributionComponent<DistributionPackageImporter>> distributionPackageImporterMap = new ConcurrentHashMap<String, DistributionComponent<DistributionPackageImporter>>();
private final Map<String, DistributionComponent<DistributionPackageExporter>> distributionPackageExporterMap = new ConcurrentHashMap<String, DistributionComponent<DistributionPackageExporter>>();
private final Map<String, DistributionComponent<DistributionPackageBuilder>> distributionPackageBuilderMap = new ConcurrentHashMap<String, DistributionComponent<DistributionPackageBuilder>>();
private final Map<String, DistributionComponent<DistributionTrigger>> distributionTriggerMap = new ConcurrentHashMap<String, DistributionComponent<DistributionTrigger>>();
private final Map<String, DistributionComponent<DistributionRequestAuthorizationStrategy>> distributionRequestAuthorizationStrategy = new ConcurrentHashMap<String, DistributionComponent<DistributionRequestAuthorizationStrategy>>();
public DistributionComponent<?> getComponent(DistributionComponentKind kind, String componentName) {
Map<String, DistributionComponent<?>> componentMap = getComponentMap(kind.asClass());
return componentMap.get(componentName);
}
public List<DistributionComponent<?>> getComponents(DistributionComponentKind kind) {
Map<String, DistributionComponent<?>> componentMap = getComponentMap(kind.asClass());
List<DistributionComponent<?>> componentList = new ArrayList<DistributionComponent<?>>();
componentList.addAll(componentMap.values());
return componentList;
}
public <ComponentType> ComponentType getService(Class<ComponentType> type, String componentName) {
Map<String, DistributionComponent<?>> componentMap = getComponentMap(type);
DistributionComponent<?> component = componentMap.get(componentName);
if (component == null) {
return null;
}
// safe cast driven by the input type?
return type.cast(component.getService());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private Map<String, DistributionComponent<?>> getComponentMap(Class<?> type) {
if (type.isAssignableFrom(DistributionAgent.class)) {
return (Map) distributionAgentMap;
} else if (type.isAssignableFrom(DistributionPackageExporter.class)) {
return (Map) distributionPackageExporterMap;
} else if (type.isAssignableFrom(DistributionPackageImporter.class)) {
return (Map) distributionPackageImporterMap;
} else if (type.isAssignableFrom(DistributionQueueProvider.class)) {
return (Map) distributionQueueProviderMap;
} else if (type.isAssignableFrom(DistributionQueueDispatchingStrategy.class)) {
return (Map) distributionQueueDistributionStrategyMap;
} else if (type.isAssignableFrom(DistributionTransportSecretProvider.class)) {
return (Map) distributionTransportSecretProviderMap;
} else if (type.isAssignableFrom(DistributionPackageBuilder.class)) {
return (Map) distributionPackageBuilderMap;
} else if (type.isAssignableFrom(DistributionTrigger.class)) {
return (Map) distributionTriggerMap;
} else if (type.isAssignableFrom(DistributionRequestAuthorizationStrategy.class)) {
return (Map) distributionRequestAuthorizationStrategy;
}
throw new IllegalArgumentException(String.format("Components of type: %sĀ are not supported", type));
}
// (un)binding methods
public void bindDistributionQueueProvider(DistributionQueueProvider distributionQueueProvider, Map<String, Object> config) {
put(DistributionQueueProvider.class, distributionQueueProvider, config);
}
public void unbindDistributionQueueProvider(DistributionQueueProvider distributionQueueProvider, Map<String, Object> config) {
remove(DistributionQueueProvider.class, distributionQueueProvider, config);
}
public void bindDistributionQueueDistributionStrategy(DistributionQueueDispatchingStrategy distributionQueueDispatchingStrategy, Map<String, Object> config) {
put(DistributionQueueDispatchingStrategy.class, distributionQueueDispatchingStrategy, config);
}
public void unbindDistributionQueueDistributionStrategy(DistributionQueueDispatchingStrategy distributionQueueDispatchingStrategy, Map<String, Object> config) {
remove(DistributionQueueDispatchingStrategy.class, distributionQueueDispatchingStrategy, config);
}
public void bindDistributionTransportSecretProvider(DistributionTransportSecretProvider distributionTransportSecretProvider, Map<String, Object> config) {
put(DistributionTransportSecretProvider.class, distributionTransportSecretProvider, config);
}
public void unbindDistributionTransportSecretProvider(DistributionTransportSecretProvider distributionTransportSecretProvider, Map<String, Object> config) {
remove(DistributionTransportSecretProvider.class, distributionTransportSecretProvider, config);
}
public void bindDistributionPackageImporter(DistributionPackageImporter distributionPackageImporter, Map<String, Object> config) {
put(DistributionPackageImporter.class, distributionPackageImporter, config);
}
public void unbindDistributionPackageImporter(DistributionPackageImporter distributionPackageImporter, Map<String, Object> config) {
remove(DistributionPackageImporter.class, distributionPackageImporter, config);
}
public void bindDistributionPackageExporter(DistributionPackageExporter distributionPackageExporter, Map<String, Object> config) {
put(DistributionPackageExporter.class, distributionPackageExporter, config);
}
public void unbindDistributionPackageExporter(DistributionPackageExporter distributionPackageExporter, Map<String, Object> config) {
remove(DistributionPackageExporter.class, distributionPackageExporter, config);
}
public void bindDistributionAgent(DistributionAgent distributionAgent, Map<String, Object> config) {
put(DistributionAgent.class, distributionAgent, config);
}
public void unbindDistributionAgent(DistributionAgent distributionAgent, Map<String, Object> config) {
remove(DistributionAgent.class, distributionAgent, config);
}
public void bindDistributionPackageBuilder(DistributionPackageBuilder distributionPackageBuilder, Map<String, Object> config) {
put(DistributionPackageBuilder.class, distributionPackageBuilder, config);
}
public void unbindDistributionPackageBuilder(DistributionPackageBuilder distributionPackageBuilder, Map<String, Object> config) {
remove(DistributionPackageBuilder.class, distributionPackageBuilder, config);
}
public void bindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) {
put(DistributionTrigger.class, distributionTrigger, config);
}
public void unbindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) {
remove(DistributionTrigger.class, distributionTrigger, config);
}
public void bindDistributionRequestAuthorizationStrategy(DistributionRequestAuthorizationStrategy distributionRequestAuthorizationStrategy, Map<String, Object> config) {
put(DistributionRequestAuthorizationStrategy.class, distributionRequestAuthorizationStrategy, config);
}
public void unbindDistributionRequestAuthorizationStrategy(DistributionRequestAuthorizationStrategy distributionRequestAuthorizationStrategy, Map<String, Object> config) {
remove(DistributionRequestAuthorizationStrategy.class, distributionRequestAuthorizationStrategy, config);
}
// internals
private <ComponentType> void put(Class<ComponentType> typeClass, ComponentType service, Map<String, Object> config) {
Map<String, DistributionComponent<?>> componentMap = getComponentMap(typeClass);
String name = PropertiesUtil.toString(config.get(NAME), null);
DistributionComponentKind kind = DistributionComponentKind.fromClass(typeClass);
if (name != null && kind != null) {
componentMap.put(name, new DistributionComponent<ComponentType>(kind, name, service, config));
}
}
private <ComponentType> void remove(Class<ComponentType> typeClass, ComponentType service, Map<String, Object> config) {
Map<String, DistributionComponent<?>> componentMap = getComponentMap(typeClass);
String name = PropertiesUtil.toString(config.get(NAME), null);
if (name != null) {
componentMap.remove(name);
}
}
}