Merge branch 'release/3.12.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / cdm / api / application / CdmApplicationState.java
1 // $Id$
2 /**
3 * Copyright (C) 2015 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.api.application;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
16 import java.lang.reflect.Type;
17 import java.net.URI;
18 import java.net.URISyntaxException;
19 import java.net.URL;
20 import java.util.Dictionary;
21 import java.util.jar.Attributes;
22 import java.util.jar.JarFile;
23 import java.util.jar.Manifest;
24
25 import org.eclipse.core.runtime.FileLocator;
26 import org.eclipse.core.runtime.Platform;
27 import org.eclipse.osgi.util.ManifestElement;
28 import org.osgi.framework.Bundle;
29 import org.osgi.framework.BundleException;
30 import org.osgi.framework.Constants;
31 import org.springframework.security.core.context.SecurityContext;
32
33 import eu.etaxonomy.cdm.api.cache.CdmServiceCacher;
34 import eu.etaxonomy.cdm.api.service.ICommonService;
35 import eu.etaxonomy.cdm.api.service.IService;
36 import eu.etaxonomy.cdm.api.service.ITestService;
37 import eu.etaxonomy.cdm.io.service.IIOService;
38 import eu.etaxonomy.cdm.model.common.CdmBase;
39 import eu.etaxonomy.taxeditor.service.ICachedCommonService;
40 import eu.etaxonomy.taxeditor.session.DefaultNewEntityListener;
41
42 /**
43 * @author cmathew
44 * @date 17 Jun 2015
45 *
46 */
47 public class CdmApplicationState {
48
49 private static CdmApplicationState cdmApplicationState;
50
51 private ICdmApplicationConfiguration appConfig;
52
53 private ICdmDataChangeService dataChangeService;
54
55 private SecurityContext securityContext;
56
57 private static CdmServiceCacher cdmServiceCacher;
58
59 private static String cdmlibVersion = null;
60 private static String cdmlibLastModified = null;
61
62 public static CdmApplicationState getInstance() {
63 if(cdmApplicationState == null) {
64 cdmApplicationState = new CdmApplicationState();
65 }
66
67 return cdmApplicationState;
68 }
69
70 public void setAppConfig(ICdmApplicationConfiguration appConfig) {
71 this.appConfig = appConfig;
72 if(appConfig instanceof CdmApplicationRemoteController) {
73 CdmBase.setNewEntityListener(new DefaultNewEntityListener());
74 } else {
75 CdmBase.setNewEntityListener(null);
76 }
77 }
78
79 public ICdmApplicationConfiguration getAppConfig() {
80 return appConfig;
81 }
82
83 public static void setCurrentAppConfig(ICdmApplicationConfiguration appConfig) {
84 getInstance().setAppConfig(appConfig);
85 }
86
87 public static ICdmApplicationConfiguration getCurrentAppConfig() {
88 return getInstance().getAppConfig();
89 }
90
91 /**
92 * @return the dataChangeService
93 */
94 public ICdmDataChangeService getDataChangeService() {
95 return dataChangeService;
96 }
97
98 /**
99 * @param dataChangeService the dataChangeService to set
100 */
101 public void setDataChangeService(ICdmDataChangeService dataChangeService) {
102 this.dataChangeService = dataChangeService;
103 }
104
105 public static ICdmDataChangeService getCurrentDataChangeService() {
106 return getInstance().getDataChangeService();
107 }
108
109 public static void setCurrentDataChangeService(ICdmDataChangeService dataChangeService) {
110 getInstance().setDataChangeService(dataChangeService);
111 }
112
113
114
115 /**
116 * @return the securityContext
117 */
118 public SecurityContext getSecurityContext() {
119 return securityContext;
120 }
121
122 /**
123 * @param securityContext the securityContext to set
124 */
125 public void setSecurityContext(SecurityContext securityContext) {
126 this.securityContext = securityContext;
127 }
128
129 /**
130 * @return the securityContext
131 */
132 public static SecurityContext getCurrentSecurityContext() {
133 return getInstance().getSecurityContext();
134 }
135
136 /**
137 * @param securityContext the securityContext to set
138 */
139 public static void setCurrentSecurityContext(SecurityContext securityContext) {
140 getInstance().setSecurityContext(securityContext);
141 }
142
143 public static void dispose() {
144 getInstance().setCurrentDataChangeService(null);
145 getInstance().setAppConfig(null);
146 getInstance().setSecurityContext(null);
147 cdmApplicationState = null;
148 cdmServiceCacher = null;
149 cdmlibVersion = null;
150 cdmlibLastModified = null;
151 }
152
153
154 /**
155 * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
156 * interface. If a matching getter is found the according service implementation is returned by
157 * invoking the getter otherwise the method returns <code>null</code>.
158 *
159 * @param <T>
160 * @param serviceClass
161 * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
162 * @throws CdmApplicationException
163 */
164 public static <T extends IService> T getService(Class<T> serviceClass) throws CdmApplicationException {
165 ICdmApplicationConfiguration configuration = getCurrentAppConfig();
166
167 Method[] methods = ICdmApplicationConfiguration.class.getDeclaredMethods();
168
169 T service = null;
170
171 for (Method method : methods) {
172 Type type = method.getGenericReturnType();
173
174 if (type.equals(serviceClass)) {
175 try {
176 service = (T) method.invoke(configuration, null);
177 break;
178 } catch (IllegalArgumentException iae) {
179 throw new CdmApplicationException(iae);
180 } catch (IllegalAccessException iae) {
181 throw new CdmApplicationException(iae);
182 } catch (InvocationTargetException ite) {
183 throw new CdmApplicationException(ite);
184 }
185 }
186 }
187
188 return service;
189 }
190
191
192 /**
193 * @see #getService(Class)
194 * As ICommonService is not extending IService we need a specific request here
195 */
196 public static ICommonService getCommonService() {
197 ICdmApplicationConfiguration configuration = getCurrentAppConfig();
198
199 return configuration.getCommonService();
200
201 }
202
203 public static IIOService getIOService() {
204 ICdmApplicationConfiguration configuration = getCurrentAppConfig();
205
206 return ((CdmApplicationRemoteController)configuration).getIOService();
207
208 }
209
210
211 public static ITestService getTestService() {
212 ICdmApplicationConfiguration configuration = getCurrentAppConfig();
213
214 return ((CdmApplicationRemoteController)configuration).getTestService();
215
216 }
217
218 public static ICachedCommonService getCachedCommonService() {
219 ICdmApplicationConfiguration configuration = getCurrentAppConfig();
220
221 return ((CdmApplicationRemoteController)configuration).getCachedCommonService();
222
223 }
224
225 public static CdmServiceCacher getCdmServiceCacher() {
226 return cdmServiceCacher;
227 }
228
229 public static void setCdmServiceCacher(CdmServiceCacher cacher) {
230 cdmServiceCacher = cacher;
231 }
232
233 public static void updateCdmlibManifestInfo() {
234 cdmlibVersion = null;
235 cdmlibLastModified = null;
236 String cdmlibPathPrefix = "lib/cdmlib-services-";
237 String jarSuffix = ".jar";
238 Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.cdmlib");
239 Dictionary<String, String> headers = bundle.getHeaders();
240 String bundleClasspath = headers.get(Constants.BUNDLE_CLASSPATH);
241 try {
242 ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, bundleClasspath);
243 for (ManifestElement manifestElement : elements) {
244 String jar = manifestElement.getValue();
245 if(jar.startsWith(cdmlibPathPrefix) && jar.endsWith(jarSuffix)) {
246 URL fileURL = bundle.getEntry(jar);
247 File file = null;
248 try {
249 String urlString = FileLocator.resolve(fileURL).toExternalForm().replace(" ", "%20");
250 file = new File(new URI(urlString));
251 JarFile jarFile = new JarFile(file);
252 Manifest manifest = jarFile.getManifest();
253 Attributes attributes = manifest.getMainAttributes();
254 // from the OSGI spec the LastModified value is " the number of milliseconds
255 // since midnight Jan. 1, 1970 UTC with the condition that a change must
256 // always result in a higher value than the previous last modified time
257 // of any bundle"
258 cdmlibVersion = attributes.getValue("Bundle-Version");
259 cdmlibLastModified = attributes.getValue("Bnd-LastModified");
260
261 jarFile.close();
262 if(cdmlibVersion == null || cdmlibLastModified == null) {
263 throw new IllegalStateException("Invalid cdmlib manifest info");
264 }
265 } catch (URISyntaxException urise) {
266 throw new IllegalStateException(urise);
267 } catch (IOException ioe) {
268 throw new IllegalStateException(ioe);
269 }
270 }
271 }
272 } catch (BundleException e) {
273 throw new IllegalStateException(e);
274 }
275 }
276
277 public static String getCdmlibVersion() {
278 if(cdmlibVersion == null) {
279 updateCdmlibManifestInfo();
280 }
281 return cdmlibVersion;
282 }
283
284 public static String getCdmlibLastModified() {
285 if(cdmlibLastModified == null) {
286 updateCdmlibManifestInfo();
287 }
288 return cdmlibLastModified;
289 }
290 }