This project has retired. For details please refer to its Attic page.
FolderImpl xref

1   package org.apache.chemistry.opencmis.inmemory.storedobj.impl;
2   /*
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   *
21   */
22  
23  
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.Comparator;
27  import java.util.List;
28  import java.util.Map;
29  
30  import org.apache.chemistry.opencmis.commons.PropertyIds;
31  import org.apache.chemistry.opencmis.commons.data.PropertyData;
32  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
33  import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
34  import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
35  import org.apache.chemistry.opencmis.inmemory.FilterParser;
36  import org.apache.chemistry.opencmis.inmemory.NameValidator;
37  import org.apache.chemistry.opencmis.inmemory.storedobj.api.Document;
38  import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
39  import org.apache.chemistry.opencmis.inmemory.storedobj.api.Filing;
40  import org.apache.chemistry.opencmis.inmemory.storedobj.api.Folder;
41  import org.apache.chemistry.opencmis.inmemory.storedobj.api.MultiFiling;
42  import org.apache.chemistry.opencmis.inmemory.storedobj.api.SingleFiling;
43  import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
44  import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
45  import org.apache.commons.logging.Log;
46  import org.apache.commons.logging.LogFactory;
47  
48  public class FolderImpl extends AbstractSingleFilingImpl implements Folder {
49      private static final Log LOG = LogFactory.getLog(AbstractSingleFilingImpl.class.getName());
50  
51      FolderImpl(ObjectStoreImpl objStore) {
52          super(objStore);
53      }
54  
55      public FolderImpl(ObjectStoreImpl objStore, String name, Folder parent) {
56          super(objStore);
57          init(name, parent);
58      }
59  
60      public void addChildFolder(Folder folder) {
61          try {
62              fObjStore.lock();
63              boolean hasChild;
64              String name = folder.getName();
65              hasChild = hasChild(name);
66              if (hasChild) {
67                  throw new CmisNameConstraintViolationException("Cannot create folder " + name + ". Name already exists in parent folder");
68              }
69              folder.setParent(this);
70          } finally {
71              fObjStore.unlock();
72          }
73      }
74  
75      /*
76       * (non-Javadoc)
77       *
78       * @see
79       * org.opencmis.client.provider.spi.inmemory.IFolder#addChildDocument(org
80       * .opencmis.client.provider .spi.inmemory.storedobj.impl.DocumentImpl)
81       */
82      public void addChildDocument(Document doc) {
83          addChildObject(doc);
84      }
85  
86      public void addChildDocument(VersionedDocument doc) {
87          addChildObject(doc);
88      }
89  
90      private void addChildObject(StoredObject so) {
91          try {
92              fObjStore.lock();
93              String name = so.getName();
94              if (!NameValidator.isValidId(name)) {
95                  throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
96              }
97  
98              boolean hasChild;
99              hasChild = hasChild(name);
100             if (hasChild) {
101                 throw new CmisNameConstraintViolationException(
102                         "Cannot create object: " + name + ". Name already exists in parent folder");
103             }
104 
105             if (so instanceof SingleFiling) {
106                 ((SingleFiling) so).setParent(this);
107             } else if (so instanceof MultiFiling) {
108                 ((MultiFiling) so).addParent(this);
109             } else {
110                 throw new CmisInvalidArgumentException("Cannot create document, object is not fileable.");
111             }
112 
113         } finally {
114             fObjStore.unlock();
115         }
116     }
117 
118     public List<StoredObject> getChildren(int maxItems, int skipCount, String user) {
119         List<StoredObject> result = new ArrayList<StoredObject>();
120         for (String id : fObjStore.getIds()) {
121             StoredObject obj = fObjStore.getObject(id);
122             Filing pathObj = (Filing) obj;
123             if (fObjStore.hasReadAccess(user, obj) && pathObj.getParents(user).contains(this)) {
124                 if (pathObj instanceof VersionedDocument) {
125                     DocumentVersion ver = ((VersionedDocument) pathObj).getLatestVersion(false);
126                     result.add(ver);
127                 } else if (pathObj instanceof DocumentVersion) {
128                     // ignore
129                 } else {
130                     result.add(obj);
131                 }
132             }
133         }
134         sortFolderList(result);
135 
136         if (maxItems < 0) {
137             maxItems = result.size();
138         }
139         if (skipCount < 0) {
140             skipCount = 0;
141         }
142         int from = Math.min(skipCount, result.size());
143         int to = Math.min(maxItems + from, result.size());
144         result = result.subList(from, to);
145         return result;
146     }
147 
148     public List<Folder> getFolderChildren(int maxItems, int skipCount, String user) {
149         List<Folder> result = new ArrayList<Folder>();
150         for (String id : fObjStore.getIds()) {
151             StoredObject obj = fObjStore.getObject(id);
152             if (fObjStore.hasReadAccess(user, obj) && obj instanceof SingleFiling) {
153                 SingleFiling pathObj = (SingleFiling) obj;
154                 if (pathObj.getParent() == this && pathObj instanceof Folder) {
155                     result.add((Folder) obj);
156                 }
157             }
158         }
159         sortFolderList(result);
160         int from = Math.min(skipCount, result.size());
161         int to = Math.min(maxItems + from, result.size());
162         result = result.subList(from, to);
163         return result;
164     }
165 
166     public boolean hasChild(String name) {
167         for (String id : fObjStore.getIds()) {
168             StoredObject obj = fObjStore.getObject(id);
169             if (obj instanceof Filing) {
170                 Filing pathObj = (Filing) obj;
171                 if (pathObj.getParents(null).contains(this) && obj.getName().equals(name)) {
172                     return true;
173                 }
174             }
175         }
176         return false;
177     }
178 
179     @Override
180     public void fillProperties(Map<String, PropertyData<?>> properties, BindingsObjectFactory objFactory,
181             List<String> requestedIds) {
182 
183         super.fillProperties(properties, objFactory, requestedIds);
184 
185         // add folder specific properties
186 
187         if (FilterParser.isContainedInFilter(PropertyIds.PARENT_ID, requestedIds)) {
188             String parentId = getParent() == null ? null : getParent().getId();
189             properties.put(PropertyIds.PARENT_ID, objFactory.createPropertyIdData(PropertyIds.PARENT_ID,
190                     parentId));
191         }
192 
193         if (FilterParser.isContainedInFilter(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, requestedIds)) {
194             String allowedChildObjects = "*"; // TODO: not yet supported
195             properties.put(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, objFactory.createPropertyIdData(
196                     PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, allowedChildObjects));
197         }
198 
199         if (FilterParser.isContainedInFilter(PropertyIds.PATH, requestedIds)) {
200             String path = getPath();
201             properties.put(PropertyIds.PATH, objFactory.createPropertyStringData(PropertyIds.PATH, path));
202         }
203     }
204 
205     // Helper functions
206     private void init(String name, Folder parent) {
207         if (!NameValidator.isValidId(name)) {
208             throw new CmisInvalidArgumentException(NameValidator.ERROR_ILLEGAL_NAME);
209         }
210         setName(name);
211         setParent(parent);
212     }
213 
214     private static void sortFolderList(List<? extends StoredObject> list) {
215         // TODO evaluate orderBy, for now sort by path segment
216         class FolderComparator implements Comparator<StoredObject> {
217 
218             public int compare(StoredObject f1, StoredObject f2) {
219                 String segment1 = f1.getName();
220                 String segment2 = f2.getName();
221 
222                 return segment1.compareTo(segment2);
223             }
224         }
225 
226         Collections.sort(list, new FolderComparator());
227     }
228 
229     public void moveChildDocument(StoredObject so, Folder oldParent, Folder newParent) {
230         try {
231             fObjStore.lock();
232             if (newParent.hasChild(so.getName())) {
233                 throw new IllegalArgumentException("Cannot move object, this name already exists in target.");
234             }
235             if (!(so instanceof Filing)) {
236                 throw new IllegalArgumentException("Cannot move object, object does not have a path.");
237             }
238 
239             if (so instanceof SingleFiling) {
240                 SingleFiling pathObj = (SingleFiling) so;
241                 pathObj.setParent(newParent);
242             } else if (so instanceof MultiFiling) {
243                 MultiFiling pathObj = (MultiFiling) so;
244                 pathObj.addParent(newParent);
245                 pathObj.removeParent(oldParent);
246             }
247         } finally {
248             fObjStore.unlock();
249         }
250     }
251 
252     public List<String> getAllowedChildObjectTypeIds() {
253         // TODO implement this.
254         return null;
255     }
256 
257 }