1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
20
21 import java.io.OutputStream;
22 import java.math.BigInteger;
23 import java.util.ArrayList;
24
25 import javax.xml.stream.XMLStreamWriter;
26
27 import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
28 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
29 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
30 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomFeed;
31 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
32 import org.apache.chemistry.opencmis.client.bindings.spi.http.Output;
33 import org.apache.chemistry.opencmis.client.bindings.spi.http.Response;
34 import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
35 import org.apache.chemistry.opencmis.commons.data.ObjectData;
36 import org.apache.chemistry.opencmis.commons.data.ObjectList;
37 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
38 import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
39 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
40 import org.apache.chemistry.opencmis.commons.impl.Constants;
41 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
42 import org.apache.chemistry.opencmis.commons.impl.XMLConverter;
43 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
44 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
45 import org.apache.chemistry.opencmis.commons.impl.dataobjects.QueryTypeImpl;
46 import org.apache.chemistry.opencmis.commons.spi.DiscoveryService;
47 import org.apache.chemistry.opencmis.commons.spi.ExtendedHolder;
48 import org.apache.chemistry.opencmis.commons.spi.Holder;
49
50
51
52
53 public class DiscoveryServiceImpl extends AbstractAtomPubService implements DiscoveryService {
54
55
56
57
58 public DiscoveryServiceImpl(BindingSession session) {
59 setSession(session);
60 }
61
62 @Override
63 public ObjectList getContentChanges(String repositoryId, Holder<String> changeLogToken, Boolean includeProperties,
64 String filter, Boolean includePolicyIds, Boolean includeACL, BigInteger maxItems, ExtensionsData extension) {
65 ObjectListImpl result = new ObjectListImpl();
66
67
68 String link = null;
69 UrlBuilder url = null;
70
71
72
73 if (changeLogToken instanceof ExtendedHolder && changeLogToken.getValue() == null) {
74 link = (String) ((ExtendedHolder<String>) changeLogToken).getExtraValue(Constants.REP_REL_CHANGES);
75 if (link != null) {
76 url = new UrlBuilder(link);
77 }
78 }
79
80
81 if (link == null) {
82 link = loadRepositoryLink(repositoryId, Constants.REP_REL_CHANGES);
83 if (link != null) {
84 url = new UrlBuilder(link);
85 url.addParameter(Constants.PARAM_CHANGE_LOG_TOKEN,
86 (changeLogToken == null ? null : changeLogToken.getValue()));
87 url.addParameter(Constants.PARAM_PROPERTIES, includeProperties);
88 url.addParameter(Constants.PARAM_FILTER, filter);
89 url.addParameter(Constants.PARAM_POLICY_IDS, includePolicyIds);
90 url.addParameter(Constants.PARAM_ACL, includeACL);
91 url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
92 }
93 }
94
95 if (link == null) {
96 throw new CmisObjectNotFoundException("Unknown repository or content changes not supported!");
97 }
98
99
100 Response resp = read(url);
101 AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
102 String lastChangeLogToken = null;
103
104
105 String nextLink = null;
106 for (AtomElement element : feed.getElements()) {
107 if (element.getObject() instanceof AtomLink) {
108 if (isNextLink(element)) {
109 result.setHasMoreItems(Boolean.TRUE);
110 nextLink = ((AtomLink) element.getObject()).getHref();
111 }
112 } else if (isInt(NAME_NUM_ITEMS, element)) {
113 result.setNumItems((BigInteger) element.getObject());
114 } else if (isStr("changeLogToken", element)) {
115 lastChangeLogToken = (String) element.getObject();
116 }
117 }
118
119
120 if (!feed.getEntries().isEmpty()) {
121 result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
122
123 for (AtomEntry entry : feed.getEntries()) {
124 ObjectData hit = null;
125
126
127 for (AtomElement element : entry.getElements()) {
128 if (element.getObject() instanceof ObjectData) {
129 hit = (ObjectData) element.getObject();
130 }
131 }
132
133 if (hit != null) {
134 result.getObjects().add(hit);
135 }
136 }
137 }
138
139 if (changeLogToken != null) {
140
141
142 changeLogToken.setValue(lastChangeLogToken);
143
144
145 if (changeLogToken instanceof ExtendedHolder && nextLink != null) {
146 ((ExtendedHolder<String>) changeLogToken).setExtraValue(Constants.REP_REL_CHANGES, nextLink);
147 }
148 }
149
150 return result;
151 }
152
153 @Override
154 public ObjectList query(String repositoryId, String statement, Boolean searchAllVersions,
155 Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
156 BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
157 ObjectListImpl result = new ObjectListImpl();
158
159
160 String link = loadCollection(repositoryId, Constants.COLLECTION_QUERY);
161
162 if (link == null) {
163 throw new CmisObjectNotFoundException("Unknown repository or query not supported!");
164 }
165
166 UrlBuilder url = new UrlBuilder(link);
167
168
169 final QueryTypeImpl query = new QueryTypeImpl();
170 query.setStatement(statement);
171 query.setSearchAllVersions(searchAllVersions);
172 query.setIncludeAllowableActions(includeAllowableActions);
173 query.setIncludeRelationships(includeRelationships);
174 query.setRenditionFilter(renditionFilter);
175 query.setMaxItems(maxItems);
176 query.setSkipCount(skipCount);
177
178 final CmisVersion cmisVersion = getCmisVersion(repositoryId);
179
180
181 Response resp = post(url, Constants.MEDIATYPE_QUERY, new Output() {
182 @Override
183 public void write(OutputStream out) throws Exception {
184 XMLStreamWriter writer = XMLUtils.createWriter(out);
185 XMLUtils.startXmlDocument(writer);
186 XMLConverter.writeQuery(writer, cmisVersion, query);
187 XMLUtils.endXmlDocument(writer);
188 }
189 });
190 AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
191
192
193 for (AtomElement element : feed.getElements()) {
194 if (element.getObject() instanceof AtomLink) {
195 if (isNextLink(element)) {
196 result.setHasMoreItems(Boolean.TRUE);
197 }
198 } else if (isInt(NAME_NUM_ITEMS, element)) {
199 result.setNumItems((BigInteger) element.getObject());
200 }
201 }
202
203
204 if (!feed.getEntries().isEmpty()) {
205 result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
206
207 for (AtomEntry entry : feed.getEntries()) {
208 ObjectData hit = null;
209
210
211 for (AtomElement element : entry.getElements()) {
212 if (element.getObject() instanceof ObjectData) {
213 hit = (ObjectData) element.getObject();
214 }
215 }
216
217 if (hit != null) {
218 result.getObjects().add(hit);
219 }
220 }
221 }
222
223 return result;
224 }
225 }