Rating Service. Work ongoing.

Added a POST webscript to apply a rating to a node.
  Associated REST test: apply rating as user one, get, apply rating as user two, get.
  Deleted the PUT webscript (half-formed anyway)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21086 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Neil McErlean
2010-07-12 11:33:57 +00:00
parent 91efe3970c
commit 83bb722d2e
6 changed files with 255 additions and 55 deletions

View File

@@ -18,21 +18,88 @@
*/
package org.alfresco.repo.web.scripts.rating;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.rating.RatingScheme;
import org.alfresco.service.cmr.repository.NodeRef;
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
*
* This class is the controller for the rating.post webscript.
*
* @author Neil McErlean
* @since 3.4
*/
public class RatingPost extends AbstractRatingWebScript
{
// Web script parameters.
private static final String RATING_SCHEME = "ratingScheme";
private static final String RATING = "rating";
private static final String RATED_NODE = "ratedNode";
// Url format
private final static String NODE_RATINGS_URL_FORMAT = "/api/node/{0}/ratings";
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
return null;
Map<String, Object> model = new HashMap<String, Object>();
NodeRef nodeRefToBeRated = parseRequestForNodeRef(req);
JSONObject json = null;
try
{
// read request json
json = new JSONObject(new JSONTokener(req.getContent().getContent()));
// Check mandatory parameters.
if (json.has(RATING) == false)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "rating parameter missing when applying rating");
}
if (json.has(RATING_SCHEME) == false)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "schemeName parameter missing when applying rating");
}
// Check that the scheme name actually exists
String schemeName = json.getString(RATING_SCHEME);
RatingScheme scheme = ratingService.getRatingScheme(schemeName);
if (scheme == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unknown scheme name: " + schemeName);
}
// Range checking of the rating score will be done within the RatingService.
// So we can just apply the rating.
int rating = json.getInt(RATING);
ratingService.applyRating(nodeRefToBeRated, rating, schemeName);
// We'll return the URL to the ratings of the just-rated node.
String ratedNodeUrlFragment = nodeRefToBeRated.toString().replace("://", "/");
String ratedNodeUrl = MessageFormat.format(NODE_RATINGS_URL_FORMAT, ratedNodeUrlFragment);
model.put(RATED_NODE, ratedNodeUrl);
}
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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.rating;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author unknown
*
*/
public class RatingPut extends RatingPost
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
return null;
}
}

View File

