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