This project has retired. For details please refer to its
Attic page.
DiscoveryService xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.server.impl.atompub;
20
21 import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
22 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_CHANGES;
23 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_QUERY;
24 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
25 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrlBuilder;
26 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.writeContentChangesObjectEntry;
27 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBigIntegerParameter;
28 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
29 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
30 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
31
32 import java.math.BigInteger;
33 import java.util.GregorianCalendar;
34
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpServletResponse;
37 import javax.xml.bind.JAXBElement;
38 import javax.xml.bind.Unmarshaller;
39
40 import org.apache.chemistry.opencmis.commons.data.ObjectData;
41 import org.apache.chemistry.opencmis.commons.data.ObjectList;
42 import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
43 import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
44 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
45 import org.apache.chemistry.opencmis.commons.impl.Constants;
46 import org.apache.chemistry.opencmis.commons.impl.JaxBHelper;
47 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
48 import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisObjectType;
49 import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisQueryType;
50 import org.apache.chemistry.opencmis.commons.server.CallContext;
51 import org.apache.chemistry.opencmis.commons.server.CmisService;
52 import org.apache.chemistry.opencmis.commons.spi.Holder;
53
54
55
56
57 public class DiscoveryService {
58
59 private static final String METHOD_GET = "GET";
60 private static final String METHOD_POST = "POST";
61
62 private DiscoveryService() {
63 }
64
65
66
67
68 public static void query(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
69 HttpServletResponse response) throws Exception {
70
71 String statement = null;
72 Boolean searchAllVersions = null;
73 Boolean includeAllowableActions = null;
74 IncludeRelationships includeRelationships = null;
75 String renditionFilter = null;
76 BigInteger maxItems = null;
77 BigInteger skipCount = null;
78
79 int statusCode = 0;
80
81 if (METHOD_POST.equals(request.getMethod())) {
82
83 Object queryRequest = null;
84 try {
85 Unmarshaller u = JaxBHelper.createUnmarshaller();
86 queryRequest = u.unmarshal(request.getInputStream());
87 } catch (Exception e) {
88 throw new CmisInvalidArgumentException("Invalid query request: " + e, e);
89 }
90
91 if (!(queryRequest instanceof JAXBElement<?>)) {
92 throw new CmisInvalidArgumentException("Not a query document!");
93 }
94
95 if (!(((JAXBElement<?>) queryRequest).getValue() instanceof CmisQueryType)) {
96 throw new CmisInvalidArgumentException("Not a query document!");
97 }
98
99 CmisQueryType queryType = (CmisQueryType) ((JAXBElement<?>) queryRequest).getValue();
100
101 statement = queryType.getStatement();
102 searchAllVersions = queryType.isSearchAllVersions();
103 includeAllowableActions = queryType.isIncludeAllowableActions();
104 includeRelationships = convert(IncludeRelationships.class, queryType.getIncludeRelationships());
105 renditionFilter = queryType.getRenditionFilter();
106 maxItems = queryType.getMaxItems();
107 skipCount = queryType.getSkipCount();
108
109 statusCode = HttpServletResponse.SC_CREATED;
110 } else if (METHOD_GET.equals(request.getMethod())) {
111
112 statement = getStringParameter(request, Constants.PARAM_Q);
113 searchAllVersions = getBooleanParameter(request, Constants.PARAM_SEARCH_ALL_VERSIONS);
114 includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
115 includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS, IncludeRelationships.class);
116 renditionFilter = null;
117 maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
118 skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
119
120 statusCode = HttpServletResponse.SC_OK;
121 } else {
122 throw new CmisRuntimeException("Invalid HTTP method!");
123 }
124
125
126 ObjectList results = service.query(repositoryId, statement, searchAllVersions, includeAllowableActions,
127 includeRelationships, renditionFilter, maxItems, skipCount, null);
128
129 if (results == null) {
130 throw new CmisRuntimeException("Results are null!");
131 }
132
133
134 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
135
136 UrlBuilder pagingUrl = compileUrlBuilder(baseUrl, RESOURCE_QUERY, null);
137 pagingUrl.addParameter(Constants.PARAM_Q, statement);
138 pagingUrl.addParameter(Constants.PARAM_SEARCH_ALL_VERSIONS, searchAllVersions);
139 pagingUrl.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
140 pagingUrl.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
141
142 UrlBuilder location = new UrlBuilder(pagingUrl);
143 location.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
144 location.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
145
146 response.setStatus(statusCode);
147 response.setContentType(Constants.MEDIATYPE_FEED);
148
149
150
151
152
153
154
155 response.setHeader("Location", location.toString());
156
157
158 AtomFeed feed = new AtomFeed();
159 feed.startDocument(response.getOutputStream());
160 feed.startFeed(true);
161
162
163 GregorianCalendar now = new GregorianCalendar();
164 feed.writeFeedElements("query", "", "Query", now, null, results.getNumItems());
165
166
167 feed.writeServiceLink(baseUrl.toString(), repositoryId);
168
169 feed.writePagingLinks(pagingUrl, maxItems, skipCount, results.getNumItems(), results.hasMoreItems(),
170 AtomPubUtils.PAGE_SIZE);
171
172 if (results.getObjects() != null) {
173 AtomEntry entry = new AtomEntry(feed.getWriter());
174 int idCounter = 0;
175 for (ObjectData result : results.getObjects()) {
176 if (result == null) {
177 continue;
178 }
179 idCounter++;
180 writeQueryResultEntry(entry, result, "id-" + idCounter, now);
181 }
182 }
183
184
185 feed.endFeed();
186 feed.endDocument();
187 }
188
189 private static void writeQueryResultEntry(AtomEntry entry, ObjectData result, String id, GregorianCalendar now)
190 throws Exception {
191 CmisObjectType resultJaxb = convert(result);
192 if (resultJaxb == null) {
193 return;
194 }
195
196
197 entry.startEntry(false);
198
199
200 entry.writeAuthor("");
201 entry.writeId(entry.generateAtomId(id));
202 entry.writePublished(now);
203 entry.writeTitle("Query Result " + id);
204 entry.writeUpdated(now);
205
206
207 JaxBHelper.marshal(JaxBHelper.CMIS_EXTRA_OBJECT_FACTORY.createObject(resultJaxb), entry.getWriter(), true);
208
209
210 entry.endEntry();
211 }
212
213
214
215
216 public static void getContentChanges(CallContext context, CmisService service, String repositoryId,
217 HttpServletRequest request, HttpServletResponse response) throws Exception {
218
219 String changeLogToken = getStringParameter(request, Constants.PARAM_CHANGE_LOG_TOKEN);
220 Boolean includeProperties = getBooleanParameter(request, Constants.PARAM_PROPERTIES);
221 String filter = getStringParameter(request, Constants.PARAM_FILTER);
222 Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
223 Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
224 BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
225
226
227 Holder<String> changeLogTokenHolder = new Holder<String>(changeLogToken);
228 ObjectList changes = service.getContentChanges(repositoryId, changeLogTokenHolder, includeProperties, filter,
229 includePolicyIds, includeAcl, maxItems, null);
230
231 if (changes == null) {
232 throw new CmisRuntimeException("Changes are null!");
233 }
234
235
236 response.setStatus(HttpServletResponse.SC_OK);
237 response.setContentType(Constants.MEDIATYPE_FEED);
238
239
240 AtomFeed feed = new AtomFeed();
241 feed.startDocument(response.getOutputStream());
242 feed.startFeed(true);
243
244
245 GregorianCalendar now = new GregorianCalendar();
246 feed.writeFeedElements("contentChanges", "", "Content Change", now, null, changes.getNumItems());
247
248
249 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
250
251 feed.writeServiceLink(baseUrl.toString(), repositoryId);
252
253 if (changeLogTokenHolder.getValue() != null) {
254 UrlBuilder nextLink = compileUrlBuilder(baseUrl, RESOURCE_CHANGES, null);
255 nextLink.addParameter(Constants.PARAM_CHANGE_LOG_TOKEN, changeLogTokenHolder.getValue());
256 nextLink.addParameter(Constants.PARAM_PROPERTIES, includeProperties);
257 nextLink.addParameter(Constants.PARAM_FILTER, filter);
258 nextLink.addParameter(Constants.PARAM_POLICY_IDS, includePolicyIds);
259 nextLink.addParameter(Constants.PARAM_ACL, includeAcl);
260 nextLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
261 feed.writeNextLink(nextLink.toString());
262 }
263
264
265 if (changes.getObjects() != null) {
266 AtomEntry entry = new AtomEntry(feed.getWriter());
267 for (ObjectData object : changes.getObjects()) {
268 if (object == null) {
269 continue;
270 }
271 writeContentChangesObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false);
272 }
273 }
274
275
276 feed.endFeed();
277 feed.endDocument();
278 }
279 }