001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Florent Guillaume
011 */
012package org.nuxeo.ecm.core.opencmis.impl.client;
013
014import java.util.ArrayList;
015import java.util.List;
016import java.util.Map;
017
018import org.apache.chemistry.opencmis.client.api.CmisObject;
019import org.apache.chemistry.opencmis.client.api.Document;
020import org.apache.chemistry.opencmis.client.api.FileableCmisObject;
021import org.apache.chemistry.opencmis.client.api.Folder;
022import org.apache.chemistry.opencmis.client.api.Item;
023import org.apache.chemistry.opencmis.client.api.ItemIterable;
024import org.apache.chemistry.opencmis.client.api.ObjectId;
025import org.apache.chemistry.opencmis.client.api.ObjectType;
026import org.apache.chemistry.opencmis.client.api.OperationContext;
027import org.apache.chemistry.opencmis.client.api.Policy;
028import org.apache.chemistry.opencmis.client.api.SecondaryType;
029import org.apache.chemistry.opencmis.client.api.Tree;
030import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl;
031import org.apache.chemistry.opencmis.client.runtime.util.AbstractPageFetcher;
032import org.apache.chemistry.opencmis.client.runtime.util.CollectionIterable;
033import org.apache.chemistry.opencmis.commons.data.Ace;
034import org.apache.chemistry.opencmis.commons.data.ContentStream;
035import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
036import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
037import org.apache.chemistry.opencmis.commons.enums.VersioningState;
038import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
039import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
040import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
041import org.nuxeo.ecm.core.api.CoreSession;
042import org.nuxeo.ecm.core.api.DocumentModel;
043import org.nuxeo.ecm.core.api.DocumentModelList;
044import org.nuxeo.ecm.core.api.IdRef;
045import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData;
046
047/**
048 * Live local CMIS Folder, which is backed by a Nuxeo folderish document.
049 */
050public class NuxeoFolder extends NuxeoFileableObject implements Folder {
051
052    public NuxeoFolder(NuxeoSession session, NuxeoObjectData data, ObjectType type,
053            List<SecondaryType> secondaryTypes) {
054        super(session, data, type, secondaryTypes);
055    }
056
057    @Override
058    public Document createDocument(Map<String, ?> properties, ContentStream contentStream,
059            VersioningState versioningState) {
060        return createDocument(properties, contentStream, versioningState, null, null, null, session.getDefaultContext());
061    }
062
063    @Override
064    public Document createDocument(Map<String, ?> properties, ContentStream contentStream,
065            VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces,
066            OperationContext context) {
067        String id = service.createDocument(getRepositoryId(), session.convertProperties(properties), getId(),
068                contentStream, versioningState, objectFactory.convertPolicies(policies),
069                objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null);
070        // must now refetch doc
071        return (Document) session.getObject(new ObjectIdImpl(id), context);
072    }
073
074    @Override
075    public NuxeoDocument createDocumentFromSource(ObjectId source, Map<String, ?> properties,
076            VersioningState versioningState) {
077        return createDocumentFromSource(source, properties, versioningState, null, null, null,
078                session.getDefaultContext());
079    }
080
081    @Override
082    public NuxeoDocument createDocumentFromSource(ObjectId source, Map<String, ?> properties,
083            VersioningState versioningState, List<Policy> policies, List<Ace> addACEs, List<Ace> removeACEs,
084            OperationContext context) {
085        if (source == null || source.getId() == null) {
086            throw new CmisInvalidArgumentException("Invalid source: " + source);
087        }
088        if (context == null) {
089            context = session.getDefaultContext();
090        }
091        NuxeoObjectData newData = nuxeoCmisService.copy(source.getId(), getId(), properties, type, versioningState,
092                policies, addACEs, removeACEs, context);
093        return (NuxeoDocument) session.getObjectFactory().convertObject(newData, context);
094    }
095
096    @Override
097    public Folder createFolder(Map<String, ?> properties) {
098        return createFolder(properties, null, null, null, session.getDefaultContext());
099    }
100
101    @Override
102    public Folder createFolder(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
103            List<Ace> removeAces, OperationContext context) {
104        // TODO Auto-generated method stub
105        throw new UnsupportedOperationException();
106    }
107
108    @Override
109    public Policy createPolicy(Map<String, ?> properties) {
110        return createPolicy(properties, null, null, null, session.getDefaultContext());
111    }
112
113    @Override
114    public Policy createPolicy(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
115            List<Ace> removeAces, OperationContext context) {
116        throw new CmisNotSupportedException();
117    }
118
119    @Override
120    public Item createItem(Map<String, ?> properties) {
121        return createItem(properties, null, null, null, session.getDefaultContext());
122    }
123
124    @Override
125    public Item createItem(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces,
126            OperationContext context) {
127        throw new CmisNotSupportedException();
128    }
129
130    @Override
131    public List<String> deleteTree(boolean allVersions, UnfileObject unfile, boolean continueOnFailure) {
132        FailedToDeleteData failed = service.deleteTree(getRepositoryId(), getId(), Boolean.valueOf(allVersions),
133                unfile, Boolean.valueOf(continueOnFailure), null);
134        if (failed == null || failed.getIds() == null || failed.getIds().isEmpty()) {
135            return null;
136        }
137        return failed.getIds();
138    }
139
140    @Override
141    public List<ObjectType> getAllowedChildObjectTypes() {
142        // TODO Auto-generated method stub
143        throw new UnsupportedOperationException();
144    }
145
146    @Override
147    public ItemIterable<Document> getCheckedOutDocs() {
148        return getCheckedOutDocs(session.getDefaultContext());
149    }
150
151    @Override
152    public ItemIterable<Document> getCheckedOutDocs(OperationContext context) {
153        // TODO Auto-generated method stub
154        throw new UnsupportedOperationException();
155    }
156
157    @Override
158    public ItemIterable<CmisObject> getChildren() {
159        return getChildren(session.getDefaultContext());
160    }
161
162    @Override
163    public ItemIterable<CmisObject> getChildren(final OperationContext context) {
164        AbstractPageFetcher<CmisObject> pageFetcher = new AbstractPageFetcher<CmisObject>(context.getMaxItemsPerPage()) {
165            @Override
166            protected Page<CmisObject> fetchPage(long skipCount) {
167                List<CmisObject> items = new ArrayList<CmisObject>();
168                DocumentModelList children = nuxeoCmisService.getCoreSession().getChildren(data.doc.getRef());
169                long totalItems = 0;
170                long skip = skipCount;
171                // TODO orderBy
172                for (DocumentModel child : children) {
173                    if (nuxeoCmisService.isFilteredOut(child)) {
174                        continue;
175                    }
176                    totalItems++;
177                    if (skip > 0) {
178                        skip--;
179                        continue;
180                    }
181                    if (items.size() > maxNumItems) {
182                        continue;
183                    }
184                    NuxeoObjectData data = new NuxeoObjectData(service, child, context);
185                    CmisObject ob = objectFactory.convertObject(data, context);
186                    items.add(ob);
187                }
188                return new Page<CmisObject>(items, totalItems, totalItems > skipCount + items.size());
189            }
190        };
191        return new CollectionIterable<CmisObject>(pageFetcher);
192    }
193
194    @Override
195    public List<Tree<FileableCmisObject>> getDescendants(int depth) {
196        // TODO Auto-generated method stub
197        throw new UnsupportedOperationException();
198    }
199
200    @Override
201    public List<Tree<FileableCmisObject>> getDescendants(int depth, OperationContext context) {
202        // TODO Auto-generated method stub
203        throw new UnsupportedOperationException();
204    }
205
206    @Override
207    public Folder getFolderParent() {
208        if (isRootFolder()) {
209            return null;
210        }
211        List<Folder> parents = getParents();
212        if (parents == null || parents.isEmpty()) {
213            return null;
214        }
215        return parents.get(0);
216    }
217
218    @Override
219    public String getParentId() {
220        CoreSession coreSession = data.doc.getCoreSession();
221        DocumentModel parent = coreSession.getParentDocument(new IdRef(getId()));
222        if (parent == null || nuxeoCmisService.isFilteredOut(parent)) {
223            return null;
224        }
225        return parent.getId();
226    }
227
228    @Override
229    public List<Tree<FileableCmisObject>> getFolderTree(int depth) {
230        // TODO Auto-generated method stub
231        throw new UnsupportedOperationException();
232    }
233
234    @Override
235    public List<Tree<FileableCmisObject>> getFolderTree(int depth, OperationContext context) {
236        // TODO Auto-generated method stub
237        throw new UnsupportedOperationException();
238    }
239
240    @Override
241    public String getPath() {
242        return data.doc.getPathAsString();
243    }
244
245    @Override
246    public boolean isRootFolder() {
247        return data.doc.getPath().isRoot();
248    }
249
250}