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.io.InputStream; 019import java.util.Calendar; 020import java.util.Collection; 021import java.util.Date; 022import java.util.List; 023import java.util.Map; 024import java.util.Optional; 025 026import org.apache.chemistry.opencmis.client.api.Document; 027import org.apache.chemistry.opencmis.client.api.Folder; 028import org.apache.chemistry.opencmis.commons.data.ContentStream; 029import org.apache.commons.lang3.Strings; 030import org.xml.sax.ContentHandler; 031import org.xml.sax.SAXException; 032 033import org.ametys.core.user.UserIdentity; 034import org.ametys.core.user.population.UserPopulationDAO; 035import org.ametys.plugins.explorer.ExplorerNode; 036import org.ametys.plugins.explorer.resources.Resource; 037import org.ametys.plugins.repository.AmetysObject; 038import org.ametys.plugins.repository.AmetysRepositoryException; 039import org.ametys.plugins.repository.data.UnknownDataException; 040import org.ametys.plugins.repository.data.holder.DataHolder; 041import org.ametys.plugins.repository.data.holder.ModifiableDataHolder; 042import org.ametys.plugins.repository.data.holder.group.Composite; 043import org.ametys.plugins.repository.data.repositorydata.RepositoryData; 044import org.ametys.plugins.repository.data.type.ModelItemTypeExtensionPoint; 045import org.ametys.runtime.model.exception.BadItemTypeException; 046import org.ametys.runtime.model.exception.NotUniqueTypeException; 047import org.ametys.runtime.model.exception.UnknownTypeException; 048import org.ametys.runtime.model.type.DataContext; 049import org.ametys.runtime.model.type.ModelItemType; 050 051/** 052 * Implementation of an {@link Resource}, backed by a server CMIS.<br> 053 */ 054public class CMISResource implements Resource 055{ 056 private final Document _cmisDocument; 057 private final CMISRootResourcesCollection _root; 058 private AmetysObject _parent; 059 060 /** 061 * Creates a {@link CMISResource} 062 * @param document The CMIS document 063 * @param root The root of the virtual tree 064 * @param parent the parent {@link AmetysObject} if known 065 */ 066 public CMISResource(Document document, CMISRootResourcesCollection root, AmetysObject parent) 067 { 068 _cmisDocument = document; 069 _root = root; 070 _parent = parent; 071 } 072 073 /** 074 * Retrieves the {@link CMISRootResourcesCollection} 075 * @return the {@link CMISRootResourcesCollection} 076 */ 077 public CMISRootResourcesCollection getCmisRoot () 078 { 079 return _root; 080 } 081 082 /** 083 * Retrieves the {@link Folder} 084 * @return the {@link Folder} 085 */ 086 public Document getCmisDocument () 087 { 088 return _cmisDocument; 089 } 090 091 @Override 092 public String getId() throws AmetysRepositoryException 093 { 094 return getCmisRoot().getId() + "/" + getCmisDocument().getId(); 095 } 096 097 @Override 098 public String getName() 099 { 100 String fileName = getCmisDocument().getName(); 101 102 if (fileName == null) 103 { 104 fileName = getCmisDocument().getContentStreamFileName(); 105 } 106 if (fileName == null) 107 { 108 ContentStream cs = getCmisDocument().getContentStream(); 109 if (cs != null) 110 { 111 fileName = cs.getFileName(); 112 } 113 else 114 { 115 throw new AmetysRepositoryException("contentStream is empty on CMIS Document '" + getCmisDocument().getId() + "'"); 116 } 117 118 if (fileName == null) 119 { 120 throw new AmetysRepositoryException("fileName is null on CMIS Document '" + getCmisDocument().getId() + "'"); 121 } 122 } 123 return fileName; 124 } 125 126 @Override 127 @SuppressWarnings("unchecked") 128 public AmetysObject getParent() throws AmetysRepositoryException 129 { 130 if (_parent != null) 131 { 132 return _parent; 133 } 134 135 // iterate on all parents and returns the first valid parent 136 String rootPath = _root.getRootFolder().getPath(); 137 String rootId = _root.getRootFolder().getId(); 138 for (Folder parent : getCmisDocument().getParents()) 139 { 140 // check if the parent is valid by making sure that it is below the root folder 141 // This is necessary to unsure that the parent is included in the mount point 142 if (Strings.CS.contains(parent.getPath(), rootPath)) 143 { 144 if (Strings.CS.equals(parent.getId(), rootId)) 145 { 146 _parent = getCmisRoot(); 147 } 148 else 149 { 150 _parent = new CMISResourcesCollection(parent, _root, null); 151 } 152 return _parent; 153 } 154 } 155 156 throw new AmetysRepositoryException("Failed to retrieve the parent of folder " + getName() + ". This is most likely due to the fact that we couldn't find one in the CMIS mount point."); 157 } 158 159 @Override 160 public String getParentPath() throws AmetysRepositoryException 161 { 162 return getParent().getPath(); 163 } 164 165 @Override 166 public String getPath() throws AmetysRepositoryException 167 { 168 return getParentPath() + "/" + getName(); 169 } 170 171 @Override 172 public UserIdentity getCreator() 173 { 174 // FIXME We cannot convert the CMIS remote user to an Ametys user. We need to know the population. If not found, return the system user. 175 // getCmisDocument().getCreatedBy(); 176 return UserPopulationDAO.SYSTEM_USER_IDENTITY; 177 } 178 179 @Override 180 public InputStream getInputStream() throws AmetysRepositoryException 181 { 182 ContentStream contentStream = getCmisDocument().getContentStream(); 183 if (contentStream != null) 184 { 185 return contentStream.getStream(); 186 } 187 return null; 188 } 189 190 @Override 191 public Date getLastModified() 192 { 193 Calendar calendar = getCmisDocument().getLastModificationDate(); 194 return calendar.getTime(); 195 } 196 197 @Override 198 public long getLength() 199 { 200 return getCmisDocument().getContentStreamLength(); 201 } 202 203 204 @Override 205 public String getMimeType() throws AmetysRepositoryException 206 { 207 String mimeType = getCmisDocument().getContentStreamMimeType(); 208 209 return mimeType != null ? mimeType : "application/unknown"; 210 } 211 212 @Override 213 public String[] getKeywords() throws AmetysRepositoryException 214 { 215 return new String[0]; 216 } 217 218 @Override 219 public String getKeywordsAsString() throws AmetysRepositoryException 220 { 221 return ""; 222 } 223 224 @Override 225 public String getResourcePath() throws AmetysRepositoryException 226 { 227 return ((ExplorerNode) getParent()).getExplorerPath() + "/" + getName(); 228 } 229 230 // Dublin Core metadata. // 231 232 @Override 233 public String getDCTitle() throws AmetysRepositoryException 234 { 235 return null; 236 } 237 238 @Override 239 public String getDCCreator() throws AmetysRepositoryException 240 { 241 return null; 242 } 243 244 @Override 245 public String[] getDCSubject() throws AmetysRepositoryException 246 { 247 return null; 248 } 249 250 @Override 251 public String getDCDescription() throws AmetysRepositoryException 252 { 253 return null; 254 } 255 256 @Override 257 public String getDCPublisher() throws AmetysRepositoryException 258 { 259 return null; 260 } 261 262 @Override 263 public String getDCContributor() throws AmetysRepositoryException 264 { 265 return null; 266 } 267 268 @Override 269 public Date getDCDate() throws AmetysRepositoryException 270 { 271 return null; 272 } 273 274 @Override 275 public String getDCType() throws AmetysRepositoryException 276 { 277 return null; 278 } 279 280 @Override 281 public String getDCFormat() throws AmetysRepositoryException 282 { 283 return null; 284 } 285 286 @Override 287 public String getDCIdentifier() throws AmetysRepositoryException 288 { 289 return null; 290 } 291 292 @Override 293 public String getDCSource() throws AmetysRepositoryException 294 { 295 return null; 296 } 297 298 @Override 299 public String getDCLanguage() throws AmetysRepositoryException 300 { 301 return null; 302 } 303 304 @Override 305 public String getDCRelation() throws AmetysRepositoryException 306 { 307 return null; 308 } 309 310 @Override 311 public String getDCCoverage() throws AmetysRepositoryException 312 { 313 return null; 314 } 315 316 @Override 317 public String getDCRights() throws AmetysRepositoryException 318 { 319 return null; 320 } 321 322 public Date getCreationDate() throws AmetysRepositoryException 323 { 324 Calendar calendar = getCmisDocument().getCreationDate(); 325 return calendar.getTime(); 326 } 327 328 public UserIdentity getLastContributor() throws AmetysRepositoryException 329 { 330 return UserIdentity.stringToUserIdentity(getCmisDocument().getLastModifiedBy()); 331 } 332 333 // Data holder methods // 334 335 public Composite getComposite(String compositePath) throws IllegalArgumentException, UnknownTypeException, BadItemTypeException 336 { 337 return null; 338 } 339 340 public boolean hasValue(String dataPath) throws IllegalArgumentException 341 { 342 return false; 343 } 344 345 public boolean hasValue(String dataPath, String dataTypeId) throws IllegalArgumentException 346 { 347 return false; 348 } 349 350 public boolean hasValueOrEmpty(String dataPath) throws IllegalArgumentException 351 { 352 return false; 353 } 354 355 public Collection<String> getDataNames() 356 { 357 return List.of(); 358 } 359 360 public <T> T getValue(String dataPath) throws IllegalArgumentException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 361 { 362 return null; 363 } 364 365 public <T> T getValueOrDefault(String dataPath, T defaultValue) throws IllegalArgumentException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 366 { 367 return null; 368 } 369 370 public <T> T getValueOfType(String dataPath, String dataTypeId) throws IllegalArgumentException, UnknownTypeException, BadItemTypeException 371 { 372 return null; 373 } 374 375 public <T> T getValueOfTypeOrDefault(String dataPath, String dataTypeId, T defaultValue) throws IllegalArgumentException, UnknownTypeException, BadItemTypeException 376 { 377 return null; 378 } 379 380 public boolean isMultiple(String dataPath) throws IllegalArgumentException, UnknownDataException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 381 { 382 return false; 383 } 384 385 public boolean isMultiple(String dataPath, String dataTypeId) throws IllegalArgumentException, UnknownDataException, UnknownTypeException, BadItemTypeException 386 { 387 return false; 388 } 389 390 public <X extends ModelItemType> X getType(String dataPath) throws IllegalArgumentException, UnknownDataException, UnknownTypeException, NotUniqueTypeException 391 { 392 return null; 393 } 394 395 public ModelItemTypeExtensionPoint getModelItemTypeExtensionPoint() 396 { 397 return null; 398 } 399 400 public void copyTo(ModifiableDataHolder dataHolder) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 401 { 402 // Do nothing 403 } 404 405 public void copyTo(ModifiableDataHolder dataHolder, DataContext context) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 406 { 407 // Do nothing 408 } 409 410 public void dataToSAX(ContentHandler contentHandler, DataContext context) throws SAXException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 411 { 412 // Do nothing 413 } 414 415 public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 416 { 417 // Do nothing 418 } 419 420 public Map<String, Object> dataToJSON(DataContext context) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 421 { 422 return null; 423 } 424 425 public Object dataToJSON(String dataPath, DataContext context) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 426 { 427 return null; 428 } 429 430 public boolean hasDifferences(Map<String, Object> values) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 431 { 432 return false; 433 } 434 435 public RepositoryData getRepositoryData() 436 { 437 return null; 438 } 439 440 public Optional<? extends DataHolder> getParentDataHolder() 441 { 442 return Optional.empty(); 443 } 444 445 public DataHolder getRootDataHolder() 446 { 447 return null; 448 } 449}