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