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