001/* 002 * Copyright 2010 Anyware Services 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 */ 016package org.ametys.plugins.explorer.cmis; 017 018import java.util.ArrayList; 019import java.util.Collection; 020 021import org.apache.chemistry.opencmis.client.api.CmisObject; 022import org.apache.chemistry.opencmis.client.api.Document; 023import org.apache.chemistry.opencmis.client.api.Folder; 024import org.apache.chemistry.opencmis.client.api.ItemIterable; 025import org.apache.chemistry.opencmis.client.api.Session; 026import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; 027import org.apache.commons.lang.StringUtils; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031import org.ametys.plugins.explorer.ExplorerNode; 032import org.ametys.plugins.explorer.resources.ResourceCollection; 033import org.ametys.plugins.repository.AmetysObject; 034import org.ametys.plugins.repository.AmetysRepositoryException; 035import org.ametys.plugins.repository.CollectionIterable; 036import org.ametys.plugins.repository.UnknownAmetysObjectException; 037 038/** 039 * Implementation of an {@link ExplorerNode}, backed by a CMIS server.<br> 040 */ 041public class CMISResourcesCollection implements ResourceCollection 042{ 043 /** Application id for resources collections. */ 044 public static final String APPLICATION_ID = "Ametys.plugins.explorer.applications.resources.Resources"; 045 046 private static final Logger __LOGGER = LoggerFactory.getLogger(CMISResourcesCollection.class); 047 048 private final Folder _cmisFolder; 049 private final CMISRootResourcesCollection _root; 050 private AmetysObject _parent; 051 052 /** 053 * Creates a {@link CMISResourcesCollection} 054 * @param folder The CMIS folder 055 * @param root The root of the virtual tree 056 * @param parent the parent {@link AmetysObject} if known 057 */ 058 public CMISResourcesCollection(Folder folder, CMISRootResourcesCollection root, AmetysObject parent) 059 { 060 _cmisFolder = folder; 061 _root = root; 062 _parent = parent; 063 } 064 065 @Override 066 public String getApplicationId() 067 { 068 return APPLICATION_ID; 069 } 070 071 @Override 072 public String getIconCls() 073 { 074 return "ametysicon-folder249"; 075 } 076 077 @Override 078 public String getId() throws AmetysRepositoryException 079 { 080 return getCmisRoot().getId() + "/" + getCmisFolder().getId(); 081 } 082 083 @Override 084 public String getName() throws AmetysRepositoryException 085 { 086 return getCmisFolder().getName(); 087 } 088 089 /** 090 * Retrieves the {@link CMISRootResourcesCollection} 091 * @return the {@link CMISRootResourcesCollection} 092 */ 093 public CMISRootResourcesCollection getCmisRoot () 094 { 095 return _root; 096 } 097 098 /** 099 * Retrieves the {@link Folder} 100 * @return the {@link Folder} 101 */ 102 public Folder getCmisFolder () 103 { 104 return _cmisFolder; 105 } 106 107 @SuppressWarnings("unchecked") 108 @Override 109 public AmetysObject getParent() throws AmetysRepositoryException 110 { 111 if (_parent != null) 112 { 113 return _parent; 114 } 115 116 Session session = getCmisRoot().getSession(); 117 if (session == null) 118 { 119 throw new UnknownAmetysObjectException("Failed to connect to CMIS server"); 120 } 121 122 String parentId = _cmisFolder.getParentId(); 123 Folder parent = (Folder) session.getObject(parentId); 124 125 if (parent.isRootFolder()) 126 { 127 _parent = getCmisRoot(); 128 return _parent; 129 } 130 else 131 { 132 _parent = new CMISResourcesCollection(parent, _root, null); 133 return _parent; 134 } 135 } 136 137 @Override 138 public String getParentPath() throws AmetysRepositoryException 139 { 140 return getParent().getPath(); 141 } 142 143 @Override 144 public String getPath() throws AmetysRepositoryException 145 { 146 return getParentPath() + "/" + getName(); 147 } 148 149 @Override 150 @SuppressWarnings("unchecked") 151 public AmetysObject getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException 152 { 153 Session session = getCmisRoot().getSession(); 154 if (session == null) 155 { 156 throw new UnknownAmetysObjectException("Failed to connect to CMIS server"); 157 } 158 159 CmisObject child = session.getObjectByPath(path); 160 BaseTypeId baseTypeId = child.getBaseType().getBaseTypeId(); 161 162 if (baseTypeId.equals(BaseTypeId.CMIS_FOLDER)) 163 { 164 return new CMISResourcesCollection((Folder) child, _root, this); 165 } 166 if (baseTypeId.equals(BaseTypeId.CMIS_DOCUMENT)) 167 { 168 Document cmisDoc = (Document) child; 169 // Check if CMIS document has content, if not ignore it 170 if (cmisDoc.getContentStream() != null) 171 { 172 return new CMISResource((Document) child, _root, this); 173 } 174 throw new UnknownAmetysObjectException("The CMIS document " + path + " has no content"); 175 } 176 else 177 { 178 throw new UnknownAmetysObjectException("Unhandled CMIS type '" + baseTypeId + "', cannot get child at path " + path); 179 } 180 } 181 182 183 @Override 184 public CollectionIterable<AmetysObject> getChildren() throws AmetysRepositoryException 185 { 186 Collection<AmetysObject> aoChildren = new ArrayList<>(); 187 188 ItemIterable<CmisObject> children = getCmisFolder().getChildren(); 189 for (CmisObject child : children) 190 { 191 BaseTypeId baseTypeId = child.getBaseTypeId(); 192 if (baseTypeId.equals(BaseTypeId.CMIS_FOLDER)) 193 { 194 aoChildren.add(new CMISResourcesCollection((Folder) child, _root, this)); 195 } 196 else if (baseTypeId.equals(BaseTypeId.CMIS_DOCUMENT)) 197 { 198 Document cmisDoc = (Document) child; 199 200 // Check if CMIS document has content, if not ignore it 201 if (StringUtils.isNotEmpty(cmisDoc.getContentStreamFileName())) 202 { 203 aoChildren.add(new CMISResource(cmisDoc, _root, this)); 204 } 205 } 206 else 207 { 208 __LOGGER.warn("Unhandled CMIS type {}. It will be ignored.", baseTypeId); 209 } 210 } 211 212 return new CollectionIterable<>(aoChildren); 213 } 214 215 @Override 216 public boolean hasChild(String name) throws AmetysRepositoryException 217 { 218 ItemIterable<CmisObject> children = _cmisFolder.getChildren(); 219 for (CmisObject child : children) 220 { 221 if (child.getName().equals(name)) 222 { 223 return true; 224 } 225 } 226 227 return false; 228 } 229 230 public boolean hasChildResources() throws AmetysRepositoryException 231 { 232 // we don't actually know if there are children or not, 233 // but it's an optimization to don't make another CMIS request 234 return true; 235 } 236 237 public boolean hasChildExplorerNodes() throws AmetysRepositoryException 238 { 239 // we don't actually know if there are children or not, 240 // but it's an optimization to don't make another CMIS request 241 return true; 242 } 243 244 @Override 245 public String getExplorerPath() 246 { 247 AmetysObject parent = getParent(); 248 249 if (parent instanceof ExplorerNode) 250 { 251 return ((ExplorerNode) parent).getExplorerPath() + "/" + getName(); 252 } 253 else 254 { 255 return ""; 256 } 257 } 258 259 @Override 260 public String getResourcePath() throws AmetysRepositoryException 261 { 262 return getExplorerPath(); 263 } 264 265 @Override 266 public String getDescription() 267 { 268 return null; 269 } 270}