RM-1144 & RM-1145 - changes to file to action

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@61046 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Hibbins
2014-02-04 18:19:37 +00:00
parent 45f47af6a9
commit 01a232a29a
10 changed files with 183 additions and 37 deletions

View File

@@ -114,4 +114,7 @@
</condition> </condition>
<antcall target="copyWebDirectory"></antcall> <antcall target="copyWebDirectory"></antcall>
</target> </target>
</project>
<target name="quickBuildAndDeployExploded" depends="install, deployExploded" description="" />
</project>

View File

@@ -1,28 +1,29 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<project name="rm-server" basedir="."> <project name="rm-server" basedir=".">
<import file="../build.xml" /> <import file="../build.xml" />
<property file="../build.local.properties" /> <property file="../build.local.properties" />
<property file="../build.properties" /> <property file="../build.properties" />
<property file="build.local.properties" /> <property file="build.local.properties" />
<property file="build.properties" /> <property file="build.properties" />
<target name="copyDBDriver"> <target name="copyDBDriver">
<exec executable="${mvn.exec}" failonerror="true"> <exec executable="${mvn.exec}" failonerror="true">
<arg value="dependency:get" /> <arg value="dependency:get" />
<arg value="-DgroupId=${db.driver.groupId}" /> <arg value="-DgroupId=${db.driver.groupId}" />
<arg value="-DartifactId=${db.driver.artifactId}" /> <arg value="-DartifactId=${db.driver.artifactId}" />
<arg value="-Dversion=${db.driver.version}" /> <arg value="-Dversion=${db.driver.version}" />
<arg value="-Dpackaging=${db.driver.packaging}" /> <arg value="-Dpackaging=${db.driver.packaging}" />
<arg value="-Ddest=${app.tomcat.folder}/lib" /> <arg value="-Ddest=${app.tomcat.folder}/lib" />
</exec> </exec>
</target> </target>
<target name="copyDevContextFile"> <target name="copyDevContextFile">
<property name="devContextFile" value="../root/projects/repository/config/alfresco/extension/dev-context.xml" /> <property name="devContextFile" value="../root/projects/repository/config/alfresco/extension/dev-context.xml" />
<copy file="${devContextFile}" todir="${app.tomcat.folder}/shared/classes/alfresco/extension" failonerror="true" /> <copy file="${devContextFile}" todir="${app.tomcat.folder}/shared/classes/alfresco/extension" failonerror="true" />
<copy file="${devContextFile}" todir="config/alfresco/extension" failonerror="true" /> <copy file="${devContextFile}" todir="config/alfresco/extension" failonerror="true" />
</target> </target>
<target name="prepareEnv" depends="copyDBDriver, copyDevContextFile" description="" />
<target name="prepareEnv" depends="copyDBDriver, copyDevContextFile" description="" />
</project> </project>

View File

@@ -78,7 +78,7 @@ unfreeze.description=Unfreezes a record.
fileTo.title=File to fileTo.title=File to
fileTo.description=Files a record to the specified record folder. fileTo.description=Files a record to the specified record folder.
fileTo.path.display-label=Path to Record Folder fileTo.path.display-label=Path to Record Folder
fileTo.createRecordFolder.display-label=Create Record Folder fileTo.createRecordPath.display-label=Create Record Path
# Reject # Reject
reject.title=Reject reject.title=Reject
reject.description=Rejects a record and moves the document to its original location reject.description=Rejects a record and moves the document to its original location

View File

@@ -566,4 +566,11 @@
<property name="authorityService" ref="AuthorityService" /> <property name="authorityService" ref="AuthorityService" />
</bean> </bean>
<!-- REST impl for GET Substitution Suggestions for RM -->
<bean id="webscript.org.alfresco.repository.substitutionsuggestions.rm-substitutionsuggestions.get"
class="org.alfresco.repo.web.scripts.substitutionsuggestions.RmSubstitutionSuggestionsGet"
parent="webscript">
<property name="parameterProcessorComponent" ref="parameterProcessorComponent"/>
</bean>
</beans> </beans>

View File

