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.Collection; 016import java.util.Collections; 017import java.util.GregorianCalendar; 018import java.util.HashMap; 019import java.util.List; 020import java.util.Map; 021import java.util.Map.Entry; 022import java.util.Set; 023 024import org.apache.chemistry.opencmis.client.api.CmisObject; 025import org.apache.chemistry.opencmis.client.api.ObjectId; 026import org.apache.chemistry.opencmis.client.api.ObjectType; 027import org.apache.chemistry.opencmis.client.api.Policy; 028import org.apache.chemistry.opencmis.client.api.Property; 029import org.apache.chemistry.opencmis.client.api.Relationship; 030import org.apache.chemistry.opencmis.client.api.Rendition; 031import org.apache.chemistry.opencmis.client.api.SecondaryType; 032import org.apache.chemistry.opencmis.client.runtime.RenditionImpl; 033import org.apache.chemistry.opencmis.commons.PropertyIds; 034import org.apache.chemistry.opencmis.commons.data.Ace; 035import org.apache.chemistry.opencmis.commons.data.Acl; 036import org.apache.chemistry.opencmis.commons.data.AllowableActions; 037import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement; 038import org.apache.chemistry.opencmis.commons.data.RenditionData; 039import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; 040import org.apache.chemistry.opencmis.commons.enums.AclPropagation; 041import org.apache.chemistry.opencmis.commons.enums.Action; 042import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; 043import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel; 044import org.apache.chemistry.opencmis.commons.enums.Updatability; 045import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException; 046import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; 047import org.apache.chemistry.opencmis.commons.server.CmisService; 048import org.nuxeo.ecm.core.api.CoreSession; 049import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService; 050import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData; 051import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoPropertyData.NuxeoPropertyDataName; 052import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoPropertyDataBase; 053 054/** 055 * Base abstract live local CMIS Object, wrapping a {@link NuxeoSession} and a {@link NuxeoObjectData} which is backed 056 * by a Nuxeo document. 057 */ 058public abstract class NuxeoObject implements CmisObject { 059 060 protected static final Set<Updatability> UPDATABILITY_READWRITE = Collections.singleton(Updatability.READWRITE); 061 062 protected final NuxeoSession session; 063 064 protected final CmisService service; 065 066 protected final NuxeoCmisService nuxeoCmisService; 067 068 protected final NuxeoObjectFactory objectFactory; 069 070 public final NuxeoObjectData data; 071 072 protected final ObjectType type; 073 074 public static NuxeoObject construct(NuxeoSession session, NuxeoObjectData data, ObjectType type) { 075 BaseTypeId baseTypeId = type.getBaseTypeId(); 076 switch (baseTypeId) { 077 case CMIS_FOLDER: 078 return new NuxeoFolder(session, data, type); 079 case CMIS_DOCUMENT: 080 return new NuxeoDocument(session, data, type); 081 case CMIS_POLICY: 082 throw new UnsupportedOperationException(baseTypeId.toString()); 083 case CMIS_RELATIONSHIP: 084 return new NuxeoRelationship(session, data, type); 085 default: 086 throw new RuntimeException(baseTypeId.toString()); 087 } 088 } 089 090 public NuxeoObject(NuxeoSession session, NuxeoObjectData data, ObjectType type) { 091 this.session = session; 092 service = session.getService(); 093 nuxeoCmisService = NuxeoCmisService.extractFromCmisService(service); 094 objectFactory = session.getObjectFactory(); 095 this.data = data; 096 this.type = type; 097 } 098 099 @SuppressWarnings("unchecked") 100 @Override 101 public <T> T getAdapter(Class<T> adapterInterface) { 102 throw new CmisRuntimeException("Cannot adapt to " + adapterInterface.getName()); 103 } 104 105 public String getRepositoryId() { 106 return session.getRepositoryId(); 107 } 108 109 @Override 110 public String getId() { 111 return data.getId(); 112 } 113 114 @Override 115 public ObjectType getType() { 116 return type; 117 } 118 119 @Override 120 public BaseTypeId getBaseTypeId() { 121 return data.getBaseTypeId(); 122 } 123 124 @Override 125 public ObjectType getBaseType() { 126 return session.getTypeDefinition(getBaseTypeId().value()); 127 } 128 129 @Override 130 public List<SecondaryType> getSecondaryTypes() { 131 // TODO secondary types 132 return Collections.emptyList(); 133 } 134 135 @Override 136 public List<ObjectType> findObjectType(String id) { 137 if (type.getPropertyDefinitions().containsKey(id)) { 138 return Collections.singletonList(type); 139 } 140 // TODO secondary types 141 return null; 142 } 143 144 @Override 145 public String getName() { 146 return NuxeoPropertyDataName.getValue(data.doc); 147 } 148 149 @Override 150 public String getChangeToken() { 151 return getPropertyValue(PropertyIds.CHANGE_TOKEN); 152 } 153 154 @Override 155 public String getCreatedBy() { 156 return getPropertyValue(PropertyIds.CREATED_BY); 157 } 158 159 @Override 160 public GregorianCalendar getCreationDate() { 161 return getPropertyValue(PropertyIds.CREATION_DATE); 162 } 163 164 @Override 165 public GregorianCalendar getLastModificationDate() { 166 return getPropertyValue(PropertyIds.LAST_MODIFICATION_DATE); 167 } 168 169 @Override 170 public String getLastModifiedBy() { 171 return getPropertyValue(PropertyIds.LAST_MODIFIED_BY); 172 } 173 174 @Override 175 public String getDescription() { 176 return getPropertyValue(PropertyIds.DESCRIPTION); 177 } 178 179 @Override 180 public void delete(boolean allVersions) { 181 service.deleteObject(getRepositoryId(), getId(), Boolean.valueOf(allVersions), null); 182 } 183 184 @Override 185 public void delete() { 186 delete(true); 187 } 188 189 @Override 190 public CmisObject updateProperties(Map<String, ?> properties) { 191 ObjectId objectId = updateProperties(properties, true); 192 return session.getObject(objectId); 193 } 194 195 @Override 196 public ObjectId updateProperties(Map<String, ?> properties, boolean refresh) { 197 for (Entry<String, ?> en : properties.entrySet()) { 198 ((NuxeoPropertyDataBase<?>) data.getProperty(en.getKey())).setValue(en.getValue()); 199 } 200 CoreSession coreSession = session.getCoreSession(); 201 data.doc = coreSession.saveDocument(data.doc); 202 coreSession.save(); 203 return this; 204 } 205 206 @Override 207 public CmisObject rename(String newName) { 208 if (newName == null || newName.length() == 0) { 209 throw new IllegalArgumentException("New name must not be empty!"); 210 } 211 212 Map<String, Object> prop = new HashMap<String, Object>(); 213 prop.put(PropertyIds.NAME, newName); 214 215 return updateProperties(prop); 216 } 217 218 @Override 219 public ObjectId rename(String newName, boolean refresh) { 220 if (newName == null || newName.length() == 0) { 221 throw new IllegalArgumentException("New name must not be empty!"); 222 } 223 224 Map<String, Object> prop = new HashMap<String, Object>(); 225 prop.put(PropertyIds.NAME, newName); 226 227 return updateProperties(prop, refresh); 228 } 229 230 @SuppressWarnings("unchecked") 231 @Override 232 public <T> T getPropertyValue(String id) { 233 return (T) data.getProperty(id).getValue(); 234 } 235 236 @Override 237 public <T> Property<T> getProperty(String id) { 238 return new NuxeoProperty<T>(this, type, id); 239 } 240 241 @Override 242 public List<Property<?>> getProperties() { 243 Collection<PropertyDefinition<?>> defs = type.getPropertyDefinitions().values(); 244 List<Property<?>> list = new ArrayList<Property<?>>(defs.size()); 245 for (PropertyDefinition<?> pd : defs) { 246 list.add(new NuxeoProperty<Object>(this, type, pd.getId())); 247 } 248 return list; 249 } 250 251 @Override 252 public Acl addAcl(List<Ace> addAces, AclPropagation aclPropagation) { 253 return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(addAces), null, aclPropagation, 254 null); 255 } 256 257 @Override 258 public Acl applyAcl(List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) { 259 return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(addAces), 260 objectFactory.convertAces(removeAces), aclPropagation, null); 261 } 262 263 @Override 264 public Acl setAcl(List<Ace> aces) { 265 return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(aces), 266 AclPropagation.REPOSITORYDETERMINED); 267 } 268 269 @Override 270 public Acl getAcl() { 271 return data.getAcl(); 272 } 273 274 @Override 275 public Acl removeAcl(List<Ace> removeAces, AclPropagation aclPropagation) { 276 return service.applyAcl(getRepositoryId(), getId(), null, objectFactory.convertAces(removeAces), 277 aclPropagation, null); 278 } 279 280 @Override 281 public AllowableActions getAllowableActions() { 282 // we don't call data.getAllowableActions as includeAllowableActions 283 // may be false 284 return NuxeoObjectData.getAllowableActions(data.doc, data.creation); 285 } 286 287 @Override 288 public List<Policy> getPolicies() { 289 return Collections.emptyList(); 290 } 291 292 @Override 293 public void applyPolicy(ObjectId... policyIds) { 294 throw new CmisNotSupportedException(); 295 } 296 297 @Override 298 public void removePolicy(ObjectId... policyIds) { 299 throw new CmisNotSupportedException(); 300 } 301 302 @Override 303 public List<Relationship> getRelationships() { 304 throw new CmisNotSupportedException(); 305 } 306 307 @Override 308 public List<Rendition> getRenditions() { 309 List<RenditionData> renditions = data.getRenditions(); 310 if (renditions == null) { 311 return Collections.emptyList(); 312 } 313 List<Rendition> res = new ArrayList<Rendition>(renditions.size()); 314 for (RenditionData ren : renditions) { 315 long length = ren.getBigLength() == null ? -1 : ren.getBigLength().longValue(); 316 int height = ren.getBigHeight() == null ? -1 : ren.getBigHeight().intValue(); 317 int width = ren.getBigWidth() == null ? -1 : ren.getBigWidth().intValue(); 318 RenditionImpl rendition = new RenditionImpl(session, getId(), ren.getStreamId(), 319 ren.getRenditionDocumentId(), ren.getKind(), length, ren.getMimeType(), ren.getTitle(), height, 320 width); 321 res.add(rendition); 322 } 323 return res; 324 } 325 326 @Override 327 public void refresh() { 328 data.doc.refresh(); 329 } 330 331 @Override 332 public void refreshIfOld(long durationInMillis) { 333 // TODO Auto-generated method stub 334 throw new UnsupportedOperationException(); 335 } 336 337 @Override 338 public long getRefreshTimestamp() { 339 // TODO Auto-generated method stub 340 throw new UnsupportedOperationException(); 341 } 342 343 @Override 344 public List<CmisExtensionElement> getExtensions(ExtensionLevel level) { 345 // TODO Auto-generated method stub 346 throw new UnsupportedOperationException(); 347 } 348 349 @Override 350 public boolean hasAllowableAction(Action action) { 351 // TODO Auto-generated method stub 352 throw new UnsupportedOperationException(); 353 } 354 355 @Override 356 public Set<String> getPermissonsForPrincipal(String principalId) { 357 // TODO Auto-generated method stub 358 throw new UnsupportedOperationException(); 359 } 360 361}