Copyright (c) 2013 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2013 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.osgi.internal.log; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.osgi.internal.log.ExtendedLogServiceFactory.EquinoxLoggerContext; import org.osgi.framework.Bundle; import org.osgi.framework.Version; import org.osgi.service.log.admin.LoggerContext; public class LoggerContextTargetMap { private final Map<Bundle, ExtendedLogServiceImpl> logServices = new HashMap<>(); private final Map<String, EquinoxLoggerContext> loggerContexts = new HashMap<>(); private final Map<Bundle, List<String>> targetToQualifiedNames = new HashMap<>(); private final Map<String, Collection<Bundle>> qualifiedNameToTargets = new HashMap<>(); List<String> add(Bundle b) { 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 = ExtendedLogServiceFactory.secureAction.getLocation(b); List<String> result = new ArrayList<>(3); StringBuilder sb = new StringBuilder(bsn); getTargetsInternal(bsn).add(b); sb.append('|').append(version); String bsnVersion = sb.toString(); getTargetsInternal(bsnVersion).add(b); sb.append('|').append(location); String bsnVersionLocation = sb.toString(); getTargetsInternal(bsnVersionLocation).add(b); result.add(bsnVersionLocation); result.add(bsnVersion); result.add(bsn); List<String> unmodifiable = Collections.unmodifiableList(result); targetToQualifiedNames.put(b, unmodifiable); return unmodifiable; } void remove(Bundle b) { List<String> qualifiedNames = targetToQualifiedNames.remove(b); if (qualifiedNames != null) { for (String qualifiedName : qualifiedNames) { Collection<Bundle> targets = qualifiedNameToTargets.get(qualifiedName); if (targets != null) { targets.remove(b); if (targets.isEmpty()) { qualifiedNameToTargets.remove(qualifiedName); } } } } logServices.remove(b); } private Collection<Bundle> getTargetsInternal(String pid) { Collection<Bundle> targets = qualifiedNameToTargets.get(pid); if (targets == null) { targets = new ArrayList<>(1); qualifiedNameToTargets.put(pid, targets); } return targets; } ExtendedLogServiceImpl getLogService(Bundle bundle, ExtendedLogServiceFactory factory) { ExtendedLogServiceImpl logService = logServices.get(bundle); if (logService == null) { // add bundle to target maps before constructing add(bundle); logService = new ExtendedLogServiceImpl(factory, bundle); if (bundle != null && bundle.getState() != Bundle.UNINSTALLED) logServices.put(bundle, logService); } return logService; } void replaceSystemBundleLogService(Bundle previousBundle, Bundle currentBundle) { ExtendedLogServiceImpl existing = logServices.get(previousBundle); if (existing != null) { remove(previousBundle); add(currentBundle); logServices.put(currentBundle, existing); existing.applyLogLevels(getEffectiveLoggerContext(currentBundle)); } } void clear() { logServices.clear(); qualifiedNameToTargets.clear(); targetToQualifiedNames.clear(); loggerContexts.clear(); } LoggerContext createLoggerContext(String name, ExtendedLogServiceFactory factory) { EquinoxLoggerContext loggerContext = loggerContexts.get(name); if (loggerContext == null) { loggerContext = factory.createEquinoxLoggerContext(name); loggerContexts.put(name, loggerContext); } return loggerContext; } EquinoxLoggerContext getRootLoggerContext() { return loggerContexts.get(null); } void applyLogLevels(EquinoxLoggerContext loggerContext) { Collection<Bundle> matching; boolean isRoot = loggerContext.getName() == null; if (isRoot) { // root applies to all loggers matching = logServices.keySet(); } else { matching = qualifiedNameToTargets.get(loggerContext.getName()); } if (matching == null) { return; } for (Bundle bundle : matching) { ExtendedLogServiceImpl logService = logServices.get(bundle); if (logService != null) { // Always apply the effective log context. // This may be more costly but it is more simple than checking // if the changed context overrides the existing settings logService.applyLogLevels(getEffectiveLoggerContext(bundle)); } } } EquinoxLoggerContext getEffectiveLoggerContext(Bundle bundle) { List<String> qualifiedNames = targetToQualifiedNames.get(bundle); if (qualifiedNames != null) { for (String qualifiedName : qualifiedNames) { EquinoxLoggerContext loggerContext = loggerContexts.get(qualifiedName); if (loggerContext != null && !loggerContext.isEmpty()) { return loggerContext; } } } return getRootLoggerContext(); } }