/***************************************************************************** * Copyright (c) 2008 CEA LIST. * * * 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: * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.infra.core.contentoutline; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.papyrus.infra.core.editor.BackboneException; import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor; import org.eclipse.papyrus.infra.core.extension.BadClassNameException; import org.eclipse.papyrus.infra.core.extension.NotFoundException; import org.eclipse.papyrus.infra.core.extension.diagrameditor.EditorDescriptorExtensionFactory; import org.osgi.framework.Bundle; public class ContentOutlineRegistry { /** ID of the editor extension (schema filename) */ public static final String EDITOR_EXTENSION_ID = "papyrusContentOutline"; private static String classAttributeName = "class"; private static String actionBarContributorIdPropertyName = "actionBarContributorId"; /** Namespace where to look for the extension points. */ protected String extensionPointNamespace; /** * The selected content outline. */ protected IPapyrusContentOutlinePage contentOutline; /** * Associated editor. */ private IMultiDiagramEditor multiEditor; /** * Constructor. defaultContext, input and site are explicitly required in * order be sure that they are initialized. The multiEditor should be * initialized. In particular, getEditorSite(), getEditorInput() and * getDefaultContext() should return initialized values. * * @param multiEditor * @param defaultContext * @param input * @param site * @param extensionPointNamespace */ public ContentOutlineRegistry(IMultiDiagramEditor multiEditor, String extensionPointNamespace) { this.multiEditor = multiEditor; this.extensionPointNamespace = extensionPointNamespace; } /** * Returns the single instance of the content outline. Creates one if * necessary. * * @return the contentOutline the single instance of the content outline * @throws BackboneException * exception thrown when the outline can not be created. */ public IPapyrusContentOutlinePage getContentOutline() throws BackboneException { if(contentOutline == null) { createContentOutline(); } return contentOutline; } /** * Return the {@link ContentOutlineDescriptor} with the highest priority. * * @return * @throws BackboneException * @throws NotFoundException * If no ContentOutline can be found in extensions */ private ContentOutlineDescriptor getContentOutlineDescriptor() throws BackboneException { IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID); ContentOutlineDescriptor found = null; // look for the one with the highest priority for(IConfigurationElement ele : configElements) { ContentOutlineDescriptor desc = new ContentOutlineDescriptor(ele); if(desc.isHigher(found)) found = desc; } // Instanciate the object if(found == null) throw new NotFoundException("No ContentOutline registered."); return found; } /** * Creates the content outline from the selected extension. * * @throws BackboneException * exception thrown when the outline can not be created. */ private void createContentOutline() throws BackboneException { ContentOutlineDescriptor found = getContentOutlineDescriptor(); // Instanciate the object if(found != null) { contentOutline = found.createContentOutlinePage(); } } /** * Inner Descriptor for content outline. This class load data from Eclipse * extension mechanism TODO Change the parent class. It is here just to have * quick code. */ protected class ContentOutlineDescriptor extends EditorDescriptorExtensionFactory { private int priority; private String className; private String actionBarContributorID; private IConfigurationElement element; /** * Instance is created when requested. */ protected IPapyrusContentOutlinePage instance = null; /** * Create a descriptor backuped by the config element. */ protected ContentOutlineDescriptor(IConfigurationElement element) throws BackboneException { String tagName = "contentoutline"; checkTagName(element, tagName); this.className = element.getAttribute(classAttributeName); this.actionBarContributorID = element.getAttribute(actionBarContributorIdPropertyName); try { this.priority = Integer.parseInt(element.getAttribute("priority")); } catch (NumberFormatException e) { this.priority = 0; } this.element = element; // check parameters if(className == null) throw new BadClassNameException("Class name must be set", "contentoutline", classAttributeName); } /** * Compare priority. The highest priority win. */ public boolean isHigher(ContentOutlineDescriptor found) { if(found == null) { return true; } return this.getPriority() > found.getPriority(); } /** * Return the higher value of the descriptor. This value is used to * order the contentOutline. The highest priority win. */ private int getPriority() { return priority; } /** * @return the actionBarContributorID */ public String getActionBarContributorID() { return actionBarContributorID; } /** * Returns the content outline page instance (lazy initialization) * * @return the context outline page * @throws BackboneException * exception thrown when a problem occurs. */ protected IPapyrusContentOutlinePage getContentOutline() throws BackboneException { if(instance == null) { instance = createContentOutlinePage(); } return instance; } /** * Create the class corresponding to the class attribute. */ private Class<IPapyrusContentOutlinePage> loadClass() throws BadClassNameException { if(className == null || className.length() == 0) { throw new BadClassNameException("Classname should be set.", "contentoutline", classAttributeName); } Class<IPapyrusContentOutlinePage> factoryClass; try { factoryClass = (Class<IPapyrusContentOutlinePage>)Class.forName(className); } catch (ClassNotFoundException e) { // try another way try { String declaringID = element.getContributor().getName(); Bundle bundle = Platform.getBundle(declaringID); factoryClass = (Class<IPapyrusContentOutlinePage>)bundle.loadClass(className); } catch (ClassNotFoundException e1) { throw new BadClassNameException("", "contentoutline", classAttributeName, e1); } } return factoryClass; } /** * create the outlinepage by calling constructor without parameter and * then call init method * * @return the outline. * @throws BackboneException */ protected IPapyrusContentOutlinePage createContentOutlinePage() throws BackboneException { try { IPapyrusContentOutlinePage outline = loadClass().newInstance(); outline.init(multiEditor); return outline; } catch (SecurityException e) { // Lets propagate. This is an implementation problem that should // be solved by programmer. throw new RuntimeException(e); } catch (InstantiationException e) { // Lets propagate. This is an implementation problem that should // be solved by programmer. // throw new RuntimeException(e); } catch (IllegalAccessException e) { // Lets propagate. This is an implementation problem that should // be solved by programmer. throw new RuntimeException(e); } return null; } } // end class }