/* * 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.server; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.chemistry.opencmis.commons.data.PermissionMapping; import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer; import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList; import org.apache.chemistry.opencmis.commons.enums.AclPropagation; import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; import org.apache.chemistry.opencmis.commons.enums.CapabilityAcl; import org.apache.chemistry.opencmis.commons.enums.CapabilityChanges; import org.apache.chemistry.opencmis.commons.enums.CapabilityContentStreamUpdates; import org.apache.chemistry.opencmis.commons.enums.CapabilityJoin; import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery; import org.apache.chemistry.opencmis.commons.enums.CapabilityRenditions; import org.apache.chemistry.opencmis.commons.enums.SupportedPermissions; import org.apache.chemistry.opencmis.commons.impl.dataobjects.AclCapabilitiesDataImpl; import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryCapabilitiesImpl; import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryInfoImpl; import org.eclipse.ecr.core.api.security.SecurityConstants; import org.eclipse.ecr.core.schema.DocumentType; import org.eclipse.ecr.core.schema.SchemaManager; import org.eclipse.ecr.opencmis.impl.util.TypeManagerImpl; import org.eclipse.ecr.runtime.api.Framework; /** * Information about a Nuxeo repository. */ public class NuxeoRepository { public static final String NUXEO_VERSION_PROP = "org.nuxeo.distribution.version"; protected final String repositoryId; protected final String rootFolderId; protected TypeManagerImpl typeManager; public NuxeoRepository(String repositoryId, String rootFolderId) { this.repositoryId = repositoryId; this.rootFolderId = rootFolderId; } public String getId() { return repositoryId; } // no need to have it synchronized public TypeManagerImpl getTypeManager() { if (typeManager == null) { typeManager = initializeTypes(); } return typeManager; } protected static TypeManagerImpl initializeTypes() { SchemaManager schemaManager; try { schemaManager = Framework.getService(SchemaManager.class); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new RuntimeException(e.toString(), e); // TODO } // scan the types to find super/inherited relationships Map<String, List<String>> typesChildren = new HashMap<String, List<String>>(); for (DocumentType dt : schemaManager.getDocumentTypes()) { org.eclipse.ecr.core.schema.types.Type st = dt.getSuperType(); if (st == null) { continue; } String name = st.getName(); List<String> siblings = typesChildren.get(name); if (siblings == null) { siblings = new LinkedList<String>(); typesChildren.put(name, siblings); } siblings.add(dt.getName()); } // convert the transitive closure for Folder and Document subtypes Set<String> done = new HashSet<String>(); TypeManagerImpl typeManager = new TypeManagerImpl(); typeManager.addTypeDefinition(NuxeoTypeHelper.constructCmisBase( BaseTypeId.CMIS_DOCUMENT, schemaManager)); typeManager.addTypeDefinition(NuxeoTypeHelper.constructCmisBase( BaseTypeId.CMIS_FOLDER, schemaManager)); typeManager.addTypeDefinition(NuxeoTypeHelper.constructCmisBase( BaseTypeId.CMIS_RELATIONSHIP, schemaManager)); addTypesRecursively(typeManager, NuxeoTypeHelper.NUXEO_DOCUMENT, typesChildren, done, schemaManager); addTypesRecursively(typeManager, NuxeoTypeHelper.NUXEO_FOLDER, typesChildren, done, schemaManager); addTypesRecursively(typeManager, NuxeoTypeHelper.NUXEO_RELATION, typesChildren, done, schemaManager); return typeManager; } protected static void addTypesRecursively(TypeManagerImpl typeManager, String name, Map<String, List<String>> typesChildren, Set<String> done, SchemaManager schemaManager) { if (done.contains(name)) { return; } done.add(name); DocumentType dt = schemaManager.getDocumentType(name); String parentTypeId = NuxeoTypeHelper.getParentTypeId(dt); if (parentTypeId != null) { if (typeManager.getTypeById(parentTypeId) == null) { // if parent was ignored, reparent under cmis:document parentTypeId = BaseTypeId.CMIS_DOCUMENT.value(); } typeManager.addTypeDefinition(NuxeoTypeHelper.construct(dt, parentTypeId)); } // recurse in children List<String> children = typesChildren.get(name); if (children == null) { return; } for (String sub : children) { addTypesRecursively(typeManager, sub, typesChildren, done, schemaManager); } } public String getRootFolderId() { return rootFolderId; } public RepositoryInfo getRepositoryInfo(String latestChangeLogToken) { RepositoryInfoImpl repositoryInfo = new RepositoryInfoImpl(); repositoryInfo.setId(repositoryId); repositoryInfo.setName("Nuxeo Repository " + repositoryId); repositoryInfo.setDescription("Nuxeo Repository " + repositoryId); repositoryInfo.setCmisVersionSupported("1.0"); repositoryInfo.setPrincipalAnonymous("Guest"); // TODO repositoryInfo.setPrincipalAnyone(SecurityConstants.EVERYONE); repositoryInfo.setThinClientUri(null); // TODO repositoryInfo.setChangesIncomplete(Boolean.FALSE); repositoryInfo.setChangesOnType(Arrays.asList(BaseTypeId.CMIS_DOCUMENT, BaseTypeId.CMIS_FOLDER)); repositoryInfo.setLatestChangeLogToken(latestChangeLogToken); repositoryInfo.setVendorName("Nuxeo"); repositoryInfo.setProductName("Nuxeo OpenCMIS Connector"); String version = Framework.getProperty(NUXEO_VERSION_PROP, "5.4 dev"); repositoryInfo.setProductVersion(version); repositoryInfo.setRootFolder(rootFolderId); RepositoryCapabilitiesImpl caps = new RepositoryCapabilitiesImpl(); repositoryInfo.setCapabilities(caps); AclCapabilitiesDataImpl aclCaps = new AclCapabilitiesDataImpl(); repositoryInfo.setAclCapabilities(aclCaps); caps.setAllVersionsSearchable(Boolean.TRUE); caps.setCapabilityAcl(CapabilityAcl.NONE); caps.setCapabilityChanges(CapabilityChanges.OBJECTIDSONLY); caps.setCapabilityContentStreamUpdates(CapabilityContentStreamUpdates.PWCONLY); caps.setCapabilityJoin(CapabilityJoin.INNERANDOUTER); caps.setCapabilityQuery(CapabilityQuery.BOTHCOMBINED); caps.setCapabilityRendition(CapabilityRenditions.READ); caps.setIsPwcSearchable(Boolean.TRUE); caps.setIsPwcUpdatable(Boolean.TRUE); caps.setSupportsGetDescendants(Boolean.TRUE); caps.setSupportsGetFolderTree(Boolean.TRUE); caps.setSupportsMultifiling(Boolean.FALSE); caps.setSupportsUnfiling(Boolean.FALSE); caps.setSupportsVersionSpecificFiling(Boolean.FALSE); aclCaps.setAclPropagation(AclPropagation.REPOSITORYDETERMINED); aclCaps.setPermissionDefinitionData(new ArrayList<PermissionDefinition>( 0)); aclCaps.setPermissionMappingData(new HashMap<String, PermissionMapping>()); aclCaps.setSupportedPermissions(SupportedPermissions.BASIC); return repositoryInfo; } // Structures are not copied when returned public TypeDefinition getTypeDefinition(String typeId) { TypeDefinitionContainer typec = getTypeManager().getTypeById(typeId); return typec == null ? null : typec.getTypeDefinition(); } // Structures are not copied when returned public TypeDefinitionList getTypeChildren(String typeId, Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount) { return getTypeManager().getTypeChildren(typeId, includePropertyDefinitions, maxItems, skipCount); } public List<TypeDefinitionContainer> getTypeDescendants(String typeId, int depth, Boolean includePropertyDefinitions) { return getTypeManager().getTypeDescendants(typeId, depth, includePropertyDefinitions); } }