/******************************************************************************* * Copyright (c) 2008, 2013 Spring IDE Developers * 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: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.aop.core.internal.model.builder; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.springframework.ide.eclipse.aop.core.Activator; import org.springframework.ide.eclipse.aop.core.model.IAspectDefinition; import org.springframework.ide.eclipse.aop.core.model.builder.IAspectDefinitionBuilder; import org.springframework.ide.eclipse.aop.core.model.builder.IDocumentFactory; import org.springframework.ide.eclipse.core.io.ExternalFile; import org.springframework.ide.eclipse.core.java.IProjectClassLoaderSupport; /** * @author Christian Dupuis * @author Martin Lippert * @since 2.3.1 */ @SuppressWarnings("restriction") class AspectDefinitionBuilderHelper { private static final String CLASS_ATTRIBUTE = "class"; private static final String ASPECT_DEFINITION_BUILDER_ELEMENT = "aspectDefinitionBuilder"; private static final String ASPECT_DEFINITION_BUILDER_EXTENSION_POINT = Activator.PLUGIN_ID + ".aspectdefinitionbuilder"; private Set<IAspectDefinitionBuilder> builders = null; private DefaultDocumentFactory documentFactory = null; public AspectDefinitionBuilderHelper() { builders = loadAspectDefinitionBuilder(); documentFactory = new DefaultDocumentFactory(); } private Set<IAspectDefinitionBuilder> loadAspectDefinitionBuilder() { Set<IAspectDefinitionBuilder> builders = new HashSet<IAspectDefinitionBuilder>(); IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint( ASPECT_DEFINITION_BUILDER_EXTENSION_POINT); if (point != null) { for (IExtension extension : point.getExtensions()) { for (IConfigurationElement config : extension.getConfigurationElements()) { if (ASPECT_DEFINITION_BUILDER_ELEMENT.equals(config.getName()) && config.getAttribute(CLASS_ATTRIBUTE) != null) { try { Object handler = config.createExecutableExtension(CLASS_ATTRIBUTE); if (handler instanceof IAspectDefinitionBuilder) { builders.add((IAspectDefinitionBuilder) handler); } } catch (CoreException e) { Activator.log(e); } } } } } return builders; } public List<IAspectDefinition> buildAspectDefinitions(IFile file, IProjectClassLoaderSupport classLoaderSupport) { List<IAspectDefinition> aspectInfos = new ArrayList<IAspectDefinition>(); for (IAspectDefinitionBuilder builder : builders) { builder.buildAspectDefinitions(aspectInfos, file, classLoaderSupport, documentFactory); } return aspectInfos; } private class DefaultDocumentFactory implements IDocumentFactory { private Map<IFile, IDOMModel> cache = new ConcurrentHashMap<IFile, IDOMModel>(); @SuppressWarnings("deprecation") public IDOMDocument createDocument(IFile file) { if (cache.containsKey(file)) { return cache.get(file).getDocument(); } IStructuredModel model = null; try { if (file instanceof ExternalFile) { try { model = StructuredModelManager.getModelManager().getModelForRead(file.getName(), file.getContents(), null); } catch (RuntimeException e) { // WTP throws an exception is this is not an XML document } } else { try { model = StructuredModelManager.getModelManager().getExistingModelForRead(file); } catch (RuntimeException e) { // sometimes WTP throws a NPE in concurrency situations } if (model == null) { model = StructuredModelManager.getModelManager().getModelForRead(file); } } if (model != null) { try { IDOMDocument document = ((IDOMModel) model).getDocument(); if (document != null && document.getDocumentElement() != null) { cache.put(file, (IDOMModel) model); return document; } } catch (RuntimeException e) { if (model != null) { model.releaseFromRead(); } return null; } } } catch (IOException e) { Activator.log(e); } catch (CoreException e) { Activator.log(e); } return null; } protected void releaseModels() { for (IDOMModel document : cache.values()) { try { document.releaseFromRead(); } catch (Exception e) { // ignore } } } } public void close() { documentFactory.releaseModels(); } }