/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.core.opencmis.impl.client; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; 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.SecondaryType; 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.Action; 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.apache.chemistry.opencmis.commons.server.CmisService; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService; import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData; import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoPropertyData.NuxeoPropertyDataName; import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoPropertyDataBase; /** * 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 CmisService service; protected final NuxeoCmisService nuxeoCmisService; protected final NuxeoObjectFactory objectFactory; public final NuxeoObjectData data; protected final ObjectType type; protected final List<SecondaryType> secondaryTypes; /** type + secondaryTypes */ protected final List<ObjectType> allTypes; public static NuxeoObject construct(NuxeoSession session, NuxeoObjectData data, ObjectType type, List<SecondaryType> secondaryTypes) { BaseTypeId baseTypeId = type.getBaseTypeId(); switch (baseTypeId) { case CMIS_FOLDER: return new NuxeoFolder(session, data, type, secondaryTypes); case CMIS_DOCUMENT: return new NuxeoDocument(session, data, type, secondaryTypes); case CMIS_POLICY: throw new UnsupportedOperationException(baseTypeId.toString()); case CMIS_RELATIONSHIP: return new NuxeoRelationship(session, data, type, secondaryTypes); default: throw new RuntimeException(baseTypeId.toString()); } } public NuxeoObject(NuxeoSession session, NuxeoObjectData data, ObjectType type, List<SecondaryType> secondaryTypes) { this.session = session; service = session.getService(); nuxeoCmisService = NuxeoCmisService.extractFromCmisService(service); objectFactory = session.getObjectFactory(); this.data = data; this.type = type; this.secondaryTypes = secondaryTypes; allTypes = new ArrayList<>(1 + secondaryTypes.size()); allTypes.add(type); allTypes.addAll(secondaryTypes); } @SuppressWarnings("unchecked") @Override public <T> T getAdapter(Class<T> adapterInterface) { throw new CmisRuntimeException("Cannot adapt to " + adapterInterface.getName()); } 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 List<SecondaryType> getSecondaryTypes() { return secondaryTypes; } @Override public List<ObjectType> findObjectType(String id) { List<ObjectType> types = new ArrayList<>(1); for (ObjectType t : allTypes) { if (t.getPropertyDefinitions().containsKey(id)) { types.add(t); } } return types; } @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 String getDescription() { return getPropertyValue(PropertyIds.DESCRIPTION); } @Override public void delete(boolean allVersions) { service.deleteObject(getRepositoryId(), getId(), Boolean.valueOf(allVersions), null); } @Override public void delete() { delete(true); } @Override public CmisObject updateProperties(Map<String, ?> properties) { return updateProperties(properties, null, null); } @Override public ObjectId updateProperties(Map<String, ?> properties, boolean refresh) { return updateProperties(properties, null, null, refresh); } @Override public CmisObject updateProperties(Map<String, ?> properties, List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds) { ObjectId objectId = updateProperties(properties, addSecondaryTypeIds, removeSecondaryTypeIds, true); return session.getObject(objectId); } @Override public ObjectId updateProperties(Map<String, ?> properties, List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds, boolean refresh) { // refresh is ignored if (addSecondaryTypeIds != null) { for (String facet : addSecondaryTypeIds) { data.doc.addFacet(facet); } } if (removeSecondaryTypeIds != null) { for (String facet : removeSecondaryTypeIds) { data.doc.removeFacet(facet); } } if (properties != null) { for (Entry<String, ?> en : properties.entrySet()) { ((NuxeoPropertyDataBase<?>) data.getProperty(en.getKey())).setValue(en.getValue()); } } CoreSession coreSession = session.getCoreSession(); data.doc = coreSession.saveDocument(data.doc); coreSession.save(); return this; } @Override public CmisObject rename(String newName) { if (newName == null || newName.length() == 0) { throw new IllegalArgumentException("New name must not be empty!"); } Map<String, Object> prop = new HashMap<String, Object>(); prop.put(PropertyIds.NAME, newName); return updateProperties(prop); } @Override public ObjectId rename(String newName, boolean refresh) { if (newName == null || newName.length() == 0) { throw new IllegalArgumentException("New name must not be empty!"); } Map<String, Object> prop = new HashMap<String, Object>(); prop.put(PropertyIds.NAME, newName); return updateProperties(prop, refresh); } @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, id); } @Override public List<Property<?>> getProperties() { List<Property<?>> list = new ArrayList<Property<?>>(); for (ObjectType t : allTypes) { Collection<PropertyDefinition<?>> defs = t.getPropertyDefinitions().values(); for (PropertyDefinition<?> pd : defs) { list.add(new NuxeoProperty<Object>(this, pd.getId())); } } return list; } @Override public Acl addAcl(List<Ace> addAces, AclPropagation aclPropagation) { return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(addAces), null, aclPropagation, null); } @Override public Acl applyAcl(List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) { return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), aclPropagation, null); } @Override public Acl setAcl(List<Ace> aces) { return service.applyAcl(getRepositoryId(), getId(), objectFactory.convertAces(aces), AclPropagation.REPOSITORYDETERMINED); } @Override public Acl getAcl() { return data.getAcl(); } @Override public Acl removeAcl(List<Ace> removeAces, AclPropagation aclPropagation) { return service.applyAcl(getRepositoryId(), getId(), null, objectFactory.convertAces(removeAces), aclPropagation, null); } @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() { List<RenditionData> renditions = data.getRenditions(); if (renditions == null) { return Collections.emptyList(); } 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() { data.doc.refresh(); } @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(); } @Override public boolean hasAllowableAction(Action action) { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } @Override public Set<String> getPermissionsForPrincipal(String principalId) { throw new UnsupportedOperationException(); } @Override public void applyPolicy(ObjectId policyId, boolean refresh) { throw new UnsupportedOperationException(); } @Override public void removePolicy(ObjectId policyId, boolean refresh) { throw new UnsupportedOperationException(); } }