/***************************************************************************** * Copyright (c) 2010 Atos Origin. * * * 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: * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.infra.services.resourceloading.impl; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.MissingResourceException; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.CommonPlugin; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.papyrus.infra.core.Activator; import org.eclipse.papyrus.infra.core.resource.ModelSet; import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel; import org.eclipse.papyrus.infra.services.resourceloading.HistoryRoutingManager; import org.eclipse.papyrus.infra.services.resourceloading.ILoadingStrategy; import org.eclipse.papyrus.infra.services.resourceloading.ILoadingStrategyExtension; import org.eclipse.papyrus.infra.services.resourceloading.IProxyManager; import org.eclipse.papyrus.infra.services.resourceloading.IStrategyChooser; /** * The Class ProxyManager that manages the proxy resolving according to a specific strategy. */ public class ProxyManager implements IProxyManager { // === Manage strategies /** extension point ID for loading strategy */ private static final String LOADING_STRATEGY_EXTENSION_POINT_ID = "org.eclipse.papyrus.infra.services.resourceloading.loadingStrategy"; /** element ID for the loading strategy element */ private static final String LOADING_STRATEGY_ELEMENT_ID = "loadingStrategy"; /** attribute ID for identification of the strategy */ private static final String LOADING_STRATEGY_ID = "id"; /** attribute ID for the description of the strategy */ private static final String LOADING_STRATEGY_DESCRIPTION_ID = "description"; /** attribute ID for the implementation of the strategy */ private static final String STRATEGY_ID = "strategy"; // ==== Manage strategy extensions (for UML profile) /** extension point ID for strategy extensions */ private static final String STRATEGY_EXTENDER_EXTENSION_POINT_ID = "org.eclipse.papyrus.infra.services.resourceloading.loadingStrategyExtender"; /** element ID for the loading strategy extension element */ private static final String STRATEGY_EXTENDER_ELEMENT_ID = "strategyExtender"; /** attribute ID for the implementation of the strategy extension */ private static final String STRATEGY_EXTENSION_ID = "strategyExtension"; // === Manage strategy chooser extension /** extension point ID for strategy chooser extension */ private static final String STRATEGY_CHOOSER_EXTENSION_POINT_ID = "org.eclipse.papyrus.infra.services.resourceloading.currentStrategyChooser"; /** attribute ID for the implementation of the strategy chooser extension used in preferences */ private static final String STRATEGY_CHOOSER_CHOOSER_ATTRIBUTE = "chooser"; private static IStrategyChooser strategyChooser = getStrategyChooser(); // === /** The strategies id and descriptions for preferences */ private static Map<Integer, String> strategiesAndDescriptions = new HashMap<Integer, String>(); /** custom commands from extensions */ private static Map<Integer, ILoadingStrategy> availableStrategies = getLoadingStrategies(); /** custom commands from strategy extensions */ private static Set<ILoadingStrategyExtension> strategyExtensions = getLoadingStrategyExtensions(); private ModelSet modelSet; private HistoryRoutingManager routeManager = new HistoryRoutingManager(this); public ProxyManager(ModelSet modelSet) { super(); this.modelSet = modelSet; } /* * (non-Javadoc) * * @see org.eclipse.papyrus.infra.services.resourceloading.IProxyManager#loadResource(URI) */ public boolean loadResource(URI uri) { boolean result = availableStrategies.get(getCurrentStrategy()).loadResource(modelSet, uri); Iterator<ILoadingStrategyExtension> iterator = strategyExtensions.iterator(); while(!result && iterator.hasNext()) { ILoadingStrategyExtension extension = (ILoadingStrategyExtension)iterator.next(); result = extension.loadResource(modelSet, uri.trimFragment()); } return result; } /** * Gets the eobject according to the strategy. * * @param uri * the specified uri to load * @return the resolved eobject or the proxy, depending on the loading strategy * @throws MissingResourceException * the missing resource exception */ public EObject getEObjectFromStrategy(URI uri) throws MissingResourceException { // ask the strategy if the resource of the uri must be loaded URI trimFragment = uri.trimFragment(); boolean loadOnDemand = loadResource(trimFragment); // accept to recover object, either if strategy provides it, or if it has already been loaded anyway Resource resource = modelSet.getResource(trimFragment, loadOnDemand); if(resource != null) { String fragment = uri.fragment(); EObject object = resource.getEObject(fragment); if(object != null) { // object find in the resource return object; } // use HistoryRoutingManager to explore routes in di resource historic else { String fileExtension = uri.fileExtension(); Resource diResource = null; String resourceName = ""; if(SashModel.MODEL_FILE_EXTENSION.equals(fileExtension)) { // proxy is in DI resource diResource = modelSet.getResource(trimFragment, loadOnDemand); resourceName = trimFragment.toString(); } else { // retrieve the DI resource from the uri to get the historic URI newURI = trimFragment.trimFileExtension().appendFileExtension(SashModel.MODEL_FILE_EXTENSION); diResource = modelSet.getResource(newURI.trimFragment(), loadOnDemand); resourceName = newURI.trimFragment().toString(); } if(diResource != null) { // call the HistoryRoutingManager to get the EObject // we assume di/notation are at the same level in folder hierarchy EObject eobject = routeManager.getEObject(modelSet, uri.lastSegment().toString(), fragment); if(eobject == null) { throw new MissingResourceException(CommonPlugin.INSTANCE.getString("_UI_StringResourceNotFound_exception", new Object[]{ resourceName }), getClass().getName(), resourceName); } return eobject; } else { // resource di not found // warn the user, ask him to select the resource throw new MissingResourceException(CommonPlugin.INSTANCE.getString("_UI_StringResourceNotFound_exception", new Object[]{ resourceName }), getClass().getName(), resourceName); } } } else if(loadOnDemand) { // resource not found // warn the user, ask him to select a resource to search in // or ask to search in the entire resource set // or use a proxy // strategy used for the specified resource only throw new MissingResourceException(CommonPlugin.INSTANCE.getString("_UI_StringResourceNotFound_exception", new Object[]{ trimFragment.toString() }), getClass().getName(), trimFragment.toString()); } else { // we just want to manage a proxy for this object return null; } } /** * Gets the current strategy. * * @return the current strategy, strategy 0 (load all resources) is loaded by default if null */ private static int getCurrentStrategy() { if(strategyChooser == null) { return 0; } return strategyChooser.getCurrentStrategy(); } /** * Gets the all strategies. * * @return the all strategies */ public static Map<Integer, String> getAllStrategies() { return strategiesAndDescriptions; } /** * Gets the available strategies from extensions * * @return the strategies */ private static Map<Integer, ILoadingStrategy> getLoadingStrategies() { Map<Integer, ILoadingStrategy> strategies = new HashMap<Integer, ILoadingStrategy>(); IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(LOADING_STRATEGY_EXTENSION_POINT_ID); for(IConfigurationElement element : extensions) { if(LOADING_STRATEGY_ELEMENT_ID.equals(element.getName())) { try { // use description in extension to define preferences from the extensions int id = Integer.valueOf(element.getAttribute(LOADING_STRATEGY_ID)); String description = element.getAttribute(LOADING_STRATEGY_DESCRIPTION_ID); ILoadingStrategy strategy = (ILoadingStrategy)element.createExecutableExtension(STRATEGY_ID); strategies.put(id, strategy); strategiesAndDescriptions.put(id, description); } catch (CoreException e1) { Activator.log.error(e1.getMessage(), e1); e1.printStackTrace(); } catch (NumberFormatException e2) { Activator.log.error(e2.getMessage(), e2); e2.printStackTrace(); } } } return strategies; } /** * Gets the strategy extensions * * @return the strategy extensions */ private static Set<ILoadingStrategyExtension> getLoadingStrategyExtensions() { Set<ILoadingStrategyExtension> strategies = new HashSet<ILoadingStrategyExtension>(); IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(STRATEGY_EXTENDER_EXTENSION_POINT_ID); for(IConfigurationElement element : extensions) { if(STRATEGY_EXTENDER_ELEMENT_ID.equals(element.getName())) { try { ILoadingStrategyExtension strategyExtension = (ILoadingStrategyExtension)element.createExecutableExtension(STRATEGY_EXTENSION_ID); strategies.add(strategyExtension); } catch (CoreException e) { Activator.log.error(e.getMessage(), e); e.printStackTrace(); } } } return strategies; } /** * There is only one Strategy chooser chosen in extension registry. * * @return */ public static IStrategyChooser getStrategyChooser() { IStrategyChooser result = null; IConfigurationElement[] element = Platform.getExtensionRegistry().getConfigurationElementsFor(STRATEGY_CHOOSER_EXTENSION_POINT_ID); if(element.length > 0) { IConfigurationElement e = element[0]; try { result = (IStrategyChooser)e.createExecutableExtension(STRATEGY_CHOOSER_CHOOSER_ATTRIBUTE); } catch (CoreException e1) { Activator.log.error(e1.getMessage(), e1); e1.printStackTrace(); } } return result; } /* * (non-Javadoc) * * @see org.eclipse.papyrus.infra.services.resourceloading.IProxyManager#dispose() */ public void dispose() { routeManager.unload(); } }