]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
6c0ad81c144e21481728d0d6071a3182dc65df0d
[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.vocabulary.nuxeo;
25
26 import java.util.Map;
27
28 import javax.ws.rs.core.Response;
29
30 import org.collectionspace.services.client.AuthorityClient;
31 import org.collectionspace.services.client.PayloadInputPart;
32 import org.collectionspace.services.client.VocabularyClient;
33 import org.collectionspace.services.client.PoxPayloadIn;
34 import org.collectionspace.services.client.PoxPayloadOut;
35 import org.collectionspace.services.common.api.RefName;
36 import org.collectionspace.services.common.api.RefName.Authority;
37 import org.collectionspace.services.common.api.RefNameUtils;
38 import org.collectionspace.services.common.api.RefNameUtils.AuthorityInfo;
39 import org.collectionspace.services.common.api.Tools;
40 import org.collectionspace.services.common.context.ServiceContext;
41 import org.collectionspace.services.common.document.DocumentException;
42 import org.collectionspace.services.common.document.DocumentNotFoundException;
43 import org.collectionspace.services.common.document.DocumentWrapper;
44 import org.collectionspace.services.common.document.DocumentHandler.Action;
45 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
46 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
47 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
48 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
49 import org.collectionspace.services.config.service.ObjectPartType;
50 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentFilter;
51 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
52 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
53 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
54 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
55 import org.nuxeo.ecm.core.api.ClientException;
56 import org.nuxeo.ecm.core.api.DocumentModel;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.testng.Assert;
60
61 /**
62  * AuthorityDocumentModelHandler
63  *
64  * $LastChangedRevision: $
65  * $LastChangedDate: $
66  */
67 public abstract class AuthorityDocumentModelHandler<AuthCommon>
68         extends NuxeoDocumentModelHandler<AuthCommon> {
69
70     private final Logger logger = LoggerFactory.getLogger(AuthorityDocumentModelHandler.class); 
71     protected String authorityCommonSchemaName;
72     protected String authorityItemCommonSchemaName;
73
74     public AuthorityDocumentModelHandler(String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
75         this.authorityCommonSchemaName = authorityCommonSchemaName;
76         this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
77     }
78     
79     /**
80      * The entity type expected from the JAX-RS Response object
81      */
82     public Class<String> getEntityResponseType() {
83         return String.class;
84     }
85     
86     protected PayloadInputPart extractPart(Response res, String partLabel)
87             throws Exception {
88             PoxPayloadIn input = new PoxPayloadIn((String)res.readEntity(getEntityResponseType()));
89             PayloadInputPart payloadInputPart = input.getPart(partLabel);
90             Assert.assertNotNull(payloadInputPart,
91                     "Part " + partLabel + " was unexpectedly null.");
92             return payloadInputPart;
93     }
94     
95     @Override
96     public void handleSync(DocumentWrapper<Specifier> wrapDoc) throws Exception {
97         
98         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
99         Specifier specifier = wrapDoc.getWrappedObject();
100         //
101         // Get the rev number of the authority so we can compare with rev number of shared authority
102         //
103         DocumentModel docModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName, specifier);
104         Long rev = (Long) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REV);
105         String shortId = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
106         String refName = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REF_NAME);
107         AuthorityInfo authorityInfo = RefNameUtils.parseAuthorityInfo(refName);
108         //
109         // Using the short ID of the local authority, created a URN specifier to retrieve the SAS authority
110         //
111         Specifier sasSpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(shortId));
112         Long sasRev = getRevFromSASInstance(sasSpecifier);
113         
114         AuthorityClient client = ctx.getAuthorityClient();
115         Response res = client.read(sasSpecifier.value);
116         try {
117                 int statusCode = res.getStatus();
118         
119                 // Check the status code of the response: does it match
120                 // the expected response(s)?
121                 if (logger.isDebugEnabled()) {
122                     logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
123                 }
124                 
125                         PayloadInputPart payloadInputPart = extractPart(res, client.getCommonPartName());
126                         if (payloadInputPart != null) {
127                                 result = (CPT) payloadInputPart.getBody();
128                         }
129         } finally {
130                 res.close();
131         }
132         
133     }
134     
135     private Long getRevFromSASInstance(Specifier specifier) {
136         Long result = null;
137         
138         VocabularyClient client = new VocabularyClient();
139         String uri = getUri(specifier);
140         
141         return result;
142     }
143
144     /*
145      * Non standard injection of CSID into common part, since caller may access through
146      * shortId, and not know the CSID.
147      * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
148      */
149     @Override
150     protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
151             throws Exception {
152         Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
153
154         // Add the CSID to the common part
155         if (partMeta.getLabel().equalsIgnoreCase(authorityCommonSchemaName)) {
156             String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
157             unQObjectProperties.put("csid", csid);
158         }
159
160         return unQObjectProperties;
161     }
162     
163     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
164         super.fillAllParts(wrapDoc, action);
165         //
166         // Update the record's revision number on both CREATE and UPDATE actions
167         //
168         updateRevNumbers(wrapDoc);
169     }
170     
171     protected void updateRevNumbers(DocumentWrapper<DocumentModel> wrapDoc) {
172         DocumentModel documentModel = wrapDoc.getWrappedObject();
173         Long rev = (Long)documentModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV);
174         if (rev == null) {
175                 rev = (long)0;
176         } else {
177                 rev++;
178         }
179         documentModel.setProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV, rev);
180     }
181     
182     @Override
183     public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
184         super.handleCreate(wrapDoc);
185         // CSPACE-3178:
186         // Uncomment once debugged and App layer is read to integrate
187         // Experimenting with this uncommented now ...
188         handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityCommonSchemaName);
189         updateRefnameForAuthority(wrapDoc, authorityCommonSchemaName);//CSPACE-3178
190     }
191     
192     protected String buildWhereForShortId(String name) {
193         return authorityCommonSchemaName
194                 + ":" + AuthorityJAXBSchema.SHORT_IDENTIFIER
195                 + "='" + name + "'";
196     }
197     
198     private boolean isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
199         return true;
200     }
201     
202     private boolean temp_isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
203         boolean result = true;
204         
205         ServiceContext ctx = this.getServiceContext();
206         String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
207         String nxqlWhereClause = buildWhereForShortId(shortIdentifier);
208         try {
209                         DocumentWrapper<DocumentModel> searchResultWrapper = getRepositoryClient(ctx).findDoc(ctx, nxqlWhereClause);
210                         if (searchResultWrapper != null) {
211                                 result = false;
212                                 if (logger.isInfoEnabled() == true) {
213                                         DocumentModel searchResult = searchResultWrapper.getWrappedObject();
214                                         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'",
215                                                         shortIdentifier, searchResult.getName());
216                                         logger.trace(debugMsg);
217                                 }
218                         }
219                 } catch (DocumentNotFoundException e) {
220                         // Not a problem, just means we couldn't find another authority with that short ID
221                 }
222         
223         return result;
224     }
225
226     /**
227      * If no short identifier was provided in the input payload,
228      * generate a short identifier from the display name. Either way though,
229      * the short identifier needs to be unique.
230      */
231     private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
232         String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
233         String displayName = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.DISPLAY_NAME);
234         String shortDisplayName = "";
235         String generateShortIdentifier = null;
236         if (Tools.isEmpty(shortIdentifier)) {
237                 generateShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(displayName, shortDisplayName);
238             docModel.setProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER, shortIdentifier);
239         }
240         
241         if (isUnique(docModel, schemaName) == false) {
242                 String shortId = generateShortIdentifier == null ? shortIdentifier : generateShortIdentifier;
243                 String errMsgVerb = generateShortIdentifier == null ? "supplied" : "generated";
244                 String errMsg = String.format("The %s short identifier '%s' was not unique, so the new authority could not be created.",
245                                 errMsgVerb, shortId);
246                 throw new DocumentException(errMsg);
247         }
248     }
249  
250     /**
251      * Generate a refName for the authority from the short identifier
252      * and display name.
253      * 
254      * All refNames for authorities are generated.  If a client supplies
255      * a refName, it will be overwritten during create (per this method) 
256      * or discarded during update (per filterReadOnlyPropertiesForPart).
257      * 
258      * @see #filterReadOnlyPropertiesForPart(Map<String, Object>, org.collectionspace.services.common.service.ObjectPartType)
259      * 
260      */
261     protected void updateRefnameForAuthority(DocumentWrapper<DocumentModel> wrapDoc, String schemaName) throws Exception {
262         DocumentModel docModel = wrapDoc.getWrappedObject();
263         RefName.Authority authority = (Authority) getRefName(getServiceContext(), docModel);
264         String refName = authority.toString();
265         docModel.setProperty(schemaName, AuthorityJAXBSchema.REF_NAME, refName);
266     }
267     
268     @Override
269     public RefName.RefNameInterface getRefName(ServiceContext ctx,
270                 DocumentModel docModel) {
271         RefName.RefNameInterface refname = null;
272
273         try {
274                 String shortIdentifier = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
275                 String displayName = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.DISPLAY_NAME);
276                 RefName.Authority authority = RefName.Authority.buildAuthority(ctx.getTenantName(),
277                         ctx.getServiceName(),
278                         null,   // Only use shortId form!!!
279                         shortIdentifier,
280                         displayName);
281                 refname = authority;
282         } catch (Exception e) {
283                 logger.error(e.getMessage(), e);
284         }
285         
286         return refname;
287     }
288     
289     @Override
290     protected String getRefnameDisplayName(DocumentWrapper<DocumentModel> docWrapper) {
291         String result = null;
292         
293         DocumentModel docModel = docWrapper.getWrappedObject();
294         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
295         RefName.Authority refname = (RefName.Authority)getRefName(ctx, docModel);
296         result = refname.getDisplayName();
297         
298         return result;
299     }    
300     
301     public String getShortIdentifier(String authCSID, String schemaName) throws Exception {
302         String shortIdentifier = null;
303         CoreSessionInterface repoSession = null;
304
305         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
306         RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
307         try {
308                 repoSession = nuxeoRepoClient.getRepositorySession(ctx);
309             DocumentWrapper<DocumentModel> wrapDoc = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, authCSID);
310             DocumentModel docModel = wrapDoc.getWrappedObject();
311             shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
312         } catch (ClientException ce) {
313             throw new RuntimeException("AuthorityDocHandler Internal Error: cannot get shortId!", ce);
314         } finally {
315                 if (repoSession != null) {
316                         nuxeoRepoClient.releaseRepositorySession(ctx, repoSession);
317                 }
318         }
319         
320         return shortIdentifier;
321     }
322
323     /**
324      * Filters out selected values supplied in an update request.
325      * 
326      * @param objectProps the properties filtered out from the update payload
327      * @param partMeta metadata for the object to fill
328      */
329     @Override
330     public void filterReadOnlyPropertiesForPart(
331             Map<String, Object> objectProps, ObjectPartType partMeta) {
332         super.filterReadOnlyPropertiesForPart(objectProps, partMeta);
333         String commonPartLabel = getServiceContext().getCommonPartLabel();
334         if (partMeta.getLabel().equalsIgnoreCase(commonPartLabel)) {
335             objectProps.remove(AuthorityJAXBSchema.CSID);
336             objectProps.remove(AuthorityJAXBSchema.SHORT_IDENTIFIER);
337             objectProps.remove(AuthorityJAXBSchema.REF_NAME);
338         }
339     }    
340 }