diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.desc.xml
new file mode 100644
index 0000000000..4a773a46cc
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.desc.xml
@@ -0,0 +1,12 @@
+
+ GET rating scheme definitions
+
+ ]]>
+
+ /api/rating/schemedefinitions
+
+ user
+ required
+ internal
+
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.json.ftl
new file mode 100644
index 0000000000..76756158c3
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratingdefinitions.get.json.ftl
@@ -0,0 +1,17 @@
+<#escape x as jsonUtils.encodeJSONString(x)>
+{
+ "data":
+ {
+ "ratingSchemes":
+ [
+ <#list schemeDefs?keys as key>
+ {
+ "name": "${schemeDefs[key].name!""}",
+ "minRating": ${schemeDefs[key].minRating},
+ "maxRating": ${schemeDefs[key].maxRating}
+ }<#if key_has_next>,#if>
+ #list>
+ ]
+ }
+}
+#escape>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.desc.xml
new file mode 100644
index 0000000000..59266077f7
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.desc.xml
@@ -0,0 +1,16 @@
+
+ GET rating
+
+ The ratings returned will be those applied by the currently authenticated user. There
+ will be one for each rating scheme in which the user has submitted a rating. If the
+ currently authenticated user has not applied any ratings to this content the list
+ will be empty.
+ ]]>
+
+ /api/node/{store_type}/{store_id}/{id}/ratings
+
+ user
+ required
+ internal
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.json.ftl
new file mode 100644
index 0000000000..191fd3fb71
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rating/ratings.get.json.ftl
@@ -0,0 +1,19 @@
+<#escape x as jsonUtils.encodeJSONString(x)>
+{
+ "data":
+ {
+ "nodeRef": "${nodeRef}",
+ "ratings":
+ [
+ <#list ratings as rating>
+ {
+ "ratingScheme": "${rating.scheme.name!""}",
+ "rating": ${rating.score},
+ "appliedAt": "${rating.appliedAt}",
+ "appliedBy": "${rating.appliedBy}"
+ }<#if rating_has_next>,#if>
+ #list>
+ ]
+ }
+}
+#escape>
\ No newline at end of file
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index e170419c4c..b65f9590aa 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -734,6 +734,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/AbstractRatingWebScript.java b/source/java/org/alfresco/repo/web/scripts/rating/AbstractRatingWebScript.java
new file mode 100644
index 0000000000..b0694ed754
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/AbstractRatingWebScript.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.service.cmr.rating.RatingService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.springframework.extensions.webscripts.DeclarativeWebScript;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * This class is an abstract base class for the various webscript controllers in the
+ * RatingService.
+ *
+ * @author Neil McErlean
+ * @since 3.4
+ */
+public abstract class AbstractRatingWebScript extends DeclarativeWebScript
+{
+ protected NodeService nodeService;
+ protected RatingService ratingService;
+
+ /**
+ * Sets the node service instance
+ *
+ * @param nodeService the node service to set
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * Sets the rating service instance
+ *
+ * @param ratingService the rating service to set
+ */
+ public void setRatingService(RatingService ratingService)
+ {
+ this.ratingService = ratingService;
+ }
+
+ protected NodeRef parseRequestForNodeRef(WebScriptRequest req)
+ {
+ // get the parameters that represent the NodeRef, we know they are present
+ // otherwise this webscript would not have matched
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ String storeType = templateVars.get("store_type");
+ String storeId = templateVars.get("store_id");
+ String nodeId = templateVars.get("id");
+
+ // create the NodeRef and ensure it is valid
+ StoreRef storeRef = new StoreRef(storeType, storeId);
+ NodeRef nodeRef = new NodeRef(storeRef, nodeId);
+
+ if (!this.nodeService.exists(nodeRef))
+ {
+ throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: " + nodeRef.toString());
+ }
+
+ return nodeRef;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/AllRatingTests.java b/source/java/org/alfresco/repo/web/scripts/rating/AllRatingTests.java
new file mode 100644
index 0000000000..0f789a7332
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/AllRatingTests.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import org.alfresco.repo.rating.RatingNodePropertiesTest;
+import org.alfresco.repo.rating.RatingServiceIntegrationTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * This class is a holder for the various test classes associated with the Rating Service.
+ * It is not (at the time of writing) intended to be incorporated into the automatic build
+ * which will find the various test classes and run them individually.
+ *
+ * @author Neil McErlean
+ * @since 3.4
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ RatingNodePropertiesTest.class,
+ RatingServiceIntegrationTest.class,
+ RatingRestApiTest.class
+})
+public class AllRatingTests
+{
+ // Intentionally empty
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/RatingDefinitionsGet.java b/source/java/org/alfresco/repo/web/scripts/rating/RatingDefinitionsGet.java
new file mode 100644
index 0000000000..670a6537b1
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/RatingDefinitionsGet.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.service.cmr.rating.RatingScheme;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * This class is the controller class for the rating.definitions.get webscript.
+ *
+ * @author Neil McErlean
+ * @since 3.4
+ */
+public class RatingDefinitionsGet extends AbstractRatingWebScript
+{
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ Map model = new HashMap();
+
+ Map schemes = this.ratingService.getRatingSchemes();
+
+ model.put("schemeDefs", schemes);
+
+ return model;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/RatingPost.java b/source/java/org/alfresco/repo/web/scripts/rating/RatingPost.java
new file mode 100644
index 0000000000..50d1497feb
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/RatingPost.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.rule.Rule;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * @author unknown
+ *
+ */
+public class RatingPost extends AbstractRatingWebScript
+{
+ @SuppressWarnings("unused")
+ private static Log logger = LogFactory.getLog(RatingPost.class);
+
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ Map model = new HashMap();
+
+ // get request parameters
+ NodeRef nodeRef = parseRequestForNodeRef(req);
+
+ Rule rule = null;
+ JSONObject json = null;
+
+ try
+ {
+ // read request json
+ json = new JSONObject(new JSONTokener(req.getContent().getContent()));
+
+// // parse request json
+// rule = parseJsonRule(json);
+//
+// // create rule
+// ruleService.saveRule(nodeRef, rule);
+//
+// RuleRef ruleRef = new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule)));
+//
+// model.put("ruleRef", ruleRef);
+ }
+ catch (IOException iox)
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox);
+ }
+ catch (JSONException je)
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je);
+ }
+
+ return model;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/RatingPut.java b/source/java/org/alfresco/repo/web/scripts/rating/RatingPut.java
new file mode 100644
index 0000000000..54db2d4013
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/RatingPut.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.repo.action.ActionConditionImpl;
+import org.alfresco.repo.action.ActionImpl;
+import org.alfresco.repo.action.CompositeActionImpl;
+import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef;
+import org.alfresco.service.cmr.action.Action;
+import org.alfresco.service.cmr.action.ActionCondition;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.rule.Rule;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * @author unknown
+ *
+ */
+public class RatingPut extends RatingPost
+{
+ @SuppressWarnings("unused")
+ private static Log logger = LogFactory.getLog(RatingPut.class);
+
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ Map model = new HashMap();
+
+ // get request parameters
+ NodeRef nodeRef = parseRequestForNodeRef(req);
+
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ String ruleId = templateVars.get("rule_id");
+
+ Rule ruleToUpdate = null;
+
+ // get all rules for given nodeRef
+// List rules = ruleService.getRules(nodeRef);
+//
+// //filter by rule id
+// for (Rule rule : rules)
+// {
+// if (rule.getNodeRef().getId().equalsIgnoreCase(ruleId))
+// {
+// ruleToUpdate = rule;
+// break;
+// }
+// }
+//
+ if (ruleToUpdate == null)
+ {
+ throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + ruleId);
+ }
+
+ JSONObject json = null;
+
+ try
+ {
+ // read request json
+ json = new JSONObject(new JSONTokener(req.getContent().getContent()));
+
+ // parse request json
+ updateRuleFromJSON(json, ruleToUpdate);
+
+// // save changes
+// ruleService.saveRule(nodeRef, ruleToUpdate);
+//
+// RuleRef updatedRuleRef = new RuleRef(ruleToUpdate, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(ruleToUpdate)));
+//
+// model.put("ruleRef", updatedRuleRef);
+ }
+ catch (IOException iox)
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox);
+ }
+ catch (JSONException je)
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je);
+ }
+
+ return model;
+ }
+
+ protected void updateRuleFromJSON(JSONObject jsonRule, Rule ruleToUpdate) throws JSONException
+ {
+ if (jsonRule.has("title"))
+ {
+ ruleToUpdate.setTitle(jsonRule.getString("title"));
+ }
+
+ if (jsonRule.has("description"))
+ {
+ ruleToUpdate.setDescription(jsonRule.getString("description"));
+ }
+
+ if (jsonRule.has("ruleType"))
+ {
+ JSONArray jsonTypes = jsonRule.getJSONArray("ruleType");
+ List types = new ArrayList();
+
+ for (int i = 0; i < jsonTypes.length(); i++)
+ {
+ types.add(jsonTypes.getString(i));
+ }
+ ruleToUpdate.setRuleTypes(types);
+ }
+
+ if (jsonRule.has("applyToChildren"))
+ {
+ ruleToUpdate.applyToChildren(jsonRule.getBoolean("applyToChildren"));
+ }
+
+ if (jsonRule.has("executeAsynchronously"))
+ {
+ ruleToUpdate.setExecuteAsynchronously(jsonRule.getBoolean("executeAsynchronously"));
+ }
+
+ if (jsonRule.has("disabled"))
+ {
+ ruleToUpdate.setRuleDisabled(jsonRule.getBoolean("disabled"));
+ }
+
+ if (jsonRule.has("action"))
+ {
+ JSONObject jsonAction = jsonRule.getJSONObject("action");
+
+ // update rule action
+// Action action = updateActionFromJson(jsonAction, (ActionImpl) ruleToUpdate.getAction());
+//
+// ruleToUpdate.setAction(action);
+ }
+ }
+
+// protected Action updateActionFromJson(JSONObject jsonAction, ActionImpl actionToUpdate) throws JSONException
+// {
+// ActionImpl result = null;
+//
+// if (jsonAction.has("id"))
+// {
+// // update existing action
+// result = actionToUpdate;
+// }
+// else
+// {
+// // create new object as id was not sent by client
+// result = parseJsonAction(jsonAction);
+// return result;
+// }
+//
+// if (jsonAction.has("description"))
+// {
+// result.setDescription(jsonAction.getString("description"));
+// }
+//
+// if (jsonAction.has("title"))
+// {
+// result.setTitle(jsonAction.getString("title"));
+// }
+//
+// if (jsonAction.has("parameterValues"))
+// {
+// JSONObject jsonParameterValues = jsonAction.getJSONObject("parameterValues");
+// result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionDefinitionName(), true));
+// }
+//
+// if (jsonAction.has("executeAsync"))
+// {
+// result.setExecuteAsynchronously(jsonAction.getBoolean("executeAsync"));
+// }
+//
+// if (jsonAction.has("runAsUser"))
+// {
+// result.setRunAsUser(jsonAction.getString("runAsUser"));
+// }
+//
+// if (jsonAction.has("actions"))
+// {
+// JSONArray jsonActions = jsonAction.getJSONArray("actions");
+// if (jsonActions.length() == 0)
+// {
+// // empty array was sent -> clear list
+// ((CompositeActionImpl) result).getActions().clear();
+// }
+// else
+// {
+// List existingActions = ((CompositeActionImpl) result).getActions();
+// List newActions = new ArrayList();
+//
+// for (int i = 0; i < jsonActions.length(); i++)
+// {
+// JSONObject innerJsonAction = jsonActions.getJSONObject(i);
+//
+// if (innerJsonAction.has("id"))
+// {
+// // update existing object
+// String actionId = innerJsonAction.getString("id");
+//
+// Action existingAction = getAction(existingActions, actionId);
+// existingActions.remove(existingAction);
+//
+// Action updatedAction = updateActionFromJson(innerJsonAction, (ActionImpl) existingAction);
+// newActions.add(updatedAction);
+// }
+// else
+// {
+// //create new action as id was not sent
+// newActions.add(parseJsonAction(innerJsonAction));
+// }
+// }
+// existingActions.clear();
+//
+// for (Action action : newActions)
+// {
+// existingActions.add(action);
+// }
+// }
+// }
+//
+// if (jsonAction.has("conditions"))
+// {
+// JSONArray jsonConditions = jsonAction.getJSONArray("conditions");
+//
+// if (jsonConditions.length() == 0)
+// {
+// // empty array was sent -> clear list
+// result.getActionConditions().clear();
+// }
+// else
+// {
+// List existingConditions = result.getActionConditions();
+// List newConditions = new ArrayList();
+//
+// for (int i = 0; i < jsonConditions.length(); i++)
+// {
+// JSONObject jsonCondition = jsonConditions.getJSONObject(i);
+//
+// if (jsonCondition.has("id"))
+// {
+// // update existing object
+// String conditionId = jsonCondition.getString("id");
+//
+// ActionCondition existingCondition = getCondition(existingConditions, conditionId);
+// existingConditions.remove(existingCondition);
+//
+// ActionCondition updatedActionCondition = updateActionConditionFromJson(jsonCondition, (ActionConditionImpl) existingCondition);
+// newConditions.add(updatedActionCondition);
+// }
+// else
+// {
+// // create new object as id was not sent
+// newConditions.add(parseJsonActionCondition(jsonCondition));
+// }
+// }
+//
+// existingConditions.clear();
+//
+// for (ActionCondition condition : newConditions)
+// {
+// existingConditions.add(condition);
+// }
+// }
+// }
+//
+// if (jsonAction.has("compensatingAction"))
+// {
+// JSONObject jsonCompensatingAction = jsonAction.getJSONObject("compensatingAction");
+// Action compensatingAction = updateActionFromJson(jsonCompensatingAction, (ActionImpl) actionToUpdate.getCompensatingAction());
+//
+// actionToUpdate.setCompensatingAction(compensatingAction);
+// }
+// return result;
+// }
+
+// protected ActionCondition updateActionConditionFromJson(JSONObject jsonCondition, ActionConditionImpl conditionToUpdate) throws JSONException
+// {
+// ActionConditionImpl result = null;
+//
+// if (jsonCondition.has("id"))
+// {
+// // update exiting object
+// result = conditionToUpdate;
+// }
+// else
+// {
+// // create new onject as id was not sent
+// result = parseJsonActionCondition(jsonCondition);
+// return result;
+// }
+//
+// if (jsonCondition.has("invertCondition"))
+// {
+// result.setInvertCondition(jsonCondition.getBoolean("invertCondition"));
+// }
+//
+// if (jsonCondition.has("parameterValues"))
+// {
+// JSONObject jsonParameterValues = jsonCondition.getJSONObject("parameterValues");
+// result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionConditionDefinitionName(), false));
+// }
+//
+// return result;
+// }
+//
+// private Action getAction(List actions, String id)
+// {
+// Action result = null;
+// for (Action action : actions)
+// {
+// if (action.getId().equalsIgnoreCase(id))
+// {
+// result = action;
+// break;
+// }
+// }
+//
+// return result;
+// }
+//
+ private ActionCondition getCondition(List conditions, String id)
+ {
+ ActionCondition result = null;
+ for (ActionCondition сondition : conditions)
+ {
+ if (сondition.getId().equalsIgnoreCase(id))
+ {
+ result = сondition;
+ break;
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/RatingRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/rating/RatingRestApiTest.java
new file mode 100644
index 0000000000..b2f017a319
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/RatingRestApiTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.text.MessageFormat;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.model.Repository;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
+import org.alfresco.repo.web.scripts.BaseWebScriptTest;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
+import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
+
+public class RatingRestApiTest extends BaseWebScriptTest
+{
+ private final static String GET_RATINGS_URL_FORMAT = "/api/node/{0}/ratings";
+ private final static String GET_RATING_DEFS_URL = "/api/rating/schemedefinitions";
+
+ private static final String APPLICATION_JSON = "application/json";
+
+ private NodeRef testNode;
+
+ protected NodeService nodeService;
+ protected Repository repositoryHelper;
+ protected RetryingTransactionHelper transactionHelper;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService");
+ repositoryHelper = (Repository) getServer().getApplicationContext().getBean("repositoryHelper");
+ transactionHelper = (RetryingTransactionHelper)getServer().getApplicationContext().getBean("retryingTransactionHelper");
+
+ AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
+
+ // Create a test node which we will rate. It doesn't matter that it has no content.
+ testNode = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
+ {
+ public NodeRef execute() throws Throwable
+ {
+ ChildAssociationRef result = nodeService.createNode(repositoryHelper.getCompanyHome(),
+ ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS,
+ ContentModel.TYPE_CONTENT, null);
+ return result.getChildRef();
+ }
+ });
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ if (testNode != null && nodeService.exists(testNode))
+ {
+ nodeService.deleteNode(testNode);
+ }
+ return null;
+ }
+ });
+ }
+
+ //TODO test POST out-of-range.
+ //TODO test get my-ratings on node with mine & others' ratings.
+ //TODO test GET average
+ //TODO test POST and PUT (same)
+
+ public void testGetRatingSchemeDefinitions() throws Exception
+ {
+ // May as well return all of them in one call.
+ final int expectedStatus = 200;
+ Response rsp = sendRequest(new GetRequest(GET_RATING_DEFS_URL), expectedStatus);
+
+ JSONObject jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
+
+
+ System.err.println(jsonRsp);
+
+ JSONObject dataObj = (JSONObject)jsonRsp.get("data");
+ assertNotNull("JSON 'data' object was null", dataObj);
+
+ JSONArray ratingSchemesArray = (JSONArray)dataObj.get("ratingSchemes");
+ assertNotNull("JSON 'ratingSchemesArray' object was null", ratingSchemesArray);
+ assertEquals(2, ratingSchemesArray.length());
+
+ JSONObject scheme1 = ratingSchemesArray.getJSONObject(0);
+ JSONObject scheme2 = ratingSchemesArray.getJSONObject(1);
+
+ assertEquals("likesRatingScheme", scheme1.getString("name"));
+ assertEquals(1, scheme1.getInt("minRating"));
+ assertEquals(1, scheme1.getInt("maxRating"));
+ assertEquals("fiveStarRatingScheme", scheme2.getString("name"));
+ assertEquals(1, scheme2.getInt("minRating"));
+ assertEquals(5, scheme2.getInt("maxRating"));
+ }
+
+ public void testGetRatingsFromUnratedNodeRef() throws Exception
+ {
+ // GET ratings
+ String nodeUrl = testNode.toString().replace("://", "/");
+ String ratingUrl = MessageFormat.format(GET_RATINGS_URL_FORMAT, nodeUrl);
+
+ final int expectedStatus = 200;
+ Response rsp = sendRequest(new GetRequest(ratingUrl), expectedStatus);
+
+ JSONObject jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
+
+ System.err.println(jsonRsp);
+
+ JSONObject dataObj = (JSONObject)jsonRsp.get("data");
+ assertNotNull("JSON 'data' object was null", dataObj);
+
+ assertEquals(testNode.toString(), dataObj.getString("nodeRef"));
+ final JSONArray ratingsArray = dataObj.getJSONArray("ratings");
+ assertEquals(0, ratingsArray.length());
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/rating/RatingsGet.java b/source/java/org/alfresco/repo/web/scripts/rating/RatingsGet.java
new file mode 100644
index 0000000000..68da83c52e
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/rating/RatingsGet.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2010 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.rating;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.service.cmr.rating.Rating;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * This class is the controller for the ratings.get web script.
+ *
+ * @author Neil McErlean
+ * @since 3.4
+ */
+public class RatingsGet extends AbstractRatingWebScript
+{
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ Map model = new HashMap();
+
+ NodeRef nodeRef = parseRequestForNodeRef(req);
+
+ List ratings = new ArrayList();
+
+ for (String schemeName : ratingService.getRatingSchemes().keySet())
+ {
+ final Rating ratingByCurrentUser = ratingService.getRatingByCurrentUser(nodeRef, schemeName);
+ if (ratingByCurrentUser != null)
+ {
+ ratings.add(ratingByCurrentUser);
+ }
+ }
+
+ model.put("nodeRef", nodeRef.toString());
+ model.put("ratings", ratings);
+
+ return model;
+ }
+}