/* * (C) Copyright 2014-2016 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: * Maxime Hilaire * Florent Guillaume */ package org.nuxeo.ecm.directory.core; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentNotFoundException; import org.nuxeo.ecm.core.api.DocumentRef; import org.nuxeo.ecm.core.api.PathRef; import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; import org.nuxeo.ecm.core.api.security.ACE; import org.nuxeo.ecm.core.api.security.ACL; import org.nuxeo.ecm.core.api.security.ACP; import org.nuxeo.ecm.core.schema.SchemaManager; import org.nuxeo.ecm.core.schema.types.Field; import org.nuxeo.ecm.core.schema.types.Schema; import org.nuxeo.ecm.directory.AbstractDirectory; import org.nuxeo.ecm.directory.DirectoryException; import org.nuxeo.ecm.directory.DirectoryFieldMapper; import org.nuxeo.ecm.directory.Session; import org.nuxeo.runtime.api.Framework; /** * Implementation of a {@link Directory} on top of a core repository. * * @since 8.2 */ public class CoreDirectory extends AbstractDirectory { private static final Log log = LogFactory.getLog(CoreDirectory.class); protected final Schema schema; public CoreDirectory(CoreDirectoryDescriptor descriptor) { super(descriptor); SchemaManager schemaManager = Framework.getService(SchemaManager.class); schema = schemaManager.getSchema(descriptor.schemaName); fieldMapper = new DirectoryFieldMapper(descriptor.fieldMapping); if (schema == null) { throw new DirectoryException( String.format("Unknown schema '%s' for directory '%s' ", descriptor.schemaName, getName())); } start(); } @Override public CoreDirectoryDescriptor getDescriptor() { return (CoreDirectoryDescriptor) descriptor; } public void start() { CoreDirectoryDescriptor descriptor = getDescriptor(); UnrestrictedSessionRunner directoryInitializer = new UnrestrictedSessionRunner(descriptor.getRepositoryName()) { @Override public void run() { String createPath = descriptor.getCreatePath(); DocumentModel rootFolder = null; DocumentRef rootRef = new PathRef(createPath); if (session.exists(rootRef)) { rootFolder = session.getDocument(rootRef); } if (rootFolder == null) { String parentFolder = createPath.substring(0, createPath.lastIndexOf("/")); if (createPath.lastIndexOf("/") == 0) { parentFolder = "/"; } String createFolder = createPath.substring(createPath.lastIndexOf("/") + 1, createPath.length()); log.info(String.format( "Root folder '%s' has not been found for the directory '%s' on the repository '%s', will create it with given ACL", createPath, getName(), descriptor.getRepositoryName())); if (descriptor.canCreateRootFolder()) { try { DocumentModel doc = session.createDocumentModel(parentFolder, createFolder, "Folder"); doc.setProperty("dublincore", "title", createFolder); session.createDocument(doc); // Set ACL from descriptor for (int i = 0; i < descriptor.acls.length; i++) { String userOrGroupName = descriptor.acls[i].userOrGroupName; String privilege = descriptor.acls[i].privilege; boolean granted = descriptor.acls[i].granted; setACL(doc, userOrGroupName, privilege, granted); } session.save(); } catch (DocumentNotFoundException e) { throw new DirectoryException(String.format( "The root folder '%s' can not be created under '%s' for the directory '%s' on the repository '%s'," + " please make sure you have set the right path or that the path exist", createFolder, parentFolder, getName(), descriptor.getRepositoryName()), e); } } } else { log.info(String.format( "Root folder '%s' has been found for the directory '%s' on the repository '%s', ACL will not be set", createPath, getName(), descriptor.getRepositoryName())); } } }; directoryInitializer.runUnrestricted(); } protected DocumentModel setACL(DocumentModel rootFolder, String userOrGroupName, String privilege, boolean granted) { ACP acp = rootFolder.getACP(); ACL localACL = acp.getOrCreateACL(); localACL.add(new ACE(userOrGroupName, privilege, granted)); rootFolder.setACP(acp, true); if (log.isDebugEnabled()) { log.debug(String.format( "Set ACL on root folder '%s' : userOrGroupName = '%s', privilege = '%s' , granted = '%s' ", rootFolder.getPathAsString(), userOrGroupName, privilege, granted)); } return rootFolder.getCoreSession().saveDocument(rootFolder); } public Field getField(String name) throws DirectoryException { Field field = schema.getField(name); if (field == null) { throw new DirectoryException( String.format("Field '%s' does not exist in the schema '%s'", name, schema.getName())); } return field; } @Override public Session getSession() throws DirectoryException { CoreDirectorySession session = new CoreDirectorySession(this); addSession(session); return session; } }