diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.desc.xml
new file mode 100644
index 0000000000..6591b6cb4e
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.desc.xml
@@ -0,0 +1,21 @@
+
+ GET facetable properties defined within the repository
+
+ :/alfresco/api/facet/facetable-properties
+
+ Example response from this web script:
+
+ {
+ TODO
+ }
+ ]]>
+
+ /api/facet/classes/{classname}/facetable-properties
+ /api/facet/facetable-properties
+ argument
+ user
+ required
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.json.ftl
new file mode 100644
index 0000000000..671386a576
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/facet/facetable-properties.get.json.ftl
@@ -0,0 +1,12 @@
+<#escape x as jsonUtils.encodeJSONString(x)>
+{
+ "properties" : {
+ <#list properties as property>
+ "${property.name}" : {
+ "modelQName" : "${property.model.name.prefixString}",
+ "dataType" : "${property.dataType.name.prefixString}"
+ }<#if property_has_next>,#if>
+ #list>
+ }
+}
+#escape>
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index dfe6b3bab2..3e41bcb21e 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -1820,6 +1820,12 @@
+
+
+
.
+ */
+
+package org.alfresco.repo.web.scripts.facet;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
+import org.alfresco.service.namespace.NamespaceException;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * This class is the controller for the "facetable-properties.get" web script.
+ *
+ * @since 5.0
+ * @author Neil Mc Erlean
+ */
+public class FacetablePropertiesGet extends AbstractSolrFacetConfigAdminWebScript
+{
+ public static final Log logger = LogFactory.getLog(FacetablePropertiesGet.class);
+ public static final String PROPERTIES_KEY = "properties";
+
+ private NamespaceService namespaceService;
+
+ public void setNamespaceService(NamespaceService service) { this.namespaceService = service; }
+
+ @Override protected Map executeImpl(final WebScriptRequest req, final Status status, final Cache cache)
+ {
+ // Allow all authenticated users view the filters
+ return unprotectedExecuteImpl(req, status, cache);
+ }
+
+ @Override protected Map unprotectedExecuteImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ // There are multiple defined URIs for this REST endpoint. Some define a "classname" template var.
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ final String contentClassName = templateVars.get("classname");
+
+ QName contentClassQName;
+ try
+ {
+ contentClassQName = contentClassName == null ? null : QName.createQName(contentClassName, namespaceService);
+ } catch (NamespaceException e)
+ {
+ throw new WebScriptException(Status.STATUS_NOT_FOUND, "Unrecognised classname: " + contentClassName, e);
+ }
+
+ final Map model = new HashMap<>();
+
+ final Set facetableProperties;
+ if (contentClassQName == null)
+ {
+ facetableProperties = facetService.getFacetableProperties();
+ }
+ else
+ {
+ facetableProperties = facetService.getFacetableProperties(contentClassQName);
+ }
+
+ model.put(PROPERTIES_KEY, facetableProperties);
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Retrieved " + facetableProperties.size() + " available facets");
+ }
+
+ return model;
+ }
+}
diff --git a/source/test-java/org/alfresco/repo/web/scripts/facet/FacetRestApiTest.java b/source/test-java/org/alfresco/repo/web/scripts/facet/FacetRestApiTest.java
index 3592cfe419..b7b07d605f 100644
--- a/source/test-java/org/alfresco/repo/web/scripts/facet/FacetRestApiTest.java
+++ b/source/test-java/org/alfresco/repo/web/scripts/facet/FacetRestApiTest.java
@@ -57,7 +57,9 @@ public class FacetRestApiTest extends BaseWebScriptTest
private static final String NON_SEARCH_ADMIN_USER = "nonSearchAdmin";
private static final String FACETS = "facets";
-
+
+ private final static String GET_ALL_FACETABLE_PROPERTIES_URL = "/api/facet/facetable-properties";
+ private final static String GET_SPECIFIC_FACETABLE_PROPERTIES_URL = "/api/facet/classes/{classname}/facetable-properties";
private final static String GET_FACETS_URL = "/api/facet/facet-config";
private final static String PUT_FACET_URL_FORMAT = "/api/facet/facet-config/{0}?relativePos={1}";
private final static String POST_FACETS_URL = GET_FACETS_URL;
@@ -620,7 +622,53 @@ public class FacetRestApiTest extends BaseWebScriptTest
}
}, SEARCH_ADMIN_USER);
}
-
+
+ public void testGetAllFacetableProperties() throws Exception
+ {
+ AuthenticationUtil.runAs(new RunAsWork()
+ {
+ @Override public Void doWork() throws Exception
+ {
+ final Response rsp = sendRequest(new GetRequest(GET_ALL_FACETABLE_PROPERTIES_URL), 200);
+
+ // For now, we'll only perform limited testing of the response as we primarily
+ // want to know that the GET call succeeded and that it correctly identified
+ // *some* facetable properties.
+ JSONObject jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
+
+ JSONObject properties = jsonRsp.getJSONObject(FacetablePropertiesGet.PROPERTIES_KEY);
+
+ final int arbitraryLimit = 25;
+ assertTrue("Expected 'many' properties, but found 'not very many'", properties.length() > arbitraryLimit);
+
+ return null;
+ }
+ }, SEARCH_ADMIN_USER);
+ }
+
+ public void testGetFacetablePropertiesForSpecificContentClasses() throws Exception
+ {
+ AuthenticationUtil.runAs(new RunAsWork()
+ {
+ @Override public Void doWork() throws Exception
+ {
+ final Response rsp = sendRequest(new GetRequest(GET_SPECIFIC_FACETABLE_PROPERTIES_URL.replace("{classname}", "cm:content")), 200);
+
+ // For now, we'll only perform limited testing of the response as we primarily
+ // want to know that the GET call succeeded and that it correctly identified
+ // *some* facetable properties.
+ JSONObject jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
+
+ JSONObject properties = jsonRsp.getJSONObject(FacetablePropertiesGet.PROPERTIES_KEY);
+
+ final int arbitraryLimit = 100;
+ assertTrue("Expected 'not very many' properties, but found 'many'", properties.length() < arbitraryLimit);
+
+ return null;
+ }
+ }, SEARCH_ADMIN_USER);
+ }
+
private List getListFromJsonArray(JSONArray facetsArray) throws JSONException
{
List result = new ArrayList<>();