/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Florent Guillaume */ package org.eclipse.ecr.opencmis.impl.client; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.GregorianCalendar; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.ObjectId; import org.apache.chemistry.opencmis.client.api.ObjectType; import org.apache.chemistry.opencmis.client.api.Policy; import org.apache.chemistry.opencmis.client.api.Property; import org.apache.chemistry.opencmis.client.api.Relationship; import org.apache.chemistry.opencmis.client.api.Rendition; import org.apache.chemistry.opencmis.client.api.TransientCmisObject; import org.apache.chemistry.opencmis.client.api.TransientDocument; import org.apache.chemistry.opencmis.client.api.TransientFolder; import org.apache.chemistry.opencmis.client.api.TransientRelationship; import org.apache.chemistry.opencmis.client.runtime.RenditionImpl; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.data.Ace; import org.apache.chemistry.opencmis.commons.data.Acl; import org.apache.chemistry.opencmis.commons.data.AllowableActions; import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement; import org.apache.chemistry.opencmis.commons.data.RenditionData; import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; import org.apache.chemistry.opencmis.commons.enums.AclPropagation; import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel; import org.apache.chemistry.opencmis.commons.enums.Updatability; import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException; import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; import org.eclipse.ecr.core.api.ClientException; import org.eclipse.ecr.core.api.CoreSession; import org.eclipse.ecr.opencmis.impl.server.NuxeoCmisService; import org.eclipse.ecr.opencmis.impl.server.NuxeoObjectData; import org.eclipse.ecr.opencmis.impl.server.NuxeoPropertyDataBase; import org.eclipse.ecr.opencmis.impl.server.NuxeoPropertyData.NuxeoPropertyDataName; /** * Base abstract live local CMIS Object, wrapping a {@link NuxeoSession} and a * {@link NuxeoObjectData} which is backed by a Nuxeo document. */ public abstract class NuxeoObject implements CmisObject { protected static final Set<Updatability> UPDATABILITY_READWRITE = Collections.singleton(Updatability.READWRITE); protected final NuxeoSession session; protected final NuxeoCmisService service; public final NuxeoObjectData data; protected final ObjectType type; public static NuxeoObject construct(NuxeoSession session, NuxeoObjectData data, ObjectType type) { BaseTypeId baseTypeId = type.getBaseTypeId(); switch (baseTypeId) { case CMIS_FOLDER: return new NuxeoFolder(session, data, type); case CMIS_DOCUMENT: return new NuxeoDocument(session, data, type); case CMIS_POLICY: throw new UnsupportedOperationException(baseTypeId.toString()); case CMIS_RELATIONSHIP: return new NuxeoRelationship(session, data, type); default: throw new RuntimeException(baseTypeId.toString()); } } public NuxeoObject(NuxeoSession session, NuxeoObjectData data, ObjectType type) { this.session = session; service = session.getService(); this.data = data; this.type = type; } @SuppressWarnings("unchecked") @Override public <T> T getAdapter(Class<T> adapterInterface) { if (TransientDocument.class.isAssignableFrom(adapterInterface) && this instanceof NuxeoDocument) { return (T) new NuxeoTransientDocument(this); } if (TransientFolder.class.isAssignableFrom(adapterInterface) && this instanceof NuxeoFolder) { return (T) new NuxeoTransientFolder(this); } if (TransientRelationship.class.isAssignableFrom(adapterInterface) && this instanceof NuxeoRelationship) { return (T) new NuxeoTransientRelationship(this); } throw new CmisRuntimeException("Cannot adapt to " + adapterInterface.getName()); } @Override public TransientCmisObject getTransientObject() { return (TransientCmisObject) getAdapter(TransientCmisObject.class); } public String getRepositoryId() { return session.getRepositoryId(); } @Override public String getId() { return data.getId(); } @Override public ObjectType getType() { return type; } @Override public BaseTypeId getBaseTypeId() { return data.getBaseTypeId(); } @Override public ObjectType getBaseType() { return session.getTypeDefinition(getBaseTypeId().value()); } @Override public String getName() { return NuxeoPropertyDataName.getValue(data.doc); } @Override public String getChangeToken() { return getPropertyValue(PropertyIds.CHANGE_TOKEN); } @Override public String getCreatedBy() { return getPropertyValue(PropertyIds.CREATED_BY); } @Override public GregorianCalendar getCreationDate() { return getPropertyValue(PropertyIds.CREATION_DATE); } @Override public GregorianCalendar getLastModificationDate() { return getPropertyValue(PropertyIds.LAST_MODIFICATION_DATE); } @Override public String getLastModifiedBy() { return getPropertyValue(PropertyIds.LAST_MODIFIED_BY); } @Override public void delete(boolean allVersions) { service.deleteObject(getRepositoryId(), getId(), Boolean.valueOf(allVersions), null); } @Override public CmisObject updateProperties(Map<String, ?> properties) { ObjectId objectId = updateProperties(properties, true); return session.getObject(objectId); } @Override public ObjectId updateProperties(Map<String, ?> properties, boolean refresh) { for (Entry<String, ?> en : properties.entrySet()) { ((NuxeoPropertyDataBase<?>) data.getProperty(en.getKey())).setValue(en.getValue()); } try { CoreSession coreSession = session.getCoreSession(); data.doc = coreSession.saveDocument(data.doc); coreSession.save(); return this; } catch (ClientException e) { throw new CmisRuntimeException(e.toString(), e); } } @SuppressWarnings("unchecked") @Override public <T> T getPropertyValue(String id) { return (T) data.getProperty(id).getValue(); } @Override public <T> Property<T> getProperty(String id) { return new NuxeoProperty<T>(this, type, id); } @Override public List<Property<?>> getProperties() { Collection<PropertyDefinition<?>> defs = type.getPropertyDefinitions().values(); List<Property<?>> list = new ArrayList<Property<?>>(defs.size()); for (PropertyDefinition<?> pd : defs) { list.add(new NuxeoProperty<Object>(this, type, pd.getId())); } return list; } @Override public Acl addAcl(List<Ace> addAces, AclPropagation aclPropagation) { throw new CmisNotSupportedException(); } @Override public Acl applyAcl(List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) { throw new CmisNotSupportedException(); } @Override public Acl getAcl() { throw new CmisNotSupportedException(); } @Override public Acl removeAcl(List<Ace> removeAces, AclPropagation aclPropagation) { throw new CmisNotSupportedException(); } @Override public AllowableActions getAllowableActions() { // we don't call data.getAllowableActions as includeAllowableActions // may be false return NuxeoObjectData.getAllowableActions(data.doc, data.creation); } @Override public List<Policy> getPolicies() { return Collections.emptyList(); } @Override public void applyPolicy(ObjectId... policyIds) { throw new CmisNotSupportedException(); } @Override public void removePolicy(ObjectId... policyIds) { throw new CmisNotSupportedException(); } @Override public List<Relationship> getRelationships() { throw new CmisNotSupportedException(); } @Override public List<Rendition> getRenditions() { // we don't call data.getRenditions as renditionFilter may be incomplete List<RenditionData> renditions = NuxeoObjectData.getRenditions( data.doc, null, null, service.getCallContext()); List<Rendition> res = new ArrayList<Rendition>(renditions.size()); for (RenditionData ren : renditions) { long length = ren.getBigLength() == null ? -1 : ren.getBigLength().longValue(); int height = ren.getBigHeight() == null ? -1 : ren.getBigHeight().intValue(); int width = ren.getBigWidth() == null ? -1 : ren.getBigWidth().intValue(); RenditionImpl rendition = new RenditionImpl(session, getId(), ren.getStreamId(), ren.getRenditionDocumentId(), ren.getKind(), length, ren.getMimeType(), ren.getTitle(), height, width); res.add(rendition); } return res; } @Override public void refresh() { try { data.doc.refresh(); } catch (ClientException e) { throw new CmisRuntimeException(e.toString(), e); } } @Override public void refreshIfOld(long durationInMillis) { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } @Override public long getRefreshTimestamp() { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } @Override public List<CmisExtensionElement> getExtensions(ExtensionLevel level) { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } }