/******************************************************************************* * Copyright (c) 2011 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.core.extension; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.jboss.tools.cdi.core.CDICoreNature; import org.jboss.tools.cdi.core.extension.feature.IAmbiguousBeanResolverFeature; import org.jboss.tools.cdi.core.extension.feature.IBuildParticipantFeature; import org.jboss.tools.cdi.core.extension.feature.ICDIFeature; import org.jboss.tools.cdi.core.extension.feature.IProcessAnnotatedMemberFeature; import org.jboss.tools.cdi.core.extension.feature.IProcessAnnotatedTypeFeature; import org.jboss.tools.cdi.core.extension.feature.IValidatorFeature; /** * * @author Viacheslav Kabanovich * */ public class CDIExtensionManager { CDICoreNature n; /** * Mapping of jar path to CDI extensions declared in it. */ Map<String, Set<String>> runtimes = new HashMap<String, Set<String>>(); Set<String> allRuntimes = new HashSet<String>(); /** * Mapping of extension ids (class names) to instances. */ Map<String, ICDIExtension> instances = new HashMap<String, ICDIExtension>(); /** * Mapping of runtime extension class names to instances. */ Map<String, ICDIExtension> instancesByRuntime = new HashMap<String, ICDIExtension>(); /** * Mapping of feature ids to extension instances. */ Map<Class<?>, Set<ICDIExtension>> featureToExtensions = new HashMap<Class<?>, Set<ICDIExtension>>(); Map<Class<? extends ICDIFeature>, Set<?>> featureStorage = new HashMap<Class<? extends ICDIFeature>, Set<?>>(); public CDIExtensionManager() { } public void setProject(CDICoreNature n) { this.n = n; } public boolean isCDIExtensionAvailable(String runtimeClassName) { return allRuntimes.contains(runtimeClassName); } public void pathRemoved(String path) { Set<String> rs = runtimes.remove(path); if(rs == null) return; for (String runtime: rs) { deleteRuntime(runtime); } } public boolean setRuntimes(String path, Set<String> newRuntimes) { Set<String> oldRuntimes = runtimes.get(path); if(oldRuntimes == null) { if(newRuntimes.isEmpty()) { return false; } oldRuntimes = new HashSet<String>(); } boolean result = false; for (String runtime: oldRuntimes) { if(!newRuntimes.contains(runtime)) { deleteRuntime(runtime); result = true; } } for (String runtime: newRuntimes) { if(!oldRuntimes.contains(runtime)) { addRuntime(runtime); result = true; } } if(newRuntimes.isEmpty()) runtimes.remove(path); else runtimes.put(path, newRuntimes); return result; } private void addRuntime(String runtime) { allRuntimes.add(runtime); CDIExtensionFactory factory = CDIExtensionFactory.getInstance(); Set<String> clss = factory.getExtensionClassesByRuntime(runtime); if(clss != null) { for (String cls: clss) { ICDIExtension ext = factory.createExtensionInstance(cls); if(ext == null) continue; instances.put(cls, ext); instancesByRuntime.put(runtime, ext); for (Class<?> feature: CDIExtensionFactory.getInstance().getFeatures(ext)) { Set<ICDIExtension> es = featureToExtensions.get(feature); if(es == null) { es = new HashSet<ICDIExtension>(); featureToExtensions.put(feature, es); } es.add(ext); } featureStorage.clear(); } } } private void deleteRuntime(String runtime) { allRuntimes.remove(runtime); instancesByRuntime.remove(runtime); Set<String> clss = CDIExtensionFactory.getInstance().getExtensionClassesByRuntime(runtime); if(clss != null) { for (String cls: clss) { ICDIExtension ext = instances.remove(cls); if(ext != null) { Class<?>[] is = featureToExtensions.keySet().toArray(new Class<?>[0]); for (Class<?> feature: is) { Set<ICDIExtension> es = featureToExtensions.get(feature); if(es != null) { es.remove(ext); if(es.isEmpty()) featureToExtensions.remove(feature); } } } } if(!clss.isEmpty()) { featureStorage.clear(); } } } static Set<ICDIExtension> EMPTY = new HashSet<ICDIExtension>(); public Set<ICDIExtension> getExtensions(Class<?> feature) { return featureToExtensions.containsKey(feature) ? featureToExtensions.get(feature) : EMPTY; } public ICDIExtension getExtensionByRuntime(String runtime) { return instancesByRuntime.get(runtime); } public Set<IProcessAnnotatedMemberFeature> getProcessAnnotatedMemberFeatures() { return getFeatures(IProcessAnnotatedMemberFeature.class); } public Set<IProcessAnnotatedTypeFeature> getProcessAnnotatedTypeFeatures() { return getFeatures(IProcessAnnotatedTypeFeature.class); } public Set<IBuildParticipantFeature> getBuildParticipantFeatures() { return getFeatures(IBuildParticipantFeature.class); } public Set<IAmbiguousBeanResolverFeature> getAmbiguousBeanResolverFeatures() { return getFeatures(IAmbiguousBeanResolverFeature.class); } public Set<IValidatorFeature> getValidatorFeatures() { return getFeatures(IValidatorFeature.class); } /** * Returns set of feature implementation objects by feature class. * * @param cls * @return set of feature implementation objects by feature class */ public <F extends ICDIFeature> Set<F> getFeatures(Class<F> cls) { @SuppressWarnings("unchecked") Set<F> result = (Set<F>)featureStorage.get(cls); if(result == null) { result = new HashSet<F>(); Set<ICDIExtension> extensions = getExtensions(cls); if(!extensions.isEmpty()) { for (ICDIExtension ext: extensions) { F feature = CDIExtensionFactory.adaptTo(ext, cls); if(feature != null) { result.add(feature); } } } featureStorage.put(cls, result); } return result; } }