]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
d3fba73699141487af555427cc0deb69f847d365
[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.servicegroup.nuxeo;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Response;
34
35 import org.collectionspace.services.nuxeo.client.java.CommonList;
36 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
37 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
38 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
39 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
40 import org.collectionspace.services.jaxb.AbstractCommonList;
41 import org.collectionspace.services.client.CollectionSpaceClient;
42 import org.collectionspace.services.client.IQueryManager;
43 import org.collectionspace.services.client.IRelationsManager;
44 import org.collectionspace.services.client.PoxPayloadIn;
45 import org.collectionspace.services.client.PoxPayloadOut;
46 import org.collectionspace.services.common.NuxeoBasedResource;
47 import org.collectionspace.services.common.CSWebApplicationException;
48 import org.collectionspace.services.common.ServiceMain;
49 import org.collectionspace.services.common.ServiceMessages;
50 import org.collectionspace.services.common.StoredValuesUriTemplate;
51 import org.collectionspace.services.common.UriTemplateFactory;
52 import org.collectionspace.services.common.UriTemplateRegistry;
53 import org.collectionspace.services.common.UriTemplateRegistryKey;
54 import org.collectionspace.services.common.api.RefName;
55 import org.collectionspace.services.common.api.RefNameUtils;
56 import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
57 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
58 import org.collectionspace.services.common.context.AbstractServiceContextImpl;
59 import org.collectionspace.services.common.context.ServiceBindingUtils;
60 import org.collectionspace.services.common.context.ServiceContext;
61 import org.collectionspace.services.common.document.DocumentException;
62 import org.collectionspace.services.common.document.DocumentFilter;
63 import org.collectionspace.services.common.document.DocumentNotFoundException;
64 import org.collectionspace.services.common.document.DocumentWrapper;
65 import org.collectionspace.services.common.document.TransactionException;
66 import org.collectionspace.services.common.security.SecurityUtils;
67 import org.collectionspace.services.common.query.QueryContext;
68 import org.collectionspace.services.common.query.nuxeo.QueryManagerNuxeoImpl;
69 import org.collectionspace.services.common.relation.nuxeo.RelationsUtils;
70 import org.collectionspace.services.config.service.ListResultField;
71 import org.collectionspace.services.config.service.ServiceBindingType;
72 import org.collectionspace.services.config.service.ServiceObjectType;
73 import org.collectionspace.services.servicegroup.ServicegroupsCommon;
74 import org.collectionspace.services.common.vocabulary.AuthorityResource;
75 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
76 import org.nuxeo.ecm.core.api.DocumentModel;
77 import org.nuxeo.ecm.core.api.DocumentModelList;
78 import org.nuxeo.ecm.core.api.PropertyException;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82 public class ServiceGroupDocumentModelHandler 
83         extends NuxeoDocumentModelHandler<ServicegroupsCommon> {
84         
85     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
86     
87     protected static final int NUM_META_FIELDS = 4; // the number of meta fields -i.e., DOC_TYPE_FIELD, DOC_NUMBER_FIELD, DOC_NAME_FIELD, STANDARD_LIST_MARK_RT_FIELD
88     protected static final String DOC_TYPE_FIELD = "docType";
89     protected static final String DOC_NUMBER_FIELD = "docNumber";
90     protected static final String DOC_NAME_FIELD = "docName";
91         protected static final String STANDARD_LIST_MARK_RT_FIELD = "related";
92     
93     //
94     // Returns a service payload for an authority item
95     //
96     private PoxPayloadOut getAuthorityItem(ServiceContext ctx, String termRefName) throws Exception {
97         PoxPayloadOut result = null;
98         
99         RefName.AuthorityItem item = RefName.AuthorityItem.parse(termRefName, true);
100         AuthorityResource authorityResource = (AuthorityResource) ctx.getResourceMap().get(item.inAuthority.resource);
101         
102         AuthorityTermInfo authorityTermInfo = RefNameUtils.parseAuthorityTermInfo(termRefName);
103         String parentIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.inAuthority.name);
104         String itemIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.name);
105         
106         result = authorityResource.getAuthorityItemWithExistingContext(ctx, parentIdentifier, itemIdentifier);
107         
108         return result;
109     }
110
111     public PoxPayloadOut getResourceItemForCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
112                 List<String> serviceGroupNames,
113                 String csid) throws DocumentException {
114         PoxPayloadOut result = null;
115         CoreSessionInterface repoSession = null;
116         boolean releaseRepoSession = false;
117         
118         try { 
119                 RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
120                 repoSession = this.getRepositorySession();
121                 if (repoSession == null) {
122                         repoSession = repoClient.getRepositorySession(ctx);
123                         releaseRepoSession = true;
124                 }
125                 try {
126                 Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();
127                 DocumentModelList docList = this.getDocListForGroup(ctx, serviceGroupNames, queriedServiceBindings,
128                                 repoSession, repoClient);
129                 if (docList == null) { // found no authRef fields - nothing to process
130                     throw new DocumentNotFoundException();
131                 }
132                 DocumentModel docModel = docList.get(0);
133                 //
134                 // Determine if the docModel is an authority term, object, or some other procedure record.
135                 //
136                 String termRefName = (String) NuxeoUtils.getProperyValue(docModel, CollectionSpaceClient.COLLECTIONSPACE_CORE_REFNAME);
137                 if (isAuthorityTermDocument(termRefName) == true) {
138                         result = getAuthorityItem(ctx, termRefName);
139                 } else {                
140                         TenantBindingConfigReaderImpl bindingReader = ServiceMain.getInstance().getTenantBindingConfigReader();
141                         String serviceName = ServiceBindingUtils.getServiceNameFromObjectName(bindingReader, ctx.getTenantId(),
142                                         docModel.getDocumentType().getName());
143                         NuxeoBasedResource resource = (NuxeoBasedResource) ctx.getResourceMap().get(serviceName);
144                         result = resource.getWithParentCtx(ctx, csid);
145                 }
146                 } catch (DocumentException de) {
147                         throw de;
148                 } catch (Exception e) {
149                         if (logger.isDebugEnabled()) {
150                                 logger.debug("Caught exception ", e);
151                         }
152                         throw new DocumentException(e);
153                 } finally {
154                         if (releaseRepoSession && repoSession != null) {
155                                 repoClient.releaseRepositorySession(ctx, repoSession);
156                         }
157                 }
158         } catch (Exception e) {
159                 if (logger.isDebugEnabled()) {
160                         logger.debug("Caught exception ", e);
161                 }
162                 throw new DocumentException(e);
163         }
164         
165         return result;
166     }
167     
168     private boolean isAuthorityTermDocument(String termRefName) {
169                 boolean result = true;
170                 
171                 try {
172                 //String inAuthorityCsid = (String) NuxeoUtils.getProperyValue(docModel, "inAuthority"); //docModel.getPropertyValue("inAuthority"); // AuthorityItemJAXBSchema.IN_AUTHORITY
173                 //String refName = (String) NuxeoUtils.getProperyValue(docModel, CollectionSpaceClient.COLLECTIONSPACE_CORE_REFNAME);
174                 RefName.AuthorityItem item = RefName.AuthorityItem.parse(termRefName, true);
175                 } catch (IllegalArgumentException e) {
176                         result = false;
177                 }
178                 
179         return result;
180         }
181
182         private DocumentModelList getDocListForGroup(
183                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
184                 List<String> serviceGroupNames,
185                 Map<String, ServiceBindingType> queriedServiceBindings,
186                 CoreSessionInterface repoSession,
187                 RepositoryClientImpl repoClient) throws Exception {
188         
189         RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)repoClient;
190         // Get the service bindings for this tenant
191         TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader();
192         // We need to get all the procedures, authorities, and objects.
193         List<ServiceBindingType> servicebindings = 
194                         tReader.getServiceBindingsByType(ctx.getTenantId(), serviceGroupNames);
195         if (servicebindings == null || servicebindings.isEmpty()) {
196             Response response = Response.status(Response.Status.NOT_FOUND).entity(
197                     ServiceMessages.READ_FAILED + 
198                     ServiceMessages.resourceNotFoundMsg(implode(serviceGroupNames, ","))).type("text/plain").build();
199             throw new CSWebApplicationException(response);
200         }
201         
202         servicebindings = SecurityUtils.getReadableServiceBindingsForCurrentUser(servicebindings);
203         // Build the list of docTypes for allowed serviceBindings
204         ArrayList<String> docTypes = new ArrayList<String>();
205         for(ServiceBindingType binding:servicebindings) {
206                 ServiceObjectType serviceObj = binding.getObject();
207                 if(serviceObj!=null) {
208                 String docType = serviceObj.getName();
209                         docTypes.add(docType);
210                 queriedServiceBindings.put(docType, binding);
211                 }
212         }
213         
214         // This should be type "Document" but CMIS is gagging on that right now.
215         ctx.getQueryParams().add(IQueryManager.SELECT_DOC_TYPE_FIELD, QueryManagerNuxeoImpl.COLLECTIONSPACE_DOCUMENT_TYPE);
216         
217         // Now we have to issue the search
218         // The findDocs() method will build a QueryContext, which wants to see a docType for our context
219         ctx.setDocumentType(QueryManagerNuxeoImpl.NUXEO_DOCUMENT_TYPE);
220         DocumentWrapper<DocumentModelList> docListWrapper = 
221                         nuxeoRepoClient.findDocs(ctx, this, repoSession, docTypes );
222         // Now we gather the info for each document into the list and return
223         DocumentModelList docList = docListWrapper.getWrappedObject();
224         
225         return docList;
226     }
227     
228     public AbstractCommonList getItemListForGroup(
229                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
230                 List<String> serviceGroupNames) throws Exception {
231         CommonList commonList = new CommonList();
232         AbstractCommonList list = (AbstractCommonList)commonList;
233         CoreSessionInterface repoSession = null;
234         boolean releaseRepoSession = false;
235         
236         try { 
237             DocumentFilter myFilter = getDocumentFilter();
238                 int pageSize = myFilter.getPageSize();
239                 int pageNum = myFilter.getStartPage();
240                 list.setPageNum(pageNum);
241                 list.setPageSize(pageSize);
242
243                 RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
244                 repoSession = this.getRepositorySession();
245                 if (repoSession == null) {
246                         repoSession = repoClient.getRepositorySession(ctx);
247                         releaseRepoSession = true;
248                 }
249                 try {
250                 Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();
251                 DocumentModelList docList = this.getDocListForGroup(ctx, serviceGroupNames, queriedServiceBindings,
252                                 repoSession, repoClient);
253                 if (docList == null) { // found no authRef fields - nothing to process
254                     return list;
255                 }
256                 processDocList(ctx, docList, queriedServiceBindings, commonList);
257                 list.setItemsInPage(docList.size());
258                 list.setTotalItems(docList.totalSize());
259                 } catch (DocumentException de) {
260                         throw de;
261                 } catch (Exception e) {
262                         if (logger.isDebugEnabled()) {
263                                 logger.debug("Caught exception ", e);
264                         }
265                         throw new DocumentException(e);
266                 } finally {
267                         if (releaseRepoSession && repoSession != null) {
268                                 repoClient.releaseRepositorySession(ctx, repoSession);
269                         }
270                 }
271         } catch (Exception e) {
272                 if (logger.isDebugEnabled()) {
273                         logger.debug("Caught exception ", e);
274                 }
275                 throw new DocumentException(e);
276         }
277         
278         return list;
279     }
280     
281     // Move this to a Utils class!
282     public static String implode(List<String> stringList, String sep) {
283         StringBuilder sb = new StringBuilder();
284         
285         boolean fFirst = false;
286         for (String name:stringList) {
287                 if(fFirst) {
288                         fFirst = false;
289                 } else {
290                         sb.append(sep);
291                 }
292                 sb.append(name);
293         }
294         
295         return sb.toString();
296     }
297     
298     private String getUriFromServiceBinding(ServiceBindingType sb, String csid) {
299         return "/" + sb.getName().toLowerCase() + "/" + csid;
300     }
301     
302     private void processDocList(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
303                         DocumentModelList docList,
304                         Map<String, ServiceBindingType> queriedServiceBindings,
305                         CommonList list) throws DocumentException {
306         
307                 String tenantId = ctx.getTenantId();
308                 CoreSessionInterface repoSession = null;
309                 RepositoryClientImpl repoClient = null;
310                 boolean releaseRepoSession = false;
311                 
312                 MultivaluedMap<String, String> queryParams = getServiceContext().getQueryParams();
313                 String markRtSbj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT);
314                 if (markRtSbj != null && markRtSbj.isEmpty()) {
315                         markRtSbj = null;
316                 }
317                 
318                 String markRtSbjOrObj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_EITHER);
319                 if (markRtSbjOrObj != null && markRtSbjOrObj.isEmpty()) {
320                         markRtSbjOrObj = null;
321                 }
322                 
323                 try {
324                         if (markRtSbj != null || markRtSbjOrObj != null) {
325                                 repoClient = (RepositoryClientImpl) this.getRepositoryClient(ctx);
326                                 RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient;
327                                 repoSession = this.getRepositorySession();
328                                 if (repoSession == null) {
329                                         repoSession = repoClient.getRepositorySession(ctx);
330                                         releaseRepoSession = true;
331                                 }
332                         }
333                                         
334                 String fields[] = new String[NUM_META_FIELDS + NUM_STANDARD_LIST_RESULT_FIELDS];
335                 fields[0] = STANDARD_LIST_CSID_FIELD;
336                 fields[1] = STANDARD_LIST_URI_FIELD;
337                 fields[2] = STANDARD_LIST_UPDATED_AT_FIELD;
338                 fields[3] = STANDARD_LIST_WORKFLOW_FIELD;
339                 fields[4] = STANDARD_LIST_REFNAME_FIELD;
340                 fields[5] = DOC_NAME_FIELD;
341                 fields[6] = DOC_NUMBER_FIELD;
342                 fields[7] = DOC_TYPE_FIELD;             
343                         if (markRtSbj != null || markRtSbjOrObj != null) {
344                         fields[8] = STANDARD_LIST_MARK_RT_FIELD;
345                         }
346
347                 list.setFieldsReturned(fields);
348                 
349                 Iterator<DocumentModel> iter = docList.iterator();
350                         HashMap<String, Object> item = new HashMap<String, Object>();
351                 while (iter.hasNext()) {
352                     DocumentModel docModel = iter.next();
353                     String docType = docModel.getDocumentType().getName();
354                     docType = ServiceBindingUtils.getUnqualifiedTenantDocType(docType);
355                     ServiceBindingType sb = queriedServiceBindings.get(docType);
356                     if (sb == null) {
357                         throw new RuntimeException("processDocList: No Service Binding for docType: " + docType);
358                     }
359                     
360                     String csid = NuxeoUtils.getCsid(docModel);
361                     item.put(STANDARD_LIST_CSID_FIELD, csid);
362
363                                 //
364                                 // If the mark-related query param was set, check to see if the doc we're processing
365                                 // is related to the value specified in the mark-related query param.
366                                 //                  
367                                 if (markRtSbj != null || markRtSbjOrObj != null) {
368                                         String relationClause = RelationsUtils.buildWhereClause(markRtSbj, null, null, csid, null, markRtSbjOrObj);
369                                         String whereClause = relationClause + IQueryManager.SEARCH_QUALIFIER_AND
370                                                         + NuxeoUtils.buildWorkflowNotDeletedWhereClause();
371                                         QueryContext queryContext = new QueryContext(ctx, whereClause);
372                                         queryContext.setDocType(IRelationsManager.DOC_TYPE);
373                                         String query = NuxeoUtils.buildNXQLQuery(queryContext);
374                                         // Search for 1 relation that matches. 1 is enough to fail
375                                         // the filter
376                                         DocumentModelList queryDocList = repoSession.query(query, null, 1, 0, false);
377                                         item.put(STANDARD_LIST_MARK_RT_FIELD, queryDocList.isEmpty() ? "false" : "true");
378                                 }
379
380                     UriTemplateRegistry uriTemplateRegistry = ServiceMain.getInstance().getUriTemplateRegistry();            
381                     StoredValuesUriTemplate storedValuesResourceTemplate = uriTemplateRegistry.get(new UriTemplateRegistryKey(tenantId, docType));
382                             Map<String, String> additionalValues = new HashMap<String, String>();
383                             if (storedValuesResourceTemplate.getUriTemplateType() == UriTemplateFactory.ITEM) {
384                         try {
385                             String inAuthorityCsid = (String) NuxeoUtils.getProperyValue(docModel, "inAuthority"); //docModel.getPropertyValue("inAuthority"); // AuthorityItemJAXBSchema.IN_AUTHORITY
386                             additionalValues.put(UriTemplateFactory.IDENTIFIER_VAR, inAuthorityCsid);
387                             additionalValues.put(UriTemplateFactory.ITEM_IDENTIFIER_VAR, csid);
388                         } catch (Exception e) {
389                                 String msg = String.format("Could not extract inAuthority property from authority item with CSID = ", docModel.getName());
390                             logger.warn(msg, e);
391                         }
392                             } else {
393                         additionalValues.put(UriTemplateFactory.IDENTIFIER_VAR, csid);
394                     }
395                             
396                     String uriStr = storedValuesResourceTemplate.buildUri(additionalValues);
397                     item.put(STANDARD_LIST_URI_FIELD, uriStr);
398                     try {
399                         item.put(STANDARD_LIST_UPDATED_AT_FIELD, getUpdatedAtAsString(docModel));
400                         item.put(STANDARD_LIST_WORKFLOW_FIELD, docModel.getCurrentLifeCycleState());
401                         item.put(STANDARD_LIST_REFNAME_FIELD, getRefname(docModel));
402                     } catch(Exception e) {
403                         logger.error("Error getting core values for doc ["+csid+"]: "+e.getLocalizedMessage());
404                     }
405         
406                     String value = ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel);
407                     if (value != null) {
408                         item.put(DOC_NUMBER_FIELD, value);
409                     }
410                     
411                     value = ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel);
412                     if (value != null) {
413                         item.put(DOC_NAME_FIELD, value);
414                     }
415                     
416                     item.put(DOC_TYPE_FIELD, docType);
417                     // add the item to the list
418                     list.addItem(item);
419                     item.clear();
420                 }
421             } catch (Exception e) {
422                         if (logger.isDebugEnabled()) {
423                                 logger.debug("Caught exception ", e);
424                         }
425                         throw new DocumentException(e);
426                 } finally {
427                         // If we got/acquired a new session then we're responsible for releasing it.
428                         if (releaseRepoSession && repoSession != null) {
429                                 repoClient.releaseRepositorySession(ctx, repoSession);
430                         }
431                 }
432     }
433 }
434