]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
b30bf5a0db88b72f511c9a2547cd5996f963f925
[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.security.acl.Group;
27 import java.util.ArrayList;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import javax.security.auth.Subject;
34 import javax.security.jacc.PolicyContext;
35 import javax.security.jacc.PolicyContextException;
36 import javax.ws.rs.core.MultivaluedMap;
37
38 import org.collectionspace.authentication.AuthN;
39 import org.collectionspace.authentication.CSpaceTenant;
40
41 import org.collectionspace.services.common.ClientType;
42 import org.collectionspace.services.common.ServiceMain;
43 import org.collectionspace.services.common.config.PropertyItemUtils;
44 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
45 import org.collectionspace.services.common.document.DocumentHandler;
46 import org.collectionspace.services.common.document.DocumentFilter;
47 import org.collectionspace.services.common.document.ValidatorHandler;
48 import org.collectionspace.services.common.security.UnauthorizedException;
49 import org.collectionspace.services.common.service.ObjectPartType;
50 import org.collectionspace.services.common.service.ServiceBindingType;
51 import org.collectionspace.services.common.service.ServiceObjectType;
52 import org.collectionspace.services.common.tenant.TenantBindingType;
53 import org.collectionspace.services.common.types.PropertyItemType;
54 import org.collectionspace.services.common.types.PropertyType;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 /**
59  * AbstractServiceContext
60  *
61  * $LastChangedRevision: $
62  * $LastChangedDate: $
63  */
64 public abstract class AbstractServiceContextImpl<IT, OT>
65         implements ServiceContext<IT, OT> {
66
67     /** The logger. */
68     final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
69     
70     /** The properties. */
71     Map<String, Object> properties = new HashMap<String, Object>();
72     
73     /** The object part map. */
74     Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
75     
76     /** The service binding. */
77     private ServiceBindingType serviceBinding;
78     
79     /** The tenant binding. */
80     private TenantBindingType tenantBinding;
81     
82     /** The override document type. */
83     private String overrideDocumentType = null;
84     
85     /** The val handlers. */
86     private List<ValidatorHandler> valHandlers = null;
87     
88     /** The doc handler. */
89     private DocumentHandler docHandler = null;
90
91     private AbstractServiceContextImpl() {} // private constructor for singleton pattern
92     
93     // request query params
94     private MultivaluedMap<String, String> queryParams;
95     
96     /**
97      * Instantiates a new abstract service context impl.
98      * 
99      * @param serviceName the service name
100      * 
101      * @throws UnauthorizedException the unauthorized exception
102      */
103     protected AbstractServiceContextImpl(String serviceName) throws UnauthorizedException {
104         TenantBindingConfigReaderImpl tReader =
105                 ServiceMain.getInstance().getTenantBindingConfigReader();
106         //FIXME retrieveTenantId is not working consistently in non-auth mode
107         //TODO: get tenant binding from security context
108         String tenantId = retrieveTenantId();
109         if (tenantId == null) {
110             //for testing purposes
111             tenantId = "1"; //hardcoded for movingimages.us
112         }
113         tenantBinding = tReader.getTenantBinding(tenantId);
114         if (tenantBinding == null) {
115             String msg = "No tenant binding found for tenantId=" + tenantId
116                     + " while processing request for service= " + serviceName;
117             logger.error(msg);
118             throw new IllegalStateException(msg);
119         }
120         serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
121         if (serviceBinding == null) {
122             String msg = "No service binding found while processing request for "
123                     + serviceName + " for tenant id=" + getTenantId()
124                     + " name=" + getTenantName();
125             logger.error(msg);
126             throw new IllegalStateException(msg);
127         }
128         if (logger.isDebugEnabled()) {
129             logger.debug("tenantId=" + tenantId
130                     + " service binding=" + serviceBinding.getName());
131         }
132     }
133
134     /**
135      * getCommonPartLabel get common part label
136      * @return
137      */
138     @Override
139     public String getCommonPartLabel() {
140         return getCommonPartLabel(getServiceName());
141     }
142
143     /**
144      * getCommonPartLabel get common part label
145      * @return
146      */
147     public String getCommonPartLabel(String schemaName) {
148         return schemaName.toLowerCase() + PART_LABEL_SEPERATOR + PART_COMMON_LABEL;
149     }
150
151     /* (non-Javadoc)
152      * @see org.collectionspace.services.common.context.ServiceContext#getPartsMetadata()
153      */
154     @Override
155     public Map<String, ObjectPartType> getPartsMetadata() {
156         if (objectPartMap.size() != 0) {
157             return objectPartMap;
158         }
159         ServiceBindingUtils.getPartsMetadata(getServiceBinding(), objectPartMap);
160         return objectPartMap;
161     }
162
163     /**
164      * Gets the properties for part.
165      * 
166      * @param partLabel the part label
167      * 
168      * @return the properties for part
169      */
170     public List<PropertyItemType> getPropertiesForPart(String partLabel) {
171         Map<String, ObjectPartType> partMap = getPartsMetadata();
172         ObjectPartType part = partMap.get(partLabel);
173         if(part==null) {
174                 throw new RuntimeException("No such part found: "+partLabel);
175         }
176         List<PropertyType> propNodeList = part.getProperties();
177         return propNodeList.isEmpty()?null:propNodeList.get(0).getItem();
178     }
179
180     /**
181      * Gets the property values for part.
182      * 
183      * @param partLabel the part label
184      * @param propName the prop name
185      * 
186      * @return the property values for part
187      */
188     public List<String> getPropertyValuesForPart(String partLabel, String propName) {
189         List<PropertyItemType> allProps = getPropertiesForPart(partLabel);
190         return PropertyItemUtils.getPropertyValuesByName(allProps, propName);
191     }
192
193     /**
194      * Gets the all parts property values.
195      * 
196      * @param propName the prop name
197      * 
198      * @return the all parts property values
199      */
200     public List<String> getAllPartsPropertyValues(String propName) {
201         return ServiceBindingUtils.getAllPartsPropertyValues(getServiceBinding(), propName);
202     }
203     
204     /* (non-Javadoc)
205      * @see org.collectionspace.services.common.context.ServiceContext#getServiceBindingPropertyValue(java.lang.String)
206      */
207     public String getServiceBindingPropertyValue(String propName) {
208         return ServiceBindingUtils.getPropertyValue(getServiceBinding(), propName);
209     }
210     
211     /**
212      * Gets the common part properties.
213      * 
214      * @return the common part properties
215      */
216     public List<PropertyItemType> getCommonPartProperties() {
217         return getPropertiesForPart(getCommonPartLabel());
218     }
219
220     /**
221      * Gets the common part property values.
222      * 
223      * @param propName the prop name
224      * 
225      * @return the common part property values
226      */
227     public List<String> getCommonPartPropertyValues(String propName) {
228         return getPropertyValuesForPart(getCommonPartLabel(), propName);
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     /* (non-Javadoc)
320      * @see org.collectionspace.services.common.context.ServiceContext#getTenantId()
321      */
322     @Override
323     public String getTenantId() {
324         return tenantBinding.getId();
325     }
326
327     /* (non-Javadoc)
328      * @see org.collectionspace.services.common.context.ServiceContext#getTenantName()
329      */
330     @Override
331     public String getTenantName() {
332         return tenantBinding.getName();
333     }
334
335     /* (non-Javadoc)
336      * @see org.collectionspace.services.common.context.ServiceContext#getInput()
337      */
338     @Override
339     public abstract IT getInput();
340
341     /* (non-Javadoc)
342      * @see org.collectionspace.services.common.context.ServiceContext#setInput(java.lang.Object)
343      */
344     @Override
345     public abstract void setInput(IT input);
346
347     /* (non-Javadoc)
348      * @see org.collectionspace.services.common.context.ServiceContext#getOutput()
349      */
350     @Override
351     public abstract OT getOutput();
352
353     /* (non-Javadoc)
354      * @see org.collectionspace.services.common.context.ServiceContext#setOutput(java.lang.Object)
355      */
356     @Override
357     public abstract void setOutput(OT output);
358
359     /* (non-Javadoc)
360      * @see org.collectionspace.services.common.context.ServiceContext#getProperties()
361      */
362     @Override
363     public Map<String, Object> getProperties() {
364         return properties;
365     }
366
367     /* (non-Javadoc)
368      * @see org.collectionspace.services.common.context.ServiceContext#setProperties(java.util.Map)
369      */
370     @Override
371     public void setProperties(Map<String, Object> props) {
372         properties.putAll(props);
373     }
374
375     /* (non-Javadoc)
376      * @see org.collectionspace.services.common.context.ServiceContext#getProperty(java.lang.String)
377      */
378     public Object getProperty(String name) {
379         return properties.get(name);
380     }
381
382     /* (non-Javadoc)
383      * @see org.collectionspace.services.common.context.ServiceContext#setProperty(java.lang.String, java.lang.Object)
384      */
385     public void setProperty(String name, Object o) {
386         properties.put(name, o);
387     }
388
389
390     /**
391      * Retrieve tenant id.
392      * 
393      * @return the string
394      * 
395      * @throws UnauthorizedException the unauthorized exception
396      */
397     private String retrieveTenantId() throws UnauthorizedException {
398
399         String[] tenantIds = AuthN.get().getTenantIds();
400         if (tenantIds.length == 0) {
401             String msg = "Could not find tenant context";
402             logger.error(msg);
403             throw new UnauthorizedException(msg);
404         }
405         //TODO: if a user is associated with more than one tenants, the tenant
406         //id should be matched with the one sent over the wire
407         return tenantIds[0];
408     }
409     
410     /**
411      * Creates the document handler instance.
412      * 
413      * @return the document handler
414      * 
415      * @throws Exception the exception
416      */
417     private DocumentHandler createDocumentHandlerInstance() throws Exception {
418         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
419         Class c = tccl.loadClass(getDocumentHandlerClass());
420         if (DocumentHandler.class.isAssignableFrom(c)) {
421             docHandler = (DocumentHandler) c.newInstance();
422         } else {
423             throw new IllegalArgumentException("Not of type "
424                     + DocumentHandler.class.getCanonicalName());
425         }
426         //
427         // create a default document filter with pagination if the context
428         // was created with query params
429         //
430         docHandler.setServiceContext(this);
431         DocumentFilter docFilter = docHandler.createDocumentFilter();
432         docFilter.setPagination(this.getQueryParams());
433         docHandler.setDocumentFilter(docFilter);
434         
435         return docHandler;      
436     }
437
438     /* (non-Javadoc)
439      * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHandler()
440      */
441     @Override
442     public DocumentHandler getDocumentHandler() throws Exception {
443         DocumentHandler result = docHandler;            
444         // create a new instance if one does not yet exist
445         if (result == null) {
446                 result = createDocumentHandlerInstance();
447         }       
448         return result;
449     }
450         
451     /* (non-Javadoc)
452      * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHanlder(javax.ws.rs.core.MultivaluedMap)
453      */
454     @Override
455     public DocumentHandler getDocumentHandler(MultivaluedMap<String, String> queryParams) throws Exception {
456         DocumentHandler result = getDocumentHandler();
457         DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view
458         documentFilter.setPagination(queryParams);
459         return result;
460     }
461
462     /**
463      * Gets the document handler class.
464      * 
465      * @return the document handler class
466      */
467     private String getDocumentHandlerClass() {
468         if (serviceBinding.getDocumentHandler() == null
469                 || serviceBinding.getDocumentHandler().isEmpty()) {
470             String msg = "Missing documentHandler in service binding for "
471                     + getServiceName() + " for tenant id=" + getTenantId()
472                     + " name=" + getTenantName();
473             logger.error(msg);
474             throw new IllegalStateException(msg);
475         }
476         return serviceBinding.getDocumentHandler().trim();
477     }
478
479     /* (non-Javadoc)
480      * @see org.collectionspace.services.common.context.ServiceContext#getValidatorHandlers()
481      */
482     @Override
483     public List<ValidatorHandler> getValidatorHandlers() throws Exception {
484         if (valHandlers != null) {
485             return valHandlers;
486         }
487         List<String> handlerClazzes = getServiceBinding().getValidatorHandler();
488         List<ValidatorHandler> handlers = new ArrayList<ValidatorHandler>(handlerClazzes.size());
489         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
490         for (String clazz : handlerClazzes) {
491             clazz = clazz.trim();
492             Class c = tccl.loadClass(clazz);
493             if (ValidatorHandler.class.isAssignableFrom(c)) {
494                 handlers.add((ValidatorHandler) c.newInstance());
495             }
496         }
497         valHandlers = handlers;
498         return valHandlers;
499     }
500
501     /* (non-Javadoc)
502      * @see java.lang.Object#toString()
503      */
504     @Override
505     public String toString() {
506         StringBuilder msg = new StringBuilder();
507         msg.append("AbstractServiceContext [");
508         msg.append("service name=" + serviceBinding.getName() + " ");
509         msg.append("service version=" + serviceBinding.getVersion() + " ");
510         msg.append("tenant id=" + tenantBinding.getId() + " ");
511         msg.append("tenant name=" + tenantBinding.getName() + " ");
512         msg.append(tenantBinding.getDisplayName() + " ");
513         msg.append("tenant repository domain=" + tenantBinding.getRepositoryDomain());
514         for (Map.Entry<String, Object> entry : properties.entrySet()) {
515             msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
516         }
517         msg.append("]");
518         return msg.toString();
519     }
520     
521     @Override
522     public MultivaluedMap<String, String> getQueryParams() {
523         return this.queryParams;
524     }
525     
526     @Override
527     public void setQueryParams(MultivaluedMap<String, String> queryParams) {
528         this.queryParams = queryParams;
529     }    
530 }