]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
58a412ca4b196914d4f6539d4357954c46f5e7dc
[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 org.collectionspace.authentication.CSpaceTenant;
37
38 import org.collectionspace.services.common.ClientType;
39 import org.collectionspace.services.common.ServiceMain;
40 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
41 import org.collectionspace.services.common.document.DocumentHandler;
42 import org.collectionspace.services.common.document.ValidatorHandler;
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.service.ServiceObjectType;
47 import org.collectionspace.services.common.tenant.TenantBindingType;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 /**
52  * AbstractServiceContext
53  *
54  * $LastChangedRevision: $
55  * $LastChangedDate: $
56  */
57 public abstract class AbstractServiceContextImpl<IT, OT>
58         implements ServiceContext<IT, OT> {
59
60     final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
61     Map<String, Object> properties = new HashMap<String, Object>();
62     Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
63     private ServiceBindingType serviceBinding;
64     private TenantBindingType tenantBinding;
65     private String overrideDocumentType = null;
66     private List<ValidatorHandler> valHandlers = null;
67     private DocumentHandler docHandler = null;
68
69     public AbstractServiceContextImpl(String serviceName) throws UnauthorizedException {
70         TenantBindingConfigReaderImpl tReader =
71                 ServiceMain.getInstance().getTenantBindingConfigReader();
72         //FIXME retrieveTenantId is not working consistently in non-auth mode
73         //TODO: get tenant binding from security context
74         String tenantId = retrieveTenantId();
75         if (tenantId == null) {
76             //for testing purposes
77             tenantId = "1"; //hardcoded for movingimages.us
78         }
79         tenantBinding = tReader.getTenantBinding(tenantId);
80         if (tenantBinding == null) {
81             String msg = "No tenant binding found for tenantId=" + tenantId
82                     + " while processing request for service= " + serviceName;
83             logger.error(msg);
84             throw new IllegalStateException(msg);
85         }
86         serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
87         if (serviceBinding == null) {
88             String msg = "No service binding found while processing request for "
89                     + serviceName + " for tenant id=" + getTenantId()
90                     + " name=" + getTenantName();
91             logger.error(msg);
92             throw new IllegalStateException(msg);
93         }
94         if (logger.isDebugEnabled()) {
95             logger.debug("tenantId=" + tenantId
96                     + " service binding=" + serviceBinding.getName());
97         }
98     }
99
100     /**
101      * getCommonPartLabel get common part label
102      * @return
103      */
104     @Override
105     public String getCommonPartLabel() {
106         return getCommonPartLabel(getServiceName());
107     }
108
109     /**
110      * getCommonPartLabel get common part label
111      * @return
112      */
113     public String getCommonPartLabel(String schemaName) {
114         return schemaName.toLowerCase() + PART_LABEL_SEPERATOR + PART_COMMON_LABEL;
115     }
116
117     @Override
118     public Map<String, ObjectPartType> getPartsMetadata() {
119         if (objectPartMap.size() != 0) {
120             return objectPartMap;
121         }
122         ServiceBindingType serviceBinding = getServiceBinding();
123         ServiceObjectType objectType = serviceBinding.getObject();
124         List<ObjectPartType> objectPartTypes = objectType.getPart();
125         for (ObjectPartType objectPartType : objectPartTypes) {
126             objectPartMap.put(objectPartType.getLabel(), objectPartType);
127         }
128         return objectPartMap;
129     }
130
131     @Override
132     public String getQualifiedServiceName() {
133         return TenantBindingConfigReaderImpl.getTenantQualifiedServiceName(getTenantId(), getServiceName());
134     }
135
136     @Override
137     public String getRepositoryClientName() {
138         if (serviceBinding.getRepositoryClient() == null) {
139             return null;
140         }
141         return serviceBinding.getRepositoryClient().trim();
142     }
143
144     @Override
145     public ClientType getRepositoryClientType() {
146         //assumption: there is only one repository client configured
147         return ServiceMain.getInstance().getClientType();
148     }
149
150     @Override
151     public String getRepositoryDomainName() {
152         return tenantBinding.getRepositoryDomain();
153     }
154
155     @Override
156     public String getRepositoryWorkspaceId() {
157         TenantBindingConfigReaderImpl tbConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
158         return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
159     }
160
161     @Override
162     public String getRepositoryWorkspaceName() {
163         //service name is workspace name by convention
164         return serviceBinding.getName();
165     }
166
167     @Override
168     public ServiceBindingType getServiceBinding() {
169         return serviceBinding;
170     }
171
172     @Override
173     public String getServiceName() {
174         return serviceBinding.getName();
175     }
176
177     @Override
178     public String getDocumentType() {
179         // If they have not overridden the setting, use the type of the service
180         // object.
181         return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
182     }
183
184     @Override
185     public void setDocumentType(String docType) {
186         overrideDocumentType = docType;
187     }
188
189     @Override
190     public String getTenantId() {
191         return tenantBinding.getId();
192     }
193
194     @Override
195     public String getTenantName() {
196         return tenantBinding.getName();
197     }
198
199     @Override
200     public abstract IT getInput();
201
202     @Override
203     public abstract void setInput(IT input);
204
205     @Override
206     public abstract OT getOutput();
207
208     @Override
209     public abstract void setOutput(OT output);
210
211     @Override
212     public Map<String, Object> getProperties() {
213         return properties;
214     }
215
216     @Override
217     public void setProperties(Map<String, Object> props) {
218         properties.putAll(props);
219     }
220
221     public Object getProperty(String name) {
222         return properties.get(name);
223     }
224
225     public void setProperty(String name, Object o) {
226         properties.put(name, o);
227     }
228     private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
229
230     private String retrieveTenantId() throws UnauthorizedException {
231
232         String tenantId = null;
233         Subject caller = null;
234         Set<Group> groups = null;
235         try {
236             caller = (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
237             if (caller == null) {
238                 //logger.warn("security not enabled...");
239                 return tenantId;
240             }
241             groups = caller.getPrincipals(Group.class);
242             if (groups != null && groups.size() == 0) {
243                 //TODO: find out why subject is not null
244                 if (logger.isDebugEnabled()) {
245                     logger.debug("no tenant(s) found!");
246                 }
247                 return tenantId;
248             }
249         } catch (PolicyContextException pce) {
250             String msg = "Could not retrieve principal information";
251             logger.error(msg, pce);
252             throw new UnauthorizedException(msg);
253         }
254         for (Group g : groups) {
255             if ("Tenants".equals(g.getName())) {
256                 Enumeration members = g.members();
257                 while (members.hasMoreElements()) {
258                     CSpaceTenant tenant = (CSpaceTenant) members.nextElement();
259                     tenantId = tenant.getId();
260                     if (logger.isDebugEnabled()) {
261                         logger.debug("found tenant id=" + tenant.getId()
262                                 + " name=" + tenant.getName());
263                     }
264                 }
265             }
266         }
267         //TODO: if a user is associated with more than one tenants, the tenant
268         //id should be matched with sent over the wire
269         if (tenantId == null) {
270             String msg = "Could not find tenant context";
271             logger.error(msg);
272             throw new UnauthorizedException(msg);
273         }
274         return tenantId;
275     }
276
277     @Override
278     public DocumentHandler getDocumentHandler() throws Exception {
279         if (docHandler != null) {
280             return docHandler;
281         }
282         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
283         Class c = tccl.loadClass(getDocumentHandlerClass());
284         if (DocumentHandler.class.isAssignableFrom(c)) {
285             docHandler = (DocumentHandler) c.newInstance();
286         } else {
287             throw new IllegalArgumentException("Not of type " +
288                     DocumentHandler.class.getCanonicalName());
289         }
290         docHandler.setServiceContext(this);
291         return docHandler;
292     }
293
294     private String getDocumentHandlerClass() {
295         if (serviceBinding.getDocumentHandler() == null
296                 || serviceBinding.getDocumentHandler().isEmpty()) {
297             String msg = "Missing documentHandler in service binding for "
298                     + getServiceName() + " for tenant id=" + getTenantId()
299                     + " name=" + getTenantName();
300             logger.error(msg);
301             throw new IllegalStateException(msg);
302         }
303         return serviceBinding.getDocumentHandler().trim();
304     }
305
306     @Override
307     public List<ValidatorHandler> getValidatorHandlers() throws Exception {
308         if (valHandlers != null) {
309             return valHandlers;
310         }
311         List<String> handlerClazzes = getServiceBinding().getValidatorHandler();
312         List<ValidatorHandler> handlers = new ArrayList<ValidatorHandler>(handlerClazzes.size());
313         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
314         for (String clazz : handlerClazzes) {
315             clazz = clazz.trim();
316             Class c = tccl.loadClass(clazz);
317             if (ValidatorHandler.class.isAssignableFrom(c)) {
318                 handlers.add((ValidatorHandler) c.newInstance());
319             }
320         }
321         valHandlers = handlers;
322         return valHandlers;
323     }
324
325     @Override
326     public String toString() {
327         StringBuilder msg = new StringBuilder();
328         msg.append("AbstractServiceContext [");
329         msg.append("service name=" + serviceBinding.getName() + " ");
330         msg.append("service version=" + serviceBinding.getVersion() + " ");
331         msg.append("tenant id=" + tenantBinding.getId() + " ");
332         msg.append("tenant name=" + tenantBinding.getName() + " ");
333         msg.append(tenantBinding.getDisplayName() + " ");
334         msg.append("tenant repository domain=" + tenantBinding.getRepositoryDomain());
335         for (Map.Entry<String, Object> entry : properties.entrySet()) {
336             msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
337         }
338         msg.append("]");
339         return msg.toString();
340     }
341 }