]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
54d821bf48b5ceab1ce6178037edaddb41ab7f35
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.common.context;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import javax.ws.rs.core.MultivaluedMap;
31
32 import org.collectionspace.services.common.ClientType;
33 import org.collectionspace.services.common.ServiceMain;
34 import org.collectionspace.services.common.config.PropertyItemUtils;
35 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
36 import org.collectionspace.services.common.document.DocumentHandler;
37 import org.collectionspace.services.common.document.DocumentFilter;
38 import org.collectionspace.services.common.document.ValidatorHandler;
39 import org.collectionspace.services.common.security.SecurityContext;
40 import org.collectionspace.services.common.security.SecurityContextImpl;
41 import org.collectionspace.services.common.security.UnauthorizedException;
42 import org.collectionspace.services.common.service.ObjectPartType;
43 import org.collectionspace.services.common.service.ServiceBindingType;
44 import org.collectionspace.services.common.tenant.TenantBindingType;
45 import org.collectionspace.services.common.types.PropertyItemType;
46 import org.collectionspace.services.common.types.PropertyType;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51  * AbstractServiceContext
52  *
53  * $LastChangedRevision: $
54  * $LastChangedDate: $
55  */
56 /**
57  * @author pschmitz
58  *
59  * @param <IT>
60  * @param <OT>
61  */
62 /**
63  * @author pschmitz
64  *
65  * @param <IT>
66  * @param <OT>
67  */
68 public abstract class AbstractServiceContextImpl<IT, OT>
69         implements ServiceContext<IT, OT> {
70
71     /** The logger. */
72     final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
73     /** The properties. */
74     Map<String, Object> properties = new HashMap<String, Object>();
75     /** The object part map. */
76     Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
77     /** The service binding. */
78     private ServiceBindingType serviceBinding;
79     /** The tenant binding. */
80     private TenantBindingType tenantBinding;
81     /** The override document type. */
82     private String overrideDocumentType = null;
83     /** The val handlers. */
84     private List<ValidatorHandler> valHandlers = null;
85     /** The doc handler. */
86     private DocumentHandler docHandler = null;
87     /** security context */
88     private SecurityContext securityContext;
89
90     /**
91      * Instantiates a new abstract service context impl.
92      */
93     private AbstractServiceContextImpl() {
94         // private constructor for singleton pattern
95     } 
96
97     // request query params
98     /** The query params. */
99     private MultivaluedMap<String, String> queryParams;
100
101     /**
102      * Instantiates a new abstract service context impl.
103      * 
104      * @param serviceName the service name
105      * 
106      * @throws UnauthorizedException the unauthorized exception
107      */
108     protected AbstractServiceContextImpl(String serviceName) throws UnauthorizedException {
109
110         //establish security context
111         securityContext = new SecurityContextImpl();
112         //make sure tenant context exists
113         checkTenantContext();
114
115         //retrieve service bindings
116         TenantBindingConfigReaderImpl tReader =
117                 ServiceMain.getInstance().getTenantBindingConfigReader();
118         String tenantId = securityContext.getCurrentTenantId();
119         tenantBinding = tReader.getTenantBinding(tenantId);
120         if (tenantBinding == null) {
121             String msg = "No tenant binding found for tenantId=" + tenantId
122                     + " while processing request for service= " + serviceName;
123             logger.error(msg);
124             throw new IllegalStateException(msg);
125         }
126         serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
127         if (serviceBinding == null) {
128             String msg = "No service binding found while processing request for "
129                     + serviceName + " for tenant id=" + getTenantId()
130                     + " name=" + getTenantName();
131             logger.error(msg);
132             throw new IllegalStateException(msg);
133         }
134         if (logger.isDebugEnabled()) {
135             logger.debug("tenantId=" + tenantId
136                     + " service binding=" + serviceBinding.getName());
137         }
138     }
139
140     /* (non-Javadoc)
141      * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel()
142      */
143     @Override
144     public String getCommonPartLabel() {
145         return getCommonPartLabel(getServiceName());
146     }
147
148     /* (non-Javadoc)
149      * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel(java.lang.String)
150      */
151     public String getCommonPartLabel(String schemaName) {
152         return schemaName.toLowerCase() + PART_LABEL_SEPERATOR + PART_COMMON_LABEL;
153     }
154
155     /* (non-Javadoc)
156      * @see org.collectionspace.services.common.context.ServiceContext#getPartsMetadata()
157      */
158     @Override
159     public Map<String, ObjectPartType> getPartsMetadata() {
160         if (objectPartMap.size() != 0) {
161             return objectPartMap;
162         }
163         ServiceBindingUtils.getPartsMetadata(getServiceBinding(), objectPartMap);
164         return objectPartMap;
165     }
166
167     /**
168      * Gets the properties for part.
169      * 
170      * @param partLabel the part label
171      * 
172      * @return the properties for part
173      */
174     public List<PropertyItemType> getPropertiesForPart(String partLabel) {
175         Map<String, ObjectPartType> partMap = getPartsMetadata();
176         ObjectPartType part = partMap.get(partLabel);
177         if (part == null) {
178             throw new RuntimeException("No such part found: " + partLabel);
179         }
180         List<PropertyType> propNodeList = part.getProperties();
181         return propNodeList.isEmpty() ? null : propNodeList.get(0).getItem();
182     }
183
184     /**
185      * @param partLabel The name of the scehma part to search in
186      * @param propName The name of the property (or properties) to find
187      * @param qualified Whether the returned values should be qualified with the
188      *          partLabel. This is when the property values are schema field references.
189      * @return List of property values for the matched property on the named schema part.
190      */
191     public List<String> getPropertyValuesForPart(String partLabel, String propName, boolean qualified) {
192         List<PropertyItemType> allProps = getPropertiesForPart(partLabel);
193         return PropertyItemUtils.getPropertyValuesByName(allProps, propName,
194                 (qualified ? (partLabel + ":") : null));
195     }
196
197     /**
198      * @param propName The name of the property (or properties) to find
199      * @param qualified Whether the returned values should be qualified with the
200      *          partLabel. This is when the property values are schema field references.
201      * @return List of property values for the matched property on any schema part.
202      */
203     public List<String> getAllPartsPropertyValues(String propName, boolean qualified) {
204         return ServiceBindingUtils.getAllPartsPropertyValues(getServiceBinding(), propName, qualified);
205     }
206
207     /* (non-Javadoc)
208      * @see org.collectionspace.services.common.context.ServiceContext#getServiceBindingPropertyValue(java.lang.String)
209      */
210     public String getServiceBindingPropertyValue(String propName) {
211         return ServiceBindingUtils.getPropertyValue(getServiceBinding(), propName);
212     }
213
214     /**
215      * Gets the common part properties.
216      * 
217      * @return the common part properties
218      */
219     public List<PropertyItemType> getCommonPartProperties() {
220         return getPropertiesForPart(getCommonPartLabel());
221     }
222
223     /**
224      * @param propName The name of the property (or properties) to find
225      * @param qualified Whether the returned values should be qualified with the
226      *          partLabel. This is when the property values are schema field references.
227      * @return List of property values for the matched property on the common schema part.
228      */
229     public List<String> getCommonPartPropertyValues(String propName, boolean qualified) {
230         return getPropertyValuesForPart(getCommonPartLabel(), propName, qualified);
231     }
232
233     /* (non-Javadoc)
234      * @see org.collectionspace.services.common.context.ServiceContext#getQualifiedServiceName()
235      */
236     @Override
237     public String getQualifiedServiceName() {
238         return TenantBindingConfigReaderImpl.getTenantQualifiedServiceName(getTenantId(), getServiceName());
239     }
240
241     /* (non-Javadoc)
242      * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientName()
243      */
244     @Override
245     public String getRepositoryClientName() {
246         if (serviceBinding.getRepositoryClient() == null) {
247             return null;
248         }
249         return serviceBinding.getRepositoryClient().trim();
250     }
251
252     /* (non-Javadoc)
253      * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientType()
254      */
255     @Override
256     public ClientType getRepositoryClientType() {
257         //assumption: there is only one repository client configured
258         return ServiceMain.getInstance().getClientType();
259     }
260
261     /* (non-Javadoc)
262      * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryDomainName()
263      */
264     @Override
265     public String getRepositoryDomainName() {
266         return tenantBinding.getRepositoryDomain();
267     }
268
269     /* (non-Javadoc)
270      * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceId()
271      */
272     @Override
273     public String getRepositoryWorkspaceId() {
274         TenantBindingConfigReaderImpl tbConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
275         return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
276     }
277
278     /* (non-Javadoc)
279      * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceName()
280      */
281     @Override
282     public String getRepositoryWorkspaceName() {
283         //service name is workspace name by convention
284         return serviceBinding.getName();
285     }
286
287     /* (non-Javadoc)
288      * @see org.collectionspace.services.common.context.ServiceContext#getServiceBinding()
289      */
290     @Override
291     public ServiceBindingType getServiceBinding() {
292         return serviceBinding;
293     }
294
295     /* (non-Javadoc)
296      * @see org.collectionspace.services.common.context.ServiceContext#getServiceName()
297      */
298     @Override
299     public String getServiceName() {
300         return serviceBinding.getName();
301     }
302
303     /* (non-Javadoc)
304      * @see org.collectionspace.services.common.context.ServiceContext#getDocumentType()
305      */
306     @Override
307     public String getDocumentType() {
308         // If they have not overridden the setting, use the type of the service
309         // object.
310         return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
311     }
312
313     /* (non-Javadoc)
314      * @see org.collectionspace.services.common.context.ServiceContext#setDocumentType(java.lang.String)
315      */
316     @Override
317     public void setDocumentType(String docType) {
318         overrideDocumentType = docType;
319     }
320
321     /* (non-Javadoc)
322      * @see org.collectionspace.services.common.context.ServiceContext#getSecurityContext()
323      */
324     @Override
325     public SecurityContext getSecurityContext() {
326         return securityContext;
327     }
328
329     /* (non-Javadoc)
330      * @see org.collectionspace.services.common.context.ServiceContext#getUserId()
331      */
332     @Override
333     public String getUserId() {
334         return securityContext.getUserId();
335     }
336
337     /* (non-Javadoc)
338      * @see org.collectionspace.services.common.context.ServiceContext#getTenantId()
339      */
340     @Override
341     public String getTenantId() {
342         return securityContext.getCurrentTenantId();
343     }
344
345     /* (non-Javadoc)
346      * @see org.collectionspace.services.common.context.ServiceContext#getTenantName()
347      */
348     @Override
349     public String getTenantName() {
350         return securityContext.getCurrentTenantName();
351     }
352
353     /* (non-Javadoc)
354      * @see org.collectionspace.services.common.context.ServiceContext#getInput()
355      */
356     @Override
357     public abstract IT getInput();
358
359     /* (non-Javadoc)
360      * @see org.collectionspace.services.common.context.ServiceContext#setInput(java.lang.Object)
361      */
362     @Override
363     public abstract void setInput(IT input);
364
365     /* (non-Javadoc)
366      * @see org.collectionspace.services.common.context.ServiceContext#getOutput()
367      */
368     @Override
369     public abstract OT getOutput();
370
371     /* (non-Javadoc)
372      * @see org.collectionspace.services.common.context.ServiceContext#setOutput(java.lang.Object)
373      */
374     @Override
375     public abstract void setOutput(OT output);
376
377     /* (non-Javadoc)
378      * @see org.collectionspace.services.common.context.ServiceContext#getProperties()
379      */
380     @Override
381     public Map<String, Object> getProperties() {
382         return properties;
383     }
384
385     /* (non-Javadoc)
386      * @see org.collectionspace.services.common.context.ServiceContext#setProperties(java.util.Map)
387      */
388     @Override
389     public void setProperties(Map<String, Object> props) {
390         properties.putAll(props);
391     }
392
393     /* (non-Javadoc)
394      * @see org.collectionspace.services.common.context.ServiceContext#getProperty(java.lang.String)
395      */
396     public Object getProperty(String name) {
397         return properties.get(name);
398     }
399
400     /* (non-Javadoc)
401      * @see org.collectionspace.services.common.context.ServiceContext#setProperty(java.lang.String, java.lang.Object)
402      */
403     public void setProperty(String name, Object o) {
404         properties.put(name, o);
405     }
406
407     /**
408      * checkTenantContext makss sure tenant context exists
409      *
410      * @return the string
411      *
412      * @throws UnauthorizedException the unauthorized exception
413      */
414     private void checkTenantContext() throws UnauthorizedException {
415
416         String tenantId = securityContext.getCurrentTenantId();
417         if (tenantId == null) {
418             String msg = "Could not find tenant context";
419             logger.error(msg);
420             throw new UnauthorizedException(msg);
421         }
422     }
423
424     /**
425      * Creates the document handler instance.
426      * 
427      * @return the document handler
428      * 
429      * @throws Exception the exception
430      */
431     private DocumentHandler createDocumentHandlerInstance() throws Exception {
432         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
433         Class<?> c = tccl.loadClass(getDocumentHandlerClass());
434         if (DocumentHandler.class.isAssignableFrom(c)) {
435             docHandler = (DocumentHandler) c.newInstance();
436         } else {
437             throw new IllegalArgumentException("Not of type "
438                     + DocumentHandler.class.getCanonicalName());
439         }
440         //
441         // create a default document filter with pagination if the context
442         // was created with query params
443         //
444         docHandler.setServiceContext(this);
445         DocumentFilter docFilter = docHandler.createDocumentFilter();
446         docFilter.setPagination(this.getQueryParams());
447         docHandler.setDocumentFilter(docFilter);
448
449         return docHandler;
450     }
451
452     /* (non-Javadoc)
453      * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHandler()
454      */
455     @Override
456     public DocumentHandler getDocumentHandler() throws Exception {
457         DocumentHandler result = docHandler;
458         // create a new instance if one does not yet exist
459         if (result == null) {
460             result = createDocumentHandlerInstance();
461         }
462         return result;
463     }
464
465     /* (non-Javadoc)
466      * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHanlder(javax.ws.rs.core.MultivaluedMap)
467      */
468     @Override
469     public DocumentHandler getDocumentHandler(MultivaluedMap<String, String> queryParams) throws Exception {
470         DocumentHandler result = getDocumentHandler();
471         DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view
472         documentFilter.setPagination(queryParams);
473         return result;
474     }
475
476     /**
477      * Gets the document handler class.
478      * 
479      * @return the document handler class
480      */
481     private String getDocumentHandlerClass() {
482         if (serviceBinding.getDocumentHandler() == null
483                 || serviceBinding.getDocumentHandler().isEmpty()) {
484             String msg = "Missing documentHandler in service binding for "
485                     + getServiceName() + " for tenant id=" + getTenantId()
486                     + " name=" + getTenantName();
487             logger.error(msg);
488             throw new IllegalStateException(msg);
489         }
490         return serviceBinding.getDocumentHandler().trim();
491     }
492
493     /* (non-Javadoc)
494      * @see org.collectionspace.services.common.context.ServiceContext#getValidatorHandlers()
495      */
496     @Override
497     public List<ValidatorHandler> getValidatorHandlers() throws Exception {
498         if (valHandlers != null) {
499             return valHandlers;
500         }
501         List<String> handlerClazzes = getServiceBinding().getValidatorHandler();
502         List<ValidatorHandler> handlers = new ArrayList<ValidatorHandler>(handlerClazzes.size());
503         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
504         for (String clazz : handlerClazzes) {
505             clazz = clazz.trim();
506             Class<?> c = tccl.loadClass(clazz);
507             if (ValidatorHandler.class.isAssignableFrom(c)) {
508                 handlers.add((ValidatorHandler) c.newInstance());
509             }
510         }
511         valHandlers = handlers;
512         return valHandlers;
513     }
514
515     /* (non-Javadoc)
516      * @see java.lang.Object#toString()
517      */
518     @Override
519     public String toString() {
520         StringBuilder msg = new StringBuilder();
521         msg.append("AbstractServiceContext [");
522         msg.append("service name=" + serviceBinding.getName() + " ");
523         msg.append("service version=" + serviceBinding.getVersion() + " ");
524         msg.append("tenant id=" + tenantBinding.getId() + " ");
525         msg.append("tenant name=" + tenantBinding.getName() + " ");
526         msg.append(tenantBinding.getDisplayName() + " ");
527         msg.append("tenant repository domain=" + tenantBinding.getRepositoryDomain());
528         for (Map.Entry<String, Object> entry : properties.entrySet()) {
529             msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
530         }
531         msg.append("]");
532         return msg.toString();
533     }
534
535     /* (non-Javadoc)
536      * @see org.collectionspace.services.common.context.ServiceContext#getQueryParams()
537      */
538     @Override
539     public MultivaluedMap<String, String> getQueryParams() {
540         return this.queryParams;
541     }
542
543     /* (non-Javadoc)
544      * @see org.collectionspace.services.common.context.ServiceContext#setQueryParams(javax.ws.rs.core.MultivaluedMap)
545      */
546     @Override
547     public void setQueryParams(MultivaluedMap<String, String> theQueryParams) {
548         this.queryParams = theQueryParams;
549     }
550 }