This project has retired. For details please refer to its
Attic page.
AbstractAtomPubService 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.client.bindings.spi.atompub;
20
21 import static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNotEmpty;
22
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.math.BigInteger;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import javax.xml.stream.XMLStreamWriter;
34
35 import org.apache.chemistry.opencmis.client.bindings.impl.CmisBindingsHelper;
36 import org.apache.chemistry.opencmis.client.bindings.impl.RepositoryInfoCache;
37 import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
38 import org.apache.chemistry.opencmis.client.bindings.spi.LinkAccess;
39 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomAcl;
40 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomBase;
41 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
42 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
43 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
44 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.RepositoryWorkspace;
45 import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.ServiceDoc;
46 import org.apache.chemistry.opencmis.client.bindings.spi.http.HttpInvoker;
47 import org.apache.chemistry.opencmis.client.bindings.spi.http.Output;
48 import org.apache.chemistry.opencmis.client.bindings.spi.http.Response;
49 import org.apache.chemistry.opencmis.commons.PropertyIds;
50 import org.apache.chemistry.opencmis.commons.SessionParameter;
51 import org.apache.chemistry.opencmis.commons.data.Ace;
52 import org.apache.chemistry.opencmis.commons.data.Acl;
53 import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
54 import org.apache.chemistry.opencmis.commons.data.ObjectData;
55 import org.apache.chemistry.opencmis.commons.data.Properties;
56 import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
57 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
58 import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
59 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
60 import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
61 import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
62 import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
63 import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
64 import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
65 import org.apache.chemistry.opencmis.commons.exceptions.CmisFilterNotValidException;
66 import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
67 import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
68 import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
69 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
70 import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
71 import org.apache.chemistry.opencmis.commons.exceptions.CmisProxyAuthenticationException;
72 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
73 import org.apache.chemistry.opencmis.commons.exceptions.CmisServiceUnavailableException;
74 import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
75 import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
76 import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
77 import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
78 import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
79 import org.apache.chemistry.opencmis.commons.impl.Constants;
80 import org.apache.chemistry.opencmis.commons.impl.ReturnVersion;
81 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
82 import org.apache.chemistry.opencmis.commons.impl.XMLConverter;
83 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
84 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
85 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
86 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
87 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectDataImpl;
88 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PolicyIdListImpl;
89 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
90 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
91 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
92
93
94
95
96 public abstract class AbstractAtomPubService implements LinkAccess {
97
98 protected enum IdentifierType {
99 ID, PATH
100 }
101
102 protected static final String NAME_COLLECTION = "collection";
103 protected static final String NAME_URI_TEMPLATE = "uritemplate";
104 protected static final String NAME_PATH_SEGMENT = "pathSegment";
105 protected static final String NAME_RELATIVE_PATH_SEGMENT = "relativePathSegment";
106 protected static final String NAME_NUM_ITEMS = "numItems";
107
108 private BindingSession session;
109
110
111
112
113 protected void setSession(BindingSession session) {
114 this.session = session;
115 }
116
117
118
119
120 protected BindingSession getSession() {
121 return session;
122 }
123
124
125
126
127 protected HttpInvoker getHttpInvoker() {
128 return CmisBindingsHelper.getHttpInvoker(session);
129 }
130
131
132
133
134 protected String getServiceDocURL() {
135 Object url = session.get(SessionParameter.ATOMPUB_URL);
136 if (url instanceof String) {
137 return (String) url;
138 }
139
140 return null;
141 }
142
143
144
145
146 protected CmisVersion getCmisVersion(String repositoryId) {
147 if (CmisBindingsHelper.getForcedCmisVersion(session) != null) {
148 return CmisBindingsHelper.getForcedCmisVersion(session);
149 }
150
151 RepositoryInfoCache cache = CmisBindingsHelper.getRepositoryInfoCache(session);
152 RepositoryInfo info = cache.get(repositoryId);
153
154 if (info == null) {
155 List<RepositoryInfo> infoList = getRepositoriesInternal(repositoryId);
156 if (isNotEmpty(infoList)) {
157 info = infoList.get(0);
158 cache.put(info);
159 }
160 }
161
162 return (info == null ? CmisVersion.CMIS_1_0 : info.getCmisVersion());
163 }
164
165
166
167
168
169
170 protected LinkCache getLinkCache() {
171 LinkCache linkCache = (LinkCache) getSession().get(SpiSessionParameter.LINK_CACHE);
172 if (linkCache == null) {
173 linkCache = new LinkCache(getSession());
174 getSession().put(SpiSessionParameter.LINK_CACHE, linkCache);
175 }
176
177 return linkCache;
178 }
179
180
181
182
183 protected String getLink(String repositoryId, String id, String rel, String type) {
184 if (repositoryId == null) {
185 throw new CmisInvalidArgumentException("Repository ID must be set!");
186 }
187
188 if (id == null) {
189 throw new CmisInvalidArgumentException("Object ID must be set!");
190 }
191
192 return getLinkCache().getLink(repositoryId, id, rel, type);
193 }
194
195
196
197
198 protected String getLink(String repositoryId, String id, String rel) {
199 return getLink(repositoryId, id, rel, null);
200 }
201
202
203
204
205
206 public String loadLink(String repositoryId, String id, String rel, String type) {
207 String link = getLink(repositoryId, id, rel, type);
208 if (link == null) {
209 getObjectInternal(repositoryId, IdentifierType.ID, id, ReturnVersion.THIS, "cmis:objectId", Boolean.FALSE,
210 IncludeRelationships.NONE, "cmis:none", Boolean.FALSE, Boolean.FALSE, null);
211 link = getLink(repositoryId, id, rel, type);
212 }
213
214 return link;
215 }
216
217
218
219
220
221 public String loadContentLink(String repositoryId, String id) {
222 return loadLink(repositoryId, id, AtomPubParser.LINK_REL_CONTENT, null);
223 }
224
225
226
227
228
229 public String loadRenditionContentLink(String repositoryId, String id, String streamId) {
230 return loadLink(repositoryId, id, Constants.REL_ALTERNATE, streamId);
231 }
232
233
234
235
236 protected void addLink(String repositoryId, String id, String rel, String type, String link) {
237 getLinkCache().addLink(repositoryId, id, rel, type, link);
238 }
239
240
241
242
243 protected void addLink(String repositoryId, String id, AtomLink link) {
244 getLinkCache().addLink(repositoryId, id, link.getRel(), link.getType(), link.getHref());
245 }
246
247
248
249
250 protected void removeLinks(String repositoryId, String id) {
251 getLinkCache().removeLinks(repositoryId, id);
252 }
253
254
255
256
257 protected void lockLinks() {
258 getLinkCache().lockLinks();
259 }
260
261
262
263
264 protected void unlockLinks() {
265 getLinkCache().unlockLinks();
266 }
267
268
269
270
271 protected void throwLinkException(String repositoryId, String id, String rel, String type) {
272 int index = getLinkCache().checkLink(repositoryId, id, rel, type);
273
274 switch (index) {
275 case 0:
276 throw new CmisObjectNotFoundException("Unknown repository!");
277 case 1:
278 throw new CmisObjectNotFoundException("Unknown object!");
279 case 2:
280 throw new CmisNotSupportedException("Operation not supported by the repository for this object!");
281 case 3:
282 throw new CmisNotSupportedException("No link with matching media type!");
283 case 4:
284 throw new CmisRuntimeException("Nothing wrong! Either this is a bug or a threading issue.");
285 default:
286 throw new CmisRuntimeException("Unknown error!");
287 }
288 }
289
290
291
292
293 protected String getTypeLink(String repositoryId, String typeId, String rel, String type) {
294 if (repositoryId == null) {
295 throw new CmisInvalidArgumentException("Repository ID must be set!");
296 }
297
298 if (typeId == null) {
299 throw new CmisInvalidArgumentException("Type ID must be set!");
300 }
301
302 return getLinkCache().getTypeLink(repositoryId, typeId, rel, type);
303 }
304
305
306
307
308 protected String getTypeLink(String repositoryId, String typeId, String rel) {
309 return getTypeLink(repositoryId, typeId, rel, null);
310 }
311
312
313
314
315
316 protected String loadTypeLink(String repositoryId, String typeId, String rel, String type) {
317 String link = getTypeLink(repositoryId, typeId, rel, type);
318 if (link == null) {
319 getTypeDefinitionInternal(repositoryId, typeId);
320 link = getTypeLink(repositoryId, typeId, rel, type);
321 }
322
323 return link;
324 }
325
326
327
328
329 protected void addTypeLink(String repositoryId, String typeId, String rel, String type, String link) {
330 getLinkCache().addTypeLink(repositoryId, typeId, rel, type, link);
331 }
332
333
334
335
336 protected void addTypeLink(String repositoryId, String typeId, AtomLink link) {
337 getLinkCache().addTypeLink(repositoryId, typeId, link.getRel(), link.getType(), link.getHref());
338 }
339
340
341
342
343 protected void removeTypeLinks(String repositoryId, String id) {
344 getLinkCache().removeTypeLinks(repositoryId, id);
345 }
346
347
348
349
350 protected void lockTypeLinks() {
351 getLinkCache().lockTypeLinks();
352 }
353
354
355
356
357 protected void unlockTypeLinks() {
358 getLinkCache().unlockTypeLinks();
359 }
360
361
362
363
364 protected String getCollection(String repositoryId, String collection) {
365 return getLinkCache().getCollection(repositoryId, collection);
366 }
367
368
369
370
371
372 protected String loadCollection(String repositoryId, String collection) {
373 String link = getCollection(repositoryId, collection);
374 if (link == null) {
375
376 getRepositoriesInternal(repositoryId);
377 link = getCollection(repositoryId, collection);
378 }
379
380 return link;
381 }
382
383
384
385
386 protected void addCollection(String repositoryId, String collection, String link) {
387 getLinkCache().addCollection(repositoryId, collection, link);
388 }
389
390
391
392
393 protected String getRepositoryLink(String repositoryId, String rel) {
394 return getLinkCache().getRepositoryLink(repositoryId, rel);
395 }
396
397
398
399
400
401 protected String loadRepositoryLink(String repositoryId, String rel) {
402 String link = getRepositoryLink(repositoryId, rel);
403 if (link == null) {
404
405 getRepositoriesInternal(repositoryId);
406 link = getRepositoryLink(repositoryId, rel);
407 }
408
409 return link;
410 }
411
412
413
414
415 protected void addRepositoryLink(String repositoryId, String rel, String link) {
416 getLinkCache().addRepositoryLink(repositoryId, rel, link);
417 }
418
419
420
421
422 protected void addRepositoryLink(String repositoryId, AtomLink link) {
423 addRepositoryLink(repositoryId, link.getRel(), link.getHref());
424 }
425
426
427
428
429 protected String getTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
430 return getLinkCache().getTemplateLink(repositoryId, type, parameters);
431 }
432
433
434
435
436
437 protected String loadTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
438 String link = getTemplateLink(repositoryId, type, parameters);
439 if (link == null) {
440
441 getRepositoriesInternal(repositoryId);
442 link = getTemplateLink(repositoryId, type, parameters);
443 }
444
445 return link;
446 }
447
448
449
450
451 protected void addTemplate(String repositoryId, String type, String link) {
452 getLinkCache().addTemplate(repositoryId, type, link);
453 }
454
455
456
457
458
459
460 protected CmisBaseException convertStatusCode(int code, String message, String errorContent, Throwable t) {
461 String exception = extractException(errorContent);
462 message = extractErrorMessage(message, errorContent);
463
464 switch (code) {
465 case 301:
466 case 302:
467 case 303:
468 case 307:
469 return new CmisConnectionException("Redirects are not supported (HTTP status code " + code + "): "
470 + message, errorContent, t);
471 case 400:
472 if (CmisFilterNotValidException.EXCEPTION_NAME.equals(exception)) {
473 return new CmisFilterNotValidException(message, errorContent, t);
474 }
475 return new CmisInvalidArgumentException(message, errorContent, t);
476 case 401:
477 return new CmisUnauthorizedException(message, errorContent, t);
478 case 403:
479 if (CmisStreamNotSupportedException.EXCEPTION_NAME.equals(exception)) {
480 return new CmisStreamNotSupportedException(message, errorContent, t);
481 }
482 return new CmisPermissionDeniedException(message, errorContent, t);
483 case 404:
484 return new CmisObjectNotFoundException(message, errorContent, t);
485 case 405:
486 return new CmisNotSupportedException(message, errorContent, t);
487 case 407:
488 return new CmisProxyAuthenticationException(message, errorContent, t);
489 case 409:
490 if (CmisContentAlreadyExistsException.EXCEPTION_NAME.equals(exception)) {
491 return new CmisContentAlreadyExistsException(message, errorContent, t);
492 } else if (CmisVersioningException.EXCEPTION_NAME.equals(exception)) {
493 return new CmisVersioningException(message, errorContent, t);
494 } else if (CmisUpdateConflictException.EXCEPTION_NAME.equals(exception)) {
495 return new CmisUpdateConflictException(message, errorContent, t);
496 } else if (CmisNameConstraintViolationException.EXCEPTION_NAME.equals(exception)) {
497 return new CmisNameConstraintViolationException(message, errorContent, t);
498 }
499 return new CmisConstraintException(message, errorContent, t);
500 case 503:
501 return new CmisServiceUnavailableException(message, errorContent, t);
502 default:
503 if (CmisStorageException.EXCEPTION_NAME.equals(exception)) {
504 return new CmisStorageException(message, errorContent, t);
505 }
506 return new CmisRuntimeException(message, errorContent, t);
507 }
508 }
509
510 protected String extractException(String errorContent) {
511 if (errorContent == null) {
512 return null;
513 }
514
515 int begin = errorContent.indexOf("<!--exception-->");
516 int end = errorContent.indexOf("<!--/exception-->");
517
518 if (begin == -1 || end == -1 || begin > end) {
519 return null;
520 }
521
522 return errorContent.substring(begin + "<!--exception-->".length(), end);
523 }
524
525 protected String extractErrorMessage(String message, String errorContent) {
526 if (errorContent == null) {
527 return message;
528 }
529
530 int begin = errorContent.indexOf("<!--message-->");
531 int end = errorContent.indexOf("<!--/message-->");
532
533 if (begin == -1 || end == -1 || begin > end) {
534 return message;
535 }
536
537 return errorContent.substring(begin + "<!--message-->".length(), end);
538 }
539
540
541
542 protected boolean is(String name, AtomElement element) {
543 return name.equals(element.getName().getLocalPart());
544 }
545
546 protected boolean isStr(String name, AtomElement element) {
547 return is(name, element) && (element.getObject() instanceof String);
548 }
549
550 protected boolean isInt(String name, AtomElement element) {
551 return is(name, element) && (element.getObject() instanceof BigInteger);
552 }
553
554 protected boolean isNextLink(AtomElement element) {
555 return Constants.REL_NEXT.equals(((AtomLink) element.getObject()).getRel());
556 }
557
558
559
560
561 protected ObjectDataImpl createObject(Properties properties, String changeToken, List<String> policies) {
562 ObjectDataImpl object = new ObjectDataImpl();
563
564 boolean omitChangeToken = getSession().get(SessionParameter.OMIT_CHANGE_TOKENS, false);
565
566 if (properties == null) {
567 properties = new PropertiesImpl();
568 if (changeToken != null && !omitChangeToken) {
569 ((PropertiesImpl) properties)
570 .addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN, changeToken));
571 }
572 } else {
573 if (omitChangeToken) {
574 if (properties.getProperties().containsKey(PropertyIds.CHANGE_TOKEN)) {
575 properties = new PropertiesImpl(properties);
576 ((PropertiesImpl) properties).removeProperty(PropertyIds.CHANGE_TOKEN);
577 }
578 } else {
579 if (changeToken != null && !properties.getProperties().containsKey(PropertyIds.CHANGE_TOKEN)) {
580 properties = new PropertiesImpl(properties);
581 ((PropertiesImpl) properties).addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN,
582 changeToken));
583 }
584 }
585 }
586
587 object.setProperties(properties);
588
589 if (isNotEmpty(policies)) {
590 PolicyIdListImpl policyIdList = new PolicyIdListImpl();
591 policyIdList.setPolicyIds(policies);
592 object.setPolicyIds(policyIdList);
593 }
594
595 return object;
596 }
597
598
599
600
601 protected ObjectData createIdObject(String objectId) {
602 ObjectDataImpl object = new ObjectDataImpl();
603
604 PropertiesImpl properties = new PropertiesImpl();
605 object.setProperties(properties);
606
607 properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, objectId));
608
609 return object;
610 }
611
612
613
614
615 @SuppressWarnings("unchecked")
616 protected <T extends AtomBase> T parse(InputStream stream, Class<T> clazz) {
617 AtomPubParser parser = new AtomPubParser(stream);
618
619 try {
620 parser.parse();
621 } catch (Exception e) {
622 throw new CmisConnectionException("Parsing exception!", e);
623 }
624
625 AtomBase parseResult = parser.getResults();
626
627 if (!clazz.isInstance(parseResult)) {
628 throw new CmisConnectionException("Unexpected document! Received: "
629 + (parseResult == null ? "something unknown" : parseResult.getType()));
630 }
631
632 return (T) parseResult;
633 }
634
635
636
637
638
639 protected Response read(UrlBuilder url) {
640
641 Response resp = getHttpInvoker().invokeGET(url, session);
642
643
644 if (resp.getResponseCode() != 200) {
645 throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp.getErrorContent(), null);
646 }
647
648 return resp;
649 }
650
651
652
653
654
655 protected Response post(UrlBuilder url, String contentType, Output writer) {
656
657 Response resp = getHttpInvoker().invokePOST(url, contentType, writer, session);
658
659
660 if (resp.getResponseCode() != 201) {
661 throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp.getErrorContent(), null);
662 }
663
664 return resp;
665 }
666
667
668
669
670
671 protected Response put(UrlBuilder url, String contentType, Output writer) {
672 return put(url, contentType, null, writer);
673 }
674
675
676
677
678
679 protected Response put(UrlBuilder url, String contentType, Map<String, String> headers, Output writer) {
680
681 Response resp = getHttpInvoker().invokePUT(url, contentType, headers, writer, session);
682
683
684 if ((resp.getResponseCode() < 200) || (resp.getResponseCode() > 299)) {
685 throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp.getErrorContent(), null);
686 }
687
688 return resp;
689 }
690
691
692
693
694
695 protected void delete(UrlBuilder url) {
696
697 Response resp = getHttpInvoker().invokeDELETE(url, session);
698
699
700 if (resp.getResponseCode() != 204) {
701 throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp.getErrorContent(), null);
702 }
703 }
704
705
706
707
708
709
710 protected boolean isAclMergeRequired(Acl addAces, Acl removeAces) {
711 return (addAces != null && isNotEmpty(addAces.getAces()))
712 || (removeAces != null && isNotEmpty(removeAces.getAces()));
713 }
714
715
716
717
718 protected Acl mergeAcls(Acl originalAces, Acl addAces, Acl removeAces) {
719 Map<String, Set<String>> originals = convertAclToMap(originalAces);
720 Map<String, Set<String>> adds = convertAclToMap(addAces);
721 Map<String, Set<String>> removes = convertAclToMap(removeAces);
722 List<Ace> newAces = new ArrayList<Ace>();
723
724
725 for (Map.Entry<String, Set<String>> ace : originals.entrySet()) {
726
727
728 Set<String> addPermissions = adds.get(ace.getKey());
729 if (addPermissions != null) {
730 ace.getValue().addAll(addPermissions);
731 }
732
733
734 Set<String> removePermissions = removes.get(ace.getKey());
735 if (removePermissions != null) {
736 ace.getValue().removeAll(removePermissions);
737 }
738
739
740 if (!ace.getValue().isEmpty()) {
741 newAces.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ace.getKey()),
742 new ArrayList<String>(ace.getValue())));
743 }
744 }
745
746
747
748 for (Map.Entry<String, Set<String>> ace : adds.entrySet()) {
749 if (!originals.containsKey(ace.getKey()) && !ace.getValue().isEmpty()) {
750 newAces.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ace.getKey()),
751 new ArrayList<String>(ace.getValue())));
752 }
753 }
754
755 return new AccessControlListImpl(newAces);
756 }
757
758
759
760
761 private static Map<String, Set<String>> convertAclToMap(Acl acl) {
762 Map<String, Set<String>> result = new HashMap<String, Set<String>>();
763
764 if (acl == null || acl.getAces() == null) {
765 return result;
766 }
767
768 for (Ace ace : acl.getAces()) {
769
770 if (!ace.isDirect()) {
771
772 continue;
773 }
774
775
776 if (ace.getPrincipal() == null || ace.getPrincipal().getId() == null) {
777
778 continue;
779 }
780
781 Set<String> permissions = result.get(ace.getPrincipal().getId());
782 if (permissions == null) {
783 permissions = new HashSet<String>();
784 result.put(ace.getPrincipal().getId(), permissions);
785 }
786
787 if (ace.getPermissions() != null) {
788 permissions.addAll(ace.getPermissions());
789 }
790 }
791
792 return result;
793 }
794
795
796
797
798
799 @SuppressWarnings("unchecked")
800 protected List<RepositoryInfo> getRepositoriesInternal(String repositoryId) {
801 List<RepositoryInfo> repInfos = new ArrayList<RepositoryInfo>();
802
803
804 UrlBuilder url = new UrlBuilder(getServiceDocURL());
805 url.addParameter(Constants.PARAM_REPOSITORY_ID, repositoryId);
806
807
808 Response resp = read(url);
809 ServiceDoc serviceDoc = parse(resp.getStream(), ServiceDoc.class);
810
811
812 for (RepositoryWorkspace ws : serviceDoc.getWorkspaces()) {
813 if (ws.getId() == null) {
814
815 continue;
816 }
817
818 for (AtomElement element : ws.getElements()) {
819 if (is(NAME_COLLECTION, element)) {
820 Map<String, String> colMap = (Map<String, String>) element.getObject();
821 addCollection(ws.getId(), colMap.get("collectionType"), colMap.get("href"));
822 } else if (element.getObject() instanceof AtomLink) {
823 addRepositoryLink(ws.getId(), (AtomLink) element.getObject());
824 } else if (is(NAME_URI_TEMPLATE, element)) {
825 Map<String, String> tempMap = (Map<String, String>) element.getObject();
826 addTemplate(ws.getId(), tempMap.get("type"), tempMap.get("template"));
827 } else if (element.getObject() instanceof RepositoryInfo) {
828 repInfos.add((RepositoryInfo) element.getObject());
829 }
830 }
831 }
832
833 return repInfos;
834 }
835
836
837
838
839 protected ObjectData getObjectInternal(String repositoryId, IdentifierType idOrPath, String objectIdOrPath,
840 ReturnVersion returnVersion, String filter, Boolean includeAllowableActions,
841 IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds,
842 Boolean includeAcl, ExtensionsData extension) {
843
844 Map<String, Object> parameters = new HashMap<String, Object>();
845 parameters.put(Constants.PARAM_ID, objectIdOrPath);
846 parameters.put(Constants.PARAM_PATH, objectIdOrPath);
847 parameters.put(Constants.PARAM_RETURN_VERSION, returnVersion);
848 parameters.put(Constants.PARAM_FILTER, filter);
849 parameters.put(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
850 parameters.put(Constants.PARAM_ACL, includeAcl);
851 parameters.put(Constants.PARAM_POLICY_IDS, includePolicyIds);
852 parameters.put(Constants.PARAM_RELATIONSHIPS, includeRelationships);
853 parameters.put(Constants.PARAM_RENDITION_FILTER, renditionFilter);
854
855 String link = loadTemplateLink(repositoryId, (idOrPath == IdentifierType.ID ? Constants.TEMPLATE_OBJECT_BY_ID
856 : Constants.TEMPLATE_OBJECT_BY_PATH), parameters);
857 if (link == null) {
858 throw new CmisObjectNotFoundException("Unknown repository!");
859 }
860
861 UrlBuilder url = new UrlBuilder(link);
862
863 if (returnVersion != null && returnVersion != ReturnVersion.THIS) {
864 url.addParameter(Constants.PARAM_RETURN_VERSION, returnVersion);
865 }
866
867
868 Response resp = read(url);
869 AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
870
871
872 if (entry.getId() == null) {
873 throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
874 }
875
876 lockLinks();
877 ObjectData result = null;
878 try {
879
880 removeLinks(repositoryId, entry.getId());
881
882
883 for (AtomElement element : entry.getElements()) {
884 if (element.getObject() instanceof AtomLink) {
885 addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
886 } else if (element.getObject() instanceof ObjectData) {
887 result = (ObjectData) element.getObject();
888 }
889 }
890 } finally {
891 unlockLinks();
892 }
893
894 return result;
895 }
896
897
898
899
900 protected TypeDefinition getTypeDefinitionInternal(String repositoryId, String typeId) {
901
902 Map<String, Object> parameters = new HashMap<String, Object>();
903 parameters.put(Constants.PARAM_ID, typeId);
904
905 String link = loadTemplateLink(repositoryId, Constants.TEMPLATE_TYPE_BY_ID, parameters);
906 if (link == null) {
907 throw new CmisObjectNotFoundException("Unknown repository!");
908 }
909
910
911 Response resp = read(new UrlBuilder(link));
912 AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
913
914
915 if (entry.getId() == null) {
916 throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
917 }
918
919 lockTypeLinks();
920 TypeDefinition result = null;
921 try {
922
923 removeTypeLinks(repositoryId, entry.getId());
924
925
926 for (AtomElement element : entry.getElements()) {
927 if (element.getObject() instanceof AtomLink) {
928 addTypeLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
929 } else if (element.getObject() instanceof TypeDefinition) {
930 result = (TypeDefinition) element.getObject();
931 }
932 }
933 } finally {
934 unlockTypeLinks();
935 }
936
937 return result;
938 }
939
940
941
942
943 public Acl getAclInternal(String repositoryId, String objectId, Boolean onlyBasicPermissions,
944 ExtensionsData extension) {
945
946
947 String link = loadLink(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
948
949 if (link == null) {
950 throwLinkException(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
951 }
952
953 UrlBuilder url = new UrlBuilder(link);
954 url.addParameter(Constants.PARAM_ONLY_BASIC_PERMISSIONS, onlyBasicPermissions);
955
956
957 Response resp = read(url);
958 AtomAcl acl = parse(resp.getStream(), AtomAcl.class);
959
960 return acl.getACL();
961 }
962
963
964
965
966 protected AtomAcl updateAcl(String repositoryId, String objectId, final Acl acl, AclPropagation aclPropagation) {
967
968
969 String link = loadLink(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
970
971 if (link == null) {
972 throwLinkException(repositoryId, objectId, Constants.REL_ACL, Constants.MEDIATYPE_ACL);
973 }
974
975 UrlBuilder aclUrl = new UrlBuilder(link);
976 aclUrl.addParameter(Constants.PARAM_ACL_PROPAGATION, aclPropagation);
977
978 final CmisVersion cmisVersion = getCmisVersion(repositoryId);
979
980
981 Response resp = put(aclUrl, Constants.MEDIATYPE_ACL, new Output() {
982 public void write(OutputStream out) throws Exception {
983 XMLStreamWriter writer = XMLUtils.createWriter(out);
984 XMLUtils.startXmlDocument(writer);
985 XMLConverter.writeAcl(writer, cmisVersion, true, acl);
986 XMLUtils.endXmlDocument(writer);
987 }
988 });
989
990
991 return parse(resp.getStream(), AtomAcl.class);
992 }
993
994 }