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