]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
b6fa057bf94e09d459400239435c67d1f4e96184
[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             PoxPayloadIn input = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response!
126                 
127                         PayloadInputPart payloadInputPart = extractPart(res, client.getCommonPartName());
128                         if (payloadInputPart != null) {
129 //                              result = (client.getc) payloadInputPart.getBody();
130                         }
131         } finally {
132                 res.close();
133         }
134         
135     }
136     
137     private Long getRevFromSASInstance(Specifier specifier) {
138         Long result = null;
139         
140         VocabularyClient client = new VocabularyClient();
141         String uri = getUri(specifier);
142         
143         return result;
144     }
145
146     /*
147      * Non standard injection of CSID into common part, since caller may access through
148      * shortId, and not know the CSID.
149      * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
150      */
151     @Override
152     protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
153             throws Exception {
154         Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
155
156         // Add the CSID to the common part
157         if (partMeta.getLabel().equalsIgnoreCase(authorityCommonSchemaName)) {
158             String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
159             unQObjectProperties.put("csid", csid);
160         }
161
162         return unQObjectProperties;
163     }
164     
165     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
166         super.fillAllParts(wrapDoc, action);
167         //
168         // Update the record's revision number on both CREATE and UPDATE actions
169         //
170         updateRevNumbers(wrapDoc);
171     }
172     
173     protected void updateRevNumbers(DocumentWrapper<DocumentModel> wrapDoc) {
174         DocumentModel documentModel = wrapDoc.getWrappedObject();
175         Long rev = (Long)documentModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV);
176         if (rev == null) {
177                 rev = (long)0;
178         } else {
179                 rev++;
180         }
181         documentModel.setProperty(authorityCommonSchemaName, AuthorityJAXBSchema.REV, rev);
182     }
183     
184     @Override
185     public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
186         super.handleCreate(wrapDoc);
187         // CSPACE-3178:
188         // Uncomment once debugged and App layer is read to integrate
189         // Experimenting with this uncommented now ...
190         handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityCommonSchemaName);
191         updateRefnameForAuthority(wrapDoc, authorityCommonSchemaName);//CSPACE-3178
192     }
193     
194     protected String buildWhereForShortId(String name) {
195         return authorityCommonSchemaName
196                 + ":" + AuthorityJAXBSchema.SHORT_IDENTIFIER
197                 + "='" + name + "'";
198     }
199     
200     private boolean isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
201         return true;
202     }
203     
204     private boolean temp_isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
205         boolean result = true;
206         
207         ServiceContext ctx = this.getServiceContext();
208         String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
209         String nxqlWhereClause = buildWhereForShortId(shortIdentifier);
210         try {
211                         DocumentWrapper<DocumentModel> searchResultWrapper = getRepositoryClient(ctx).findDoc(ctx, nxqlWhereClause);
212                         if (searchResultWrapper != null) {
213                                 result = false;
214                                 if (logger.isInfoEnabled() == true) {
215                                         DocumentModel searchResult = searchResultWrapper.getWrappedObject();
216                                         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'",
217                                                         shortIdentifier, searchResult.getName());
218                                         logger.trace(debugMsg);
219                                 }
220                         }
221                 } catch (DocumentNotFoundException e) {
222                         // Not a problem, just means we couldn't find another authority with that short ID
223                 }
224         
225         return result;
226     }
227
228     /**
229      * If no short identifier was provided in the input payload,
230      * generate a short identifier from the display name. Either way though,
231      * the short identifier needs to be unique.
232      */
233     private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
234         String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
235         String displayName = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.DISPLAY_NAME);
236         String shortDisplayName = "";
237         String generateShortIdentifier = null;
238         if (Tools.isEmpty(shortIdentifier)) {
239                 generateShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(displayName, shortDisplayName);
240             docModel.setProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER, shortIdentifier);
241         }
242         
243         if (isUnique(docModel, schemaName) == false) {
244                 String shortId = generateShortIdentifier == null ? shortIdentifier : generateShortIdentifier;
245                 String errMsgVerb = generateShortIdentifier == null ? "supplied" : "generated";
246                 String errMsg = String.format("The %s short identifier '%s' was not unique, so the new authority could not be created.",
247                                 errMsgVerb, shortId);
248                 throw new DocumentException(errMsg);
249         }
250     }
251  
252     /**
253      * Generate a refName for the authority from the short identifier
254      * and display name.
255      * 
256      * All refNames for authorities are generated.  If a client supplies
257      * a refName, it will be overwritten during create (per this method) 
258      * or discarded during update (per filterReadOnlyPropertiesForPart).
259      * 
260      * @see #filterReadOnlyPropertiesForPart(Map<String, Object>, org.collectionspace.services.common.service.ObjectPartType)
261      * 
262      */
263     protected void updateRefnameForAuthority(DocumentWrapper<DocumentModel> wrapDoc, String schemaName) throws Exception {
264         DocumentModel docModel = wrapDoc.getWrappedObject();
265         RefName.Authority authority = (Authority) getRefName(getServiceContext(), docModel);
266         String refName = authority.toString();
267         docModel.setProperty(schemaName, AuthorityJAXBSchema.REF_NAME, refName);
268     }
269     
270     @Override
271     public RefName.RefNameInterface getRefName(ServiceContext ctx,
272                 DocumentModel docModel) {
273         RefName.RefNameInterface refname = null;
274
275         try {
276                 String shortIdentifier = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
277                 String displayName = (String) docModel.getProperty(authorityCommonSchemaName, AuthorityJAXBSchema.DISPLAY_NAME);
278                 RefName.Authority authority = RefName.Authority.buildAuthority(ctx.getTenantName(),
279                         ctx.getServiceName(),
280                         null,   // Only use shortId form!!!
281                         shortIdentifier,
282                         displayName);
283                 refname = authority;
284         } catch (Exception e) {
285                 logger.error(e.getMessage(), e);
286         }
287         
288         return refname;
289     }
290     
291     @Override
292     protected String getRefnameDisplayName(DocumentWrapper<DocumentModel> docWrapper) {
293         String result = null;
294         
295         DocumentModel docModel = docWrapper.getWrappedObject();
296         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
297         RefName.Authority refname = (RefName.Authority)getRefName(ctx, docModel);
298         result = refname.getDisplayName();
299         
300         return result;
301     }    
302     
303     public String getShortIdentifier(String authCSID, String schemaName) throws Exception {
304         String shortIdentifier = null;
305         CoreSessionInterface repoSession = null;
306
307         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
308         RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx);
309         try {
310                 repoSession = nuxeoRepoClient.getRepositorySession(ctx);
311             DocumentWrapper<DocumentModel> wrapDoc = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, authCSID);
312             DocumentModel docModel = wrapDoc.getWrappedObject();
313             shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
314         } catch (ClientException ce) {
315             throw new RuntimeException("AuthorityDocHandler Internal Error: cannot get shortId!", ce);
316         } finally {
317                 if (repoSession != null) {
318                         nuxeoRepoClient.releaseRepositorySession(ctx, repoSession);
319                 }
320         }
321         
322         return shortIdentifier;
323     }
324
325     /**
326      * Filters out selected values supplied in an update request.
327      * 
328      * @param objectProps the properties filtered out from the update payload
329      * @param partMeta metadata for the object to fill
330      */
331     @Override
332     public void filterReadOnlyPropertiesForPart(
333             Map<String, Object> objectProps, ObjectPartType partMeta) {
334         super.filterReadOnlyPropertiesForPart(objectProps, partMeta);
335         String commonPartLabel = getServiceContext().getCommonPartLabel();
336         if (partMeta.getLabel().equalsIgnoreCase(commonPartLabel)) {
337             objectProps.remove(AuthorityJAXBSchema.CSID);
338             objectProps.remove(AuthorityJAXBSchema.SHORT_IDENTIFIER);
339             objectProps.remove(AuthorityJAXBSchema.REF_NAME);
340         }
341     }    
342 }