@@ -15,6 +15,7 @@ import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -32,14 +33,14 @@ public class FileToAction extends RMActionExecuterAbstractBase
/** action parameters */ /** action parameters */
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder"; public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder";
public static final String PARAM_PATH = "path"; public static final String PARAM_PATH = "path";
public static final String PARAM_CREATE_RECORD_FOLDER = "createRecordFolder"; public static final String PARAM_CREATE_RECORD_PATH = "createRecordPath";
/** file folder service */ /** file folder service */
private FileFolderService fileFolderService; private FileFolderService fileFolderService;
/** file plan service */ /** file plan service */
private FilePlanService filePlanService; private FilePlanService filePlanService;
/** /**
* @param fileFolderService file folder service * @param fileFolderService file folder service
*/ */
@@ -63,7 +64,7 @@ public class FileToAction extends RMActionExecuterAbstractBase
protected void addParameterDefinitions(List<ParameterDefinition> paramList) protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{ {
paramList.add(new ParameterDefinitionImpl(PARAM_PATH, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_PATH))); paramList.add(new ParameterDefinitionImpl(PARAM_PATH, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_PATH)));
paramList.add(new ParameterDefinitionImpl(PARAM_CREATE_RECORD_FOLDER, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_CREATE_RECORD_FOLDER))); paramList.add(new ParameterDefinitionImpl(PARAM_CREATE_RECORD_PATH, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_CREATE_RECORD_PATH)));
} }
/** /**
@@ -141,7 +142,7 @@ public class FileToAction extends RMActionExecuterAbstractBase
// look for the creation strategy // look for the creation strategy
boolean create = false; boolean create = false;
Boolean createValue = (Boolean)action.getParameterValue(PARAM_CREATE_RECORD_FOLDER); Boolean createValue = (Boolean)action.getParameterValue(PARAM_CREATE_RECORD_PATH);
if (createValue != null) if (createValue != null)
{ {
create = createValue.booleanValue(); create = createValue.booleanValue();
@@ -155,7 +156,7 @@ public class FileToAction extends RMActionExecuterAbstractBase
if (create == true) if (create == true)
{ {
// get the parent into which we are going to create the new record folder // get the parent into which we are going to create the new record folder
NodeRef parent = resolveParent(context, pathValues); NodeRef parent = resolveParent(context, pathValues, create);
if (parent == null) if (parent == null)
{ {
throw new AlfrescoRuntimeException("Unable to create new record folder, because destination parent could not be found."); throw new AlfrescoRuntimeException("Unable to create new record folder, because destination parent could not be found.");
@@ -187,12 +188,43 @@ public class FileToAction extends RMActionExecuterAbstractBase
* @return * @return
*/ */
private NodeRef resolvePath(final NodeRef context, final String[] pathValues) private NodeRef resolvePath(final NodeRef context, final String[] pathValues)
{
return resolvePath(context, pathValues, false);
}
/**
*
* @param context
* @param pathValues
* @param create Create any missing path elements
* @return
*/
private NodeRef resolvePath(final NodeRef context, final String[] pathValues, boolean create)
{ {
NodeRef result = null; NodeRef result = null;
FileInfo fileInfo = null; FileInfo fileInfo = null;
try try
{ {
fileInfo = fileFolderService.resolveNamePath(context, new ArrayList<String>(Arrays.asList(pathValues)), false); List<String> pathValueList = new ArrayList<String>(Arrays.asList(pathValues));
fileInfo = fileFolderService.resolveNamePath(context, pathValueList, false);
if((fileInfo == null) && create)
{
NodeRef parent = this.filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
for(int i = 1; i <= pathValueList.size(); i++)
{
List<String> partialPathValueList = pathValueList.subList(0, i);
fileInfo = fileFolderService.resolveNamePath(context, partialPathValueList, false);
if(fileInfo == null)
{
parent = this.filePlanService.createRecordCategory(parent, partialPathValueList.get(partialPathValueList.size() - 1));
}
else
{
parent = fileInfo.getNodeRef();
}
}
result = parent;
}
} }
catch (FileNotFoundException e) catch (FileNotFoundException e)
{ {
@@ -212,6 +244,18 @@ public class FileToAction extends RMActionExecuterAbstractBase
* @return * @return
*/ */
private NodeRef resolveParent(NodeRef context, String[] pathValues) private NodeRef resolveParent(NodeRef context, String[] pathValues)
{
return resolveParent(context, pathValues, false);
}
/**
*
* @param context
* @param pathValues
* @param create Create any missing path elements
* @return
*/
private NodeRef resolveParent(NodeRef context, String[] pathValues, boolean create)
{ {
NodeRef result = null; NodeRef result = null;
@@ -229,7 +273,7 @@ public class FileToAction extends RMActionExecuterAbstractBase
else else
{ {
pathValues = (String[])ArrayUtils.remove(pathValues, pathValues.length-1); pathValues = (String[])ArrayUtils.remove(pathValues, pathValues.length-1);
result = resolvePath(context, pathValues); result = resolvePath(context, pathValues, create);
} }
return result; return result;

View File

@@ -19,7 +19,9 @@
package org.alfresco.repo.action.parameter; package org.alfresco.repo.action.parameter;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -30,7 +32,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @author Roy Wetherall * @author Roy Wetherall
* @since 2.1 * @since 2.1
*/ */
public class DateParameterProcessor extends ParameterProcessor public class DateParameterProcessor extends ParameterProcessor implements ParameterSubstitutionSuggester
{ {
private static final String DAY = "day"; private static final String DAY = "day";
private static final String WEEK = "week"; private static final String WEEK = "week";
@@ -39,6 +41,27 @@ public class DateParameterProcessor extends ParameterProcessor
private static final String SHORT = "short"; private static final String SHORT = "short";
private static final String LONG = "long"; private static final String LONG = "long";
private static final String NUMBER = "number"; private static final String NUMBER = "number";
private static final String SEP = ".";
private static final String[] ALL_FIELDS_FOR_SUBSTITUTION_QUERY = {
DAY,
DAY + SEP + SHORT,
DAY + SEP + LONG,
DAY + SEP + NUMBER,
WEEK,
WEEK + SEP + SHORT,
WEEK + SEP + LONG,
WEEK + SEP + NUMBER,
MONTH,
MONTH + SEP + SHORT,
MONTH + SEP + LONG,
MONTH + SEP + NUMBER,
YEAR,
YEAR + SEP + SHORT,
YEAR + SEP + LONG,
YEAR + SEP + NUMBER
};
/** /**
* @see org.alfresco.repo.action.parameter.ParameterProcessor#process(java.lang.String, org.alfresco.service.cmr.repository.NodeRef) * @see org.alfresco.repo.action.parameter.ParameterProcessor#process(java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
@@ -172,4 +195,28 @@ public class DateParameterProcessor extends ParameterProcessor
return style; return style;
} }
@Override
public List<String> getSubstitutionSuggestions(String substitutionFragment)
{
List<String> suggestions = new ArrayList<String>();
String namePrefix = this.getName() + ".";
if(this.getName().toLowerCase().contains(substitutionFragment.toLowerCase()))
{
for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) {
suggestions.add(namePrefix + field);
}
}
else
{
for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) {
String prefixFieldName = namePrefix + field;
if(prefixFieldName.toLowerCase().contains(substitutionFragment.toLowerCase()))
{
suggestions.add(namePrefix + field);
}
}
}
return suggestions;
}
} }

View File

@@ -19,7 +19,9 @@
package org.alfresco.repo.action.parameter; package org.alfresco.repo.action.parameter;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -28,6 +30,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.action.ParameterizedItem; import org.alfresco.service.cmr.action.ParameterizedItem;
import org.alfresco.service.cmr.action.ParameterizedItemDefinition; import org.alfresco.service.cmr.action.ParameterizedItemDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
/** /**
* Parameter processor component * Parameter processor component
@@ -35,13 +38,15 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @author Roy Wetherall * @author Roy Wetherall
* @since 2.1 * @since 2.1
*/ */
public class ParameterProcessorComponent public class ParameterProcessorComponent implements ParameterSubstitutionSuggester
{ {
/** regex used to parse parameters */ /** regex used to parse parameters */
private static final String REG_EX = "\\$\\{([^\\$\\{]+)\\}"; private static final String REG_EX_OLD = "\\$\\{([^\\$\\{]+)\\}";
private static final String REG_EX = "\\{([^\\{]+)\\}";
/** registry of parameter processors */ /** registry of parameter processors */
private Map<String, ParameterProcessor> processors = new HashMap<String, ParameterProcessor>(5); private Map<String, ParameterProcessor> processors = new HashMap<String, ParameterProcessor>(5);
private List<ParameterSubstitutionSuggester> subtitutionSuggesterProcessors = new ArrayList<ParameterSubstitutionSuggester>(5);
/** /**
* Register parameter processor * Register parameter processor
@@ -51,6 +56,10 @@ public class ParameterProcessorComponent
public void register(ParameterProcessor processor) public void register(ParameterProcessor processor)
{ {
this.processors.put(processor.getName(), processor); this.processors.put(processor.getName(), processor);
if(processor instanceof ParameterSubstitutionSuggester)
{
this.subtitutionSuggesterProcessors.add((ParameterSubstitutionSuggester)processor);
}
} }
/** /**
@@ -83,9 +92,14 @@ public class ParameterProcessorComponent
* @return String resulting value * @return String resulting value
*/ */
public String process(String value, NodeRef nodeRef) public String process(String value, NodeRef nodeRef)
{
return process(process(value, nodeRef, REG_EX_OLD), nodeRef, REG_EX);
}
public String process(String value, NodeRef nodeRef, String regExp)
{ {
// match the substitution pattern // match the substitution pattern
Pattern patt = Pattern.compile(REG_EX); Pattern patt = Pattern.compile(regExp);
Matcher m = patt.matcher(value); Matcher m = patt.matcher(value);
StringBuffer sb = new StringBuffer(value.length()); StringBuffer sb = new StringBuffer(value.length());
@@ -112,6 +126,25 @@ public class ParameterProcessorComponent
return sb.toString(); return sb.toString();
} }
/**
* Return a list of substitution suggestions for the passed string fragment.
*
* @param subtitutionFragment Text fragment to search on.
* @return A list of substitutions that match the substitution fragment.
*/
public List<String> getSubstitutionSuggestions(final String substitutionFragment)
{
List<String> suggestions = new ArrayList<String>();
if (StringUtils.isNotBlank(substitutionFragment))
{
for (ParameterSubstitutionSuggester suggestor : this.subtitutionSuggesterProcessors)
{
suggestions.addAll(suggestor.getSubstitutionSuggestions(substitutionFragment.toLowerCase()));
}
}
return suggestions;
}
/** /**
* Look up parameter processor * Look up parameter processor
* *

View File

@@ -18,6 +18,7 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.test; package org.alfresco.module.org_alfresco_module_rm.test;
import org.alfresco.repo.ParameterProcessorTestSuite;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Suite; import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
@@ -36,7 +37,8 @@ import org.junit.runners.Suite.SuiteClasses;
CapabilitiesTestSuite.class, CapabilitiesTestSuite.class,
ServicesTestSuite.class, ServicesTestSuite.class,
WebScriptTestSuite.class, WebScriptTestSuite.class,
IssueTestSuite.class IssueTestSuite.class,
ParameterProcessorTestSuite.class
}) })
public class AllTestSuite public class AllTestSuite
{ {

View File

@@ -31,6 +31,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.webscript.RmAuthoritiesRe
import org.alfresco.module.org_alfresco_module_rm.test.webscript.RmClassesRestApiTest; import org.alfresco.module.org_alfresco_module_rm.test.webscript.RmClassesRestApiTest;
import org.alfresco.module.org_alfresco_module_rm.test.webscript.RmPropertiesRestApiTest; import org.alfresco.module.org_alfresco_module_rm.test.webscript.RmPropertiesRestApiTest;
import org.alfresco.module.org_alfresco_module_rm.test.webscript.RoleRestApiTest; import org.alfresco.module.org_alfresco_module_rm.test.webscript.RoleRestApiTest;
import org.alfresco.repo.web.scripts.SubstitutionSuggestionsRestApiTest;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Suite; import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
@@ -56,7 +57,8 @@ import org.junit.runners.Suite.SuiteClasses;
ActionDefinitionsRestApiTest.class, ActionDefinitionsRestApiTest.class,
RmClassesRestApiTest.class, RmClassesRestApiTest.class,
RmPropertiesRestApiTest.class, RmPropertiesRestApiTest.class,
RmAuthoritiesRestApiTest.class RmAuthoritiesRestApiTest.class,
SubstitutionSuggestionsRestApiTest.class
}) })
public class WebScriptTestSuite public class WebScriptTestSuite
{ {

View File

@@ -46,6 +46,7 @@ public class FileToActionTest extends BaseRMTestCase
private static final String PATH2 = "/rmcontainer/rmfolder"; private static final String PATH2 = "/rmcontainer/rmfolder";
private static final String PATH_BAD = "monkey/rmfolder"; private static final String PATH_BAD = "monkey/rmfolder";
private static final String PATH_CREATE = "rmcontainer/newrmfolder"; private static final String PATH_CREATE = "rmcontainer/newrmfolder";
private static final String LONG_PATH_CREATE = "/rmcontainer/one/two/three/four/newrmfolder";
private static final String PATH_SUB1 = "rmcontainer/${node.cm:title}"; private static final String PATH_SUB1 = "rmcontainer/${node.cm:title}";
@@ -189,6 +190,12 @@ public class FileToActionTest extends BaseRMTestCase
createRecord(PATH_SUB1, "mytestvalue", "rmcontainer/mytestvalue"); createRecord(PATH_SUB1, "mytestvalue", "rmcontainer/mytestvalue");
} }
public void testCreatePath() throws Exception
{
initRecord();
createRecord(LONG_PATH_CREATE, "newrmfolder", "rmcontainer/one/two/three/four/newrmfolder");
}
private void createRecord(String path, String name) private void createRecord(String path, String name)
{ {
createRecord(path, name, path); createRecord(path, name, path);
@@ -209,7 +216,7 @@ public class FileToActionTest extends BaseRMTestCase
// set parameters // set parameters
Map<String, Serializable> params = new HashMap<String, Serializable>(1); Map<String, Serializable> params = new HashMap<String, Serializable>(1);
params.put(FileToAction.PARAM_PATH, path); params.put(FileToAction.PARAM_PATH, path);
params.put(FileToAction.PARAM_CREATE_RECORD_FOLDER, true); params.put(FileToAction.PARAM_CREATE_RECORD_PATH, true);
// execute file-to action // execute file-to action
rmActionService.executeRecordsManagementAction(dmDocument, FileToAction.NAME, params); rmActionService.executeRecordsManagementAction(dmDocument, FileToAction.NAME, params);