1 package org.collectionspace.services.export;
3 import java.math.BigInteger;
5 import java.net.URISyntaxException;
6 import java.util.Arrays;
7 import java.util.Iterator;
9 import java.util.NoSuchElementException;
11 import javax.ws.rs.core.PathSegment;
12 import javax.ws.rs.core.UriInfo;
14 import org.apache.commons.lang3.StringUtils;
15 import org.apache.http.client.utils.URIBuilder;
16 import org.collectionspace.services.client.PoxPayloadIn;
17 import org.collectionspace.services.client.PoxPayloadOut;
18 import org.collectionspace.services.common.NuxeoBasedResource;
19 import org.collectionspace.services.common.ServiceMain;
20 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
21 import org.collectionspace.services.common.context.ServiceBindingUtils;
22 import org.collectionspace.services.common.context.ServiceContext;
23 import org.collectionspace.services.common.invocable.InvocationContext;
24 import org.collectionspace.services.common.query.UriInfoImpl;
25 import org.collectionspace.services.common.vocabulary.AuthorityResource;
26 import org.collectionspace.services.config.service.ServiceBindingType;
27 import org.collectionspace.services.jaxb.AbstractCommonList;
28 import org.jboss.resteasy.specimpl.PathSegmentImpl;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public abstract class AbstractDocumentsByQueryIterator<ListItemType> implements Iterator<PoxPayloadOut> {
33 private final Logger logger = LoggerFactory.getLogger(AbstractDocumentsByQueryIterator.class);
35 private NuxeoBasedResource resource;
36 private String vocabulary;
37 private boolean isAuthorityItem = false;
38 private AbstractCommonList resultList;
39 private Iterator<ListItemType> resultItemIterator;
40 private InvocationContext.Query query;
42 protected ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext;
44 AbstractDocumentsByQueryIterator(
45 ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext,
48 InvocationContext.Query query) throws Exception {
50 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
51 ServiceBindingType serviceBinding = tenantBindingConfigReader.getServiceBindingForDocType(serviceContext.getTenantId(), docType);
52 String serviceType = serviceBinding.getType();
53 String serviceName = serviceBinding.getName();
55 this.serviceContext = serviceContext;
56 this.isAuthorityItem = ServiceBindingUtils.SERVICE_TYPE_AUTHORITY.equals(serviceType);
57 this.vocabulary = vocabulary;
59 this.resource = isAuthorityItem
60 ? AuthorityResource.getResourceForItem(serviceContext.getResourceMap(), serviceContext.getTenantId(), docType)
61 : (NuxeoBasedResource) serviceContext.getResource(serviceName.toLowerCase());
68 private void getResults(InvocationContext.Query query) throws Exception {
69 UriInfo uriInfo = createUriInfo(query);
71 resultList = isAuthorityItem
72 ? ((AuthorityResource<?, ?>) resource).getAuthorityItemList(serviceContext, vocabulary == null ? AuthorityResource.PARENT_WILDCARD : vocabulary, uriInfo)
73 : resource.getList(serviceContext, uriInfo);
75 resultItemIterator = (resultList == null) ? null : getListItems(resultList).iterator();
78 protected abstract List<ListItemType> getListItems(AbstractCommonList list);
80 private boolean hasMoreResultPages() {
81 if (resultList == null || query.getPgNum() != null) {
85 long pageSize = resultList.getPageSize();
86 long pageNum = resultList.getPageNum();
87 long totalItems = resultList.getTotalItems();
89 return (totalItems > (pageSize * (pageNum + 1)));
92 private void getNextResultPage() throws Exception {
93 if (hasMoreResultPages()) {
94 long pageSize = resultList.getPageSize();
95 long pageNum = resultList.getPageNum();
97 InvocationContext.Query nextPageQuery = new InvocationContext.Query();
99 nextPageQuery.setAs(query.getAs());
100 nextPageQuery.setKw(query.getKw());
101 nextPageQuery.setPgNum(BigInteger.valueOf(pageNum + 1));
102 nextPageQuery.setPgSz(BigInteger.valueOf(pageSize));
103 nextPageQuery.setWfDeleted(query.isWfDeleted());
105 getResults(nextPageQuery);
110 public boolean hasNext() {
113 && resultItemIterator != null
114 && (resultItemIterator.hasNext() || hasMoreResultPages())
119 public PoxPayloadOut next() {
120 if (resultList == null || resultItemIterator == null) {
121 throw new NoSuchElementException();
124 if (!resultItemIterator.hasNext()) {
125 if (!hasMoreResultPages()) {
126 throw new NoSuchElementException();
132 catch (Exception e) {
133 logger.warn("Could not get result page", e);
139 return getDocument(resultItemIterator.next());
142 protected PoxPayloadOut getDocument(ListItemType item) {
143 String csid = getListItemCsid(item);
146 return (isAuthorityItem
147 ? ((AuthorityResource<?, ?>) resource).getAuthorityItemWithExistingContext(serviceContext, AuthorityResource.PARENT_WILDCARD, csid)
148 : resource.getWithParentCtx(serviceContext, csid));
150 catch (Exception e) {
151 logger.warn("Could not get document with csid " + csid, e);
157 protected abstract String getListItemCsid(ListItemType listItem);
159 protected UriInfo createUriInfo(InvocationContext.Query query) throws URISyntaxException {
160 URI absolutePath = new URI("");
161 URI baseUri = new URI("");
162 String encodedPath = "";
164 // Some code in services assumes pathSegments will have at least one element, so add an
166 List<PathSegment> pathSegments = Arrays.asList((PathSegment) new PathSegmentImpl("", false));
168 URIBuilder uriBuilder = new URIBuilder();
170 String as = query.getAs();
172 if (StringUtils.isNotEmpty(as)) {
173 uriBuilder.addParameter("as", as);
176 String kw = query.getKw();
178 if (StringUtils.isNotEmpty(kw)) {
179 uriBuilder.addParameter("kw", kw);
182 BigInteger pgNum = query.getPgNum();
185 uriBuilder.addParameter("pgNum", pgNum.toString());
188 BigInteger pgSz = query.getPgSz();
191 uriBuilder.addParameter("pgSz", pgSz.toString());
194 Boolean wfDeleted = query.isWfDeleted();
196 if (wfDeleted != null) {
197 uriBuilder.addParameter("wf_deleted", Boolean.toString(wfDeleted));
200 String sbj = query.getSbj();
202 if (StringUtils.isNotEmpty(sbj)) {
203 uriBuilder.addParameter("sbj", sbj);
206 String sbjType = query.getSbjType();
208 if (StringUtils.isNotEmpty(sbjType)) {
209 uriBuilder.addParameter("sbjType", sbjType);
212 String prd = query.getPrd();
214 if (StringUtils.isNotEmpty(prd)) {
215 uriBuilder.addParameter("prd", prd);
218 String obj = query.getObj();
220 if (StringUtils.isNotEmpty(obj)) {
221 uriBuilder.addParameter("obj", obj);
224 String objType = query.getObjType();
226 if (StringUtils.isNotEmpty(objType)) {
227 uriBuilder.addParameter("objType", objType);
230 Boolean andReciprocal = query.isAndReciprocal();
232 if (andReciprocal != null) {
233 uriBuilder.addParameter("andReciprocal", Boolean.toString(andReciprocal));
236 String queryString = uriBuilder.toString();
238 if (StringUtils.isNotEmpty(queryString)) {
239 queryString = queryString.substring(1); // Remove ? from beginning
242 return new UriInfoImpl(absolutePath, baseUri, encodedPath, queryString, pathSegments);