Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 8a96ab44fe01364ea959cebaaca790b633ac1399 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/*****************************************************************************
 * 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."); //$NON-NLS-1$
		}

		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); //$NON-NLS-1$ //$NON-NLS-2$
			}

		}

		/**
		 * 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); //$NON-NLS-1$ //$NON-NLS-2$
			}
			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); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
			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 {
			if(false) {
				System.out.println("Not yet"); // FIXME : no syso
				return null;
			}
			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
}

Back to the top