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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.servicegroup.nuxeo;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
32 import javax.ws.rs.core.Response;
34 import org.collectionspace.services.nuxeo.client.java.CommonList;
35 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
36 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
37 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
38 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
39 import org.collectionspace.services.jaxb.AbstractCommonList;
40 import org.collectionspace.services.client.CollectionSpaceClient;
41 import org.collectionspace.services.client.IQueryManager;
42 import org.collectionspace.services.client.PoxPayloadIn;
43 import org.collectionspace.services.client.PoxPayloadOut;
44 import org.collectionspace.services.common.NuxeoBasedResource;
45 import org.collectionspace.services.common.CSWebApplicationException;
46 import org.collectionspace.services.common.ServiceMain;
47 import org.collectionspace.services.common.ServiceMessages;
48 import org.collectionspace.services.common.StoredValuesUriTemplate;
49 import org.collectionspace.services.common.UriTemplateFactory;
50 import org.collectionspace.services.common.UriTemplateRegistry;
51 import org.collectionspace.services.common.UriTemplateRegistryKey;
52 import org.collectionspace.services.common.api.RefName;
53 import org.collectionspace.services.common.api.RefNameUtils;
54 import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
55 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
56 import org.collectionspace.services.common.context.ServiceBindingUtils;
57 import org.collectionspace.services.common.context.ServiceContext;
58 import org.collectionspace.services.common.document.DocumentException;
59 import org.collectionspace.services.common.document.DocumentFilter;
60 import org.collectionspace.services.common.document.DocumentNotFoundException;
61 import org.collectionspace.services.common.document.DocumentWrapper;
62 import org.collectionspace.services.common.security.SecurityUtils;
63 import org.collectionspace.services.common.query.nuxeo.QueryManagerNuxeoImpl;
64 import org.collectionspace.services.config.service.ServiceBindingType;
65 import org.collectionspace.services.config.service.ServiceObjectType;
66 import org.collectionspace.services.servicegroup.ServicegroupsCommon;
67 import org.collectionspace.services.common.vocabulary.AuthorityResource;
68 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
69 import org.nuxeo.ecm.core.api.DocumentModel;
70 import org.nuxeo.ecm.core.api.DocumentModelList;
71 import org.nuxeo.ecm.core.api.PropertyException;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
75 public class ServiceGroupDocumentModelHandler
76 extends NuxeoDocumentModelHandler<ServicegroupsCommon> {
78 protected final Logger logger = LoggerFactory.getLogger(this.getClass());
80 protected static final int NUM_META_FIELDS = 3;
81 protected static final String DOC_TYPE_FIELD = "docType";
82 protected static final String DOC_NUMBER_FIELD = "docNumber";
83 protected static final String DOC_NAME_FIELD = "docName";
86 // Returns a service payload for an authority item
88 private PoxPayloadOut getAuthorityItem(ServiceContext ctx, String termRefName) throws Exception {
89 PoxPayloadOut result = null;
91 RefName.AuthorityItem item = RefName.AuthorityItem.parse(termRefName);
92 AuthorityResource authorityResource = (AuthorityResource) ctx.getResourceMap().get(item.inAuthority.resource);
94 AuthorityTermInfo authorityTermInfo = RefNameUtils.parseAuthorityTermInfo(termRefName);
95 String parentIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.inAuthority.name);
96 String itemIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.name);
98 result = authorityResource.getAuthorityItemWithExistingContext(ctx, parentIdentifier, itemIdentifier);
103 public PoxPayloadOut getResourceItemForCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
104 List<String> serviceGroupNames,
105 String csid) throws DocumentException {
106 PoxPayloadOut result = null;
107 CoreSessionInterface repoSession = null;
108 boolean releaseRepoSession = false;
111 RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
112 repoSession = this.getRepositorySession();
113 if (repoSession == null) {
114 repoSession = repoClient.getRepositorySession(ctx);
115 releaseRepoSession = true;
118 Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();
119 DocumentModelList docList = this.getDocListForGroup(ctx, serviceGroupNames, queriedServiceBindings,
120 repoSession, repoClient);
121 if (docList == null) { // found no authRef fields - nothing to process
122 throw new DocumentNotFoundException();
124 DocumentModel docModel = docList.get(0);
126 // Determine if the docModel is an authority term, object, or some other procedure record.
128 String termRefName = (String) NuxeoUtils.getProperyValue(docModel, CollectionSpaceClient.COLLECTIONSPACE_CORE_REFNAME);
129 if (isAuthorityTermDocument(termRefName) == true) {
130 result = getAuthorityItem(ctx, termRefName);
132 TenantBindingConfigReaderImpl bindingReader = ServiceMain.getInstance().getTenantBindingConfigReader();
133 String serviceName = ServiceBindingUtils.getServiceNameFromObjectName(bindingReader, ctx.getTenantId(),
134 docModel.getDocumentType().getName());
135 NuxeoBasedResource resource = (NuxeoBasedResource) ctx.getResourceMap().get(serviceName);
136 result = resource.getWithParentCtx(ctx, csid);
138 } catch (DocumentException de) {
140 } catch (Exception e) {
141 if (logger.isDebugEnabled()) {
142 logger.debug("Caught exception ", e);
144 throw new DocumentException(e);
146 if (releaseRepoSession && repoSession != null) {
147 repoClient.releaseRepositorySession(ctx, repoSession);
150 } catch (Exception e) {
151 if (logger.isDebugEnabled()) {
152 logger.debug("Caught exception ", e);
154 throw new DocumentException(e);
160 private boolean isAuthorityTermDocument(String termRefName) {
161 boolean result = true;
164 //String inAuthorityCsid = (String) NuxeoUtils.getProperyValue(docModel, "inAuthority"); //docModel.getPropertyValue("inAuthority"); // AuthorityItemJAXBSchema.IN_AUTHORITY
165 //String refName = (String) NuxeoUtils.getProperyValue(docModel, CollectionSpaceClient.COLLECTIONSPACE_CORE_REFNAME);
166 RefName.AuthorityItem item = RefName.AuthorityItem.parse(termRefName);
167 } catch (IllegalArgumentException e) {
174 private DocumentModelList getDocListForGroup(
175 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
176 List<String> serviceGroupNames,
177 Map<String, ServiceBindingType> queriedServiceBindings,
178 CoreSessionInterface repoSession,
179 RepositoryClientImpl repoClient) throws Exception {
181 RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)repoClient;
182 // Get the service bindings for this tenant
183 TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader();
184 // We need to get all the procedures, authorities, and objects.
185 List<ServiceBindingType> servicebindings =
186 tReader.getServiceBindingsByType(ctx.getTenantId(), serviceGroupNames);
187 if (servicebindings == null || servicebindings.isEmpty()) {
188 Response response = Response.status(Response.Status.NOT_FOUND).entity(
189 ServiceMessages.READ_FAILED +
190 ServiceMessages.resourceNotFoundMsg(implode(serviceGroupNames, ","))).type("text/plain").build();
191 throw new CSWebApplicationException(response);
194 servicebindings = SecurityUtils.getReadableServiceBindingsForCurrentUser(servicebindings);
195 // Build the list of docTypes for allowed serviceBindings
196 ArrayList<String> docTypes = new ArrayList<String>();
197 for(ServiceBindingType binding:servicebindings) {
198 ServiceObjectType serviceObj = binding.getObject();
199 if(serviceObj!=null) {
200 String docType = serviceObj.getName();
201 docTypes.add(docType);
202 queriedServiceBindings.put(docType, binding);
206 // This should be type "Document" but CMIS is gagging on that right now.
207 ctx.getQueryParams().add(IQueryManager.SELECT_DOC_TYPE_FIELD, QueryManagerNuxeoImpl.COLLECTIONSPACE_DOCUMENT_TYPE);
209 // Now we have to issue the search
210 // The findDocs() method will build a QueryContext, which wants to see a docType for our context
211 ctx.setDocumentType(QueryManagerNuxeoImpl.NUXEO_DOCUMENT_TYPE);
212 DocumentWrapper<DocumentModelList> docListWrapper =
213 nuxeoRepoClient.findDocs(ctx, this, repoSession, docTypes );
214 // Now we gather the info for each document into the list and return
215 DocumentModelList docList = docListWrapper.getWrappedObject();
220 public AbstractCommonList getItemListForGroup(
221 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
222 List<String> serviceGroupNames) throws Exception {
223 CommonList commonList = new CommonList();
224 AbstractCommonList list = (AbstractCommonList)commonList;
225 CoreSessionInterface repoSession = null;
226 boolean releaseRepoSession = false;
229 DocumentFilter myFilter = getDocumentFilter();
230 int pageSize = myFilter.getPageSize();
231 int pageNum = myFilter.getStartPage();
232 list.setPageNum(pageNum);
233 list.setPageSize(pageSize);
235 RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
236 repoSession = this.getRepositorySession();
237 if (repoSession == null) {
238 repoSession = repoClient.getRepositorySession(ctx);
239 releaseRepoSession = true;
242 Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();
243 DocumentModelList docList = this.getDocListForGroup(ctx, serviceGroupNames, queriedServiceBindings,
244 repoSession, repoClient);
245 if (docList == null) { // found no authRef fields - nothing to process
248 processDocList(ctx.getTenantId(), docList, queriedServiceBindings, commonList);
249 list.setItemsInPage(docList.size());
250 list.setTotalItems(docList.totalSize());
251 } catch (DocumentException de) {
253 } catch (Exception e) {
254 if (logger.isDebugEnabled()) {
255 logger.debug("Caught exception ", e);
257 throw new DocumentException(e);
259 if (releaseRepoSession && repoSession != null) {
260 repoClient.releaseRepositorySession(ctx, repoSession);
263 } catch (Exception e) {
264 if (logger.isDebugEnabled()) {
265 logger.debug("Caught exception ", e);
267 throw new DocumentException(e);
273 // Move this to a Utils class!
274 public static String implode(List<String> stringList, String sep) {
275 StringBuilder sb = new StringBuilder();
277 boolean fFirst = false;
278 for (String name:stringList) {
287 return sb.toString();
290 private String getUriFromServiceBinding(ServiceBindingType sb, String csid) {
291 return "/" + sb.getName().toLowerCase() + "/" + csid;
294 private void processDocList(String tenantId,
295 DocumentModelList docList,
296 Map<String, ServiceBindingType> queriedServiceBindings,
298 String fields[] = new String[NUM_META_FIELDS + NUM_STANDARD_LIST_RESULT_FIELDS];
299 fields[0] = STANDARD_LIST_CSID_FIELD;
300 fields[1] = STANDARD_LIST_URI_FIELD;
301 fields[2] = STANDARD_LIST_UPDATED_AT_FIELD;
302 fields[3] = STANDARD_LIST_WORKFLOW_FIELD;
303 fields[4] = STANDARD_LIST_REFNAME_FIELD;
304 fields[5] = DOC_NAME_FIELD;
305 fields[6] = DOC_NUMBER_FIELD;
306 fields[7] = DOC_TYPE_FIELD;
307 list.setFieldsReturned(fields);
309 Iterator<DocumentModel> iter = docList.iterator();
310 HashMap<String, Object> item = new HashMap<String, Object>();
311 while (iter.hasNext()) {
312 DocumentModel docModel = iter.next();
313 String docType = docModel.getDocumentType().getName();
314 docType = ServiceBindingUtils.getUnqualifiedTenantDocType(docType);
315 ServiceBindingType sb = queriedServiceBindings.get(docType);
317 throw new RuntimeException("processDocList: No Service Binding for docType: " + docType);
320 String csid = NuxeoUtils.getCsid(docModel);
321 item.put(STANDARD_LIST_CSID_FIELD, csid);
323 UriTemplateRegistry uriTemplateRegistry = ServiceMain.getInstance().getUriTemplateRegistry();
324 StoredValuesUriTemplate storedValuesResourceTemplate = uriTemplateRegistry.get(new UriTemplateRegistryKey(tenantId, docType));
325 Map<String, String> additionalValues = new HashMap<String, String>();
326 if (storedValuesResourceTemplate.getUriTemplateType() == UriTemplateFactory.ITEM) {
328 String inAuthorityCsid = (String) NuxeoUtils.getProperyValue(docModel, "inAuthority"); //docModel.getPropertyValue("inAuthority"); // AuthorityItemJAXBSchema.IN_AUTHORITY
329 additionalValues.put(UriTemplateFactory.IDENTIFIER_VAR, inAuthorityCsid);
330 additionalValues.put(UriTemplateFactory.ITEM_IDENTIFIER_VAR, csid);
331 } catch (Exception e) {
332 String msg = String.format("Could not extract inAuthority property from authority item with CSID = ", docModel.getName());
336 additionalValues.put(UriTemplateFactory.IDENTIFIER_VAR, csid);
339 String uriStr = storedValuesResourceTemplate.buildUri(additionalValues);
340 item.put(STANDARD_LIST_URI_FIELD, uriStr);
342 item.put(STANDARD_LIST_UPDATED_AT_FIELD, getUpdatedAtAsString(docModel));
343 item.put(STANDARD_LIST_WORKFLOW_FIELD, docModel.getCurrentLifeCycleState());
344 item.put(STANDARD_LIST_REFNAME_FIELD, getRefname(docModel));
345 } catch(Exception e) {
346 logger.error("Error getting core values for doc ["+csid+"]: "+e.getLocalizedMessage());
349 String value = ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel);
351 item.put(DOC_NUMBER_FIELD, value);
354 value = ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel);
356 item.put(DOC_NAME_FIELD, value);
359 item.put(DOC_TYPE_FIELD, docType);
360 // add the item to the list