View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.editor;
13  import java.util.ArrayList;
14  import java.util.Collections;
15  import java.util.EnumSet;
16  import java.util.HashMap;
17  import java.util.List;
18  import java.util.Map;
19  import java.util.Set;
20  
21  import org.eclipse.core.runtime.CoreException;
22  import org.eclipse.core.runtime.IConfigurationElement;
23  import org.eclipse.core.runtime.IExtensionPoint;
24  import org.eclipse.core.runtime.IExtensionRegistry;
25  import org.eclipse.core.runtime.IStatus;
26  import org.eclipse.core.runtime.Platform;
27  
28  import sk.baka.ikslibs.ResultEnum;
29  import sk.baka.xml.gene.ExportException;
30  import sk.uniba.euromath.EuroMath;
31  /***
32   * Provides instances of editors and renderers.
33   * @author Martin Vysny
34   */
35  public final class EditInstanceProvider {
36  	/***
37  	 * The instance.
38  	 */
39  	private static EditInstanceProvider INSTANCE = new EditInstanceProvider();
40  	/***
41  	 * Returns the singleton instance.
42  	 * @return the instance of the object.
43  	 */
44  	public static EditInstanceProvider getInstance() {
45  		return INSTANCE;
46  	}
47  	/***
48  	 * Private constructor.
49  	 */
50  	private EditInstanceProvider() {
51  		super();
52  		// register editor and renderer factories using the extension
53  		// points. EuroMath2 itself defines some default factories extending
54  		// its own extension points.
55  		final IExtensionRegistry r = Platform.getExtensionRegistry();
56  		// editor factories
57  		final IExtensionPoint editorFactoryPoint = r
58  				.getExtensionPoint(IEditorFactory.EXTENSION_POINT_ID);
59  		if (editorFactoryPoint == null)
60  			throw new AssertionError();
61  		IConfigurationElement[] elements = editorFactoryPoint
62  				.getConfigurationElements();
63  		for (final IConfigurationElement element : elements) {
64  			try {
65  				final IEditorFactory factory = (IEditorFactory) element
66  						.createExecutableExtension("class"); //$NON-NLS-1$
67  				if (factory != null)
68  					registerEditorFactory(factory);
69  			} catch (CoreException ex) {
70  				EuroMath.log(IStatus.ERROR, 0, "Error loading editor factory", //$NON-NLS-1$
71  						ex);
72  			} catch (ExportException ex) {
73  				EuroMath.log(IStatus.ERROR, 0,
74  						"Error registering editor factory", ex); //$NON-NLS-1$
75  			}
76  		}
77  		// renderer factories
78  		final IExtensionPoint rendererFactoryPoint = r
79  				.getExtensionPoint(IRendererFactory.EXTENSION_POINT_ID);
80  		if (rendererFactoryPoint == null)
81  			throw new AssertionError();
82  		elements = rendererFactoryPoint.getConfigurationElements();
83  		for (final IConfigurationElement element : elements) {
84  			try {
85  				final IRendererFactory factory = (IRendererFactory) element
86  						.createExecutableExtension("class"); //$NON-NLS-1$
87  				if (factory != null)
88  					registerRendererFactory(factory);
89  			} catch (CoreException ex) {
90  				EuroMath.log(IStatus.ERROR, 0,
91  						"Error loading renderer factory", ex); //$NON-NLS-1$
92  			} catch (EditorException ex) {
93  				EuroMath.log(IStatus.ERROR, 0,
94  						"Error registering renderer factory", ex); //$NON-NLS-1$
95  			}
96  		}
97  	}
98  	/***
99  	 * Maps source namespace URI (the namespace of a document that the editor
100 	 * accepts) to information about the editor.
101 	 */
102 	private final Map<String, List<EditorInfo>> editors = new HashMap<String, List<EditorInfo>>();
103 	/***
104 	 * Returns all registered editors that are able to process given namespace.
105 	 * @param namespace source namespace
106 	 * @param resultTypes all kinds of result types in which the document may be
107 	 * offered
108 	 * @return list of exporters or an empty list if no exporters are
109 	 * registered.
110 	 */
111 	public List<EditorInfo> getEditorsForNamespace(final String namespace,
112 			final EnumSet<ResultEnum> resultTypes) {
113 		final List<EditorInfo> allEditors = this.editors.get(namespace);
114 		if (allEditors == null)
115 			return new ArrayList<EditorInfo>();
116 		// verify the editors if they are capable of processing given source
117 		// types
118 		final List<EditorInfo> result = new ArrayList<EditorInfo>(allEditors
119 				.size());
120 		for (EditorInfo info : allEditors) {
121 			if (ResultEnum.getBestResultSourcePair(resultTypes,
122 					info.sourceTypes) != null) {
123 				result.add(info);
124 			}
125 		}
126 		return result;
127 	}
128 	/***
129 	 * Maps source namespace URI (the namespace of a document that the renderer
130 	 * accepts) to information about the renderer.
131 	 */
132 	private final Map<String, List<RendererInfo>> renderers = new HashMap<String, List<RendererInfo>>();
133 	/***
134 	 * Returns all registered renderers that are able to process given
135 	 * namespace.
136 	 * @param namespace source namespace
137 	 * @param resultTypes all kinds of result types in which the document may be
138 	 * offered
139 	 * @return list of renderers or an empty list if no renderers are
140 	 * registered.
141 	 */
142 	public List<RendererInfo> getRenderersForNamespace(final String namespace,
143 			final EnumSet<ResultEnum> resultTypes) {
144 		final List<RendererInfo> allRenderers = this.renderers.get(namespace);
145 		if (allRenderers == null)
146 			return new ArrayList<RendererInfo>();
147 		// verify the renderers if they are capable of processing given source
148 		// types
149 		final List<RendererInfo> result = new ArrayList<RendererInfo>(
150 				allRenderers.size());
151 		for (RendererInfo info : allRenderers) {
152 			if (ResultEnum.getBestResultSourcePair(resultTypes,
153 					info.sourceTypes) != null) {
154 				result.add(info);
155 			}
156 		}
157 		return result;
158 	}
159 	/***
160 	 * Registers the editor factory to the provider. The method must not be
161 	 * called twice for the same factory.
162 	 * @param factory factory to register.
163 	 * @throws ExportException if problem is in factory  
164 	 */
165 	private void registerEditorFactory(final IEditorFactory factory)
166 			throws ExportException {
167 		final Map<String, EditorInfo> allEditors = factory
168 				.getSupportedEditors();
169 		// register all editors
170 		for (final EditorInfo info : allEditors.values()) {
171 			List<EditorInfo> nodes = this.editors.get(info.sourceNamespace);
172 			if (nodes == null) {
173 				nodes = new ArrayList<EditorInfo>();
174 				this.editors.put(info.sourceNamespace, nodes);
175 			}
176 			nodes.add(info);
177 		}
178 	}
179 	/***
180 	 * Registers the renderer factory to the provider. The method must not be
181 	 * called twice for the same factory.
182 	 * @param factory factory to register.
183 	 * @throws EditorException if error happens during factory call.
184 	 */
185 	private void registerRendererFactory(final IRendererFactory factory)
186 			throws EditorException {
187 		final Map<String, RendererInfo> allRenderers = factory
188 				.getSupportedRenderers();
189 		// register all renderers
190 		for (final RendererInfo info : allRenderers.values()) {
191 			List<RendererInfo> nodes = this.renderers.get(info.sourceNamespace);
192 			if (nodes == null) {
193 				nodes = new ArrayList<RendererInfo>();
194                 this.renderers.put(info.sourceNamespace, nodes);
195 			}
196 			nodes.add(info);
197 		}
198 	}
199 	/***
200 	 * Returns set of all namespaces, for which at least one instance of renderer can be constructed.
201 	 * @return unmodifiable set of namespace URIs.
202 	 */
203 	public Set<? extends String> getRenderableNamespaces(){
204 		return Collections.unmodifiableSet(this.renderers.keySet());
205 	}
206 	/***
207 	 * Returns set of all namespaces, for which at least one instance of editor can be constructed.
208 	 * @return unmodifiable set of namespace URIs.
209 	 */
210 	public Set<? extends String> getEditableNamespaces(){
211 		return Collections.unmodifiableSet(this.editors.keySet());
212 	}
213 }