blob: 92c3dc56d37e8784b61f984bf8006509b3db2956 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.cm;
import java.util.*;
import org.osgi.framework.*;
public class TargetMap {
private final Map<ServiceReference<?>, List<List<String>>> targetToQualifiedPids = new HashMap<>();
private final Map<String, Collection<ServiceReference<?>>> qualifiedPidToTargets = new HashMap<>();
public List<List<String>> add(ServiceReference<?> ref) {
List<String> specifiedPids = getPids(ref.getProperty(Constants.SERVICE_PID));
if (specifiedPids.isEmpty())
return Collections.EMPTY_LIST;
Bundle b = ref.getBundle();
String bsn = b.getSymbolicName();
if (bsn == null) {
bsn = ""; //$NON-NLS-1$
}
Version v = b.getVersion();
String version = v == null ? "" : v.toString(); //$NON-NLS-1$
String location = ConfigurationAdminImpl.getLocation(b);
List<List<String>> result = new ArrayList<>(specifiedPids.size());
for (String specifiedPid : specifiedPids) {
getTargetsInternal(specifiedPid).add(ref);
StringBuilder sb = new StringBuilder(specifiedPid);
sb.append('|').append(bsn);
String pidBsn = sb.toString();
getTargetsInternal(pidBsn).add(ref);
sb.append('|').append(version);
String pidBsnVersion = sb.toString();
getTargetsInternal(pidBsnVersion).add(ref);
sb.append('|').append(location);
String pidBsnVersionLocation = sb.toString();
getTargetsInternal(pidBsnVersionLocation).add(ref);
List<String> qualifiedPIDs = new ArrayList<>(4);
qualifiedPIDs.add(pidBsnVersionLocation);
qualifiedPIDs.add(pidBsnVersion);
qualifiedPIDs.add(pidBsn);
qualifiedPIDs.add(specifiedPid);
result.add(qualifiedPIDs);
}
List<List<String>> unmodifiable = Collections.unmodifiableList(result);
targetToQualifiedPids.put(ref, unmodifiable);
return unmodifiable;
}
public static List<String> getPids(Object pid) {
List<String> specifiedPids = Collections.EMPTY_LIST;
if (pid == null)
return specifiedPids;
if (pid instanceof String) {
specifiedPids = Collections.singletonList((String) pid);
} else if (pid instanceof Collection) {
@SuppressWarnings("unchecked")
Collection<String> pidList = (Collection<String>) pid;
specifiedPids = new ArrayList<>(pidList);
} else if (pid.getClass().isArray()) {
specifiedPids = new ArrayList<>(Arrays.asList((String[]) pid));
}
return specifiedPids;
}
public void remove(ServiceReference<?> ref) {
List<List<String>> qualifiedPidLists = targetToQualifiedPids.remove(ref);
if (qualifiedPidLists != null) {
for (List<String> qualifiedPids : qualifiedPidLists) {
for (String qualifiedPid : qualifiedPids) {
Collection<ServiceReference<?>> targets = qualifiedPidToTargets.get(qualifiedPid);
if (targets != null) {
targets.remove(ref);
}
}
}
}
}
private Collection<ServiceReference<?>> getTargetsInternal(String pid) {
Collection<ServiceReference<?>> targets = qualifiedPidToTargets.get(pid);
if (targets == null) {
targets = new ArrayList<>(1);
qualifiedPidToTargets.put(pid, targets);
}
return targets;
}
List<ServiceReference<?>> getTargets(String qualifiedPid) {
Collection<ServiceReference<?>> targets = qualifiedPidToTargets.get(qualifiedPid);
return targets == null ? Collections.EMPTY_LIST : new ArrayList<>(targets);
}
List<List<String>> getQualifiedPids(ServiceReference<?> ref) {
List<List<String>> pids = targetToQualifiedPids.get(ref);
return pids == null ? Collections.EMPTY_LIST : pids;
}
}