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