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.Directory; 037import org.nuxeo.ecm.directory.DirectoryException; 038import org.nuxeo.ecm.directory.DirectoryFieldMapper; 039import org.nuxeo.ecm.directory.Session; 040import org.nuxeo.runtime.api.Framework; 041 042/** 043 * Implementation of a {@link Directory} on top of a core repository. 044 * 045 * @since 8.2 046 */ 047public class CoreDirectory extends AbstractDirectory { 048 049 private static final Log log = LogFactory.getLog(CoreDirectory.class); 050 051 protected final Schema schema; 052 053 public CoreDirectory(CoreDirectoryDescriptor descriptor) { 054 super(descriptor, null); 055 SchemaManager schemaManager = Framework.getService(SchemaManager.class); 056 schema = schemaManager.getSchema(descriptor.schemaName); 057 fieldMapper = new DirectoryFieldMapper(descriptor.fieldMapping); 058 if (schema == null) { 059 throw new DirectoryException( 060 String.format("Unknown schema '%s' for directory '%s' ", descriptor.schemaName, getName())); 061 } 062 start(); 063 } 064 065 @Override 066 public CoreDirectoryDescriptor getDescriptor() { 067 return (CoreDirectoryDescriptor) descriptor; 068 } 069 070 public void start() { 071 CoreDirectoryDescriptor descriptor = getDescriptor(); 072 UnrestrictedSessionRunner directoryInitializer = new UnrestrictedSessionRunner(descriptor.getRepositoryName()) { 073 074 @Override 075 public void run() { 076 String createPath = descriptor.getCreatePath(); 077 078 DocumentModel rootFolder = null; 079 DocumentRef rootRef = new PathRef(createPath); 080 if (session.exists(rootRef)) { 081 rootFolder = session.getDocument(rootRef); 082 } 083 084 if (rootFolder == null) { 085 086 String parentFolder = createPath.substring(0, createPath.lastIndexOf("/")); 087 if (createPath.lastIndexOf("/") == 0) { 088 parentFolder = "/"; 089 } 090 String createFolder = createPath.substring(createPath.lastIndexOf("/") + 1, createPath.length()); 091 092 log.info(String.format( 093 "Root folder '%s' has not been found for the directory '%s' on the repository '%s', will create it with given ACL", 094 createPath, getName(), descriptor.getRepositoryName())); 095 if (descriptor.canCreateRootFolder()) { 096 try { 097 DocumentModel doc = session.createDocumentModel(parentFolder, createFolder, "Folder"); 098 doc.setProperty("dublincore", "title", createFolder); 099 session.createDocument(doc); 100 // Set ACL from descriptor 101 for (int i = 0; i < descriptor.acls.length; i++) { 102 String userOrGroupName = descriptor.acls[i].userOrGroupName; 103 String privilege = descriptor.acls[i].privilege; 104 boolean granted = descriptor.acls[i].granted; 105 setACL(doc, userOrGroupName, privilege, granted); 106 } 107 session.save(); 108 109 } catch (DocumentNotFoundException e) { 110 throw new DirectoryException(String.format( 111 "The root folder '%s' can not be created under '%s' for the directory '%s' on the repository '%s'," 112 + " please make sure you have set the right path or that the path exist", 113 createFolder, parentFolder, getName(), descriptor.getRepositoryName()), e); 114 } 115 } 116 117 } else { 118 log.info(String.format( 119 "Root folder '%s' has been found for the directory '%s' on the repository '%s', ACL will not be set", 120 createPath, getName(), descriptor.getRepositoryName())); 121 } 122 123 } 124 }; 125 directoryInitializer.runUnrestricted(); 126 } 127 128 protected DocumentModel setACL(DocumentModel rootFolder, String userOrGroupName, String privilege, 129 boolean granted) { 130 ACP acp = rootFolder.getACP(); 131 ACL localACL = acp.getOrCreateACL(); 132 localACL.add(new ACE(userOrGroupName, privilege, granted)); 133 rootFolder.setACP(acp, true); 134 135 if (log.isDebugEnabled()) { 136 log.debug(String.format( 137 "Set ACL on root folder '%s' : userOrGroupName = '%s', privilege = '%s' , granted = '%s' ", 138 rootFolder.getPathAsString(), userOrGroupName, privilege, granted)); 139 } 140 141 return rootFolder.getCoreSession().saveDocument(rootFolder); 142 } 143 144 public Field getField(String name) { 145 Field field = schema.getField(name); 146 if (field == null) { 147 throw new DirectoryException( 148 String.format("Field '%s' does not exist in the schema '%s'", name, schema.getName())); 149 } 150 return field; 151 } 152 153 @Override 154 public Session getSession() { 155 CoreDirectorySession session = new CoreDirectorySession(this); 156 addSession(session); 157 return session; 158 } 159 160}