Merged V1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3876 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3925 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3927 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-09-26 00:02:52 +00:00
parent d2bce74f0b
commit d4947ef511
31 changed files with 1661 additions and 123 deletions

View File

@@ -204,11 +204,15 @@
<!-- <!--
<bean id="authenticationComponentImpl" class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImpl"> <bean id="authenticationComponentImpl" class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImpl">
<property name="accept">
<value>true</value>
</property>
</bean> </bean>
--> -->
<!-- The person service. --> <!-- The person service. -->
<bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl"> <bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl">
@@ -237,12 +241,6 @@
<property name="storeUrl"> <property name="storeUrl">
<value>${spaces.store}</value> <value>${spaces.store}</value>
</property> </property>
<!-- The path to the company home space, used to set the -->
<!-- default home space for users that are created if -->
<!-- missing. -->
<property name="companyHomePath">
<value>/${spaces.company_home.childname}</value>
</property>
<!-- Some authentication mechanisms may need to create people --> <!-- Some authentication mechanisms may need to create people -->
<!-- in the repository on demand. This enables that feature. --> <!-- in the repository on demand. This enables that feature. -->
<!-- If dsiabled an error will be generated for missing --> <!-- If dsiabled an error will be generated for missing -->
@@ -260,6 +258,88 @@
</property> </property>
</bean> </bean>
<bean name="homeFolderManager" class="org.alfresco.repo.security.person.HomeFolderManager">
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="policyComponent">
<ref bean="policyComponent" />
</property>
<property name="defaultProvider">
<ref bean="personalHomeFolderProvider" />
</property>
</bean>
<bean name="companyHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<property name="path">
<value>/${spaces.company_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
</bean>
<bean name="guestHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<property name="path">
<value>/${spaces.company_home.childname}/${spaces.guest_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="userPemissions">
<set>
<value>Consumer</value>
</set>
</property>
</bean>
<bean name="bootstrapHomeFolderProvider" class="org.alfresco.repo.security.person.BootstrapHomeFolderProvider">
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
</bean>
<bean name="personalHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<property name="path">
<value>/${spaces.company_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="inheritsPermissionsOnCreate">
<value>false</value>
</property>
<property name="ownerPemissionsToSetOnCreate">
<set>
<value>All</value>
</set>
</property>
<property name="userPemissions">
<set>
<value>All</value>
</set>
</property>
</bean>
<!-- The ticket component. --> <!-- The ticket component. -->
<!-- Used for reauthentication --> <!-- Used for reauthentication -->
<bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl"> <bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl">

View File

@@ -24,6 +24,7 @@
<cm:email></cm:email> <cm:email></cm:email>
<cm:organizationId></cm:organizationId> <cm:organizationId></cm:organizationId>
<cm:homeFolder>/${spaces.company_home.childname}</cm:homeFolder> <cm:homeFolder>/${spaces.company_home.childname}</cm:homeFolder>
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
</cm:person> </cm:person>
<!-- Guest needs to read their own person information --> <!-- Guest needs to read their own person information -->
<cm:person view:childName="cm:person"> <cm:person view:childName="cm:person">
@@ -39,6 +40,7 @@
<cm:email></cm:email> <cm:email></cm:email>
<cm:organizationId></cm:organizationId> <cm:organizationId></cm:organizationId>
<cm:homeFolder>/${spaces.company_home.childname}/${spaces.guest_home.childname}</cm:homeFolder> <cm:homeFolder>/${spaces.company_home.childname}/${spaces.guest_home.childname}</cm:homeFolder>
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
</cm:person> </cm:person>
</sys:children> </sys:children>
</sys:container> </sys:container>

View File

@@ -0,0 +1,38 @@
// Main action
function runAction()
{
out.println("Dump request details :-");
out.println(" Folder node = " + deskParams.getFolderNode());
var folder = deskParams.getFolder();
out.println(" Folder path = " + folder.getFullName());
out.println(" Number of targets = " + deskParams.numberOfTargetNodes());
if ( deskParams.numberOfTargetNodes() > 0) {
out.println(" Targets:");
for ( var i = 0; i < deskParams.numberOfTargetNodes(); i++) {
var target = deskParams.getTarget( i);
out.println(" Type = " + target.getTypeAsString() + ", path = " + target.getTarget());
out.println(" Node = " + target.getNode());
}
}
}
// Run the action
//
// Response :-
// Success - no return or return 0, or "0,<message>"
// For error or control response then return a string :-
// Error - "1,<error message>"
// FileNotFound - "2,<message>"
// AccessDenied - "3,<message>"
// BadParameter - "4,<message>
// NotWorkingCopy - "5,<message>"
// NoSuchAction - "6,<message>
// LaunchURL - "7,<URL>"
// CommandLine - "8,<commandline>"
runAction();
var response = "0,Javascript completed successfully";
response;

View File

@@ -154,14 +154,6 @@
<ref bean="namespaceService"/> <ref bean="namespaceService"/>
</property> </property>
<!--
The path to the location of a space to use as the default home folder.
This folder should be readable by all users, or a group to which all imported users belong.
-->
<property name="defaultHomeFolder">
<value>/app:company_home</value>
</property>
<!-- <!--
This property defines a mapping between attributes held on LDAP user objects and This property defines a mapping between attributes held on LDAP user objects and
the properties of user objects held in the repository. The key is the QName of an attribute in the properties of user objects held in the repository. The key is the QName of an attribute in
@@ -194,6 +186,19 @@
<!-- Active Directory: "???" --> <!-- Active Directory: "???" -->
<value>o</value> <value>o</value>
</entry> </entry>
<!-- Always use the default -->
<entry key="cm:homeFolderProvider">
<null/>
</entry>
</map>
</property>
<!-- Set a default home folder provider -->
<!-- Defaults only apply for values above -->
<property name="attributeDefaults">
<map>
<entry key="cm:homeFolderProvider">
<value>personalHomeFolderProvider</value>
</entry>
</map> </map>
</property> </property>
</bean> </bean>
@@ -356,7 +361,7 @@
<bean id="ldapPeopleImport" class="org.alfresco.repo.importer.ExportSourceImporter"> <bean id="ldapPeopleImport" class="org.alfresco.repo.importer.ExportSourceImporter">
<property name="importerService"> <property name="importerService">
<ref bean="importerComponent"/> <ref bean="importerComponentWithBehaviour"/>
</property> </property>
<property name="transactionService"> <property name="transactionService">
<ref bean="transactionComponent"/> <ref bean="transactionComponent"/>
@@ -404,7 +409,7 @@
<bean id="ldapGroupImport" class="org.alfresco.repo.importer.ExportSourceImporter"> <bean id="ldapGroupImport" class="org.alfresco.repo.importer.ExportSourceImporter">
<property name="importerService"> <property name="importerService">
<ref bean="importerComponent"/> <ref bean="importerComponentWithBehaviour"/>
</property> </property>
<property name="transactionService"> <property name="transactionService">
<ref bean="transactionComponent"/> <ref bean="transactionComponent"/>

View File

@@ -50,6 +50,7 @@
<!-- URL - launches a URL via the Windows shell --> <!-- URL - launches a URL via the Windows shell -->
<!-- CmdLine - launches the Notepad application --> <!-- CmdLine - launches the Notepad application -->
<!-- CheckInOut - checks files in/out, drag and drop files onto the application --> <!-- CheckInOut - checks files in/out, drag and drop files onto the application -->
<!-- JavaScript - run a server-side script -->
<!-- <!--
<desktopActions> <desktopActions>
<global> <global>
@@ -76,6 +77,15 @@
<name>CheckInOut</name> <name>CheckInOut</name>
<filename>__AlfrescoCheckInOut.exe</filename> <filename>__AlfrescoCheckInOut.exe</filename>
</action> </action>
<action>
<class>org.alfresco.filesys.smb.server.repo.desk.JavaScriptDesktopAction</class>
<name>JavaScript</name>
<filename>__AlfrescoScript.exe</filename>
<script>alfresco/desktop/dumpRequest.js</script>
<attributes>anyFiles, multiplePaths , allowNoParams</attributes>
<preprocess>confirm, copyToTarget</preprocess>
</action>
</desktopActions> </desktopActions>
--> -->

View File

@@ -54,6 +54,47 @@
</property> </property>
</bean> </bean>
<bean id="importerComponentWithBehaviour" class="org.alfresco.repo.importer.ImporterComponent">
<!-- For now, hard-wire the view parser -->
<property name="namespaceService">
<ref bean="NamespaceService" />
</property>
<property name="dictionaryService">
<ref bean="DictionaryService" />
</property>
<property name="nodeService">
<ref bean="NodeService" />
</property>
<property name="contentService">
<ref bean="ContentService" />
</property>
<property name="ruleService">
<ref bean="RuleService" />
</property>
<property name="permissionService">
<ref bean="PermissionService" />
</property>
<property name="authorityService">
<ref bean="AuthorityService" />
</property>
<property name="authenticationService">
<ref bean="AuthenticationService" />
</property>
<property name="viewParser">
<ref bean="viewParser" />
</property>
<property name="behaviourFilter">
<ref bean="unboundPolicyBehaviourFilter" />
</property>
<property name="searchService">
<ref bean="searchService" />
</property>
<property name="ownableService">
<ref bean="ownableService" />
</property>
</bean>
<bean id="exporterComponent" class="org.alfresco.repo.exporter.ExporterComponent"> <bean id="exporterComponent" class="org.alfresco.repo.exporter.ExporterComponent">
<property name="namespaceService"> <property name="namespaceService">
<ref bean="NamespaceService" /> <ref bean="NamespaceService" />

View File

@@ -167,6 +167,12 @@
<property name="cm:organizationId"> <property name="cm:organizationId">
<type>d:text</type> <type>d:text</type>
</property> </property>
<property name="cm:homeFolderProvider">
<type>d:text</type>
</property>
<property name="cm:defaultHomeFolderPath">
<type>d:text</type>
</property>
</properties> </properties>
</type> </type>

View File

@@ -114,7 +114,7 @@
<!-- The properties of a node may ony be read if there is read access to the parent --> <!-- The properties of a node may ony be read if there is read access to the parent -->
<!-- node. ReadChildren access to the parent node is recursive for all nodes from --> <!-- node. ReadChildren access to the parent node is recursive for all nodes from -->
<!-- which the node inherits permissions. Access is required down the permission --> <!-- which the node inherits permissions. Access is required down the permission -->
<!-- tree at all pioints. --> <!-- tree at all points. -->
<!-- --> <!-- -->
<permission name="_ReadProperties" expose="false" > <permission name="_ReadProperties" expose="false" >

View File

@@ -57,7 +57,7 @@
<property name="contentService"><ref bean="ContentService" /></property> <property name="contentService"><ref bean="ContentService" /></property>
<property name="permissionService"><ref bean="permissionService"/></property> <property name="permissionService"><ref bean="permissionService"/></property>
<property name="authenticationComponent"><ref bean="authenticationComponent"/></property> <property name="authenticationComponent"><ref bean="authenticationComponent"/></property>
<property name="checkInOutService"><ref bean="checkOutCheckInService"/></property> <property name="serviceRegistry"><ref bean="ServiceRegistry"/></property>
</bean> </bean>
<bean id="cifsHelper" class="org.alfresco.filesys.smb.server.repo.CifsHelper"> <bean id="cifsHelper" class="org.alfresco.filesys.smb.server.repo.CifsHelper">

View File

@@ -19,6 +19,12 @@
</property> </property>
</bean> </bean>
<bean id="unboundPolicyBehaviourFilter" class="org.alfresco.repo.policy.BehaviourFilterImpl">
<property name="dictionaryService">
<ref bean="dictionaryService"/>
</property>
</bean>
<bean id="policyComponent" class="org.alfresco.repo.policy.PolicyComponentImpl"> <bean id="policyComponent" class="org.alfresco.repo.policy.PolicyComponentImpl">
<constructor-arg index="0"> <constructor-arg index="0">
<ref bean="dictionaryService"/> <ref bean="dictionaryService"/>

View File

@@ -57,6 +57,7 @@ import org.alfresco.filesys.util.DataBuffer;
import org.alfresco.filesys.util.WildCard; import org.alfresco.filesys.util.WildCard;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.lock.NodeLockedException; import org.alfresco.service.cmr.lock.NodeLockedException;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
@@ -99,10 +100,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
private SearchService searchService; private SearchService searchService;
private ContentService contentService; private ContentService contentService;
private PermissionService permissionService; private PermissionService permissionService;
private CheckOutCheckInService checkOutInService;
private AuthenticationComponent authComponent; private AuthenticationComponent authComponent;
// Service registry for desktop actions
private ServiceRegistry serviceRegistry;
/** /**
* Class constructor * Class constructor
* *
@@ -173,13 +177,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
} }
/** /**
* Return the check in/out service * Return the service registry
* *
* @return CheckOutInService * @return ServiceRegistry
*/ */
public final CheckOutCheckInService getCheckInOutService() public final ServiceRegistry getServiceRegistry()
{ {
return this.checkOutInService; return this.serviceRegistry;
} }
/** /**
@@ -233,13 +237,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
} }
/** /**
* Set the check in/out service * Set the service registry
* *
* @param checkInService CheckOutInService * @param serviceRegistry
*/ */
public void setCheckInOutService(CheckOutCheckInService checkInService) public void setServiceRegistry(ServiceRegistry serviceRegistry)
{ {
this.checkOutInService = checkInService; this.serviceRegistry = serviceRegistry;
} }
/** /**

View File

@@ -27,7 +27,6 @@ import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.smb.server.repo.pseudo.LocalPseudoFile; import org.alfresco.filesys.smb.server.repo.pseudo.LocalPseudoFile;
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile; import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
@@ -35,8 +34,6 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/** /**
* Desktop Action Class * Desktop Action Class
@@ -455,13 +452,13 @@ public abstract class DesktopAction {
} }
/** /**
* Return the check in/out service * Return the service registry
* *
* @return CheckOutInService * @return ServiceRegistry
*/ */
public final CheckOutCheckInService getCheckInOutService() public final ServiceRegistry getServiceRegistry()
{ {
return m_contentDriver.getCheckInOutService(); return m_contentDriver.getServiceRegistry();
} }
/** /**

View File

@@ -19,6 +19,8 @@ package org.alfresco.filesys.smb.server.repo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.mozilla.javascript.ScriptableObject;
/** /**
* Desktop Response Class * Desktop Response Class
* *
@@ -26,7 +28,11 @@ import java.util.List;
* *
* @author gkspencer * @author gkspencer
*/ */
public class DesktopResponse { public class DesktopResponse extends ScriptableObject {
// Version id
private static final long serialVersionUID = 6421278986221629296L;
// Desktop action status and optional status message // Desktop action status and optional status message
@@ -59,6 +65,28 @@ public class DesktopResponse {
m_statusMsg = msg; m_statusMsg = msg;
} }
/**
* Javascript constructor
*
* @param sts int
* @param msg String
*/
public void jsConstructor(int sts, String msg)
{
m_status = sts;
m_statusMsg = msg;
}
/**
* Return the class name
*
* @return String
*/
@Override
public String getClassName() {
return "DesktopResponse";
}
/** /**
* Return the status code * Return the status code
* *
@@ -69,6 +97,16 @@ public class DesktopResponse {
return m_status; return m_status;
} }
/**
* Return the status property
*
* @return int
*/
public int jsGet_status()
{
return m_status;
}
/** /**
* Determine if there is an optional status message * Determine if there is an optional status message
* *
@@ -89,6 +127,16 @@ public class DesktopResponse {
return m_statusMsg; return m_statusMsg;
} }
/**
* Return the status message property
*
* @return String
*/
public String jsGet_message()
{
return m_statusMsg != null ? m_statusMsg : "";
}
/** /**
* Determine if there are optional response values * Determine if there are optional response values
* *
@@ -144,6 +192,26 @@ public class DesktopResponse {
m_statusMsg = msg; m_statusMsg = msg;
} }
/**
* Set the status property
*
* @param sts int
*/
public void jsSet_status(int sts)
{
m_status = sts;
}
/**
* Set the status message property
*
* @param msg String
*/
public void jsSet_message(String msg)
{
m_statusMsg = msg;
}
/** /**
* Return the desktop response as a string * Return the desktop response as a string
* *

View File

@@ -27,6 +27,7 @@ import org.alfresco.filesys.smb.server.repo.DesktopParams;
import org.alfresco.filesys.smb.server.repo.DesktopResponse; import org.alfresco.filesys.smb.server.repo.DesktopResponse;
import org.alfresco.filesys.smb.server.repo.DesktopTarget; import org.alfresco.filesys.smb.server.repo.DesktopTarget;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -38,6 +39,10 @@ import org.alfresco.service.cmr.repository.NodeRef;
*/ */
public class CheckInOutDesktopAction extends DesktopAction { public class CheckInOutDesktopAction extends DesktopAction {
// Check in/out service
private CheckOutCheckInService m_checkInOutService;
/** /**
* Class constructor * Class constructor
*/ */
@@ -46,6 +51,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
super( DesktopAction.AttrAnyFiles, DesktopAction.PreConfirmAction + DesktopAction.PreCopyToTarget + DesktopAction.PreLocalToWorkingCopy); super( DesktopAction.AttrAnyFiles, DesktopAction.PreConfirmAction + DesktopAction.PreCopyToTarget + DesktopAction.PreLocalToWorkingCopy);
} }
/**
* Return the confirmation string to be displayed by the client
*
* @return String
*/
@Override @Override
public String getConfirmationString() { public String getConfirmationString() {
return "Run check in/out action"; return "Run check in/out action";
@@ -60,7 +70,7 @@ public class CheckInOutDesktopAction extends DesktopAction {
@Override @Override
public DesktopResponse runAction(DesktopParams params) { public DesktopResponse runAction(DesktopParams params) {
// check if there are any files/folders to process // Check if there are any files/folders to process
if ( params.numberOfTargetNodes() == 0) if ( params.numberOfTargetNodes() == 0)
return new DesktopResponse(StsSuccess); return new DesktopResponse(StsSuccess);
@@ -188,4 +198,23 @@ public class CheckInOutDesktopAction extends DesktopAction {
return response; return response;
} }
/**
* Get the check in/out service
*
* @return CheckOutCheckInService
*/
protected final CheckOutCheckInService getCheckInOutService()
{
// Check if the service has been cached
if ( m_checkInOutService == null)
{
m_checkInOutService = getServiceRegistry().getCheckOutCheckInService();
}
// Return the check in/out service
return m_checkInOutService;
}
} }

View File

@@ -0,0 +1,448 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.filesys.smb.server.repo.desk;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.smb.server.repo.DesktopAction;
import org.alfresco.filesys.smb.server.repo.DesktopActionException;
import org.alfresco.filesys.smb.server.repo.DesktopParams;
import org.alfresco.filesys.smb.server.repo.DesktopResponse;
import org.alfresco.service.cmr.repository.ScriptException;
import org.alfresco.service.cmr.repository.ScriptService;
/**
* Javascript Desktop Action Class
*
* <p>Run a server-side script against the target node(s).
*
* @author gkspencer
*/
public class JavaScriptDesktopAction extends DesktopAction {
// Script service
private ScriptService m_scriptService;
// Script name
private String m_scriptName;
// Script file details
private String m_scriptPath;
private long m_lastModified;
// Script string
private String m_script;
/**
* Class constructor
*/
public JavaScriptDesktopAction()
{
super( DesktopAction.AttrAnyFiles, DesktopAction.PreConfirmAction + DesktopAction.PreCopyToTarget);
}
/**
* Return the confirmation string to be displayed by the client
*
* @return String
*/
@Override
public String getConfirmationString()
{
return "Run Javascript action";
}
/**
* Initialize the action
*
* @param global ConfigElement
* @param config ConfigElement
* @param fileSys DiskSharedDevice
* @exception DesktopActionException
*/
@Override
public void initializeAction(ConfigElement global, ConfigElement config, DiskSharedDevice fileSys)
throws DesktopActionException
{
// Perform standard initialization
super.initializeAction(global, config, fileSys);
// Get the script file name and check that it exists
ConfigElement elem = config.getChild("script");
if ( elem != null && elem.getValue().length() > 0)
{
// Set the script name
setScriptName(elem.getValue());
// Check if the script exists on the classpath
URL scriptURL = this.getClass().getClassLoader().getResource(getScriptName());
if ( scriptURL == null)
throw new DesktopActionException("Failed to find script on classpath, " + getScriptName());
// Decode the URL path, it might contain escaped characters
String scriptURLPath = null;
try
{
scriptURLPath = URLDecoder.decode( scriptURL.getFile(), "UTF-8");
}
catch ( UnsupportedEncodingException ex)
{
throw new DesktopActionException("Failed to decode script path, " + ex.getMessage());
}
// Check that the script file exists
File scriptFile = new File(scriptURLPath);
if ( scriptFile.exists() == false)
throw new DesktopActionException("Script file not found, " + elem.getValue());
m_scriptPath = scriptFile.getAbsolutePath();
m_lastModified =scriptFile.lastModified();
// Load the script
try
{
loadScript( scriptFile);
}
catch ( IOException ex)
{
throw new DesktopActionException( "Failed to load script, " + ex.getMessage());
}
}
else
throw new DesktopActionException("Script name not specified");
// check if the desktop action attributes have been specified
elem = config.getChild("attributes");
if ( elem != null)
{
// Check if the attribute string is empty
if ( elem.getValue().length() == 0)
throw new DesktopActionException("Empty desktop action attributes");
// Parse the attribute string
int attr = 0;
StringTokenizer tokens = new StringTokenizer( elem.getValue(), ",");
while ( tokens.hasMoreTokens())
{
// Get the current attribute token and validate
String token = tokens.nextToken().trim();
if ( token.equalsIgnoreCase( "targetFiles"))
attr |= AttrTargetFiles;
else if ( token.equalsIgnoreCase( "targetFolders"))
attr |= AttrTargetFolders;
else if ( token.equalsIgnoreCase( "clientFiles"))
attr |= AttrClientFiles;
else if ( token.equalsIgnoreCase( "clientFolders"))
attr |= AttrClientFolders;
else if ( token.equalsIgnoreCase( "alfrescoFiles"))
attr |= AttrAlfrescoFiles;
else if ( token.equalsIgnoreCase( "alfrescoFolders"))
attr |= AttrAlfrescoFolders;
else if ( token.equalsIgnoreCase( "multiplePaths"))
attr |= AttrMultiplePaths;
else if ( token.equalsIgnoreCase( "allowNoParams"))
attr |= AttrAllowNoParams;
else if ( token.equalsIgnoreCase( "anyFiles"))
attr |= AttrAnyFiles;
else if ( token.equalsIgnoreCase( "anyFolders"))
attr |= AttrAnyFolders;
else if ( token.equalsIgnoreCase( "anyFilesFolders"))
attr |= AttrAnyFilesFolders;
else
throw new DesktopActionException("Unknown attribute, " + token);
}
// Set the action attributes
setAttributes( attr);
}
// Check if the desktop action pre-processing options have been specified
elem = config.getChild("preprocess");
if ( elem != null)
{
// Check if the pre-process string is empty
if ( elem.getValue().length() == 0)
throw new DesktopActionException("Empty desktop action pre-processing flags");
// Parse the pre-process string
int pre = 0;
StringTokenizer tokens = new StringTokenizer( elem.getValue(), ",");
while ( tokens.hasMoreTokens())
{
// Get the current pre-process token and validate
String token = tokens.nextToken().trim();
if ( token.equalsIgnoreCase( "copyToTarget"))
pre |= PreCopyToTarget;
else if ( token.equalsIgnoreCase( "confirm"))
pre |= PreConfirmAction;
else if ( token.equalsIgnoreCase( "localToWorkingCopy"))
pre |= PreLocalToWorkingCopy;
else
throw new DesktopActionException("Unknown pre-processing flag, " + token);
}
// Set the action pre-processing flags
setPreProcessActions( pre);
}
}
/**
* Run the desktop action
*
* @param params DesktopParams
* @return DesktopResponse
*/
@Override
public DesktopResponse runAction(DesktopParams params)
throws DesktopActionException
{
// Check if the script file has been changed
DesktopResponse response = new DesktopResponse(StsSuccess);
File scriptFile = new File(m_scriptPath);
if ( scriptFile.lastModified() != m_lastModified)
{
// Reload the script
m_lastModified = scriptFile.lastModified();
try
{
loadScript( scriptFile);
}
catch ( IOException ex)
{
response.setStatus(StsError, "Failed to reload script file, " + getScriptName());
return response;
}
}
// Start a transaction
params.getSession().beginTransaction(getTransactionService(), false);
// Access the script service
if ( getScriptService() != null)
{
// Create the objects to be passed to the script
Map<String, Object> model = new HashMap<String, Object>();
model.put("deskParams", params);
model.put("out", System.out);
// Start a transaction
params.getSession().beginTransaction(getTransactionService(), false);
// Run the script
Object result = null;
try
{
// Run the script
result = getScriptService().executeScriptString( getScript(), model);
// Check the result
if ( result != null)
{
// Check for a full response object
if ( result instanceof DesktopResponse)
{
response = (DesktopResponse) result;
}
// Status code only response
else if ( result instanceof Double)
{
Double jsSts = (Double) result;
response.setStatus( jsSts.intValue(), "");
}
// Encoded response in the format '<stsCode>,<stsMessage>'
else if ( result instanceof String)
{
String responseMsg = (String) result;
// Parse the status message
StringTokenizer token = new StringTokenizer( responseMsg, ",");
String stsToken = token.nextToken();
String msgToken = token.nextToken();
int sts = -1;
try
{
sts = Integer.parseInt( stsToken);
}
catch ( NumberFormatException ex)
{
response.setStatus( StsError, "Bad response from script");
}
// Set the response
response.setStatus( sts, msgToken != null ? msgToken : "");
}
}
}
catch (ScriptException ex)
{
// Set the error response for the client
response.setStatus( StsError, ex.getMessage());
}
}
else
{
// Return an error response, script service not available
response.setStatus( StsError, "Script service not available");
}
// Return the response
return response;
}
/**
* Get the script service
*
* @return ScriptService
*/
protected final ScriptService getScriptService()
{
// Check if the script service has been initialized
if ( m_scriptService == null)
{
// Get the script service
m_scriptService = getServiceRegistry().getScriptService();
}
// Return the script service
return m_scriptService;
}
/**
* Get the script name
*
* @return String
*/
public final String getScriptName()
{
return m_scriptName;
}
/**
* Return the script data
*
* @return String
*/
public final String getScript()
{
return m_script;
}
/**
* Set the script name
*
* @param name String
*/
protected final void setScriptName(String name)
{
m_scriptName = name;
}
/**
* Load, or reload, the script
*
* @param scriptFile File
*/
private final void loadScript(File scriptFile)
throws IOException
{
// Open the script file
BufferedReader scriptIn = new BufferedReader(new FileReader( scriptFile));
StringBuilder scriptStr = new StringBuilder((int) scriptFile.length() + 256);
String inRec = scriptIn.readLine();
while ( inRec != null)
{
scriptStr.append( inRec);
scriptStr.append( "\n");
inRec = scriptIn.readLine();
}
// Close the script file
scriptIn.close();
// Update the script string
m_script = scriptStr.toString();
}
}

View File

@@ -570,7 +570,9 @@ public class DataBuffer
// Check if there is enough space in the buffer // Check if there is enough space in the buffer
int bytLen = str.length() * 2; int bytLen = str.length() * 2;
if (m_data.length - m_pos < bytLen) if ( nulTerm)
bytLen += 2;
if ((m_data.length - m_pos) < (bytLen + 4))
extendBuffer(bytLen + 4); extendBuffer(bytLen + 4);
// Word align the buffer position, pack the Unicode string // Word align the buffer position, pack the Unicode string

View File

@@ -151,6 +151,10 @@ public interface ContentModel
static final QName PROP_LASTNAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "lastName"); static final QName PROP_LASTNAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "lastName");
static final QName PROP_EMAIL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "email"); static final QName PROP_EMAIL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "email");
static final QName PROP_ORGID = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "organizationId"); static final QName PROP_ORGID = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "organizationId");
static final QName PROP_HOME_FOLDER_PROVIDER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "homeFolderProvider");
static final QName PROP_DEFAULT_HOME_FOLDER_PATH = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "defaultHomeFolderPath");
// Ownable aspect // Ownable aspect
static final QName ASPECT_OWNABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "ownable"); static final QName ASPECT_OWNABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "ownable");

