| /* |
| * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. |
| * 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: |
| * Victor Roldan Betancort - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.internal.cdo.view; |
| |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.view.AbstractCDOViewProvider; |
| import org.eclipse.emf.cdo.view.CDOView; |
| import org.eclipse.emf.cdo.view.CDOViewProvider; |
| import org.eclipse.emf.cdo.view.CDOViewProvider.CDOViewProvider2; |
| import org.eclipse.emf.cdo.view.CDOViewProviderRegistry; |
| import org.eclipse.emf.cdo.view.CDOViewSet; |
| |
| import org.eclipse.emf.internal.cdo.bundle.OM; |
| import org.eclipse.emf.internal.cdo.messages.Messages; |
| import org.eclipse.emf.internal.cdo.session.CDOViewContainerImpl; |
| |
| import org.eclipse.net4j.util.StringUtil; |
| import org.eclipse.net4j.util.WrappedException; |
| import org.eclipse.net4j.util.collection.Pair; |
| import org.eclipse.net4j.util.container.Container; |
| import org.eclipse.net4j.util.om.OMPlatform; |
| |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.spi.cdo.InternalCDOView; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.eclipse.core.runtime.Platform; |
| |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| /** |
| * When instanced in Eclipse, it's populated with contributions from the viewProvider Extension Point. A default |
| * CDOViewProvider implementation is registered, regardless of the execution environment. |
| * |
| * @author Victor Roldan Betancort |
| * @since 2.0 |
| * @see CDOViewProvider |
| */ |
| public class CDOViewProviderRegistryImpl extends Container<CDOViewProvider>implements CDOViewProviderRegistry |
| { |
| public static final CDOViewProviderRegistryImpl INSTANCE = new CDOViewProviderRegistryImpl(); |
| |
| private static final String EXT_POINT = "viewProviders"; //$NON-NLS-1$ |
| |
| private List<CDOViewProvider> viewProviders = new ArrayList<CDOViewProvider>(); |
| |
| public CDOViewProviderRegistryImpl() |
| { |
| addViewProvider(PluginContainerViewProvider.INSTANCE); |
| } |
| |
| public CDOView provideView(URI uri, ResourceSet resourceSet) |
| { |
| if (uri == null) |
| { |
| return null; |
| } |
| |
| CDOViewSet viewSet = CDOUtil.getViewSet(resourceSet); |
| // if (viewSet != null) |
| // { |
| // try |
| // { |
| // String uuid = CDOURIUtil.extractRepositoryUUID(uri); |
| // CDOView view = viewSet.resolveView(uuid); |
| // if (view != null) |
| // { |
| // return view; |
| // } |
| // } |
| // catch (Exception ignore) |
| // { |
| // // Do nothing |
| // } |
| // } |
| |
| for (CDOViewProvider viewProvider : getViewProviders(uri)) |
| { |
| InternalCDOView view = provideView(uri, resourceSet, viewSet, viewProvider); |
| if (view != null) |
| { |
| CDOViewProvider provider = view.getProvider(); |
| if (provider != null) |
| { |
| if (provider != viewProvider) |
| { |
| throw new IllegalStateException("View providers don't match"); |
| } |
| } |
| else |
| { |
| view.setProvider(viewProvider); |
| } |
| |
| return view; |
| } |
| } |
| |
| return null; |
| } |
| |
| private InternalCDOView provideView(URI uri, ResourceSet resourceSet, CDOViewSet viewSet, |
| CDOViewProvider viewProvider) |
| { |
| if (viewSet != null && viewProvider instanceof CDOViewProvider2) |
| { |
| URI viewURI; |
| |
| try |
| { |
| viewURI = ((CDOViewProvider2)viewProvider).getViewURI(uri); |
| } |
| catch (IllegalArgumentException ex) |
| { |
| throw new IllegalArgumentException(ex.getMessage() + ": " + uri, ex); |
| } |
| catch (Error ex) |
| { |
| throw ex; |
| } |
| |
| try |
| { |
| InternalCDOView view = (InternalCDOView)viewSet.resolveView(viewURI); |
| if (view != null) |
| { |
| return view; |
| } |
| } |
| catch (Exception ex) |
| { |
| //$FALL-THROUGH$ |
| } |
| } |
| |
| try |
| { |
| CDOViewContainerImpl.VIEW_PROVIDER.set(viewProvider); |
| |
| InternalCDOView view = (InternalCDOView)viewProvider.getView(uri, resourceSet); |
| if (view != null) |
| { |
| return view; |
| } |
| } |
| finally |
| { |
| CDOViewContainerImpl.VIEW_PROVIDER.remove(); |
| } |
| |
| return null; |
| } |
| |
| @Deprecated |
| public Pair<CDOView, CDOViewProvider> provideViewWithInfo(URI uri, ResourceSet resourceSet) |
| { |
| CDOView view = provideView(uri, resourceSet); |
| if (view != null) |
| { |
| return Pair.create(view, view.getProvider()); |
| } |
| |
| return null; |
| } |
| |
| public CDOViewProvider[] getViewProviders(URI uri) |
| { |
| List<CDOViewProvider> result = new ArrayList<CDOViewProvider>(); |
| |
| synchronized (viewProviders) |
| { |
| for (CDOViewProvider viewProvider : viewProviders) |
| { |
| if (viewProvider.matchesRegex(uri)) |
| { |
| result.add(viewProvider); |
| } |
| } |
| } |
| |
| // Sort highest priority first |
| Collections.sort(result, new Comparator<CDOViewProvider>() |
| { |
| public int compare(CDOViewProvider o1, CDOViewProvider o2) |
| { |
| return -Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); |
| } |
| }); |
| |
| return result.toArray(new CDOViewProvider[result.size()]); |
| } |
| |
| public boolean hasViewProvider(CDOViewProvider viewProvider) |
| { |
| synchronized (viewProviders) |
| { |
| return viewProviders.contains(viewProvider); |
| } |
| } |
| |
| public void addViewProvider(CDOViewProvider viewProvider) |
| { |
| boolean added; |
| synchronized (viewProviders) |
| { |
| added = !viewProviders.contains(viewProvider); |
| if (added) |
| { |
| viewProviders.add(viewProvider); |
| } |
| } |
| |
| if (added) |
| { |
| fireElementAddedEvent(viewProvider); |
| } |
| } |
| |
| public void removeViewProvider(CDOViewProvider viewProvider) |
| { |
| boolean removed; |
| synchronized (viewProviders) |
| { |
| removed = viewProviders.remove(viewProvider); |
| } |
| |
| if (removed) |
| { |
| fireElementRemovedEvent(viewProvider); |
| } |
| } |
| |
| public CDOViewProvider[] getElements() |
| { |
| synchronized (viewProviders) |
| { |
| return viewProviders.toArray(new CDOViewProvider[viewProviders.size()]); |
| } |
| } |
| |
| @Override |
| public boolean isEmpty() |
| { |
| synchronized (viewProviders) |
| { |
| return viewProviders.isEmpty(); |
| } |
| } |
| |
| @Override |
| protected void doActivate() throws Exception |
| { |
| super.doActivate(); |
| if (OMPlatform.INSTANCE.isOSGiRunning()) |
| { |
| try |
| { |
| readExtensions(); |
| } |
| catch (Throwable t) |
| { |
| OM.LOG.error(t); |
| } |
| } |
| } |
| |
| public void readExtensions() |
| { |
| IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| IConfigurationElement[] configurationElements = registry.getConfigurationElementsFor(OM.BUNDLE_ID, EXT_POINT); |
| for (IConfigurationElement element : configurationElements) |
| { |
| try |
| { |
| CDOViewProviderDescriptor descriptor = new CDOViewProviderDescriptor(element); |
| addViewProvider(descriptor); |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static final class CDOViewProviderDescriptor extends AbstractCDOViewProvider |
| { |
| private IConfigurationElement element; |
| |
| public CDOViewProviderDescriptor(IConfigurationElement element) |
| { |
| super(getRegex(element), getPriority(element)); |
| this.element = element; |
| |
| if (StringUtil.isEmpty(element.getAttribute("class"))) //$NON-NLS-1$ |
| { |
| throw new IllegalArgumentException( |
| MessageFormat.format(Messages.getString("CDOViewProviderRegistryImpl.4"), element)); //$NON-NLS-1$ |
| } |
| } |
| |
| public CDOView getView(URI uri, ResourceSet resourceSet) |
| { |
| return getViewProvider().getView(uri, resourceSet); |
| } |
| |
| @Override |
| public URI getResourceURI(CDOView view, String path) |
| { |
| return getViewProvider().getResourceURI(view, path); |
| } |
| |
| @Override |
| public URI getViewURI(URI uri) |
| { |
| CDOViewProvider viewProvider = getViewProvider(); |
| if (viewProvider instanceof CDOViewProvider2) |
| { |
| return ((CDOViewProvider2)viewProvider).getViewURI(uri); |
| } |
| |
| return super.getViewURI(uri); |
| } |
| |
| @Override |
| public String getPath(URI uri) |
| { |
| CDOViewProvider viewProvider = getViewProvider(); |
| if (viewProvider instanceof CDOViewProvider2) |
| { |
| return ((CDOViewProvider2)viewProvider).getPath(uri); |
| } |
| |
| return super.getPath(uri); |
| } |
| |
| private CDOViewProvider getViewProvider() |
| { |
| try |
| { |
| return (CDOViewProvider)element.createExecutableExtension("class"); //$NON-NLS-1$ |
| } |
| catch (CoreException ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| } |
| |
| private static String getRegex(IConfigurationElement element) |
| { |
| String value = element.getAttribute("regex"); |
| if (StringUtil.isEmpty(value)) |
| { |
| throw new IllegalArgumentException( |
| MessageFormat.format(Messages.getString("CDOViewProviderRegistryImpl.6"), element)); //$NON-NLS-1$ |
| } |
| |
| return value; |
| } |
| |
| private static int getPriority(IConfigurationElement element) |
| { |
| try |
| { |
| String value = element.getAttribute("priority"); |
| return Integer.parseInt(value); |
| } |
| catch (Exception ex) |
| { |
| return DEFAULT_PRIORITY; |
| } |
| } |
| } |
| } |