001/* 002 * (C) Copyright 2014-2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Maxime Hilaire 018 * Florent Guillaume 019 */ 020package org.nuxeo.ecm.directory.core; 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.nuxeo.ecm.core.api.DocumentModel; 025import org.nuxeo.ecm.core.api.DocumentNotFoundException; 026import org.nuxeo.ecm.core.api.DocumentRef; 027import org.nuxeo.ecm.core.api.PathRef; 028import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 029import org.nuxeo.ecm.core.api.security.ACE; 030import org.nuxeo.ecm.core.api.security.ACL; 031import org.nuxeo.ecm.core.api.security.ACP; 032import org.nuxeo.ecm.core.schema.SchemaManager; 033import org.nuxeo.ecm.core.schema.types.Field; 034import org.nuxeo.ecm.core.schema.types.Schema; 035import org.nuxeo.ecm.directory.AbstractDirectory; 036import org.nuxeo.ecm.directory.DirectoryException; 037import org.nuxeo.ecm.directory.DirectoryFieldMapper; 038import org.nuxeo.ecm.directory.Session; 039import org.nuxeo.runtime.api.Framework; 040 041/** 042 * Implementation of a {@link Directory} on top of a core repository. 043 * 044 * @since 8.2 045 */ 046public class CoreDirectory extends AbstractDirectory { 047 048 private static final Log log = LogFactory.getLog(CoreDirectory.class); 049 050 protected final Schema schema; 051 052 public CoreDirectory(CoreDirectoryDescriptor descriptor) { 053 super(descriptor); 054 SchemaManager schemaManager = Framework.getService(SchemaManager.class); 055 schema = schemaManager.getSchema(descriptor.schemaName); 056 fieldMapper = new DirectoryFieldMapper(descriptor.fieldMapping); 057 if (schema == null) { 058 throw new DirectoryException( 059 String.format("Unknown schema '%s' for directory '%s' ", descriptor.schemaName, getName())); 060 } 061 start(); 062 } 063 064 @Override 065 public CoreDirectoryDescriptor getDescriptor() { 066 return (CoreDirectoryDescriptor) descriptor; 067 } 068 069 public void start() { 070 CoreDirectoryDescriptor descriptor = getDescriptor(); 071 UnrestrictedSessionRunner directoryInitializer = new UnrestrictedSessionRunner(descriptor.getRepositoryName()) { 072 073 @Override 074 public void run() { 075 String createPath = descriptor.getCreatePath(); 076 077 DocumentModel rootFolder = null; 078 DocumentRef rootRef = new PathRef(createPath); 079 if (session.exists(rootRef)) { 080 rootFolder = session.getDocument(rootRef); 081 } 082 083 if (rootFolder == null) { 084 085 String parentFolder = createPath.substring(0, createPath.lastIndexOf("/")); 086 if (createPath.lastIndexOf("/") == 0) { 087 parentFolder = "/"; 088 } 089 String createFolder = createPath.substring(createPath.lastIndexOf("/") + 1, createPath.length()); 090 091 log.info(String.format( 092 "Root folder '%s' has not been found for the directory '%s' on the repository '%s', will create it with given ACL", 093 createPath, getName(), descriptor.getRepositoryName())); 094 if (descriptor.canCreateRootFolder()) { 095 try { 096 DocumentModel doc = session.createDocumentModel(parentFolder, createFolder, "Folder"); 097 doc.setProperty("dublincore", "title", createFolder); 098 session.createDocument(doc); 099 // Set ACL from descriptor 100 for (int i = 0; i < descriptor.acls.length; i++) { 101 String userOrGroupName = descriptor.acls[i].userOrGroupName; 102 String privilege = descriptor.acls[i].privilege; 103 boolean granted = descriptor.acls[i].granted; 104 setACL(doc, userOrGroupName, privilege, granted); 105 } 106 session.save(); 107 108 } catch (DocumentNotFoundException e) { 109 throw new DirectoryException(String.format( 110 "The root folder '%s' can not be created under '%s' for the directory '%s' on the repository '%s'," 111 + " please make sure you have set the right path or that the path exist", 112 createFolder, parentFolder, getName(), descriptor.getRepositoryName()), e); 113 } 114 } 115 116 } else { 117 log.info(String.format( 118 "Root folder '%s' has been found for the directory '%s' on the repository '%s', ACL will not be set", 119 createPath, getName(), descriptor.getRepositoryName())); 120 } 121 122 } 123 }; 124 directoryInitializer.runUnrestricted(); 125 } 126 127 protected DocumentModel setACL(DocumentModel rootFolder, String userOrGroupName, String privilege, 128 boolean granted) { 129 ACP acp = rootFolder.getACP(); 130 ACL localACL = acp.getOrCreateACL(); 131 localACL.add(new ACE(userOrGroupName, privilege, granted)); 132 rootFolder.setACP(acp, true); 133 134 if (log.isDebugEnabled()) { 135 log.debug(String.format( 136 "Set ACL on root folder '%s' : userOrGroupName = '%s', privilege = '%s' , granted = '%s' ", 137 rootFolder.getPathAsString(), userOrGroupName, privilege, granted)); 138 } 139 140 return rootFolder.getCoreSession().saveDocument(rootFolder); 141 } 142 143 public Field getField(String name) throws DirectoryException { 144 Field field = schema.getField(name); 145 if (field == null) { 146 throw new DirectoryException( 147 String.format("Field '%s' does not exist in the schema '%s'", name, schema.getName())); 148 } 149 return field; 150 } 151 152 @Override 153 public Session getSession() throws DirectoryException { 154 CoreDirectorySession session = new CoreDirectorySession(this); 155 addSession(session); 156 return session; 157 } 158 159}