diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.desc.xml
new file mode 100644
index 0000000000..0211de2081
--- /dev/null
+++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.desc.xml
@@ -0,0 +1,8 @@
+
+ Get substitution suggestions for RM
+ Gets a collection of substitution suggestions for a text fragment for RM.
+ /api/rm/rm-substitutionsuggestions?fragment={fragment?}
+ argument
+ user
+ required
+
\ No newline at end of file
diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.json.ftl
new file mode 100644
index 0000000000..14c57087a6
--- /dev/null
+++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/repository/substitutionsuggestions/rm-substitutionsuggestions.get.json.ftl
@@ -0,0 +1,8 @@
+{
+ "substitutions":
+ [
+ <#list substitutions as substitution>
+ "${substitution}"<#if substitution_has_next>,#if>
+ #list>
+ ]
+}
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterSubstitutionSuggester.java b/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterSubstitutionSuggester.java
new file mode 100644
index 0000000000..2445273c20
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterSubstitutionSuggester.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.action.parameter;
+
+import java.util.List;
+
+public interface ParameterSubstitutionSuggester
+{
+ public List getSubstitutionSuggestions(final String substitutionFragment);
+}
diff --git a/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java b/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java
new file mode 100644
index 0000000000..da24e6c933
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.web.scripts.substitutionsuggestions;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.action.parameter.ParameterProcessorComponent;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.DeclarativeWebScript;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * Implementation for Java backed webscript to get substitution suggestions
+ * given a text fragment (e.g. date.month for 'mon').
+ *
+ * @author Mark Hibbins
+ * @since 2.2
+ */
+public class RmSubstitutionSuggestionsGet extends DeclarativeWebScript
+{
+ private final static String FRAGMENT_PARAMETER = "fragment";
+
+ private final static String SUBSTITUTIONS_MODEL_KEY = "substitutions";
+
+ private ParameterProcessorComponent parameterProcessorComponent;
+
+ public void setParameterProcessorComponent(ParameterProcessorComponent parameterProcessorComponent)
+ {
+ this.parameterProcessorComponent = parameterProcessorComponent;
+ }
+
+ /**
+ * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest,
+ * org.springframework.extensions.webscripts.Status,
+ * org.springframework.extensions.webscripts.Cache)
+ */
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ String fragment = req.getParameter(FRAGMENT_PARAMETER);
+ List substitutionSuggestions = this.parameterProcessorComponent.getSubstitutionSuggestions(fragment);
+
+ Map model = new HashMap();
+ model.put(SUBSTITUTIONS_MODEL_KEY, substitutionSuggestions);
+
+ return model;
+ }
+}
\ No newline at end of file
diff --git a/rm-server/test/java/org/alfresco/repo/ParameterProcessorTestSuite.java b/rm-server/test/java/org/alfresco/repo/ParameterProcessorTestSuite.java
new file mode 100644
index 0000000000..5a9371d90d
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/repo/ParameterProcessorTestSuite.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo;
+
+import org.alfresco.repo.action.parameter.DateParameterProcessorTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+
+/**
+ * RM parameter processor test suite
+ *
+ * @author Mark Hibbins
+ */
+@RunWith(Suite.class)
+@SuiteClasses(
+{
+ DateParameterProcessorTest.class
+})
+public class ParameterProcessorTestSuite
+{
+}
diff --git a/rm-server/test/java/org/alfresco/repo/action/parameter/DateParameterProcessorTest.java b/rm-server/test/java/org/alfresco/repo/action/parameter/DateParameterProcessorTest.java
new file mode 100644
index 0000000000..d1b7ce44ca
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/repo/action/parameter/DateParameterProcessorTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.action.parameter;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for the DateParameterProcessor
+ *
+ * @author Mark Hibbins
+ */
+public class DateParameterProcessorTest
+{
+
+ private DateParameterProcessor dateParameterProcessor;
+
+ @Before
+ public void setUp() throws Exception
+ {
+ this.dateParameterProcessor = new DateParameterProcessor();
+ this.dateParameterProcessor.setName("date");
+ }
+
+ @Test
+ public void testGetSubstitutionSuggestions_All_01()
+ {
+ List suggestions = this.dateParameterProcessor.getSubstitutionSuggestions("date");
+ assertTrue(suggestions.contains("date.day"));
+ assertTrue(suggestions.contains("date.day.short"));
+ assertTrue(suggestions.contains("date.day.long"));
+ assertTrue(suggestions.contains("date.day.number"));
+ assertTrue(suggestions.contains("date.week"));
+ assertTrue(suggestions.contains("date.week.short"));
+ assertTrue(suggestions.contains("date.week.long"));
+ assertTrue(suggestions.contains("date.week.number"));
+ assertTrue(suggestions.contains("date.month"));
+ assertTrue(suggestions.contains("date.month.short"));
+ assertTrue(suggestions.contains("date.month.long"));
+ assertTrue(suggestions.contains("date.month.number"));
+ assertTrue(suggestions.contains("date.year"));
+ assertTrue(suggestions.contains("date.year.short"));
+ assertTrue(suggestions.contains("date.year.long"));
+ assertTrue(suggestions.contains("date.year.number"));
+ assertEquals(16, suggestions.size());
+ }
+
+ @Test
+ public void testGetSubstitutionSuggestions_All_02()
+ {
+ List suggestions = this.dateParameterProcessor.getSubstitutionSuggestions("dat");
+ assertTrue(suggestions.contains("date.day"));
+ assertTrue(suggestions.contains("date.day.short"));
+ assertTrue(suggestions.contains("date.day.long"));
+ assertTrue(suggestions.contains("date.day.number"));
+ assertTrue(suggestions.contains("date.week"));
+ assertTrue(suggestions.contains("date.week.short"));
+ assertTrue(suggestions.contains("date.week.long"));
+ assertTrue(suggestions.contains("date.week.number"));
+ assertTrue(suggestions.contains("date.month"));
+ assertTrue(suggestions.contains("date.month.short"));
+ assertTrue(suggestions.contains("date.month.long"));
+ assertTrue(suggestions.contains("date.month.number"));
+ assertTrue(suggestions.contains("date.year"));
+ assertTrue(suggestions.contains("date.year.short"));
+ assertTrue(suggestions.contains("date.year.long"));
+ assertTrue(suggestions.contains("date.year.number"));
+ assertEquals(16, suggestions.size());
+ }
+
+ @Test
+ public void testGetSubstitutionSuggestions_All_03()
+ {
+ List suggestions = this.dateParameterProcessor.getSubstitutionSuggestions("at");
+ assertTrue(suggestions.contains("date.day"));
+ assertTrue(suggestions.contains("date.day.short"));
+ assertTrue(suggestions.contains("date.day.long"));
+ assertTrue(suggestions.contains("date.day.number"));
+ assertTrue(suggestions.contains("date.week"));
+ assertTrue(suggestions.contains("date.week.short"));
+ assertTrue(suggestions.contains("date.week.long"));
+ assertTrue(suggestions.contains("date.week.number"));
+ assertTrue(suggestions.contains("date.month"));
+ assertTrue(suggestions.contains("date.month.short"));
+ assertTrue(suggestions.contains("date.month.long"));
+ assertTrue(suggestions.contains("date.month.number"));
+ assertTrue(suggestions.contains("date.year"));
+ assertTrue(suggestions.contains("date.year.short"));
+ assertTrue(suggestions.contains("date.year.long"));
+ assertTrue(suggestions.contains("date.year.number"));
+ assertEquals(16, suggestions.size());
+ }
+
+ @Test
+ public void testGetSubstitutionSuggestions_Partial_01()
+ {
+ List suggestions = this.dateParameterProcessor.getSubstitutionSuggestions("ay");
+ assertTrue(suggestions.contains("date.day"));
+ assertTrue(suggestions.contains("date.day.short"));
+ assertTrue(suggestions.contains("date.day.long"));
+ assertTrue(suggestions.contains("date.day.number"));
+ assertEquals(4, suggestions.size());
+ }
+
+ @Test
+ public void testGetSubstitutionSuggestions_Partial_02()
+ {
+ List suggestions = this.dateParameterProcessor.getSubstitutionSuggestions("on");
+ assertTrue(suggestions.contains("date.day.long"));
+ assertTrue(suggestions.contains("date.week.long"));
+ assertTrue(suggestions.contains("date.month"));
+ assertTrue(suggestions.contains("date.month.short"));
+ assertTrue(suggestions.contains("date.month.long"));
+ assertTrue(suggestions.contains("date.month.number"));
+ assertTrue(suggestions.contains("date.year.long"));
+ assertEquals(7, suggestions.size());
+ }
+
+}
diff --git a/rm-server/test/java/org/alfresco/repo/web/scripts/SubstitutionSuggestionsRestApiTest.java b/rm-server/test/java/org/alfresco/repo/web/scripts/SubstitutionSuggestionsRestApiTest.java
new file mode 100644
index 0000000000..b88f479ad4
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/repo/web/scripts/SubstitutionSuggestionsRestApiTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.web.scripts;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
+import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
+
+/**
+ * REST API Tests for Action Definitions
+ *
+ * @author Mark Hibbins
+ * @since 2.2
+ */
+public class SubstitutionSuggestionsRestApiTest extends BaseRMWebScriptTestCase
+{
+ /** URL for the REST APIs */
+ private static final String RM_SUBSTITUTIONSUGGESTIONS_URL = "/api/rm/rm-substitutionsuggestions?fragment=month";
+
+ /**
+ * Test the REST API to retrieve the list of rm substitution suggestions
+ *
+ * @throws IOException
+ * @throws JSONException
+ */
+ public void testRmGetSubstitutionSuggestions() throws IOException, JSONException
+ {
+ // Send request
+ Response response = sendRequest(new GetRequest(RM_SUBSTITUTIONSUGGESTIONS_URL), Status.STATUS_OK);
+
+ // Check the content from the response
+ String contentAsString = response.getContentAsString();
+ assertNotNull(contentAsString);
+
+ // Convert the response to json and check the data
+ JSONObject contentAsJson = new JSONObject(contentAsString);
+ JSONArray data = contentAsJson.getJSONArray("substitutions");
+ assertNotNull(data);
+
+ // Get the list of rm action definitions from the response and check it
+ List substitutionDefinitions = getSubstitutionDefinitions();
+ List rmSubstitutionDefinitions = new ArrayList();
+ for (int i = 0; i < data.length(); i++)
+ {
+ String value = data.getString(i);
+ assertNotNull(value);
+ rmSubstitutionDefinitions.add(value);
+ }
+ assertTrue(rmSubstitutionDefinitions.containsAll(substitutionDefinitions));
+ assertTrue(substitutionDefinitions.containsAll(rmSubstitutionDefinitions));
+ }
+
+ /**
+ * Returns a (sub)list of dm action definitions
+ *
+ * @return A (sub)list of dm action definitions
+ */
+ private List getSubstitutionDefinitions()
+ {
+ return Arrays.asList(new String[]
+ {
+ "date.month",
+ "date.month.number",
+ "date.month.long",
+ "date.month.short"
+ });
+ }
+}
\ No newline at end of file