View File

@@ -35,6 +35,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyMap;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -126,7 +127,7 @@ public class AuditableAspect
public void onAddAudit(NodeRef nodeRef, QName aspect) public void onAddAudit(NodeRef nodeRef, QName aspect)
{ {
// Get the current properties // Get the current properties
Map<QName, Serializable> properties = this.nodeService.getProperties(nodeRef); PropertyMap properties = new PropertyMap();
// Set created / updated date // Set created / updated date
Date now = new Date(System.currentTimeMillis()); Date now = new Date(System.currentTimeMillis());
@@ -167,7 +168,7 @@ public class AuditableAspect
// Get the current properties // Get the current properties
try try
{ {
Map<QName, Serializable> properties = this.nodeService.getProperties(nodeRef); PropertyMap properties = new PropertyMap();
// Set updated date // Set updated date
Date now = new Date(System.currentTimeMillis()); Date now = new Date(System.currentTimeMillis());
@@ -249,7 +250,11 @@ public class AuditableAspect
*/ */
public Boolean doWork() throws Exception public Boolean doWork() throws Exception
{ {
nodeService.setProperties(nodeRef, properties); for (QName propertyQName : properties.keySet())
{
Serializable property = properties.get(propertyQName);
nodeService.setProperty(nodeRef, propertyQName, property);
}
return Boolean.TRUE; return Boolean.TRUE;
} }
} }

View File

@@ -42,10 +42,10 @@
<property name="fail" column="fail" type="boolean" not-null="true"/> <property name="fail" column="fail" type="boolean" not-null="true"/>
<!-- TODO: Check the URL length ...--> <!-- TODO: Check the URL length ...-->
<property name="serialisedURL" column="serialized_url" type="string" length="1024" not-null="false"/> <property name="serialisedURL" column="serialized_url" type="string" length="1024" not-null="false"/>
<property name="exception" column="exception" type="string" length="1024" not-null="false"/> <property name="exception" column="exception_message" type="string" length="1024" not-null="false"/>
<property name="hostInetAddress" column="host_address" type="string" length="1024" not-null="false"/> <property name="hostInetAddress" column="host_address" type="string" length="1024" not-null="false"/>
<property name="clientInetAddress" column="client_address" type="string" length="1024" not-null="false"/> <property name="clientInetAddress" column="client_address" type="string" length="1024" not-null="false"/>
<property name="message" column="message" type="string" length="1024" not-null="false"/> <property name="message" column="message_text" type="string" length="1024" not-null="false"/>
<!-- Links to dimensions --> <!-- Links to dimensions -->

View File

@@ -133,29 +133,6 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
return sb.toString(); return sb.toString();
} }
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
else if (obj == this)
{
return true;
}
else if (!(obj instanceof ChildAssoc))
{
return false;
}
ChildAssoc that = (ChildAssoc) obj;
return EqualsHelper.nullSafeEquals(id, that.getId());
}
public int hashCode()
{
return (id == null ? 0 : id.hashCode());
}
/** /**
* Orders the child associations by ID. A smaller ID has a higher priority. * Orders the child associations by ID. A smaller ID has a higher priority.
* This may change once we introduce a changeable index against which to order. * This may change once we introduce a changeable index against which to order.

View File

@@ -530,10 +530,10 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
assoc.setChildNodeNameCrc(-1L); // random names compete only with each other assoc.setChildNodeNameCrc(-1L); // random names compete only with each other
assoc.setQname(qname); assoc.setQname(qname);
assoc.setIsPrimary(isPrimary); assoc.setIsPrimary(isPrimary);
// persist it, catching the duplicate child name
getHibernateTemplate().save(assoc);
// maintain inverse sets // maintain inverse sets
assoc.buildAssociation(parentNode, childNode); assoc.buildAssociation(parentNode, childNode);
// persist it
getHibernateTemplate().save(assoc);
// done // done
return assoc; return assoc;
} }

View File

@@ -66,7 +66,7 @@ public class LDAPPersonExportSource implements ExportSource
private NamespaceService namespaceService; private NamespaceService namespaceService;
private String defaultHomeFolder; private Map<String, String> attributeDefaults;
private boolean errorOnMissingUID; private boolean errorOnMissingUID;
@@ -100,9 +100,9 @@ public class LDAPPersonExportSource implements ExportSource
this.personService = personService; this.personService = personService;
} }
public void setDefaultHomeFolder(String defaultHomeFolder) public void setAttributeDefaults(Map<String, String> attributeDefaults)
{ {
this.defaultHomeFolder = defaultHomeFolder; this.attributeDefaults = attributeDefaults;
} }
public void setNamespaceService(NamespaceService namespaceService) public void setNamespaceService(NamespaceService namespaceService)
@@ -231,35 +231,28 @@ public class LDAPPersonExportSource implements ExportSource
writer.characters(value.toCharArray(), 0, value.length()); writer.characters(value.toCharArray(), 0, value.length());
} }
} }
else
{
String defaultValue = attributeDefaults.get(key);
if(defaultValue != null)
{
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
}
}
}
else
{
String defaultValue = attributeDefaults.get(key);
if(defaultValue != null)
{
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
}
} }
writer.endElement(keyQName.getNamespaceURI(), keyQName.getLocalName(), keyQName writer.endElement(keyQName.getNamespaceURI(), keyQName.getLocalName(), keyQName
.toPrefixString(namespaceService)); .toPrefixString(namespaceService));
} }
// Default home folder
if (!(attributeMapping.keySet().contains(ContentModel.PROP_HOMEFOLDER.toString()) || attributeMapping
.keySet().contains(ContentModel.PROP_HOMEFOLDER.toPrefixString(namespaceService))))
{
// Only if we are creating the person for the first time
if (!personService.personExists(uid))
{
writer.startElement(ContentModel.PROP_HOMEFOLDER.getNamespaceURI(),
ContentModel.PROP_HOMEFOLDER.getLocalName(), ContentModel.PROP_HOMEFOLDER
.toPrefixString(namespaceService), new AttributesImpl());
if (defaultHomeFolder != null)
{
writer.characters(defaultHomeFolder.toCharArray(), 0, defaultHomeFolder.length());
}
writer.endElement(ContentModel.PROP_HOMEFOLDER.getNamespaceURI(),
ContentModel.PROP_HOMEFOLDER.getLocalName(), ContentModel.PROP_HOMEFOLDER
.toPrefixString(namespaceService));
}
}
if (personService.personExists(uid)) if (personService.personExists(uid))
{ {
String uguid = personService.getPerson(uid).getId(); String uguid = personService.getPerson(uid).getId();

View File

@@ -0,0 +1,439 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
/**
* Common support for creating home folders This is hooked into node creation events from Person type objects via the homeFolderManager. Provider must all be wired up to the
* homeFolderManager.
*
* @author Andy Hind
*/
public abstract class AbstractHomeFolderProvider implements HomeFolderProvider, BeanNameAware, InitializingBean
{
/**
* The provider name
*/
private String name;
/**
* The home folder manager
*/
private HomeFolderManager homeFolderManager;
/**
* The store ref in which to conduct searches
*/
private StoreRef storeRef;
/**
* Service registry to get hold of public services (so taht actions are audited)
*/
private ServiceRegistry serviceRegistry;
/**
* The path to a folder
*/
private String path;
/**
* Cache the result of the path look up.
*/
private NodeRef pathNodeRef;
/**
* The owner to set on creation of a home folder (if unset this will be the uid).
*/
private String ownerOnCreate;
/**
* Set if permissions are inherited when nodes are created.
*/
private boolean inheritsPermissionsOnCreate = false;
/**
* A set of permissions to set for the owner when a home folder is created
*/
private Set<String> ownerPemissionsToSetOnCreate;
/**
* General permissions to set on the node Map<(String)uid, Set<(String)permission>>.
*/
private Map<String, Set<String>> permissionsToSetOnCreate;
/**
* Permissions to set for the user - on create and reference.
*/
private Set<String> userPemissions;
/**
* Clear existing permissions on new home folders (useful of created from a template.
*/
private boolean clearExistingPermissionsOnCreate = false;
public AbstractHomeFolderProvider()
{
super();
}
/**
* Register with the homeFolderManagewr
*/
public void afterPropertiesSet() throws Exception
{
homeFolderManager.addProvider(this);
}
// === //
// IOC //
// === //
/**
* Get the home folder manager.
*/
protected HomeFolderManager getHomeFolderManager()
{
return homeFolderManager;
}
/**
* Set the home folder manager.
*
* @param homeFolderManager
*/
public void setHomeFolderManager(HomeFolderManager homeFolderManager)
{
this.homeFolderManager = homeFolderManager;
}
/**
* Get the provider name
*/
public String getName()
{
return name;
}
/**
* The provider name is taken from the bean name
*/
public void setBeanName(String name)
{
this.name = name;
}
/**
* Get the path
*
* @return
*/
protected String getPath()
{
return path;
}
/**
* Set the path
*
* @param path
*/
public void setPath(String path)
{
this.path = path;
}
/**
* Get the store ref
*
* @return
*/
protected StoreRef getStoreRef()
{
return storeRef;
}
/**
* Set the store ref
*
* @param storeRef
*/
public void setStoreRef(StoreRef storeRef)
{
this.storeRef = storeRef;
}
/**
* Set the store from the string url.
*
* @param storeUrl
*/
public void setStoreUrl(String storeUrl)
{
this.storeRef = new StoreRef(storeUrl);
}
/**
* Get the service registry.
*
* @return
*/
protected ServiceRegistry getServiceRegistry()
{
return serviceRegistry;
}
/**
* Set the service registry.
*
* @param serviceRegistry
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
/**
* Inherit permissions when home folder are created?
*
* @param inheritsPermissionsOnCreate
*/
public void setInheritsPermissionsOnCreate(boolean inheritsPermissionsOnCreate)
{
this.inheritsPermissionsOnCreate = inheritsPermissionsOnCreate;
}
/**
* The owner to set on create.
*
* @param ownerOnCreate
*/
public void setOwnerOnCreate(String ownerOnCreate)
{
this.ownerOnCreate = ownerOnCreate;
}
/**
* The owner permissions to set on create.
*
* @param ownerPemissionsToSetOnCreate
*/
public void setOwnerPemissionsToSetOnCreate(Set<String> ownerPemissionsToSetOnCreate)
{
this.ownerPemissionsToSetOnCreate = ownerPemissionsToSetOnCreate;
}
/**
* General permissions to set on create.
*
* @param permissionsToSetOnCreate
*/
public void setPermissionsToSetOnCreate(Map<String, Set<String>> permissionsToSetOnCreate)
{
this.permissionsToSetOnCreate = permissionsToSetOnCreate;
}
/**
* User permissions to set on create and on reference.
*
* @param userPemissions
*/
public void setUserPemissions(Set<String> userPemissions)
{
this.userPemissions = userPemissions;
}
/**
* Clear exising permissions on create. Useful to clear permissions from a template.
*
* @param clearExistingPermissionsOnCreate
*/
public void setClearExistingPermissionsOnCreate(boolean clearExistingPermissionsOnCreate)
{
this.clearExistingPermissionsOnCreate = clearExistingPermissionsOnCreate;
}
/**
* Cache path to node resolution/
*
* @return
*/
protected synchronized NodeRef getPathNodeRef()
{
if (pathNodeRef == null)
{
pathNodeRef = resolvePath(path);
}
return pathNodeRef;
}
/**
* Utility metho to resolve paths to nodes.
*
* @param pathToResolve
* @return
*/
protected NodeRef resolvePath(String pathToResolve)
{
List<NodeRef> refs = serviceRegistry.getSearchService().selectNodes(
serviceRegistry.getNodeService().getRootNode(storeRef), pathToResolve, null,
serviceRegistry.getNamespaceService(), false);
if (refs.size() != 1)
{
throw new IllegalStateException("Non-unique path: found : " + pathToResolve + " " + refs.size());
}
return refs.get(0);
}
/**
* The implementation of the policy binding. Run as the system user for auditing.
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{
AuthenticationUtil.RunAsWork<NodeRef> action = new OnCreateNode(childAssocRef);
AuthenticationUtil.runAs(action, AuthenticationUtil.getSystemUserName());
}
/**
* Abstract implementation to find/create the approriate home space.
*
* @param person
* @return
*/
protected abstract HomeSpaceNodeRef getHomeFolder(NodeRef person);
/**
* Helper class to encapsulate the createion settinhg permissions etc
*
* @author Andy Hind
*/
private class OnCreateNode implements AuthenticationUtil.RunAsWork<NodeRef>
{
ChildAssociationRef childAssocRef;
OnCreateNode(ChildAssociationRef childAssocRef)
{
this.childAssocRef = childAssocRef;
}
public NodeRef doWork() throws Exception
{
// Find person
NodeRef personNodeRef = childAssocRef.getChildRef();
// Get home folder
HomeSpaceNodeRef homeFolder = getHomeFolder(personNodeRef);
// If it exists
if (homeFolder.getNodeRef() != null)
{
// Get uid and keep
String uid = DefaultTypeConverter.INSTANCE.convert(String.class, serviceRegistry.getNodeService()
.getProperty(personNodeRef, ContentModel.PROP_USERNAME));
// If created or found then set (other wise it was already set correctly)
if (homeFolder.getStatus() != HomeSpaceNodeRef.Status.VALID)
{
serviceRegistry.getNodeService().setProperty(personNodeRef, ContentModel.PROP_HOMEFOLDER,
homeFolder.getNodeRef());
}
// If created..
if (homeFolder.getStatus() == HomeSpaceNodeRef.Status.CREATED)
{
// Set to a specified owner or make owned by the person.
if (ownerOnCreate != null)
{
serviceRegistry.getOwnableService().setOwner(homeFolder.getNodeRef(), ownerOnCreate);
}
else
{
serviceRegistry.getOwnableService().setOwner(homeFolder.getNodeRef(), uid);
}
// clear permissions - useful of not required from a template
if (clearExistingPermissionsOnCreate)
{
serviceRegistry.getPermissionService().deletePermissions(homeFolder.getNodeRef());
}
// inherit permissions
serviceRegistry.getPermissionService().setInheritParentPermissions(homeFolder.getNodeRef(),
inheritsPermissionsOnCreate);
// Set owner permissions
if (ownerPemissionsToSetOnCreate != null)
{
for (String permission : ownerPemissionsToSetOnCreate)
{
serviceRegistry.getPermissionService().setPermission(homeFolder.getNodeRef(),
PermissionService.OWNER_AUTHORITY, permission, true);
}
}
// Add other permissions
if (permissionsToSetOnCreate != null)
{
for (String user : permissionsToSetOnCreate.keySet())
{
Set<String> set = permissionsToSetOnCreate.get(user);
if (set != null)
{
for (String permission : set)
{
serviceRegistry.getPermissionService().setPermission(homeFolder.getNodeRef(), user,
permission, true);
}
}
}
}
}
// Add user permissions on create and reference
if (userPemissions != null)
{
for (String permission : userPemissions)
{
serviceRegistry.getPermissionService().setPermission(homeFolder.getNodeRef(), uid, permission,
true);
}
}
}
return homeFolder.getNodeRef();
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Provider to use in the boostrap process - does nothing
*
* Probably not required as behaviour/policies are disabled during normal import.
*
* @author Andy Hind
*/
public class BootstrapHomeFolderProvider extends AbstractHomeFolderProvider
{
@Override
protected HomeSpaceNodeRef getHomeFolder(NodeRef person)
{
return new HomeSpaceNodeRef(null, HomeSpaceNodeRef.Status.VALID);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
/**
* Set a home space from a simple path.
*
* @author Andy Hind
*/
public class ExistingPathBasedHomeFolderProvider extends AbstractHomeFolderProvider
{
public ExistingPathBasedHomeFolderProvider()
{
super();
}
protected HomeSpaceNodeRef getHomeFolder(NodeRef person)
{
NodeRef existingHomeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, getServiceRegistry().getNodeService().getProperty(
person, ContentModel.PROP_HOMEFOLDER));
if (existingHomeFolder == null)
{
return new HomeSpaceNodeRef(getPathNodeRef(), HomeSpaceNodeRef.Status.REFERENCED);
}
else
{
return new HomeSpaceNodeRef(existingHomeFolder, HomeSpaceNodeRef.Status.VALID);
}
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.springframework.beans.factory.InitializingBean;
/**
* Manage home folder creation by binding to events from the cm:person type.
*
* @author Andy Hind
*/
public class HomeFolderManager implements InitializingBean, NodeServicePolicies.OnCreateNodePolicy
{
private PolicyComponent policyComponent;
private NodeService nodeService;
/**
* A default provider
*/
private HomeFolderProvider defaultProvider;
/**
* Providers that have registered and are looken up by name (== bean name)
*/
private Map<String, HomeFolderProvider> providers = new HashMap<String, HomeFolderProvider>();
/**
* Bind the calss behaviour to this implementation
*/
public void afterPropertiesSet() throws Exception
{
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
}
/**
* Set the policy component.
*
* @param policyComponent
*/
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
/**
* Set the node service.
* @param nodeService
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Register a home folder provider.
*
* @param provider
*/
public void addProvider(HomeFolderProvider provider)
{
providers.put(provider.getName(), provider);
}
/**
* Set the default home folder provider (user which none is specified or when one is not found)
* @param defaultProvider
*/
public void setDefaultProvider(HomeFolderProvider defaultProvider)
{
this.defaultProvider = defaultProvider;
}
/**
* Find the provider and call.
*/
public void onCreateNode(ChildAssociationRef childAssocRef)
{
HomeFolderProvider provider = defaultProvider;
String providerName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(childAssocRef
.getChildRef(), ContentModel.PROP_HOME_FOLDER_PROVIDER));
if (providerName != null)
{
provider = providers.get(providerName);
if (provider == null)
{
provider = defaultProvider;
}
}
if (provider != null)
{
provider.onCreateNode(childAssocRef);
}
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import org.alfresco.repo.node.NodeServicePolicies;
/**
* Interface for home folder providers.
*
* @author Andy Hind
*/
public interface HomeFolderProvider extends NodeServicePolicies.OnCreateNodePolicy
{
/**
* Get the name of the provider.
*
* @return
*/
public String getName();
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* A ref to a home folder
* - the node ref
* - a simple status as to how it was obtained
*
* @author Andy Hind
*/
public class HomeSpaceNodeRef
{
public enum Status{VALID, REFERENCED, CREATED};
private NodeRef nodeRef;
private Status status;
public HomeSpaceNodeRef(NodeRef nodeRef, Status status)
{
this.nodeRef = nodeRef;
this.status = status;
}
NodeRef getNodeRef()
{
return nodeRef;
}
Status getStatus()
{
return status;
}
}

View File

@@ -64,14 +64,12 @@ public class PersonServiceImpl implements PersonService
private boolean createMissingPeople; private boolean createMissingPeople;
private String companyHomePath;
private NodeRef companyHomeNodeRef;
private static Set<QName> mutableProperties; private static Set<QName> mutableProperties;
private boolean userNamesAreCaseSensitive = false; private boolean userNamesAreCaseSensitive = false;
private String defaultHomeFolderProvider;
static static
{ {
Set<QName> props = new HashSet<QName>(); Set<QName> props = new HashSet<QName>();
@@ -99,6 +97,11 @@ public class PersonServiceImpl implements PersonService
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive; this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
} }
void setDefaultHomeFolderProvider(String defaultHomeFolderProvider)
{
this.defaultHomeFolderProvider = defaultHomeFolderProvider;
}
public NodeRef getPerson(String userName) public NodeRef getPerson(String userName)
{ {
NodeRef personNode = getPersonOrNull(userName); NodeRef personNode = getPersonOrNull(userName);
@@ -245,19 +248,14 @@ public class PersonServiceImpl implements PersonService
{ {
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>(); HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, userName); properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_HOMEFOLDER, getHomeFolder());
properties.put(ContentModel.PROP_FIRSTNAME, userName); properties.put(ContentModel.PROP_FIRSTNAME, userName);
properties.put(ContentModel.PROP_LASTNAME, ""); properties.put(ContentModel.PROP_LASTNAME, "");
properties.put(ContentModel.PROP_EMAIL, ""); properties.put(ContentModel.PROP_EMAIL, "");
properties.put(ContentModel.PROP_ORGID, ""); properties.put(ContentModel.PROP_ORGID, "");
properties.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, defaultHomeFolderProvider);
return properties; return properties;
} }
private NodeRef getHomeFolder()
{
return getCompanyHome();
}
public NodeRef createPerson(Map<QName, Serializable> properties) public NodeRef createPerson(Map<QName, Serializable> properties)
{ {
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties
@@ -373,26 +371,6 @@ public class PersonServiceImpl implements PersonService
this.storeRef = new StoreRef(storeUrl); this.storeRef = new StoreRef(storeUrl);
} }
public void setCompanyHomePath(String companyHomePath)
{
this.companyHomePath = companyHomePath;
}
public synchronized NodeRef getCompanyHome()
{
if (companyHomeNodeRef == null)
{
List<NodeRef> refs = searchService.selectNodes(nodeService.getRootNode(storeRef), companyHomePath, null,
namespacePrefixResolver, false);
if (refs.size() != 1)
{
throw new IllegalStateException("Invalid company home path: found : " + refs.size());
}
companyHomeNodeRef = refs.get(0);
}
return companyHomeNodeRef;
}
public String getUserIdentifier(String caseSensitiveUserName) public String getUserIdentifier(String caseSensitiveUserName)
{ {
NodeRef nodeRef = getPersonOrNull(caseSensitiveUserName); NodeRef nodeRef = getPersonOrNull(caseSensitiveUserName);

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.
*/
package org.alfresco.repo.security.person;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
/**
* Create home spaces based on the UID of the user.
*
* If a suitable space is found it is reused, if not it will be made.
*
* @author Andy Hind
*/
public class UIDBasedHomeFolderProvider extends ExistingPathBasedHomeFolderProvider
{
private String templatePath;
private NodeRef templateNodeRef;
public UIDBasedHomeFolderProvider()
{
super();
}
public void setTemplatePath(String templatePath)
{
this.templatePath = templatePath;
}
protected HomeSpaceNodeRef getHomeFolder(NodeRef person)
{
NodeRef existingHomeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, getServiceRegistry()
.getNodeService().getProperty(person, ContentModel.PROP_HOMEFOLDER));
if (existingHomeFolder == null)
{
String uid = DefaultTypeConverter.INSTANCE.convert(String.class, getServiceRegistry().getNodeService()
.getProperty(person, ContentModel.PROP_USERNAME));
FileInfo fileInfo;
// Test if it already exists
NodeRef exising = getServiceRegistry().getFileFolderService().searchSimple(getPathNodeRef(), uid);
if (exising != null)
{
fileInfo = getServiceRegistry().getFileFolderService().getFileInfo(exising);
}
else
{
if (templatePath == null)
{
fileInfo = getServiceRegistry().getFileFolderService().create(getPathNodeRef(), uid,
ContentModel.TYPE_FOLDER);
}
else
{
try
{
fileInfo = getServiceRegistry().getFileFolderService().copy(getTemplateNodeRef(),
getPathNodeRef(), uid);
}
catch (FileNotFoundException e)
{
throw new PersonException("Invalid template to create home space");
}
}
}
NodeRef homeFolderNodeRef = fileInfo.getNodeRef();
return new HomeSpaceNodeRef(homeFolderNodeRef, HomeSpaceNodeRef.Status.CREATED);
}
else
{
return new HomeSpaceNodeRef(existingHomeFolder, HomeSpaceNodeRef.Status.VALID);
}
}
protected synchronized NodeRef getTemplateNodeRef()
{
if (templateNodeRef == null)
{
templateNodeRef = resolvePath(templatePath);
}
return templateNodeRef;
}
}

View File

@@ -39,6 +39,10 @@ public interface CopyService
* If the new node resides in a different workspace the new node will * If the new node resides in a different workspace the new node will
* have the same id. * have the same id.
* <p> * <p>
* <b>NOTE:</b> It is up to the client code to set the name of the newly created node.
* Use the {@link NodeService node service} and catch the
* {@link DuplicateChildNodeNameException}
* <p>
* If the new node resides in the same workspace then * If the new node resides in the same workspace then
* the new node will have the Copy aspect applied to it which will * the new node will have the Copy aspect applied to it which will
* reference the original node. * reference the original node.