]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a1c1ebd7c14231e22f4fc5401293d997d48dd916
[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.lang.reflect.Constructor;
27
28 import javax.ws.rs.core.UriInfo;
29
30 import org.collectionspace.services.common.CollectionSpaceResource;
31 import org.collectionspace.services.common.ResourceMap;
32 import org.collectionspace.services.common.ServiceMain;
33 import org.collectionspace.services.common.config.ConfigUtils;
34 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
35 import org.collectionspace.services.common.document.TransactionException;
36 import org.collectionspace.services.common.security.UnauthorizedException;
37 import org.collectionspace.services.common.storage.StorageClient;
38 import org.collectionspace.services.common.storage.TransactionContext;
39 import org.collectionspace.services.common.storage.jpa.JPATransactionContext;
40 import org.collectionspace.services.config.service.ServiceBindingType;
41 import org.collectionspace.services.config.tenant.TenantBindingType;
42
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * RemoteServiceContextImpl
48  *
49  * $LastChangedRevision: $
50  * $LastChangedDate: $
51  */
52 public class RemoteServiceContextImpl<IT, OT>
53         extends AbstractServiceContextImpl<IT, OT>
54         implements RemoteServiceContext<IT, OT> {
55
56     /** The logger. */
57     final Logger logger = LoggerFactory.getLogger(RemoteServiceContextImpl.class);
58     //input stores original content as received over the wire
59     /** The input. */
60     private IT input;    
61     /** The output. */
62     private OT output;
63     /** The target of the HTTP request **/
64     JaxRsContext jaxRsContext;
65     
66     ResourceMap resourceMap = null;
67     
68     @Override
69     public void setJaxRsContext(JaxRsContext theJaxRsContext) {
70         this.jaxRsContext = theJaxRsContext;
71     }
72     
73     @Override
74     public JaxRsContext getJaxRsContext() {
75         return this.jaxRsContext;
76     }
77
78     /**
79      * Instantiates a new remote service context impl.
80      * 
81      * @param serviceName the service name
82      * 
83      * @throws UnauthorizedException the unauthorized exception
84      */
85     protected RemoteServiceContextImpl(String serviceName, UriInfo uriInfo) throws UnauthorizedException {
86         super(serviceName, uriInfo);
87     }
88
89     /**
90      * Instantiates a new remote service context impl. (This is "package" protected for the Factory class)
91      * 
92      * @param serviceName the service name
93      * 
94      * @throws UnauthorizedException the unauthorized exception
95      */
96     protected RemoteServiceContextImpl(String serviceName, IT theInput, UriInfo uriInfo) throws UnauthorizedException {
97         this(serviceName, uriInfo);
98         this.input = theInput;        
99     }
100
101     /**
102      * Instantiates a new remote service context impl. (This is "package" protected for the Factory class)
103      * 
104      * @param serviceName the service name
105      * @param theInput the the input
106      * @param queryParams the query params
107      * 
108      * @throws UnauthorizedException the unauthorized exception
109      */
110     protected RemoteServiceContextImpl(String serviceName,
111                 IT theInput,
112                 ResourceMap resourceMap,
113                 UriInfo uriInfo) throws UnauthorizedException {
114         this(serviceName, theInput, uriInfo);
115         this.setResourceMap(resourceMap);
116         this.setUriInfo(uriInfo);
117         if (uriInfo != null) {
118                 this.setQueryParams(uriInfo.getQueryParameters());
119         }
120     }
121
122     /*
123      * Returns the name of the service's acting repository.  Gets this from the tenant and service bindings files
124      */
125     @Override
126         public String getRepositoryName() throws Exception {
127         String result = null;
128         
129         TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
130         String tenantId = this.getTenantId();
131         TenantBindingType tenantBindingType = tenantBindingConfigReader.getTenantBinding(tenantId);
132         ServiceBindingType serviceBindingType = this.getServiceBinding();
133         String servicesRepoDomainName = serviceBindingType.getRepositoryDomain();
134         if (servicesRepoDomainName != null && servicesRepoDomainName.trim().isEmpty() == false) {
135                 result = ConfigUtils.getRepositoryName(tenantBindingType, servicesRepoDomainName);
136         } else {
137                 String errMsg = String.format("The '%s' service for tenant ID=%s did not declare a repository domain in its service bindings.", 
138                                 serviceBindingType.getName(), tenantId);
139                 throw new Exception(errMsg);
140         }
141         
142         return result;
143     }
144     
145     /* (non-Javadoc)
146      * @see org.collectionspace.services.common.context.AbstractServiceContextImpl#getInput()
147      */
148     @Override
149     public IT getInput() {
150         return input;
151     }
152
153     /* (non-Javadoc)
154      * @see org.collectionspace.services.common.context.AbstractServiceContextImpl#setInput(java.lang.Object)
155      */
156     @Override
157     public void setInput(IT input) {
158         //for security reasons, do not allow to set input again (from handlers)
159         if (this.input != null) {
160             String msg = "Resetting or changing an context's input is not allowed.";
161             logger.error(msg);
162             throw new IllegalStateException(msg);
163         }
164         this.input = input;
165     }
166
167     /* (non-Javadoc)
168      * @see org.collectionspace.services.common.context.AbstractServiceContextImpl#getOutput()
169      */
170     @Override
171     public OT getOutput() {
172         return output;
173     }
174
175     /* (non-Javadoc)
176      * @see org.collectionspace.services.common.context.AbstractServiceContextImpl#setOutput(java.lang.Object)
177      */
178     @Override
179     public void setOutput(OT output) {
180         this.output = output;
181     }
182
183     /**
184      * Return the JAX-RS resource for the current context.
185      * 
186      * @param ctx
187      * @return
188      * @throws Exception 
189      */
190     public CollectionSpaceResource<IT, OT> getResource(ServiceContext<?, ?> ctx) throws Exception {
191         CollectionSpaceResource<IT, OT> result = null;
192         
193         ResourceMap resourceMap = ctx.getResourceMap();
194         String resourceName = ctx.getClient().getServiceName();
195         result = (CollectionSpaceResource<IT, OT>) resourceMap.get(resourceName);
196         
197         return result;
198     }
199     
200     /**
201      * @return the map of service names to resource classes.
202      */
203     @Override
204     public ResourceMap getResourceMap() {
205         ResourceMap result = resourceMap;
206         
207         if (result == null) {
208                 result = ServiceMain.getInstance().getJaxRSResourceMap();
209         }
210         
211         return result;
212     }
213     
214     /**
215      * @param map the map of service names to resource instances.
216      */
217     @Override
218         public void setResourceMap(ResourceMap map) {
219         this.resourceMap = map;
220     }
221
222  
223     
224     /* (non-Javadoc)
225      * @see org.collectionspace.services.common.context.RemoteServiceContext#getLocalContext(java.lang.String)
226      */
227     @Override
228     public ServiceContext<IT, OT> getLocalContext(String localContextClassName) throws Exception {
229         ClassLoader cloader = Thread.currentThread().getContextClassLoader();
230         Class<?> ctxClass = cloader.loadClass(localContextClassName);
231         if (!ServiceContext.class.isAssignableFrom(ctxClass)) {
232             throw new IllegalArgumentException("getLocalContext requires "
233                     + " implementation of " + ServiceContext.class.getName());
234         }
235
236         Constructor<?> ctor = ctxClass.getConstructor(java.lang.String.class);
237         ServiceContext<IT, OT> ctx = (ServiceContext<IT, OT>) ctor.newInstance(getServiceName());
238         return ctx;
239     }
240
241         @Override
242         public CollectionSpaceResource<IT, OT> getResource() throws Exception {
243                 // TODO Auto-generated method stub
244                 throw new RuntimeException("Unimplemented method.");
245         }
246
247         @Override
248         public CollectionSpaceResource<IT, OT> getResource(String serviceName)
249                         throws Exception {
250                 // TODO Auto-generated method stub
251                 throw new RuntimeException("Unimplemented method.");
252         }
253         
254         //
255         // Transaction management methods
256         //
257         
258         private TransactionContext getCurrentTransactionContext() {
259                 return (TransactionContext) this.getProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY);
260         }
261
262         @Override
263         public void releaseConnection() throws TransactionException {
264                 if (isTransactionContextShared() == true) {
265                         throw new TransactionException("Attempted to release a shared storage connection.  Only the originator can release the connection");
266                 }
267                 
268                 TransactionContext transactionCtx = getCurrentTransactionContext();             
269                 if (transactionCtx != null) {
270                         transactionCtx.close();
271                 this.setProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY, null);
272                 } else {
273                         throw new TransactionException("Attempted to release a non-existent storage connection.  Transaction context missing from service context.");
274                 }
275         }
276
277         @Override
278         public TransactionContext openConnection() throws TransactionException {
279                 TransactionContext result = getCurrentTransactionContext();
280                 if (result != null) {
281                         throw new TransactionException("Attempted to open a new connection when a current connection is still part of the current service context.  The current connection must be closed with the releaseConnection() method.");
282                 }
283
284                 result = new JPATransactionContext(this);
285         this.setProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY, result);
286
287                 return result;
288         }
289
290         @Override
291         public void setTransactionContext(TransactionContext transactionCtx) {
292                 // TODO Auto-generated method stub
293                 
294         }
295
296         /**
297          * Returns true if the TransactionContext is shared with another ServiceContext instance
298          * @throws TransactionException 
299          */
300         @Override
301         public boolean isTransactionContextShared() throws TransactionException {
302                 boolean result = true;
303                 
304                 TransactionContext transactionCtx = getCurrentTransactionContext();
305                 if (transactionCtx != null) {
306                         if (transactionCtx.getServiceContext() == this) {  // check to see if the service context used to create the connection is the same as the current service context
307                                 result = false;
308                         }
309                 } else {
310                         throw new TransactionException("Transaction context missing from service context.");
311                 }
312                 
313                 return result;
314         }
315
316         @Override
317         public boolean hasActiveConnection() {
318                 return getCurrentTransactionContext() != null;
319         }
320 }