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.common.vocabulary.nuxeo;
28 import org.collectionspace.services.client.PoxPayloadIn;
29 import org.collectionspace.services.client.PoxPayloadOut;
30 import org.collectionspace.services.common.api.RefName;
31 import org.collectionspace.services.common.api.RefName.Authority;
32 import org.collectionspace.services.common.api.Tools;
33 import org.collectionspace.services.common.context.ServiceContext;
34 import org.collectionspace.services.common.document.DocumentException;
35 import org.collectionspace.services.common.document.DocumentFilter;
36 import org.collectionspace.services.common.document.DocumentNotFoundException;
37 import org.collectionspace.services.common.document.DocumentWrapper;
38 import org.collectionspace.services.common.document.DocumentHandler.Action;
39 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
40 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
41 import org.collectionspace.services.common.vocabulary.AuthorityResource.Specifier;
42 import org.collectionspace.services.common.vocabulary.AuthorityResource.SpecifierForm;
43 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
44 import org.collectionspace.services.config.service.ObjectPartType;
45 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentFilter;
46 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
47 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
48 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
49 import org.nuxeo.ecm.core.api.ClientException;
50 import org.nuxeo.ecm.core.api.DocumentModel;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
55 * AuthorityDocumentModelHandler
57 * $LastChangedRevision: $
60 public abstract class AuthorityDocumentModelHandler<AuthCommon>
61 extends NuxeoDocumentModelHandler<AuthCommon> {
63 private final Logger logger = LoggerFactory.getLogger(AuthorityDocumentModelHandler.class);
64 protected String authorityCommonSchemaName;
65 protected String authorityItemCommonSchemaName;
67 public AuthorityDocumentModelHandler(String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
68 this.authorityCommonSchemaName = authorityCommonSchemaName;
69 this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
73 public boolean synchronize(Specifier specifier) throws DocumentNotFoundException, DocumentException {
74 boolean result = true;
76 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
77 if (specifier.form == SpecifierForm.CSID) {
78 if (logger.isDebugEnabled()) {
79 logger.debug("Synchronize Authority with csid=" + specifier.value);
81 getRepositoryClient(ctx).get(getServiceContext(), specifier.value, this);
83 String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, specifier.value);
84 DocumentFilter myFilter = new NuxeoDocumentFilter(whereClause, 0, 1);
85 this.setDocumentFilter(myFilter);
86 getRepositoryClient(ctx).get(ctx, this);
89 PoxPayloadOut output = ctx.getOutput();
95 * Non standard injection of CSID into common part, since caller may access through
96 * shortId, and not know the CSID.
97 * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
100 protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
102 Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
104 // Add the CSID to the common part
105 if (partMeta.getLabel().equalsIgnoreCase(authorityCommonSchemaName)) {
106 String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
107 unQObjectProperties.put("csid", csid);
110 return unQObjectProperties;
113 public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
114 super.fillAllParts(wrapDoc, action);
116 // Update the record's revision number on both CREATE and UPDATE actions
118 updateRevNumbers(wrapDoc);
121 protected void updateRevNumbers(DocumentWrapper<DocumentModel> wrapDoc) {
122 DocumentModel documentModel = wrapDoc.getWrappedObject();
123 Long rev = (Long)documentModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV);
129 documentModel.setProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV, rev);
133 public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
134 super.handleCreate(wrapDoc);
136 // Uncomment once debugged and App layer is read to integrate
137 // Experimenting with this uncommented now ...
138 handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityCommonSchemaName);
139 updateRefnameForAuthority(wrapDoc, authorityCommonSchemaName);//CSPACE-3178
142 protected String buildWhereForShortId(String name) {
143 return authorityCommonSchemaName
144 + ":" + AuthorityJAXBSchema.SHORT_IDENTIFIER
148 private boolean isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
152 private boolean temp_isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
153 boolean result = true;
155 ServiceContext ctx = this.getServiceContext();
156 String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
157 String nxqlWhereClause = buildWhereForShortId(shortIdentifier);
159 DocumentWrapper<DocumentModel> searchResultWrapper = getRepositoryClient(ctx).findDoc(ctx, nxqlWhereClause);
160 if (searchResultWrapper != null) {
162 if (logger.isInfoEnabled() == true) {
163 DocumentModel searchResult = searchResultWrapper.getWrappedObject();
164 String debugMsg = String.format("Could not create a new authority with a short identifier of '%s', because one already exists with the same short identifer: CSID = '%s'",
165 shortIdentifier, searchResult.getName());
166 logger.trace(debugMsg);
169 } catch (DocumentNotFoundException e) {
170 // Not a problem, just means we couldn't find another authority with that short ID
177 * If no short identifier was provided in the input payload,
178 * generate a short identifier from the display name. Either way though,
179 * the short identifier needs to be unique.
181 private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
182 String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
183 String displayName = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.DISPLAY_NAME);
184 String shortDisplayName = "";
185 String generateShortIdentifier = null;
186 if (Tools.isEmpty(shortIdentifier)) {
187 generateShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(displayName, shortDisplayName);
188 docModel.setProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER, shortIdentifier);
191 if (isUnique(docModel, schemaName) == false) {
192 String shortId = generateShortIdentifier == null ? shortIdentifier : generateShortIdentifier;
193 String errMsgVerb = generateShortIdentifier == null ? "supplied" : "generated";
194 String errMsg = String.format("The %s short identifier '%s' was not unique, so the new authority could not be created.",
195 errMsgVerb, shortId);
196 throw new DocumentException(errMsg);
201 * Generate a refName for the authority from the short identifier
204 * All refNames for authorities are generated. If a client supplies
205 * a refName, it will be overwritten during create (per this method)
206 * or discarded during update (per filterReadOnlyPropertiesForPart).
208 * @see #filterReadOnlyPropertiesForPart(Map<String, Object>, org.collectionspace.services.common.service.ObjectPartType)
211 protected void updateRefnameForAuthority(DocumentWrapper<DocumentModel> wrapDoc, String schemaName) throws Exception {
212 DocumentModel docModel = wrapDoc.getWrappedObject();
213 RefName.Authority authority = (Authority) getRefName(getServiceContext(), docModel);
214 String refName = authority.toString();
215 docModel.setProperty(schemaName, AuthorityJAXBSchema.REF_NAME, refName);
219 public RefName.RefNameInterface getRefName(ServiceContext ctx,
220 DocumentModel docModel) {
221 RefName.RefNameInterface refname = null;
224 String shortIdentifier = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
225 String displayName = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.DISPLAY_NAME);
226 RefName.Authority authority = RefName.Authority.buildAuthority(ctx.getTenantName(),
227 ctx.getServiceName(),
228 null, // Only use shortId form!!!
232 } catch (Exception e) {
233 logger.error(e.getMessage(), e);
240 protected String getRefnameDisplayName(DocumentWrapper<DocumentModel> docWrapper) {
241 String result = null;
243 DocumentModel docModel = docWrapper.getWrappedObject();
244 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
245 RefName.Authority refname = (RefName.Authority)getRefName(ctx, docModel);
246 result = refname.getDisplayName();
251 public String getShortIdentifier(String authCSID, String schemaName) throws Exception {
252 String shortIdentifier = null;
253 CoreSessionInterface repoSession = null;
255 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
256 RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
258 repoSession = nuxeoRepoClient.getRepositorySession(ctx);
259 DocumentWrapper<DocumentModel> wrapDoc = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, authCSID);
260 DocumentModel docModel = wrapDoc.getWrappedObject();
261 shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
262 } catch (ClientException ce) {
263 throw new RuntimeException("AuthorityDocHandler Internal Error: cannot get shortId!", ce);
265 if (repoSession != null) {
266 nuxeoRepoClient.releaseRepositorySession(ctx, repoSession);
270 return shortIdentifier;
274 * Filters out selected values supplied in an update request.
276 * @param objectProps the properties filtered out from the update payload
277 * @param partMeta metadata for the object to fill
280 public void filterReadOnlyPropertiesForPart(
281 Map<String, Object> objectProps, ObjectPartType partMeta) {
282 super.filterReadOnlyPropertiesForPart(objectProps, partMeta);
283 String commonPartLabel = getServiceContext().getCommonPartLabel();
284 if (partMeta.getLabel().equalsIgnoreCase(commonPartLabel)) {
285 objectProps.remove(AuthorityJAXBSchema.CSID);
286 objectProps.remove(AuthorityJAXBSchema.SHORT_IDENTIFIER);
287 objectProps.remove(AuthorityJAXBSchema.REF_NAME);