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