]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/extension/ContributorBindingExtensionManager.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.browsing.ui.common / src / org / simantics / browsing / ui / common / extension / ContributorBindingExtensionManager.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.common.extension;\r
13 \r
14 import java.util.Arrays;\r
15 import java.util.HashSet;\r
16 import java.util.Set;\r
17 \r
18 import org.eclipse.core.runtime.CoreException;\r
19 import org.eclipse.core.runtime.IConfigurationElement;\r
20 import org.eclipse.core.runtime.IExtension;\r
21 import org.eclipse.core.runtime.IExtensionPoint;\r
22 import org.eclipse.core.runtime.Platform;\r
23 import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;\r
24 import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;\r
25 import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;\r
26 import org.eclipse.core.runtime.dynamichelpers.IFilter;\r
27 import org.simantics.browsing.ui.common.Activator;\r
28 import org.simantics.browsing.ui.common.extension.internal.ContributorBindingExtension;\r
29 import org.simantics.browsing.ui.common.extension.internal.ContributorImplementationBinding;\r
30 import org.simantics.browsing.ui.common.extension.internal.ContributorReferenceBinding;\r
31 import org.simantics.browsing.ui.content.Contributor;\r
32 import org.simantics.browsing.ui.content.ContributorBinding;\r
33 import org.simantics.scl.reflection.OntologyVersions;\r
34 import org.simantics.utils.strings.StringUtils;\r
35 \r
36 /**\r
37  * @author Antti Villberg\r
38  */\r
39 public abstract class ContributorBindingExtensionManager<Factory> implements IExtensionChangeHandler {\r
40 \r
41     private final static String                    NAMESPACE  = Activator.PLUGIN_ID;\r
42 \r
43     private ExtensionTracker                       tracker;\r
44 \r
45     private static final OntologyVersions VERSIONS = OntologyVersions.getInstance();\r
46     \r
47     @SuppressWarnings("unchecked")\r
48     private ContributorBindingExtension<Factory>[] extensions = new ContributorBindingExtension[0];\r
49 \r
50     abstract String getExtensionPointName();\r
51 \r
52     ContributorBindingExtensionManager() {\r
53         tracker = new ExtensionTracker();\r
54 \r
55         // Cache defined actions\r
56         IExtensionPoint expt = Platform.getExtensionRegistry().getExtensionPoint(NAMESPACE, getExtensionPointName());\r
57         loadExtensions(expt.getConfigurationElements());\r
58 \r
59         // Start tracking for new and removed extensions\r
60         IFilter filter = ExtensionTracker.createExtensionPointFilter(expt);\r
61         tracker.registerHandler(this, filter);\r
62     }\r
63 \r
64     @SuppressWarnings("unchecked")\r
65     void close() {\r
66         tracker.close();\r
67         tracker = null;\r
68         extensions = new ContributorBindingExtension[0];\r
69     }\r
70 \r
71     public ContributorBindingExtension<Factory>[] getExtensions() {\r
72         return extensions;\r
73     }\r
74 \r
75     abstract ContributorReferenceBinding<Factory> createReferenceBinding(double preference, String browseContext, String factoryId);\r
76 \r
77     @SuppressWarnings("unchecked")\r
78     private void loadExtensions(IConfigurationElement[] elements) {\r
79 \r
80         Set<ContributorBindingExtension<Factory>> newExtensions = new HashSet<ContributorBindingExtension<Factory>>(Arrays.asList(extensions));\r
81 \r
82         for (IConfigurationElement el : elements) {\r
83 \r
84             String browseContext = VERSIONS.currentVersion(StringUtils.safeString(el.getAttribute("browseContext")));\r
85 \r
86             for(IConfigurationElement child : el.getChildren("reference")) {\r
87 \r
88                 double preference = StringUtils.safeDouble(child.getAttribute("preference"));\r
89                 String factoryId = StringUtils.safeString(child.getAttribute("id"));\r
90 //                ContributionBindingExtension<Factory> ext = new ImagerContributionReferenceBinding(preference, browseContext, factoryId);\r
91                 ContributorBindingExtension<Factory> ext = createReferenceBinding(preference, browseContext, factoryId);\r
92 \r
93                 // Start tracking the new extension object, its removal will be notified of\r
94                 // with removeExtension(extension, Object[]).\r
95                 tracker.registerObject(el.getDeclaringExtension(), ext, IExtensionTracker.REF_STRONG);\r
96 \r
97                 newExtensions.add(ext);\r
98 \r
99             }\r
100 \r
101             for(IConfigurationElement child : el.getChildren("implementation")) {\r
102 \r
103                 double preference = StringUtils.safeDouble(child.getAttribute("preference"));\r
104 \r
105                 try {\r
106 \r
107                     Contributor<Factory> factory = (Contributor<Factory>) child.createExecutableExtension("class");\r
108                     ContributorBindingExtension<Factory> ext = new ContributorImplementationBinding<Factory>(preference, browseContext, factory);\r
109 \r
110                     // Start tracking the new extension object, its removal will be notified of\r
111                     // with removeExtension(extension, Object[]).\r
112                     tracker.registerObject(el.getDeclaringExtension(), ext, IExtensionTracker.REF_STRONG);\r
113 \r
114                     newExtensions.add(ext);\r
115 \r
116                 } catch (CoreException e) {\r
117 \r
118                     System.out.println(" == Could not load ViewpointContributionFactory '" + child.getAttribute("class") + "' due to the following error: " + e.getMessage()  );\r
119                         \r
120                 }\r
121 \r
122             }\r
123 \r
124         }\r
125 \r
126         // Atomic assignment\r
127         this.extensions = newExtensions.toArray(new ContributorBindingExtension[newExtensions.size()]);\r
128     }\r
129 \r
130     @Override\r
131     public void addExtension(IExtensionTracker tracker, IExtension extension) {\r
132         loadExtensions(extension.getConfigurationElements());\r
133     }\r
134 \r
135     @SuppressWarnings("unchecked")\r
136     @Override\r
137     public void removeExtension(IExtension extension, Object[] objects) {\r
138         Set<ContributorBindingExtension<Factory>> newExtensions = new HashSet<ContributorBindingExtension<Factory>>(Arrays.asList(extensions));\r
139 \r
140         for (Object o : objects) {\r
141             tracker.unregisterObject(extension, o);\r
142             newExtensions.remove(o);\r
143         }\r
144 \r
145         // Atomic assignment\r
146         this.extensions = newExtensions.toArray(new ContributorBindingExtension[newExtensions.size()]);\r
147     }\r
148 \r
149     public Set<ContributorBinding<Factory>> getBoundContributions(Set<String> browseContexts) {\r
150 \r
151         HashSet<ContributorBinding<Factory>> result = new HashSet<ContributorBinding<Factory>>();\r
152 \r
153         for(ContributorBindingExtension<Factory> binding : getExtensions()) {\r
154             if(browseContexts.contains(binding.getBrowseContext())) {\r
155                 Contributor<Factory> factory = binding.getFactory();\r
156                 if(factory != null) {\r
157 //                    System.out.println("----------- Plugin contribution " + binding.getFactory() + " " + binding.getPreference());\r
158                     result.add(new ContributorBindingImpl<Factory>(binding.getPreference(), factory));\r
159                 } else {\r
160 //                    System.out.println("FAILED: ----------- No factory for " + binding);\r
161                 }\r
162 \r
163             }\r
164         }\r
165 \r
166         return result;\r
167 \r
168     }\r
169 \r
170 }\r