| /****************************************************************************** |
| * Copyright (c) 2005, 2007 BEA Systems, Inc. |
| * 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: |
| * Konstantin Komissarchik |
| ******************************************************************************/ |
| |
| package org.eclipse.jst.j2ee.internal.archive; |
| |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.findExtensions; |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.findOptionalElement; |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.findRequiredAttribute; |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.findRequiredElement; |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.getTopLevelElements; |
| import static org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.instantiate; |
| import static org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.PLUGIN_ID; |
| import static org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.createErrorStatus; |
| import static org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.log; |
| import static org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.core.expressions.EvaluationContext; |
| import org.eclipse.core.expressions.EvaluationResult; |
| import org.eclipse.core.expressions.Expression; |
| import org.eclipse.core.expressions.ExpressionConverter; |
| import org.eclipse.core.resources.IProject; |
| 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.IExtensionRegistry; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jst.j2ee.archive.IArchiveExportParticipant; |
| import org.eclipse.jst.j2ee.internal.archive.ArchiveExportParticipantsExtensionPoint.PluginUtil.InvalidExtensionException; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.common.project.facet.core.runtime.IRuntime; |
| import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent; |
| import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType; |
| import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentVersion; |
| import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager; |
| import org.osgi.framework.Bundle; |
| |
| /** |
| * Contains the logic for processing the <code>org.eclipse.jst.j2ee.archiveExportParticipants</code> |
| * extension point. |
| * |
| * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a> |
| */ |
| |
| public final class ArchiveExportParticipantsExtensionPoint |
| { |
| public static final String EXTENSION_POINT_ID = "archiveExportParticipants"; //$NON-NLS-1$ |
| |
| private static final String EL_PARTICIPANT = "participant"; //$NON-NLS-1$ |
| private static final String EL_RUNTIME_COMPONENT = "runtime-component"; //$NON-NLS-1$ |
| private static final String EL_FACTORY = "factory"; //$NON-NLS-1$ |
| private static final String EL_ENABLEMENT = "enablement"; //$NON-NLS-1$ |
| private static final String ATTR_ID = "id"; //$NON-NLS-1$ |
| private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ |
| private static final String ATTR_VERSION = "version"; //$NON-NLS-1$ |
| private static final String ATTR_CLASS = "class"; //$NON-NLS-1$ |
| |
| private static List<ParticipantInfo> extensions = null; |
| |
| public static class ParticipantInfo |
| { |
| private String id; |
| private String pluginId = null; |
| private String className = null; |
| private IRuntimeComponentType runtimeComponentType = null; |
| private String runtimeComponentVersionExpr = null; |
| private Expression enablementCondition = null; |
| |
| public String getId() |
| { |
| return this.id; |
| } |
| |
| public IArchiveExportParticipant loadParticipant() |
| { |
| try |
| { |
| return instantiate( this.pluginId, this.className, IArchiveExportParticipant.class ); |
| } |
| catch( CoreException e ) |
| { |
| log( e.getStatus() ); |
| return null; |
| } |
| } |
| } |
| |
| public static List<ParticipantInfo> getExtensions( final IProject project, |
| final IRuntime runtime ) |
| { |
| readExtensions(); |
| |
| final List<ParticipantInfo> result = new ArrayList<ParticipantInfo>(); |
| |
| for( ParticipantInfo partInfo : extensions ) |
| { |
| boolean match = false; |
| |
| for( IRuntimeComponent rc : runtime.getRuntimeComponents() ) |
| { |
| final IRuntimeComponentType rct = rc.getRuntimeComponentType(); |
| |
| if( rct == partInfo.runtimeComponentType ) |
| { |
| final IRuntimeComponentVersion rcv = rc.getRuntimeComponentVersion(); |
| |
| try |
| { |
| if( rct.getVersions( partInfo.runtimeComponentVersionExpr ).contains( rcv ) ) |
| { |
| match = true; |
| break; |
| } |
| } |
| catch( CoreException e ) |
| { |
| logError( -1, e.getMessage(), e ); |
| } |
| } |
| } |
| |
| if( match && partInfo.enablementCondition != null ) |
| { |
| final EvaluationContext evalContext = new EvaluationContext( null, project ); |
| evalContext.setAllowPluginActivation( true ); |
| |
| try |
| { |
| final EvaluationResult evalResult |
| = partInfo.enablementCondition.evaluate( evalContext ); |
| |
| if( evalResult != EvaluationResult.TRUE ) |
| { |
| match = false; |
| } |
| } |
| catch( CoreException e ) |
| { |
| logError( -1, e.getMessage(), e ); |
| } |
| } |
| |
| if( match ) |
| { |
| result.add( partInfo ); |
| } |
| } |
| |
| return Collections.unmodifiableList( result ); |
| } |
| |
| private static synchronized void readExtensions() |
| { |
| if( extensions != null ) |
| { |
| return; |
| } |
| |
| extensions = new ArrayList<ParticipantInfo>(); |
| |
| for( IConfigurationElement element |
| : getTopLevelElements( findExtensions( PLUGIN_ID, EXTENSION_POINT_ID ) ) ) |
| { |
| if( element.getName().equals( EL_PARTICIPANT ) ) |
| { |
| try |
| { |
| readExtension( element ); |
| } |
| catch( InvalidExtensionException e ) |
| { |
| // Continue. The problem has been reported to the user via the log. |
| } |
| } |
| } |
| } |
| |
| private static void readExtension( final IConfigurationElement config ) |
| |
| throws InvalidExtensionException |
| |
| { |
| final ParticipantInfo info = new ParticipantInfo(); |
| |
| info.pluginId = config.getContributor().getName(); |
| info.id = info.pluginId + "." + findRequiredAttribute( config, ATTR_ID ); //$NON-NLS-1$ |
| |
| final IConfigurationElement elFactory = findRequiredElement( config, EL_FACTORY ); |
| info.className = findRequiredAttribute( elFactory, ATTR_CLASS ); |
| |
| final IConfigurationElement elRuntimeComponent |
| = findRequiredElement( config, EL_RUNTIME_COMPONENT ); |
| |
| final String rcTypeString = findRequiredAttribute( elRuntimeComponent, ATTR_TYPE ); |
| |
| if( ! RuntimeManager.isRuntimeComponentTypeDefined( rcTypeString ) ) |
| { |
| // TODO: Log the problem |
| throw new InvalidExtensionException(); |
| } |
| |
| info.runtimeComponentType = RuntimeManager.getRuntimeComponentType( rcTypeString ); |
| info.runtimeComponentVersionExpr = elRuntimeComponent.getAttribute( ATTR_VERSION ); |
| |
| final IConfigurationElement elEnablement = findOptionalElement( config, EL_ENABLEMENT ); |
| |
| try |
| { |
| info.enablementCondition = ExpressionConverter.getDefault().perform( elEnablement ); |
| } |
| catch( CoreException e ) |
| { |
| logError( -1, e.getMessage(), e ); |
| throw new InvalidExtensionException(); |
| } |
| |
| extensions.add( info ); |
| } |
| |
| /** |
| * Utility methods that are helpful for implementing extension points. |
| * |
| * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a> |
| */ |
| |
| public static final class PluginUtil |
| { |
| public static final class InvalidExtensionException |
| |
| extends Exception |
| |
| { |
| private static final long serialVersionUID = 1L; |
| } |
| |
| private PluginUtil() {} |
| |
| public static Collection<IExtension> findExtensions( final String pluginId, |
| final String extensionPointId ) |
| { |
| final IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| final IExtensionPoint point = registry.getExtensionPoint( pluginId, extensionPointId ); |
| |
| if( point == null ) |
| { |
| throw new RuntimeException(); |
| } |
| |
| final List<IExtension> extensions = new ArrayList<IExtension>(); |
| |
| for( IExtension extension : point.getExtensions() ) |
| { |
| extensions.add( extension ); |
| } |
| |
| return extensions; |
| } |
| |
| public static Collection<IConfigurationElement> getTopLevelElements( final Collection<IExtension> extensions ) |
| { |
| final List<IConfigurationElement> elements = new ArrayList<IConfigurationElement>(); |
| |
| for( IExtension extension : extensions ) |
| { |
| for( IConfigurationElement element : extension.getConfigurationElements() ) |
| { |
| elements.add( element ); |
| } |
| } |
| |
| return elements; |
| } |
| |
| public static void reportMissingAttribute( final IConfigurationElement el, |
| final String attribute ) |
| { |
| final String pluginId = el.getContributor().getName(); |
| final String extPointId = el.getDeclaringExtension().getExtensionPointUniqueIdentifier(); |
| |
| final String msg |
| = Resources.bind( Resources.missingAttribute, pluginId, extPointId, el.getName(), |
| attribute ); |
| |
| log( createErrorStatus( -1, msg, null ) ); |
| } |
| |
| public static void reportMissingElement( final IConfigurationElement el, |
| final String element ) |
| { |
| final String pluginId = el.getContributor().getName(); |
| final String extPointId = el.getDeclaringExtension().getExtensionPointUniqueIdentifier(); |
| |
| final String msg |
| = Resources.bind( Resources.missingElement, pluginId, extPointId, el.getName(), |
| element ); |
| |
| log( createErrorStatus( -1, msg, null ) ); |
| } |
| |
| public static String findRequiredAttribute( final IConfigurationElement el, |
| final String attribute ) |
| |
| throws InvalidExtensionException |
| |
| { |
| final String val = el.getAttribute( attribute ); |
| |
| if( val == null ) |
| { |
| reportMissingAttribute( el, attribute ); |
| throw new InvalidExtensionException(); |
| } |
| |
| return val; |
| } |
| |
| public static IConfigurationElement findRequiredElement( final IConfigurationElement el, |
| final String childElement ) |
| |
| throws InvalidExtensionException |
| |
| { |
| final IConfigurationElement[] children = el.getChildren( childElement ); |
| |
| if( children.length == 0 ) |
| { |
| reportMissingElement( el, childElement ); |
| throw new InvalidExtensionException(); |
| } |
| |
| return children[ 0 ]; |
| } |
| |
| public static IConfigurationElement findOptionalElement( final IConfigurationElement el, |
| final String childElement ) |
| { |
| final IConfigurationElement[] children = el.getChildren( childElement ); |
| |
| if( children.length == 0 ) |
| { |
| return null; |
| } |
| return children[ 0 ]; |
| } |
| |
| public static String getElementValue( final IConfigurationElement el, |
| final String defaultValue ) |
| { |
| if( el != null ) |
| { |
| String text = el.getValue(); |
| |
| if( text != null ) |
| { |
| text = text.trim(); |
| |
| if( text.length() > 0 ) |
| { |
| return text; |
| } |
| } |
| } |
| |
| return defaultValue; |
| } |
| |
| @SuppressWarnings( "unchecked" ) |
| public static <T> T instantiate( final String pluginId, |
| final String clname, |
| final Class<T> interfc ) |
| |
| throws CoreException |
| |
| { |
| final Bundle bundle = Platform.getBundle( pluginId ); |
| |
| final Object obj; |
| |
| try |
| { |
| final Class cl = bundle.loadClass( clname ); |
| obj = cl.newInstance(); |
| } |
| catch( Exception e ) |
| { |
| final String msg = NLS.bind( Resources.failedToCreate, clname ); |
| throw new CoreException( createErrorStatus( -1, msg, e ) ); |
| } |
| |
| if( ! interfc.isAssignableFrom( obj.getClass() ) ) |
| { |
| final String msg |
| = NLS.bind( Resources.doesNotImplement, clname, interfc.getClass().getName() ); |
| |
| throw new CoreException( createErrorStatus( -1, msg, null ) ); |
| } |
| |
| return (T) obj; |
| } |
| |
| private static final class Resources |
| |
| extends NLS |
| |
| { |
| public static String missingAttribute; |
| public static String missingElement; |
| public static String failedToCreate; |
| public static String doesNotImplement; |
| |
| static |
| { |
| initializeMessages( PluginUtil.class.getName(), Resources.class ); |
| } |
| |
| public static String bind( final String message, |
| final String arg1, |
| final String arg2, |
| final String arg3, |
| final String arg4 ) |
| { |
| return bind( message, new Object[] { arg1, arg2, arg3, arg4 } ); |
| } |
| } |
| |
| } |
| |
| } |