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