This project has retired. For details please refer to its
Attic page.
ObjectService 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.server.impl.atompub.AtomPubUtils.RESOURCE_CONTENT;
22 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_ENTRY;
23 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
24 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrl;
25 import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.writeObjectEntry;
26 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
27 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
28 import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
29
30 import java.io.BufferedInputStream;
31 import java.io.BufferedOutputStream;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.io.PrintWriter;
35 import java.math.BigInteger;
36 import java.util.Map;
37
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40
41 import org.apache.chemistry.opencmis.commons.PropertyIds;
42 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
43 import org.apache.chemistry.opencmis.commons.data.ContentStream;
44 import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
45 import org.apache.chemistry.opencmis.commons.data.ObjectData;
46 import org.apache.chemistry.opencmis.commons.data.Properties;
47 import org.apache.chemistry.opencmis.commons.data.PropertyData;
48 import org.apache.chemistry.opencmis.commons.data.PropertyString;
49 import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
50 import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
51 import org.apache.chemistry.opencmis.commons.enums.VersioningState;
52 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
53 import org.apache.chemistry.opencmis.commons.impl.Constants;
54 import org.apache.chemistry.opencmis.commons.impl.MimeHelper;
55 import org.apache.chemistry.opencmis.commons.impl.ReturnVersion;
56 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
57 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
58 import org.apache.chemistry.opencmis.commons.server.CallContext;
59 import org.apache.chemistry.opencmis.commons.server.CmisService;
60 import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
61 import org.apache.chemistry.opencmis.commons.spi.Holder;
62
63
64
65
66 public final class ObjectService {
67
68 private static final int BUFFER_SIZE = 64 * 1024;
69
70 private ObjectService() {
71 }
72
73
74
75
76 public static void create(CallContext context, CmisService service, String repositoryId,
77 HttpServletRequest request, HttpServletResponse response) throws Exception {
78
79 String folderId = getStringParameter(request, Constants.PARAM_ID);
80 String sourceFolderId = getStringParameter(request, Constants.PARAM_SOURCE_FOLDER_ID);
81 VersioningState versioningState = getEnumParameter(request, Constants.PARAM_VERSIONIG_STATE,
82 VersioningState.class);
83
84 AtomEntryParser parser = new AtomEntryParser(context.getTempDirectory(), context.getMemoryThreshold());
85 parser.setIgnoreAtomContentSrc(true);
86 parser.parse(request.getInputStream());
87
88 String objectId = parser.getId();
89
90
91 String newObjectId = null;
92
93 if (objectId == null) {
94
95 newObjectId = service.create(repositoryId, parser.getProperties(), folderId, parser.getContentStream(),
96 versioningState, parser.getPolicyIds(), null);
97 } else {
98 if ((sourceFolderId == null) || (sourceFolderId.trim().length() == 0)) {
99
100 service.addObjectToFolder(repositoryId, objectId, folderId, null, null);
101 newObjectId = objectId;
102 } else {
103
104 Holder<String> objectIdHolder = new Holder<String>(objectId);
105 service.moveObject(repositoryId, objectIdHolder, folderId, sourceFolderId, null);
106 newObjectId = objectIdHolder.getValue();
107 }
108 }
109
110 ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
111 if (objectInfo == null) {
112 throw new CmisRuntimeException("Object Info is missing!");
113 }
114
115 ObjectData object = objectInfo.getObject();
116 if (object == null) {
117 throw new CmisRuntimeException("Object is null!");
118 }
119
120
121 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
122
123 response.setStatus(HttpServletResponse.SC_CREATED);
124 response.setContentType(Constants.MEDIATYPE_ENTRY);
125 response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
126
127
128 AtomEntry entry = new AtomEntry();
129 entry.startDocument(response.getOutputStream());
130 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true);
131 entry.endDocument();
132 }
133
134
135
136
137 public static void createRelationship(CallContext context, CmisService service, String repositoryId,
138 HttpServletRequest request, HttpServletResponse response) throws Exception {
139
140 AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), context.getTempDirectory(),
141 context.getMemoryThreshold());
142
143
144 String newObjectId = service.createRelationship(repositoryId, parser.getProperties(), parser.getPolicyIds(),
145 null, null, null);
146
147 ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
148 if (objectInfo == null) {
149 throw new CmisRuntimeException("Object Info is missing!");
150 }
151
152 ObjectData object = objectInfo.getObject();
153 if (object == null) {
154 throw new CmisRuntimeException("Object is null!");
155 }
156
157
158 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
159
160 response.setStatus(HttpServletResponse.SC_CREATED);
161 response.setContentType(Constants.MEDIATYPE_ENTRY);
162 response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
163
164
165 AtomEntry entry = new AtomEntry();
166 entry.startDocument(response.getOutputStream());
167 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true);
168 entry.endDocument();
169 }
170
171
172
173
174 public static void deleteObject(CallContext context, CmisService service, String repositoryId,
175 HttpServletRequest request, HttpServletResponse response) {
176
177 String objectId = getStringParameter(request, Constants.PARAM_ID);
178 Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
179
180
181 service.deleteObjectOrCancelCheckOut(repositoryId, objectId, allVersions, null);
182
183
184 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
185 }
186
187
188
189
190 public static void deleteContentStream(CallContext context, CmisService service, String repositoryId,
191 HttpServletRequest request, HttpServletResponse response) {
192
193 String objectId = getStringParameter(request, Constants.PARAM_ID);
194 String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
195
196
197 service.deleteContentStream(repositoryId, new Holder<String>(objectId), changeToken == null ? null
198 : new Holder<String>(changeToken), null);
199
200
201 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
202 }
203
204
205
206
207 public static void setContentStream(CallContext context, CmisService service, String repositoryId,
208 HttpServletRequest request, HttpServletResponse response) throws Exception {
209
210 String objectId = getStringParameter(request, Constants.PARAM_ID);
211 String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
212 Boolean overwriteFlag = getBooleanParameter(request, Constants.PARAM_OVERWRITE_FLAG);
213
214 ContentStreamImpl contentStream = new ContentStreamImpl();
215 contentStream.setStream(request.getInputStream());
216 contentStream.setMimeType(request.getHeader("Content-Type"));
217 String lengthStr = request.getHeader("Content-Length");
218 if (lengthStr != null) {
219 try {
220 contentStream.setLength(new BigInteger(lengthStr));
221 } catch (NumberFormatException e) {
222 }
223 }
224 String contentDisposition = request.getHeader(MimeHelper.CONTENT_DISPOSITION);
225 if (contentDisposition != null) {
226 contentStream.setFileName(MimeHelper.decodeContentDispositionFilename(contentDisposition));
227 }
228
229
230 Holder<String> objectIdHolder = new Holder<String>(objectId);
231 service.setContentStream(repositoryId, objectIdHolder, overwriteFlag, changeToken == null ? null
232 : new Holder<String>(changeToken), contentStream, null);
233
234
235 String newObjectId = (objectIdHolder.getValue() == null ? objectId : objectIdHolder.getValue());
236 String location = compileUrl(compileBaseUrl(request, repositoryId), RESOURCE_CONTENT, newObjectId);
237
238 response.setStatus(HttpServletResponse.SC_CREATED);
239 response.setHeader("Content-Location", location);
240 response.setHeader("Location", location);
241 }
242
243
244
245
246 public static void deleteTree(CallContext context, CmisService service, String repositoryId,
247 HttpServletRequest request, HttpServletResponse response) throws Exception {
248
249 String folderId = getStringParameter(request, Constants.PARAM_ID);
250 Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
251 UnfileObject unfileObjects = getEnumParameter(request, Constants.PARAM_UNFILE_OBJECTS, UnfileObject.class);
252 Boolean continueOnFailure = getBooleanParameter(request, Constants.PARAM_CONTINUE_ON_FAILURE);
253
254
255 FailedToDeleteData ftd = service.deleteTree(repositoryId, folderId, allVersions, unfileObjects,
256 continueOnFailure, null);
257
258 if ((ftd != null) && (ftd.getIds() != null) && (ftd.getIds().size() > 0)) {
259
260 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
261 response.setContentType("text/plain");
262
263 PrintWriter pw = response.getWriter();
264
265 pw.println("Failed to delete the following objects:");
266 for (String id : ftd.getIds()) {
267 pw.println(id);
268 }
269
270 pw.flush();
271
272 return;
273 }
274
275
276 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
277 }
278
279
280
281
282 public static void getObject(CallContext context, CmisService service, String repositoryId,
283 HttpServletRequest request, HttpServletResponse response) throws Exception {
284
285 String objectId = getStringParameter(request, Constants.PARAM_ID);
286 ReturnVersion returnVersion = getEnumParameter(request, Constants.PARAM_RETURN_VERSION, ReturnVersion.class);
287 String filter = getStringParameter(request, Constants.PARAM_FILTER);
288 Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
289 IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
290 IncludeRelationships.class);
291 String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
292 Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
293 Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
294
295
296 ObjectData object = null;
297
298 if ((returnVersion == ReturnVersion.LATEST) || (returnVersion == ReturnVersion.LASTESTMAJOR)) {
299 object = service.getObjectOfLatestVersion(repositoryId, objectId, null,
300 returnVersion == ReturnVersion.LASTESTMAJOR, filter, includeAllowableActions, includeRelationships,
301 renditionFilter, includePolicyIds, includeAcl, null);
302 } else {
303 object = service.getObject(repositoryId, objectId, filter, includeAllowableActions, includeRelationships,
304 renditionFilter, includePolicyIds, includeAcl, null);
305 }
306
307 if (object == null) {
308 throw new CmisRuntimeException("Object is null!");
309 }
310
311 ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
312 if (objectInfo == null) {
313 throw new CmisRuntimeException("Object Info is missing!");
314 }
315
316
317 response.setStatus(HttpServletResponse.SC_OK);
318 response.setContentType(Constants.MEDIATYPE_ENTRY);
319
320
321 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
322
323 AtomEntry entry = new AtomEntry();
324 entry.startDocument(response.getOutputStream());
325 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true);
326 entry.endDocument();
327 }
328
329
330
331
332 public static void getObjectByPath(CallContext context, CmisService service, String repositoryId,
333 HttpServletRequest request, HttpServletResponse response) throws Exception {
334
335 String path = getStringParameter(request, Constants.PARAM_PATH);
336 String filter = getStringParameter(request, Constants.PARAM_FILTER);
337 Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
338 IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
339 IncludeRelationships.class);
340 String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
341 Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
342 Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
343
344
345 ObjectData object = service.getObjectByPath(repositoryId, path, filter, includeAllowableActions,
346 includeRelationships, renditionFilter, includePolicyIds, includeAcl, null);
347
348 if (object == null) {
349 throw new CmisRuntimeException("Object is null!");
350 }
351
352 ObjectInfo objectInfo = service.getObjectInfo(repositoryId, object.getId());
353 if (objectInfo == null) {
354 throw new CmisRuntimeException("Object Info is missing!");
355 }
356
357
358 response.setStatus(HttpServletResponse.SC_OK);
359 response.setContentType(Constants.MEDIATYPE_ENTRY);
360
361
362 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
363
364 AtomEntry entry = new AtomEntry();
365 entry.startDocument(response.getOutputStream());
366 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true);
367 entry.endDocument();
368 }
369
370
371
372
373 public static void getAllowableActions(CallContext context, CmisService service, String repositoryId,
374 HttpServletRequest request, HttpServletResponse response) throws Exception {
375
376 String objectId = getStringParameter(request, Constants.PARAM_ID);
377
378
379 AllowableActions allowableActions = service.getAllowableActions(repositoryId, objectId, null);
380
381 if (allowableActions == null) {
382 throw new CmisRuntimeException("Allowable Actions is null!");
383 }
384
385
386 response.setStatus(HttpServletResponse.SC_OK);
387 response.setContentType(Constants.MEDIATYPE_ALLOWABLEACTION);
388
389
390 AllowableActionsDocument allowableActionsDocument = new AllowableActionsDocument();
391 allowableActionsDocument.writeAllowableActions(allowableActions, response.getOutputStream());
392 }
393
394
395
396
397 public static void getContentStream(CallContext context, CmisService service, String repositoryId,
398 HttpServletRequest request, HttpServletResponse response) throws Exception {
399
400 String objectId = getStringParameter(request, Constants.PARAM_ID);
401 String streamId = getStringParameter(request, Constants.PARAM_STREAM_ID);
402
403 BigInteger offset = context.getOffset();
404 BigInteger length = context.getLength();
405
406
407 ContentStream content = service.getContentStream(repositoryId, objectId, streamId, offset, length, null);
408
409 if ((content == null) || (content.getStream() == null)) {
410 throw new CmisRuntimeException("Content stream is null!");
411 }
412
413 String contentType = content.getMimeType();
414 if (contentType == null) {
415 contentType = Constants.MEDIATYPE_OCTETSTREAM;
416 }
417
418
419 if ((offset == null) && (length == null)) {
420 response.setStatus(HttpServletResponse.SC_OK);
421 } else {
422 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
423 }
424 response.setContentType(contentType);
425
426
427 InputStream in = new BufferedInputStream(content.getStream(), BUFFER_SIZE);
428 OutputStream out = new BufferedOutputStream(response.getOutputStream());
429
430 byte[] buffer = new byte[BUFFER_SIZE];
431 int b;
432 while ((b = in.read(buffer)) > -1) {
433 out.write(buffer, 0, b);
434 }
435
436 in.close();
437 out.flush();
438 }
439
440
441
442
443 public static void updateProperties(CallContext context, CmisService service, String repositoryId,
444 HttpServletRequest request, HttpServletResponse response) throws Exception {
445
446 String objectId = getStringParameter(request, Constants.PARAM_ID);
447 Boolean checkin = getBooleanParameter(request, Constants.PARAM_CHECK_IN);
448 String checkinComment = getStringParameter(request, Constants.PARAM_CHECKIN_COMMENT);
449 Boolean major = getBooleanParameter(request, Constants.PARAM_MAJOR);
450
451 AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), context.getTempDirectory(),
452 context.getMemoryThreshold());
453
454
455 Holder<String> objectIdHolder = new Holder<String>(objectId);
456
457 if ((checkin != null) && (checkin.booleanValue())) {
458 service.checkIn(repositoryId, objectIdHolder, major, parser.getProperties(), parser.getContentStream(),
459 checkinComment, parser.getPolicyIds(), null, null, null);
460 } else {
461 String changeToken = extractChangeToken(parser.getProperties());
462
463 service.updateProperties(repositoryId, objectIdHolder, changeToken == null ? null : new Holder<String>(
464 changeToken), parser.getProperties(), null);
465 }
466
467 ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectIdHolder.getValue());
468 if (objectInfo == null) {
469 throw new CmisRuntimeException("Object Info is missing!");
470 }
471
472 ObjectData object = objectInfo.getObject();
473 if (object == null) {
474 throw new CmisRuntimeException("Object is null!");
475 }
476
477
478 UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
479 String location = compileUrl(baseUrl, RESOURCE_ENTRY, objectIdHolder.getValue());
480
481 response.setStatus(HttpServletResponse.SC_CREATED);
482 response.setContentType(Constants.MEDIATYPE_ENTRY);
483 response.setHeader("Content-Location", location);
484 response.setHeader("Location", location);
485
486
487 AtomEntry entry = new AtomEntry();
488 entry.startDocument(response.getOutputStream());
489 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true);
490 entry.endDocument();
491 }
492
493
494
495
496 private static String extractChangeToken(Properties properties) {
497 if (properties == null) {
498 return null;
499 }
500
501 Map<String, PropertyData<?>> propertiesMap = properties.getProperties();
502 if (propertiesMap == null) {
503 return null;
504 }
505
506 PropertyData<?> changeLogProperty = propertiesMap.get(PropertyIds.CHANGE_TOKEN);
507 if (!(changeLogProperty instanceof PropertyString)) {
508 return null;
509 }
510
511 return ((PropertyString) changeLogProperty).getFirstValue();
512 }
513 }