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>, + + ] + } +} + \ 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>, + + ] + } +} + \ 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; + } +}