]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
13042ca62aedfdd33e97597751df70a4bb97e90d
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.advancedsearch;
2
3 import java.util.Collections;
4 import java.util.Map;
5 import java.util.function.Predicate;
6 import java.util.stream.Collectors;
7 import javax.ws.rs.Consumes;
8 import javax.ws.rs.GET;
9 import javax.ws.rs.Path;
10 import javax.ws.rs.Produces;
11 import javax.ws.rs.core.Context;
12 import javax.ws.rs.core.MultivaluedMap;
13 import javax.ws.rs.core.Request;
14 import javax.ws.rs.core.UriInfo;
15 import javax.xml.bind.JAXBException;
16 import javax.xml.bind.Unmarshaller;
17
18 import org.collectionspace.services.MediaJAXBSchema;
19 import org.collectionspace.services.advancedsearch.AdvancedsearchCommonList.AdvancedsearchListItem;
20 import org.collectionspace.services.advancedsearch.mapper.CollectionObjectMapper;
21 import org.collectionspace.services.client.IClientQueryParams;
22 import org.collectionspace.services.client.IQueryManager;
23 import org.collectionspace.services.collectionobject.CollectionObjectResource;
24 import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
25 import org.collectionspace.services.common.UriInfoWrapper;
26 import org.collectionspace.services.common.context.RemoteServiceContextFactory;
27 import org.collectionspace.services.common.context.ServiceContextFactory;
28 import org.collectionspace.services.common.relation.RelationResource;
29 import org.collectionspace.services.jaxb.AbstractCommonList;
30 import org.collectionspace.services.media.MediaResource;
31 import org.collectionspace.services.nuxeo.client.handler.CSDocumentModelList;
32 import org.collectionspace.services.nuxeo.client.handler.CSDocumentModelList.CSDocumentModelResponse;
33 import org.collectionspace.services.nuxeo.client.handler.UnfilteredDocumentModelHandler;
34 import org.collectionspace.services.relation.RelationsCommonList;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.w3c.dom.Element;
38
39 /**
40  * This class defines the advanced search endpoints.
41  */
42 @Path(AdvancedSearchConstants.SERVICE_PATH)
43 @Consumes("application/xml")
44 @Produces("application/xml")
45 public class AdvancedSearch
46                 extends AbstractCollectionSpaceResourceImpl<AdvancedsearchListItem, AdvancedsearchListItem> {
47         // FIXME: it's not great to hardcode either of these
48         private static final String FIELDS_RETURNED = "uri|csid|refName|blobCsid|updatedAt|objectId|objectNumber|objectName|title|computedCurrentLocation|responsibleDepartments|responsibleDepartment|contentConcepts|briefDescription";
49
50         private final Logger logger = LoggerFactory.getLogger(AdvancedSearch.class);
51         private final CollectionObjectResource cor = new CollectionObjectResource();
52         private final MediaResource mr = new MediaResource();
53         private final RelationResource relations = new RelationResource();
54
55         private static final String PAGE_SIZE = "1";
56         private static final String PAGE_NUM = "0";
57         private static final String MEDIA_SORT_BY = "media_common:title";
58
59         public AdvancedSearch() {
60                 super();
61         }
62
63         /**
64          * Primary advanced search API endpoint.
65          * 
66          * @param request The incoming request. Injected. 
67          * @param uriInfo The URI info of the incoming request, including query parameters and other search control parameters. Injected.
68          * @return A possibly-empty AbstractCommonList of the advanced search results corresponding to the query
69          */
70         @GET
71         public AbstractCommonList getList(@Context Request request, @Context UriInfo uriInfo) {
72                 logger.info("advancedsearch called with path: {}", uriInfo.getPath());
73                 MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(true);
74                 logger.info("advancedsearch called with query params: {}", queryParams);
75                 final String markRelated = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT);
76
77                 cor.setDocumentHandlerClass(UnfilteredDocumentModelHandler.class);
78                 ObjectFactory objectFactory = new ObjectFactory();
79                 AdvancedsearchCommonList resultsList = objectFactory.createAdvancedsearchCommonList();
80
81                 AbstractCommonList abstractCommonList = cor.getList(uriInfo);
82                 if (!(abstractCommonList instanceof CSDocumentModelList)) {
83                         return resultsList;
84                 }
85
86                 Unmarshaller unmarshaller;
87                 CSDocumentModelList collectionObjectList = (CSDocumentModelList) abstractCommonList;
88                 try {
89                         unmarshaller = AdvancedSearchJAXBContext.getJaxbContext().createUnmarshaller();
90                 } catch (JAXBException e) {
91                         // this should result in a 500, need to verify from bigReThrow to see what exception it should be
92                         throw new RuntimeException("Unable to create unmarshaller for AdvancedSearch", e);
93                 }
94
95                 final CollectionObjectMapper responseMapper = new CollectionObjectMapper(unmarshaller);
96                 final UriInfoWrapper relUriInfo = relationUriInfo(uriInfo);
97                 for (CSDocumentModelResponse response : collectionObjectList.getResponseList()) {
98                         String csid = response.getCsid();
99                         UriInfoWrapper blobUriInfo = new UriInfoWrapper(uriInfo);
100                         Map<String, String> blobInfo = findBlobInfo(csid, blobUriInfo);
101
102                         AdvancedsearchListItem listItem = responseMapper.asListItem(response, blobInfo);
103                         if (listItem != null) {
104                                 if (markRelated != null) {
105                                         RelationsCommonList relationsList = relations.getRelationForSubject(markRelated, csid, relUriInfo);
106                                         listItem.setRelated(!relationsList.getRelationListItem().isEmpty());
107                                 }
108                                 resultsList.getAdvancedsearchListItem().add(listItem);
109                         }
110                 }
111
112                 resultsList.setItemsInPage(collectionObjectList.getItemsInPage());
113                 resultsList.setPageNum(collectionObjectList.getPageNum());
114                 resultsList.setPageSize(collectionObjectList.getPageSize());
115                 resultsList.setTotalItems(collectionObjectList.getTotalItems());
116                 resultsList.setFieldsReturned(FIELDS_RETURNED);
117
118                 return resultsList;
119         }
120
121         private UriInfoWrapper relationUriInfo(final UriInfo uriInfo) {
122                 final UriInfoWrapper wrapper = new UriInfoWrapper(uriInfo);
123                 final MultivaluedMap<String, String> queryParameters = wrapper.getQueryParameters();
124                 queryParameters.clear();
125                 queryParameters.add(IClientQueryParams.PAGE_SIZE_PARAM, PAGE_SIZE);
126                 queryParameters.add(IClientQueryParams.START_PAGE_PARAM, PAGE_NUM);
127                 return wrapper;
128         }
129
130         /** 
131          * Retrieves the blob CSIDs associated with a given object's CSID
132          * 
133          * @param csid The CSID of an object whose associated blobs (thumbnails) is desired
134          * @param wrappedUriInfo The wrapped (mutable) UriInfo of the incoming query that ultimately triggered this call
135          * @return A possibly-empty list of strings of the blob CSIDs associated with CSID
136          */
137         private Map<String, String> findBlobInfo(String csid, UriInfoWrapper wrappedUriInfo) {
138                 MultivaluedMap<String, String> wrappedQueryParams = wrappedUriInfo.getQueryParameters();
139                 wrappedQueryParams.clear();
140                 wrappedQueryParams.add(IQueryManager.SEARCH_RELATED_TO_CSID_AS_SUBJECT, csid);
141                 wrappedQueryParams.add(IClientQueryParams.PAGE_SIZE_PARAM, PAGE_SIZE);
142                 wrappedQueryParams.add(IClientQueryParams.START_PAGE_PARAM, PAGE_NUM);
143                 wrappedQueryParams.add(IClientQueryParams.ORDER_BY_PARAM, MEDIA_SORT_BY);
144                 AbstractCommonList associatedMedia = mr.getList(wrappedUriInfo);
145                 if (associatedMedia == null || associatedMedia.getListItem() == null) {
146                         return Collections.emptyMap();
147                 }
148
149                 Predicate<Element> tagFilter = (element -> MediaJAXBSchema.blobCsid.equals(element.getTagName()) ||
150                                                                                                    MediaJAXBSchema.altText.equals(element.getTagName()));
151                 Predicate<Element> tagNotEmpty = (element -> element.getTextContent()  != null &&
152                                                                                                          !element.getTextContent().isEmpty());
153
154         return associatedMedia.getListItem().stream()
155                         .filter(item -> item != null && item.getAny() != null)
156                         .flatMap(li -> li.getAny().stream())
157                         .filter(tagFilter.and(tagNotEmpty))
158                         .collect(Collectors.toMap(Element::getTagName, Element::getTextContent));
159         }
160
161         @Override
162         public Class<?> getCommonPartClass() {
163                 return null;
164         }
165
166         @Override
167         public ServiceContextFactory<AdvancedsearchListItem, AdvancedsearchListItem> getServiceContextFactory() {
168                 return (ServiceContextFactory<AdvancedsearchListItem, AdvancedsearchListItem>) RemoteServiceContextFactory
169                                 .get();
170         }
171
172         @Override
173         public String getServiceName() {
174                 return AdvancedSearchConstants.SERVICE_NAME;
175         }
176
177         @Override
178         protected String getVersionString() {
179                 return "0.01";
180         }
181 }