]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2e2ffde8c84c023dff6a8b68d569ee35f133f3ba
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.nuxeo.elasticsearch.materials;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Iterator;
6 import java.util.LinkedHashSet;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10
11 import org.apache.commons.lang3.StringUtils;
12
13 import org.codehaus.jackson.JsonNode;
14 import org.codehaus.jackson.map.ObjectMapper;
15 import org.codehaus.jackson.node.ObjectNode;
16 import org.codehaus.jackson.node.TextNode;
17
18 import org.collectionspace.services.common.api.RefNameUtils;
19 import org.collectionspace.services.nuxeo.elasticsearch.DefaultESDocumentWriter;
20 import org.nuxeo.ecm.core.api.CoreSession;
21 import org.nuxeo.ecm.core.api.DocumentModel;
22 import org.nuxeo.ecm.core.api.DocumentModelList;
23
24 public class MaterialsESDocumentWriter extends DefaultESDocumentWriter {
25
26         @Override
27         public ObjectNode getDenormValues(DocumentModel doc) {
28                 ObjectMapper objectMapper = new ObjectMapper();
29                 ObjectNode denormValues = objectMapper.createObjectNode();
30
31                 String docType = doc.getType();
32
33                 if (docType.startsWith("Materialitem")) {
34                         CoreSession session = doc.getCoreSession();
35
36                         // Store the csids of media records that reference this material authority item via the
37                         // coverage field.
38
39                         String refName = (String) doc.getProperty("collectionspace_core", "refName");
40
41                         if (StringUtils.isNotEmpty(refName)) {
42                                 String tenantId = (String) doc.getProperty("collectionspace_core", "tenantId");
43
44                                 denormMediaRecords(session, refName, tenantId, denormValues);
45                         }
46
47                         // Compute the title of the record for the public browser, and store it so that it can
48                         // be used for sorting ES query results.
49
50                         String title = computeTitle(doc);
51
52                         if (title != null) {
53                                 denormValues.put("title", title);
54                         }
55
56                         List<Map<String, Object>> termGroups = (List<Map<String, Object>>) doc.getProperty("materials_common", "materialTermGroupList");
57                         List<String> commercialNames = findTermDisplayNamesWithFlag(termGroups, "commercial");
58                         List<String> commonNames = findTermDisplayNamesWithFlag(termGroups, "common");
59
60                         // Find and store the commercial names and common names for this item. This simplifies
61                         // search and display in the Material Order application.
62
63                         if (commercialNames.size() > 0) {
64                                 denormValues.putArray("commercialNames").addAll(jsonNodes(commercialNames));
65                         }
66
67                         if (commonNames.size() > 0) {
68                                 denormValues.putArray("commonNames").addAll(jsonNodes(commonNames));
69                         }
70
71                         // Combine term creator organizations and term editor organizations into a holding
72                         // institutions field.
73
74                         Set<String> holdingInstitutions = new LinkedHashSet<String>();
75
76                         holdingInstitutions.addAll(getTermAttributionContributors(doc));
77                         holdingInstitutions.addAll(getTermAttributionEditors(doc));
78
79                         if (holdingInstitutions.size() > 0) {
80                                 denormValues.putArray("holdingInstitutions").addAll(jsonNodes(holdingInstitutions));
81                         }
82                 }
83
84                 // Below is sample code for denormalizing fields from the computed current location (place
85                 // item) into collection object documents. This was written for the public browser
86                 // prototype for public art.
87
88                 /*
89                 if (docType.startsWith("CollectionObject")) {
90                         CoreSession session = doc.getCoreSession();
91
92                         String refName = (String) doc.getProperty("collectionobjects_common", "computedCurrentLocation");
93
94                         if (StringUtils.isNotEmpty(refName)) {
95                                 String escapedRefName = refName.replace("'", "\\'");
96                                 String placeQuery = String.format("SELECT * FROM PlaceitemTenant5000 WHERE places_common:refName = '%s'", escapedRefName);
97
98                                 DocumentModelList placeDocs = session.query(placeQuery, 1);
99
100                                 if (placeDocs.size() > 0) {
101                                         DocumentModel placeDoc = placeDocs.get(0);
102
103                                         String placementType = (String) placeDoc.getProperty("places_publicart:placementType").getValue();
104
105                                         if (placementType != null) {
106                                                 denormValues.put("placementType", placementType);
107                                         }
108
109                                         Property geoRefGroup;
110
111                                         try {
112                                                 geoRefGroup = placeDoc.getProperty("places_common:placeGeoRefGroupList/0");
113                                         } catch (PropertyNotFoundException e) {
114                                                 geoRefGroup = null;
115                                         }
116
117                                         if (geoRefGroup != null) {
118                                                 Double decimalLatitude = (Double) geoRefGroup.getValue("decimalLatitude");
119                                                 Double decimalLongitude = (Double) geoRefGroup.getValue("decimalLongitude");
120
121                                                 if (decimalLatitude != null && decimalLongitude != null) {
122                                                         ObjectNode geoPointNode = objectMapper.createObjectNode();
123
124                                                         geoPointNode.put("lat", decimalLatitude);
125                                                         geoPointNode.put("lon", decimalLongitude);
126
127                                                         denormValues.put("geoPoint", geoPointNode);
128                                                 }
129                                         }
130                                 }
131                         }
132
133                         String uri = (String) doc.getProperty("collectionobjects_core", "uri");
134                         String csid = uri.substring(uri.lastIndexOf('/') + 1);
135                         String mediaQuery = String.format("SELECT media_common:blobCsid, media_common:title FROM Relation WHERE relations_common:subjectCsid = '%s' AND relations_common:objectDocumentType = 'Media'", csid);
136
137                         DocumentModelList mediaDocs = session.query(mediaQuery, 1);
138
139                         if (mediaDocs.size() > 0) {
140
141                         }
142                 }
143                 */
144
145                 return denormValues;
146         }
147
148         private void denormMediaRecords(CoreSession session, String refName, String tenantId, ObjectNode denormValues) {
149                 // Store the csid and alt text of media records that are related to this object.
150
151                 String escapedRefName = refName.replace("'", "\\'");
152                 String mediaQuery = String.format("SELECT * FROM Media WHERE media_common:coverage = '%s' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s' ORDER BY media_common:identificationNumber", escapedRefName, tenantId);
153                 DocumentModelList mediaDocs = session.query(mediaQuery);
154                 List<JsonNode> mediaCsids = new ArrayList<JsonNode>();
155                 List<JsonNode> mediaAltTexts = new ArrayList<JsonNode>();
156
157                 if (mediaDocs.size() > 0) {
158                         Iterator<DocumentModel> iterator = mediaDocs.iterator();
159
160                         while (iterator.hasNext()) {
161                                 DocumentModel mediaDoc = iterator.next();
162
163                                 if (isMediaPublished(mediaDoc)) {
164                                         String mediaCsid = (String) mediaDoc.getName();
165
166                                         mediaCsids.add(new TextNode(mediaCsid));
167
168                                         String altText = (String) mediaDoc.getProperty("media_common", "altText");
169
170                                         if (altText == null) {
171                                                 altText = "";
172                                         }
173
174                                         mediaAltTexts.add(new TextNode(altText));
175                                 }
176                         }
177                 }
178
179                 denormValues.putArray("mediaCsid").addAll(mediaCsids);
180                 denormValues.putArray("mediaAltText").addAll(mediaAltTexts);
181         }
182
183
184         /**
185          * Compute a title for the public browser. This needs to be indexed in ES so that it can
186          * be used for sorting. (Even if it's just extracting the primary value.)
187          */
188         private String computeTitle(DocumentModel doc) {
189                 List<Map<String, Object>> termGroups = (List<Map<String, Object>>) doc.getProperty("materials_common", "materialTermGroupList");
190                 String primaryDisplayName = null;
191
192                 if (termGroups.size() > 0) {
193                         Map<String, Object> primaryTermGroup = termGroups.get(0);
194                         primaryDisplayName = (String) primaryTermGroup.get("termDisplayName");
195                 }
196
197                 return primaryDisplayName;
198         }
199
200         private List<String> findTermDisplayNamesWithFlag(List<Map<String, Object>> termGroups, String flagShortId) {
201                 List<String> termDisplayNames = new ArrayList<String>();
202
203                 for (Map<String, Object> termGroup : termGroups) {
204                         String termFlag = (String) termGroup.get("termFlag");
205
206                         if (termFlag != null && termFlag.contains("(" + flagShortId + ")")) {
207                                 String candidateTermDisplayName = (String) termGroup.get("termDisplayName");
208
209                                 if (StringUtils.isNotEmpty(candidateTermDisplayName)) {
210                                         termDisplayNames.add(candidateTermDisplayName);
211                                 }
212                         }
213                 }
214
215                 return termDisplayNames;
216         }
217
218         private Set<String> getTermAttributionContributors(DocumentModel doc) {
219                 Set orgs = new LinkedHashSet<String>();
220
221                 List<Map<String, Object>> groups = (List<Map<String, Object>>) doc.getProperty("materials_common", "materialTermAttributionContributingGroupList");
222
223                 for (Map<String, Object> group : groups) {
224                         String org = (String) group.get("materialTermAttributionContributingOrganization");
225
226                         if (StringUtils.isNotEmpty(org)) {
227                                 orgs.add(org);
228                         }
229                 }
230
231                 return orgs;
232         }
233
234         private Set<String> getTermAttributionEditors(DocumentModel doc) {
235                 Set orgs = new LinkedHashSet<String>();
236
237                 List<Map<String, Object>> groups = (List<Map<String, Object>>) doc.getProperty("materials_common", "materialTermAttributionEditingGroupList");
238
239                 for (Map<String, Object> group : groups) {
240                         String org = (String) group.get("materialTermAttributionEditingOrganization");
241
242                         if (StringUtils.isNotEmpty(org)) {
243                                 orgs.add(org);
244                         }
245                 }
246
247                 return orgs;
248         }
249
250         private boolean isMediaPublished(DocumentModel mediaDoc) {
251                 List<String> publishToValues = (List<String>) mediaDoc.getProperty("media_materials", "publishToList");
252                 boolean isPublished = false;
253
254                 if (publishToValues != null) {
255                         for (int i=0; i<publishToValues.size(); i++) {
256                                 String value = publishToValues.get(i);
257                                 String shortId = RefNameUtils.getItemShortId(value);
258
259                                 if (shortId.equals("all") || shortId.equals("materialorder")) {
260                                         isPublished = true;
261                                         break;
262                                 }
263                         }
264                 }
265
266                 return isPublished;
267         }
268
269         private List<JsonNode> jsonNodes(Collection<String> values) {
270                 List<JsonNode> nodes = new ArrayList<JsonNode>();
271                 Iterator<String> iterator = values.iterator();
272
273                 while (iterator.hasNext()) {
274                         String value = iterator.next();
275
276                         nodes.add(new TextNode(value));
277                 }
278
279                 return nodes;
280         }
281 }