@@ -28,40 +28,57 @@ 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.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.util.PropertyMap;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
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 static final String USER_ONE = "UserOne";
private static final String USER_TWO = "UserTwo";
private final static String NODE_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;
private MutableAuthenticationService authenticationService;
private NodeService nodeService;
private PersonService personService;
private Repository repositoryHelper;
private RetryingTransactionHelper transactionHelper;
@Override
protected void setUp() throws Exception
{
super.setUp();
authenticationService = (MutableAuthenticationService) getServer().getApplicationContext().getBean("AuthenticationService");
nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService");
personService = (PersonService) getServer().getApplicationContext().getBean("PersonService");
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.
// Create some users to rate each other's content
// and a test node which we will rate.
// It doesn't matter that it has no content.
testNode = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>()
{
public NodeRef execute() throws Throwable
{
createUser(USER_ONE);
createUser(USER_TWO);
ChildAssociationRef result = nodeService.createNode(repositoryHelper.getCompanyHome(),
ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS,
ContentModel.TYPE_CONTENT, null);
@@ -74,6 +91,9 @@ public class RatingRestApiTest extends BaseWebScriptTest
public void tearDown() throws Exception
{
super.tearDown();
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
@@ -81,6 +101,8 @@ public class RatingRestApiTest extends BaseWebScriptTest
if (testNode != null && nodeService.exists(testNode))
{
nodeService.deleteNode(testNode);
deleteUser(USER_ONE);
deleteUser(USER_TWO);
}
return null;
}
@@ -88,9 +110,7 @@ public class RatingRestApiTest extends BaseWebScriptTest
}
//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
{
@@ -100,9 +120,6 @@ public class RatingRestApiTest extends BaseWebScriptTest
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);
@@ -124,16 +141,13 @@ public class RatingRestApiTest extends BaseWebScriptTest
public void testGetRatingsFromUnratedNodeRef() throws Exception
{
// GET ratings
String nodeUrl = testNode.toString().replace("://", "/");
String ratingUrl = MessageFormat.format(GET_RATINGS_URL_FORMAT, nodeUrl);
String ratingUrl = getRatingUrl(testNode);
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);
@@ -141,4 +155,126 @@ public class RatingRestApiTest extends BaseWebScriptTest
final JSONArray ratingsArray = dataObj.getJSONArray("ratings");
assertEquals(0, ratingsArray.length());
}
public void testApplyRatingAndRetrieve() throws Exception
{
// POST a new rating to the testNode - as User One.
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
final String ratingUrl = getRatingUrl(testNode);
final int ratingValue = 5;
String jsonString = new JSONStringer().object()
.key("rating").value(ratingValue)
.key("ratingScheme").value("fiveStarRatingScheme")
.endObject()
.toString();
Response rsp = sendRequest(new PostRequest(ratingUrl,
jsonString, APPLICATION_JSON), 200);
String rspContent = rsp.getContentAsString();
// Get the returned URL and validate
JSONObject jsonRsp = new JSONObject(new JSONTokener(rspContent));
JSONObject dataObj = (JSONObject)jsonRsp.get("data");
assertNotNull("JSON 'data' object was null", dataObj);
String returnedUrl = dataObj.getString("ratedNodeUrl");
assertEquals(ratingUrl, returnedUrl);
// Now GET the ratings via that returned URL
rsp = sendRequest(new GetRequest(ratingUrl), 200);
jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
dataObj = (JSONObject)jsonRsp.get("data");
assertNotNull("JSON 'data' object was null", dataObj);
// There should only be the one rating in there.
final JSONArray ratingsArray = dataObj.getJSONArray("ratings");
assertEquals(1, ratingsArray.length());
JSONObject firstRating = (JSONObject)ratingsArray.get(0);
assertEquals(ratingValue, firstRating.getInt("rating"));
assertEquals("fiveStarRatingScheme", firstRating.getString("ratingScheme"));
// Now POST a second new rating to the testNode - as User Two.
AuthenticationUtil.setFullyAuthenticatedUser(USER_TWO);
final int userTwoRatingValue = 3;
jsonString = new JSONStringer().object()
.key("rating").value(userTwoRatingValue)
.key("ratingScheme").value("fiveStarRatingScheme")
.endObject()
.toString();
rsp = sendRequest(new PostRequest(ratingUrl,
jsonString, APPLICATION_JSON), 200);
rspContent = rsp.getContentAsString();
// Get the returned URL and validate
jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
dataObj = (JSONObject)jsonRsp.get("data");
assertNotNull("JSON 'data' object was null", dataObj);
returnedUrl = dataObj.getString("ratedNodeUrl");
// Again GET the ratings via that returned URL
rsp = sendRequest(new GetRequest(returnedUrl), 200);
jsonRsp = new JSONObject(new JSONTokener(rsp.getContentAsString()));
dataObj = (JSONObject)jsonRsp.get("data");
assertNotNull("JSON 'data' object was null", dataObj);
// There should still only be the one rating in the results - because we're running
// as UserTwo and should not see UserOne's rating.
final JSONArray userTwoRatingsArray = dataObj.getJSONArray("ratings");
assertEquals(1, userTwoRatingsArray.length());
JSONObject secondRating = (JSONObject)userTwoRatingsArray.get(0);
assertEquals(userTwoRatingValue, secondRating.getInt("rating"));
assertEquals("fiveStarRatingScheme", secondRating.getString("ratingScheme"));
//TODO Could probably put the GET average call here then.
}
/**
* This method gives the 'ratings' URL for the specified NodeRef.
*/
private String getRatingUrl(NodeRef nodeRef)
{
String nodeUrl = nodeRef.toString().replace("://", "/");
String ratingUrl = MessageFormat.format(NODE_RATINGS_URL_FORMAT, nodeUrl);
return ratingUrl;
}
private void createUser(String userName)
{
if (! authenticationService.authenticationExists(userName))
{
authenticationService.createAuthentication(userName, "PWD".toCharArray());
}
if (! personService.personExists(userName))
{
PropertyMap ppOne = new PropertyMap(4);
ppOne.put(ContentModel.PROP_USERNAME, userName);
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
personService.createPerson(ppOne);
}
}
private void deleteUser(String userName)
{
if (personService.personExists(userName))
{
personService.deletePerson(userName);
}
}
}