| /****************************************************************************** |
| * Copyright (c) 2008 Oracle |
| * 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 - initial implementation and ongoing maintenance |
| ******************************************************************************/ |
| |
| package org.eclipse.jst.common.project.facet.core.libprov.internal; |
| |
| import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID; |
| import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.createErrorStatus; |
| import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log; |
| import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findOptionalElement; |
| import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredAttribute; |
| import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredElement; |
| import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getElementValue; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| 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.common.project.facet.core.libprov.ILibraryProvider; |
| import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderActionType; |
| import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework; |
| import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework; |
| import org.eclipse.wst.common.project.facet.core.IFacetedProject; |
| import org.eclipse.wst.common.project.facet.core.IProjectFacet; |
| import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; |
| import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager; |
| import org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.InvalidExtensionException; |
| import org.osgi.service.prefs.BackingStoreException; |
| import org.osgi.service.prefs.Preferences; |
| |
| /** |
| * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> |
| */ |
| |
| public final class LibraryProviderFrameworkImpl |
| { |
| private static final String UNKNOWN_LIBRARY_PROVIDER = "unknown-library-provider"; //$NON-NLS-1$ |
| |
| private static final String EXTENSION_POINT_ID = "libraryProviders"; //$NON-NLS-1$ |
| |
| private static final String EL_ACTION = "action"; //$NON-NLS-1$ |
| private static final String EL_CONFIG = "config"; //$NON-NLS-1$ |
| private static final String EL_ENABLEMENT = "enablement"; //$NON-NLS-1$ |
| private static final String EL_LABEL = "label"; //$NON-NLS-1$ |
| private static final String EL_OPERATION = "operation"; //$NON-NLS-1$ |
| private static final String EL_PARAM = "param"; //$NON-NLS-1$ |
| private static final String EL_PRIORITY = "priority"; //$NON-NLS-1$ |
| private static final String EL_PROVIDER = "provider"; //$NON-NLS-1$ |
| private static final String ATTR_ABSTRACT = "abstract"; //$NON-NLS-1$ |
| private static final String ATTR_CLASS = "class"; //$NON-NLS-1$ |
| private static final String ATTR_EXTENDS = "extends"; //$NON-NLS-1$ |
| private static final String ATTR_HIDDEN = "hidden"; //$NON-NLS-1$ |
| private static final String ATTR_ID = "id"; //$NON-NLS-1$ |
| private static final String ATTR_NAME = "name"; //$NON-NLS-1$ |
| private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ |
| private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ |
| |
| private static final String PREFS_LIBPROV = "libprov"; //$NON-NLS-1$ |
| private static final String PREFS_PROVIDER_ID = "provider-id"; //$NON-NLS-1$ |
| private static final String PREFS_LAST_PROVIDER_USED = PREFS_LIBPROV + "/last-provider-used"; //$NON-NLS-1$ |
| |
| private static LibraryProviderFrameworkImpl instance = null; |
| |
| private final Set<ILibraryProvider> providers; |
| private final Set<ILibraryProvider> providersReadOnly; |
| private final Map<String,ILibraryProvider> providersLookupTable; |
| |
| public LibraryProviderFrameworkImpl() |
| { |
| this.providers = new HashSet<ILibraryProvider>(); |
| this.providersReadOnly = Collections.unmodifiableSet( this.providers ); |
| this.providersLookupTable = new HashMap<String,ILibraryProvider>(); |
| |
| readExtensions(); |
| } |
| |
| public static synchronized LibraryProviderFrameworkImpl get() |
| { |
| if( instance == null ) |
| { |
| instance = new LibraryProviderFrameworkImpl(); |
| } |
| |
| return instance; |
| } |
| |
| public Set<ILibraryProvider> getProviders() |
| { |
| return this.providersReadOnly; |
| } |
| |
| public boolean isProviderDefined( final String id ) |
| { |
| return this.providersLookupTable.containsKey( id ); |
| } |
| |
| public ILibraryProvider getProvider( final String id ) |
| { |
| if( ! isProviderDefined( id ) ) |
| { |
| final String msg = Resources.bind( Resources.libraryProviderNotDefined, id ); |
| throw new IllegalArgumentException( msg ); |
| } |
| |
| return this.providersLookupTable.get( id ); |
| } |
| |
| public ILibraryProvider getCurrentProvider( final IProject project, |
| final IProjectFacet facet ) |
| { |
| final IFacetedProject fproj; |
| |
| try |
| { |
| fproj = ProjectFacetsManager.create( project ); |
| } |
| catch( CoreException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| |
| if( ! fproj.hasProjectFacet( facet ) ) |
| { |
| return null; |
| } |
| |
| String providerId = null; |
| |
| try |
| { |
| Preferences prefs = fproj.getPreferences( facet ); |
| |
| if( prefs.nodeExists( PREFS_LIBPROV ) ) |
| { |
| prefs = prefs.node( PREFS_LIBPROV ); |
| providerId = prefs.get( PREFS_PROVIDER_ID, null ); |
| } |
| } |
| catch( BackingStoreException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| |
| ILibraryProvider provider = null; |
| |
| if( providerId != null ) |
| { |
| if( LibraryProviderFramework.isProviderDefined( providerId ) ) |
| { |
| provider = LibraryProviderFramework.getProvider( providerId ); |
| } |
| else |
| { |
| provider = getProvider( UNKNOWN_LIBRARY_PROVIDER ); |
| } |
| } |
| else |
| { |
| provider = LegacyLibraryProviderDetectorsExtensionPoint.detect( project, facet ); |
| |
| if( provider == null ) |
| { |
| provider = getProvider( UNKNOWN_LIBRARY_PROVIDER ); |
| } |
| } |
| |
| return provider; |
| } |
| |
| public void setCurrentProvider( final IProject project, |
| final IProjectFacet facet, |
| final ILibraryProvider provider ) |
| { |
| final IFacetedProject fproj; |
| |
| try |
| { |
| fproj = ProjectFacetsManager.create( project ); |
| } |
| catch( CoreException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| |
| try |
| { |
| Preferences prefs = fproj.getPreferences( facet ).node( PREFS_LIBPROV ); |
| |
| if( provider == null ) |
| { |
| prefs.removeNode(); |
| } |
| else |
| { |
| prefs.put( PREFS_PROVIDER_ID, provider.getId() ); |
| } |
| |
| prefs.flush(); |
| } |
| catch( BackingStoreException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| } |
| |
| public ILibraryProvider getLastProviderUsed( final IProjectFacetVersion fv ) |
| { |
| try |
| { |
| final IProjectFacet facet = fv.getProjectFacet(); |
| |
| final Preferences prefs |
| = FacetedProjectFramework.getPreferences( facet ).node( PREFS_LAST_PROVIDER_USED ); |
| |
| final String providerId = prefs.get( fv.getVersionString(), null ); |
| |
| if( providerId != null ) |
| { |
| if( isProviderDefined( providerId ) ) |
| { |
| return getProvider( providerId ); |
| } |
| } |
| } |
| catch( BackingStoreException e ) |
| { |
| log( e ); |
| } |
| |
| return null; |
| } |
| |
| public void setLastProviderUsed( final IProjectFacetVersion fv, |
| final ILibraryProvider provider ) |
| { |
| try |
| { |
| final IProjectFacet facet = fv.getProjectFacet(); |
| |
| final Preferences prefs |
| = FacetedProjectFramework.getPreferences( facet ).node( PREFS_LAST_PROVIDER_USED ); |
| |
| prefs.put( fv.getVersionString(), provider.getId() ); |
| |
| prefs.flush(); |
| } |
| catch( BackingStoreException e ) |
| { |
| log( e ); |
| } |
| } |
| |
| public static void reportInvalidActionType( final String type, |
| final String pluginId ) |
| { |
| final String msg = Resources.bind( Resources.invalidActionType, type, pluginId ); |
| log( createErrorStatus( msg ) ); |
| } |
| |
| public static void reportProviderNotDefined( final String providerId, |
| final String pluginId ) |
| { |
| final String msg |
| = Resources.bind( Resources.libraryProviderNotDefinedWithPlugin, providerId, |
| pluginId ); |
| |
| log( createErrorStatus( msg ) ); |
| } |
| |
| private void readExtensions() |
| { |
| final IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| |
| final IExtensionPoint point |
| = registry.getExtensionPoint( PLUGIN_ID, EXTENSION_POINT_ID ); |
| |
| if( point == null ) |
| { |
| throw new IllegalStateException(); |
| } |
| |
| final List<IConfigurationElement> cfgels = new ArrayList<IConfigurationElement>(); |
| |
| for( IExtension extension : point.getExtensions() ) |
| { |
| for( IConfigurationElement element : extension.getConfigurationElements() ) |
| { |
| cfgels.add( element ); |
| } |
| } |
| |
| final Map<LibraryProvider,String> providerToBaseIdMap |
| = new HashMap<LibraryProvider,String>(); |
| |
| for( IConfigurationElement element : cfgels ) |
| { |
| if( ! element.getName().equals( EL_PROVIDER ) ) |
| { |
| continue; |
| } |
| |
| try |
| { |
| final LibraryProvider provider = new LibraryProvider(); |
| provider.setPluginId( element.getContributor().getName() ); |
| |
| provider.setId( findRequiredAttribute( element, ATTR_ID ) ); |
| |
| if( this.providersLookupTable.containsKey( provider.getId() ) ) |
| { |
| final String msg |
| = Resources.bind( Resources.libraryProviderIdAlreadyUsed, |
| provider.getId() ); |
| |
| log( createErrorStatus( msg ) ); |
| |
| throw new InvalidExtensionException(); |
| } |
| |
| final String baseProviderId = element.getAttribute( ATTR_EXTENDS ); |
| |
| if( baseProviderId != null ) |
| { |
| providerToBaseIdMap.put( provider, baseProviderId.trim() ); |
| } |
| |
| final String abstractAttr = element.getAttribute( ATTR_ABSTRACT ); |
| |
| if( abstractAttr != null ) |
| { |
| provider.setIsAbstract( Boolean.valueOf( abstractAttr ) ); |
| } |
| |
| final String hiddenAttr = element.getAttribute( ATTR_HIDDEN ); |
| |
| if( hiddenAttr != null ) |
| { |
| provider.setIsHidden( Boolean.valueOf( hiddenAttr ) ); |
| } |
| |
| for( IConfigurationElement child : element.getChildren() ) |
| { |
| final String childName = child.getName(); |
| |
| if( childName.equals( EL_LABEL ) ) |
| { |
| provider.setLabel( child.getValue().trim() ); |
| } |
| else if( childName.equals( EL_ENABLEMENT ) ) |
| { |
| final Expression expr; |
| |
| try |
| { |
| expr = ExpressionConverter.getDefault().perform( child ); |
| } |
| catch( CoreException e ) |
| { |
| log( e ); |
| throw new InvalidExtensionException(); |
| } |
| |
| provider.setEnablementCondition( expr ); |
| } |
| else if( childName.equals( EL_PRIORITY ) ) |
| { |
| final String priorityString = child.getValue().trim(); |
| final int priority; |
| |
| try |
| { |
| priority = Integer.parseInt( priorityString ); |
| } |
| catch( NumberFormatException e ) |
| { |
| log( e ); |
| throw new InvalidExtensionException(); |
| } |
| |
| provider.setPriority( priority ); |
| } |
| else if( childName.equals( EL_PARAM ) ) |
| { |
| final String name = findRequiredAttribute( child, ATTR_NAME ); |
| |
| String value = child.getAttribute( ATTR_VALUE ); |
| |
| if( value == null ) |
| { |
| value = getElementValue( child, null ); |
| } |
| |
| provider.addParam( name, value ); |
| } |
| else if( childName.equals( EL_ACTION ) ) |
| { |
| final String type = findRequiredAttribute( child, ATTR_TYPE ).toUpperCase(); |
| final LibraryProviderActionType t; |
| |
| try |
| { |
| t = LibraryProviderActionType.valueOf( type ); |
| } |
| catch( IllegalArgumentException e ) |
| { |
| reportInvalidActionType( type, provider.getPluginId() ); |
| throw new InvalidExtensionException(); |
| } |
| |
| final IConfigurationElement elConfig |
| = findOptionalElement( child, EL_CONFIG ); |
| |
| final String configClassName; |
| |
| if( elConfig == null ) |
| { |
| configClassName = LibraryProviderOperationConfig.class.getName(); |
| } |
| else |
| { |
| configClassName = findRequiredAttribute( elConfig, ATTR_CLASS ); |
| } |
| |
| final IConfigurationElement elOperation |
| = findRequiredElement( child, EL_OPERATION ); |
| |
| final String operationClassName |
| = findRequiredAttribute( elOperation, ATTR_CLASS ); |
| |
| provider.addActionDef( t, configClassName, operationClassName ); |
| } |
| } |
| |
| if( provider != null ) |
| { |
| this.providers.add( provider ); |
| this.providersLookupTable.put( provider.getId(), provider ); |
| } |
| } |
| catch( InvalidExtensionException e ) |
| { |
| // Ignore and continue. The problem has already been reported to the user |
| // in the log. |
| } |
| } |
| |
| for( Map.Entry<LibraryProvider,String> entry : providerToBaseIdMap.entrySet() ) |
| { |
| final LibraryProvider provider = entry.getKey(); |
| final String baseProviderId = entry.getValue(); |
| final ILibraryProvider baseProvider = this.providersLookupTable.get( baseProviderId ); |
| |
| if( baseProvider == null ) |
| { |
| reportProviderNotDefined( baseProviderId, provider.getPluginId() ); |
| this.providers.remove( provider ); |
| this.providersLookupTable.remove( provider.getId() ); |
| } |
| else |
| { |
| provider.setBaseProvider( baseProvider ); |
| } |
| } |
| } |
| |
| private static final class Resources |
| |
| extends NLS |
| |
| { |
| public static String libraryProviderNotDefined; |
| public static String libraryProviderNotDefinedWithPlugin; |
| public static String libraryProviderIdAlreadyUsed; |
| public static String invalidActionType; |
| |
| static |
| { |
| initializeMessages( LibraryProviderFrameworkImpl.class.getName(), |
| Resources.class ); |
| } |
| } |
| |
| } |