This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 5f2069c3bfb78d3134e831a6d52072c614b005e0 Author: Yannick Martel <martel@©odelutin.com> Date: Fri Dec 5 11:03:49 2014 +0100 #6016 can create new question --- .../src/main/xmi/coselmar-model.zargo | Bin 9660 -> 9735 bytes .../services/CoselmarRestApplicationListener.java | 4 +- .../services/CoselmarWebServiceSupport.java | 12 +++ .../coselmar/services/v1/QuestionsWebService.java | 104 ++++++++++++++------- coselmar-rest/src/main/resources/mapping | 9 ++ 5 files changed, 95 insertions(+), 34 deletions(-) diff --git a/coselmar-persistence/src/main/xmi/coselmar-model.zargo b/coselmar-persistence/src/main/xmi/coselmar-model.zargo index 9dd868f..830802b 100644 Binary files a/coselmar-persistence/src/main/xmi/coselmar-model.zargo and b/coselmar-persistence/src/main/xmi/coselmar-model.zargo differ diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java index e16b7a3..94799bc 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java @@ -29,6 +29,7 @@ import java.util.Set; import com.google.common.collect.Sets; import fr.ifremer.coselmar.beans.DocumentBean; +import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.UserBean; import fr.ifremer.coselmar.converter.DateConverter; import fr.ifremer.coselmar.converter.JsonArrayConverter; @@ -46,7 +47,8 @@ public class CoselmarRestApplicationListener implements WebMotionServerListener protected static final Set<Class<?>> BEAN_TYPES = Sets.<Class<?>>newHashSet( DocumentBean.class, - UserBean.class + UserBean.class, + QuestionBean.class ); @Override diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarWebServiceSupport.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarWebServiceSupport.java index 17e5af2..120e10e 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarWebServiceSupport.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarWebServiceSupport.java @@ -170,4 +170,16 @@ public abstract class CoselmarWebServiceSupport extends WebMotionController impl protected String getFullUserIdFromShort(String shortUserId) { return CoselmarUser.class.getCanonicalName() + getPersistenceContext().getTopiaIdFactory().getSeparator() + shortUserId; } + + /** + * Construct the full id of an entity from the random part contained in a Bean. + * + * @param clazz : the entity class, we want full id (use to compose the id) + * @param shortId : the short id, corresponding to the random part of the id + * + * @return the complete id, with class FQN. + */ + protected String getFullIdFromShort(Class clazz, String shortId) { + return clazz.getCanonicalName() + getPersistenceContext().getTopiaIdFactory().getSeparator() + shortId; + } } diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index 2d1791c..19fa8ef 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -2,17 +2,20 @@ package fr.ifremer.coselmar.services.v1; import java.util.Collection; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Set; import com.google.common.base.Function; import com.google.common.collect.Collections2; +import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.UserBean; import fr.ifremer.coselmar.beans.UserWebToken; import fr.ifremer.coselmar.persistence.entity.CoselmarUser; import fr.ifremer.coselmar.persistence.entity.CoselmarUserGroup; import fr.ifremer.coselmar.persistence.entity.CoselmarUserRole; +import fr.ifremer.coselmar.persistence.entity.Document; import fr.ifremer.coselmar.persistence.entity.Privacy; import fr.ifremer.coselmar.persistence.entity.Question; import fr.ifremer.coselmar.persistence.entity.Status; @@ -32,16 +35,16 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { private static final Log log = LogFactory.getLog(QuestionsWebService.class); - public void addQuestion(QuestionBean questionBean) throws InvalidCredentialException, UnauthorizedException { + public void addQuestion(QuestionBean question) throws InvalidCredentialException, UnauthorizedException { // Check authentication String authorization = getContext().getHeader("Authorization"); UserWebToken userWebToken = checkAuthentication(authorization); - // Only Expert or Supervisor can add document + // Only Supervisor can add question String userRole = userWebToken.getRole(); - if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), userRole)) { + if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole)) { String message = String.format("User %s %s ('%s') is not allowed to add question", userWebToken.getFirstName(), userWebToken.getLastName(), userWebToken.getUserId()); if (log.isWarnEnabled()) { @@ -67,58 +70,68 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { } // let's go - Question question = getQuestionDao().create(); + Question questionEntity = getQuestionDao().create(); - question.setTitle(questionBean.getTitle()); + // Question basics - question.setSummary(questionBean.getSummary()); + questionEntity.setTitle(question.getTitle()); - question.setType(questionBean.getType()); + questionEntity.setSummary(question.getSummary()); + + questionEntity.setType(question.getType()); // By default, privacy is private - String privacy = questionBean.getPrivacy(); + String privacy = question.getPrivacy(); Privacy realPrivacy = privacy != null ? Privacy.valueOf(privacy.toUpperCase()) : Privacy.PRIVATE; - question.setPrivacy(realPrivacy); + questionEntity.setPrivacy(realPrivacy); // On creation, Status is Open - question.setStatus(Status.OPEN); + questionEntity.setStatus(Status.OPEN); // Manage Dates : submission & deadline - Date submissionDate = questionBean.getSubmissionDate(); + Date submissionDate = question.getSubmissionDate(); if (submissionDate != null) { - question.setSubmissionDate(new Date(submissionDate.getTime())); + questionEntity.setSubmissionDate(new Date(submissionDate.getTime())); } - Date deadline = questionBean.getDeadline(); + Date deadline = question.getDeadline(); if (deadline != null) { - question.setDeadline(new Date(deadline.getTime())); + questionEntity.setDeadline(new Date(deadline.getTime())); } // Users around the question // First Supervisor is the one creating this question - question.addSupervisors(supervisor); + questionEntity.addSupervisors(supervisor); + + questionEntity.addAllExternalExperts(question.getExternalExperts()); - question.addAllExternalExperts(questionBean.getExternalExperts()); // Retrieve the clients - Set<UserBean> clients = questionBean.getClients(); + Set<UserBean> clients = question.getClients(); if (clients != null && !clients.isEmpty()) { - List<CoselmarUser> clientEntities = retrieveUsers(clients); - question.addAllClients(clientEntities); + Set<CoselmarUser> clientEntities = retrieveUsers(clients); + questionEntity.addAllClients(clientEntities); } // For participants, should create a dedicated group, // that could be used to restrict documents access - Set<UserBean> participants = questionBean.getParticipants(); + Set<UserBean> participants = question.getParticipants(); + CoselmarUserGroup participantGroup = getCoselmarUserGroupDao().create(); if (participants != null && !participants.isEmpty()) { - CoselmarUserGroup userGroup = getCoselmarUserGroupDao().create(); - userGroup.setName(questionBean.getTitle()); + participantGroup.setName(question.getTitle()); - List<CoselmarUser> expertEntities = retrieveUsers(participants); - userGroup.addAllMembers(expertEntities); + Set<CoselmarUser> expertEntities = retrieveUsers(participants); + participantGroup.addAllMembers(expertEntities); + + } + questionEntity.setParticipants(participantGroup); - question.setParticipants(userGroup); + // Retrieve the supervisor + Set<UserBean> supervisors = question.getSupervisors(); + if (supervisors != null && !supervisors.isEmpty()) { + Set<CoselmarUser> supervisorEntities = retrieveUsers(supervisors); + questionEntity.addAllSupervisors(supervisorEntities); } // Note : no contributors now, contributors are old participants, @@ -126,15 +139,26 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { // Hierarchy of questions - Set<QuestionBean> parents = questionBean.getParents(); + Set<QuestionBean> parents = question.getParents(); if (parents != null && !parents.isEmpty()) { List<Question> questions = retrieveQuestions(parents); - question.addAllParents(questions); + questionEntity.addAllParents(questions); } -// // Documents on init -// question.addAllRelatedDocuments(); + // Documents on init + Set<DocumentBean> relatedDocuments = question.getRelatedDocuments(); + if (relatedDocuments != null && !relatedDocuments.isEmpty()) { + List<Document> documents = retrieveDocuments(relatedDocuments); + // Manage restriction list for document with Privacy.RESTRICTED + for (Document document : documents) { + if (document.getPrivacy() == Privacy.RESTRICTED) { + document.addRestrictedList(participantGroup); + } + } + + questionEntity.addAllRelatedDocuments(documents); + } } @@ -144,17 +168,17 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { //////////////////////////////////////////////////////////////////////////// - protected List<CoselmarUser> retrieveUsers(Collection<UserBean> userBeans) { + protected Set<CoselmarUser> retrieveUsers(Collection<UserBean> userBeans) { Function<UserBean, String> getIds = new Function<UserBean, String>() { @Override public String apply(UserBean userBean) { - return getFullUserIdFromShort(userBean.getId()); + return getFullIdFromShort(CoselmarUser.class, userBean.getId()); } }; Collection<String> userIds = Collections2.transform(userBeans, getIds); List<CoselmarUser> coselmarUsers = getCoselmarUserDao().forTopiaIdIn(userIds).findAll(); - return coselmarUsers; + return new HashSet<>(coselmarUsers); } @@ -162,7 +186,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { Function<QuestionBean, String> getIds = new Function<QuestionBean, String>() { @Override public String apply(QuestionBean questionBean) { - return getFullUserIdFromShort(questionBean.getId()); + return getFullIdFromShort(Question.class, questionBean.getId()); } }; @@ -172,6 +196,20 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { } + protected List<Document> retrieveDocuments(Collection<DocumentBean> documentBeans) { + Function<DocumentBean, String> getIds = new Function<DocumentBean, String>() { + @Override + public String apply(DocumentBean documentBean) { + return getFullIdFromShort(Document.class, documentBean.getId()); + } + }; + + Collection<String> documentIds = Collections2.transform(documentBeans, getIds); + List<Document> documents = getDocumentDao().forTopiaIdIn(documentIds).findAll(); + return documents; + + } + protected String getFullQuestionIdFromShort(String shortQuestionId) { return Question.class.getCanonicalName() + getPersistenceContext().getTopiaIdFactory().getSeparator() + shortQuestionId; } diff --git a/coselmar-rest/src/main/resources/mapping b/coselmar-rest/src/main/resources/mapping index 3e698ff..8e557c1 100644 --- a/coselmar-rest/src/main/resources/mapping +++ b/coselmar-rest/src/main/resources/mapping @@ -43,3 +43,12 @@ POST /v1/users/{userId} UsersWebService.modifyUser POST /v1/users UsersWebService.addUser DELETE /v1/users/{userId} UsersWebService.deleteUser +# Questions Api + +#GET /v1/questions QuestionsWebService.getQuestions +#GET /v1/questions/{questionId} QuestionsWebService.getQuestion +#POST /v1/questions/{questionId} QuestionsWebService.saveQuestion +#POST /v1/questions/{questionId}/documents QuestionsWebService.addDocuments +POST /v1/questions QuestionsWebService.addQuestion +#DELETE /v1/questions/{questionId} QuestionsWebService.closeQuestion + -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.