diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java index 929f9c5a5b37ace81573b7929a387154ba701661..3b59736015626d702a2d6e8a99e3e98a29355b39 100644 --- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java +++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java @@ -105,7 +105,7 @@ public class LectureBlocksWebService { * Create or update a lecture block. * @response.representation.200.qname {http://www.example.com}lectureBlocksVO * @response.representation.200.mediaType application/xml, application/json - * @response.representation.200.doc The updated configuration + * @response.representation.200.doc The updated lecture block * @response.representation.200.example {@link org.olat.modules.lecture.restapi.Examples#SAMPLE_LECTUREBLOCKVO} * @response.representation.401.doc The roles of the authenticated user are not sufficient * @response.representation.404.doc The course not found diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java b/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java new file mode 100644 index 0000000000000000000000000000000000000000..722226034599c8bb594f0a0f619ea6d0fd6d366c --- /dev/null +++ b/src/main/java/org/olat/modules/reminder/manager/ReminderRulesXStream.java @@ -0,0 +1,67 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.manager; + +import java.io.InputStream; +import java.io.OutputStream; + +import org.olat.core.util.xml.XStreamHelper; +import org.olat.modules.reminder.model.ImportExportReminders; +import org.olat.modules.reminder.model.ReminderRules; + +import com.thoughtworks.xstream.XStream; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ReminderRulesXStream { + + private static final XStream ruleXStream = XStreamHelper.createXStreamInstance(); + static { + ruleXStream.alias("rule", org.olat.modules.reminder.model.ReminderRuleImpl.class); + ruleXStream.alias("rules", org.olat.modules.reminder.model.ReminderRules.class); + ruleXStream.alias("reminders", org.olat.modules.reminder.model.ImportExportReminders.class); + ruleXStream.alias("reminder", org.olat.modules.reminder.model.ImportExportReminder.class); + } + + public static ReminderRules toRules(String rulesXml) { + return (ReminderRules)ruleXStream.fromXML(rulesXml); + } + + public static ReminderRules toRules(InputStream in) { + return (ReminderRules)ruleXStream.fromXML(in); + } + + public static String toXML(ReminderRules rules) { + return ruleXStream.toXML(rules); + } + + public static void toXML(ImportExportReminders reminders, OutputStream out) { + ruleXStream.toXML(reminders, out); + } + + public static ImportExportReminders fromXML(InputStream in) { + return (ImportExportReminders)ruleXStream.fromXML(in); + } + +} diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java index 083952a24acbf478e22882d034e39c5e03af1719..864fc993b4035cb4645edd8cc69762bc773468cd 100644 --- a/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java +++ b/src/main/java/org/olat/modules/reminder/manager/ReminderServiceImpl.java @@ -50,7 +50,6 @@ import org.olat.core.util.mail.MailContextImpl; import org.olat.core.util.mail.MailManager; import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailerResult; -import org.olat.core.util.xml.XStreamHelper; import org.olat.modules.reminder.Reminder; import org.olat.modules.reminder.ReminderRule; import org.olat.modules.reminder.ReminderService; @@ -69,8 +68,6 @@ import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.thoughtworks.xstream.XStream; - /** * * Initial date: 08.04.2015<br> @@ -81,13 +78,6 @@ import com.thoughtworks.xstream.XStream; public class ReminderServiceImpl implements ReminderService { private static final OLog log = Tracing.createLoggerFor(ReminderServiceImpl.class); - private static final XStream ruleXStream = XStreamHelper.createXStreamInstance(); - static { - ruleXStream.alias("rule", org.olat.modules.reminder.model.ReminderRuleImpl.class); - ruleXStream.alias("rules", org.olat.modules.reminder.model.ReminderRules.class); - ruleXStream.alias("reminders", org.olat.modules.reminder.model.ImportExportReminders.class); - ruleXStream.alias("reminder", org.olat.modules.reminder.model.ImportExportReminder.class); - } @Autowired @@ -174,12 +164,12 @@ public class ReminderServiceImpl implements ReminderService { @Override public String toXML(ReminderRules rules) { - return ruleXStream.toXML(rules); + return ReminderRulesXStream.toXML(rules); } @Override public ReminderRules toRules(String rulesXml) { - return (ReminderRules)ruleXStream.fromXML(rulesXml); + return ReminderRulesXStream.toRules(rulesXml); } @Override @@ -192,7 +182,7 @@ public class ReminderServiceImpl implements ReminderService { ImportExportReminder exportReminder = new ImportExportReminder(reminder); exportReminders.getReminders().add(exportReminder); } - ruleXStream.toXML(exportReminders, fOut); + ReminderRulesXStream.toXML(exportReminders, fOut); } catch(Exception e) { log.error("", e); } @@ -205,7 +195,7 @@ public class ReminderServiceImpl implements ReminderService { List<Reminder> reminders = new ArrayList<>(); if(reminderFile.exists()) { try(InputStream in = new FileInputStream(reminderFile)) { - ImportExportReminders importReminders = (ImportExportReminders)ruleXStream.fromXML(in); + ImportExportReminders importReminders = ReminderRulesXStream.fromXML(in); List<ImportExportReminder> importReminderList = importReminders.getReminders(); for(ImportExportReminder importReminder:importReminderList) { Reminder reminder = reminderDao.createReminder(newEntry, creator); diff --git a/src/main/java/org/olat/modules/reminder/restapi/Examples.java b/src/main/java/org/olat/modules/reminder/restapi/Examples.java new file mode 100644 index 0000000000000000000000000000000000000000..9e5bef4138c2f4f0722acf36a077bce3facfdedf --- /dev/null +++ b/src/main/java/org/olat/modules/reminder/restapi/Examples.java @@ -0,0 +1,40 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.restapi; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class Examples { + + public static final ReminderVO SAMPLE_REMINDERVO = new ReminderVO(); + + static { + SAMPLE_REMINDERVO.setKey(231l); + SAMPLE_REMINDERVO.setRepoEntryKey(264827834l); + SAMPLE_REMINDERVO.setDescription("A nice little description"); + SAMPLE_REMINDERVO.setEmailSubject("The subject"); + SAMPLE_REMINDERVO.setEmailBody("The body"); + } + +} diff --git a/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java b/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java new file mode 100644 index 0000000000000000000000000000000000000000..1652974f82880238df2ea9f31f4536466de75450 --- /dev/null +++ b/src/main/java/org/olat/modules/reminder/restapi/ReminderRuleVO.java @@ -0,0 +1,101 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.restapi; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.olat.modules.reminder.ReminderRule; +import org.olat.modules.reminder.model.ReminderRuleImpl; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "reminderRuleVO") +public class ReminderRuleVO { + + private String type; + private String leftOperand; + private String operator; + private String rightOperand; + private String rightUnit; + + public ReminderRuleVO() { + // + } + + public static ReminderRuleVO valueOf(ReminderRule rule) { + ReminderRuleVO vo = new ReminderRuleVO(); + vo.setType(rule.getType()); + if(rule instanceof ReminderRuleImpl) { + ReminderRuleImpl ruleImpl = (ReminderRuleImpl)rule; + vo.setLeftOperand(ruleImpl.getLeftOperand()); + vo.setOperator(ruleImpl.getOperator()); + vo.setRightOperand(ruleImpl.getRightOperand()); + vo.setRightUnit(ruleImpl.getRightUnit()); + } + return vo; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLeftOperand() { + return leftOperand; + } + + public void setLeftOperand(String leftOperand) { + this.leftOperand = leftOperand; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getRightOperand() { + return rightOperand; + } + + public void setRightOperand(String rightOperand) { + this.rightOperand = rightOperand; + } + + public String getRightUnit() { + return rightUnit; + } + + public void setRightUnit(String rightUnit) { + this.rightUnit = rightUnit; + } +} diff --git a/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java b/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java new file mode 100644 index 0000000000000000000000000000000000000000..6a639459d4739caeaf6f1eb72272c60fb24ca4be --- /dev/null +++ b/src/main/java/org/olat/modules/reminder/restapi/ReminderVO.java @@ -0,0 +1,126 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.restapi; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.olat.core.util.StringHelper; +import org.olat.modules.reminder.Reminder; +import org.olat.modules.reminder.ReminderRule; +import org.olat.modules.reminder.manager.ReminderRulesXStream; +import org.olat.modules.reminder.model.ReminderRules; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "reminderVO") +public class ReminderVO { + + private Long key; + private Long repoEntryKey; + + private String description; + private String emailSubject; + private String emailBody; + + private List<ReminderRuleVO> rules = new ArrayList<>(); + + public static ReminderVO valueOf(Reminder reminder, Long repositoryEntryKey) { + ReminderVO vo = new ReminderVO(); + vo.setKey(reminder.getKey()); + vo.setRepoEntryKey(repositoryEntryKey); + vo.setDescription(reminder.getDescription()); + vo.setEmailSubject(reminder.getEmailSubject()); + vo.setEmailBody(reminder.getEmailBody()); + + String configuration = reminder.getConfiguration(); + if(StringHelper.containsNonWhitespace(configuration)) { + ReminderRules reminderRules = ReminderRulesXStream.toRules(configuration); + List<ReminderRule> rules = reminderRules.getRules(); + List<ReminderRuleVO> ruleVoes = new ArrayList<>(); + for(ReminderRule rule:rules) { + ruleVoes.add(ReminderRuleVO.valueOf(rule)); + } + vo.setRules(ruleVoes); + } + + return vo; + } + + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + public Long getRepoEntryKey() { + return repoEntryKey; + } + + public void setRepoEntryKey(Long repoEntryKey) { + this.repoEntryKey = repoEntryKey; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getEmailSubject() { + return emailSubject; + } + + public void setEmailSubject(String emailSubject) { + this.emailSubject = emailSubject; + } + + public String getEmailBody() { + return emailBody; + } + + public void setEmailBody(String emailBody) { + this.emailBody = emailBody; + } + + public List<ReminderRuleVO> getRules() { + return rules; + } + + public void setRules(List<ReminderRuleVO> rules) { + this.rules = rules; + } + + + +} diff --git a/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java b/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java new file mode 100644 index 0000000000000000000000000000000000000000..ed6806921d57ca78eff98b513933811ac486ab63 --- /dev/null +++ b/src/main/java/org/olat/modules/reminder/restapi/RemindersWebService.java @@ -0,0 +1,196 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.restapi; + +import static org.olat.restapi.security.RestSecurityHelper.getIdentity; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.olat.core.id.Identity; +import org.olat.modules.reminder.Reminder; +import org.olat.modules.reminder.ReminderService; +import org.olat.modules.reminder.manager.ReminderRulesXStream; +import org.olat.modules.reminder.model.ReminderRuleImpl; +import org.olat.modules.reminder.model.ReminderRules; +import org.olat.repository.RepositoryEntry; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RemindersWebService { + + private RepositoryEntry entry; + private final boolean administrator; + + @Autowired + private ReminderService reminderService; + + public RemindersWebService(RepositoryEntry entry, boolean administrator) { + this.entry = entry; + this.administrator = administrator; + } + + /** + * Return the reminders of the specified course or repository entry. + * @response.representation.200.qname {http://www.example.com}reminderVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc An array of lecture blocks + * @response.representation.200.example {@link org.olat.modules.reminder.restapi.Examples#SAMPLE_REMINDERVO} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The resource not found + * @return The reminders + */ + @GET + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public Response getReminders() { + if(!administrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + List<Reminder> reminders = reminderService.getReminders(entry); + List<ReminderVO> voList = new ArrayList<>(reminders.size()); + for(Reminder reminder:reminders) { + voList.add(ReminderVO.valueOf(reminder, entry.getKey())); + } + ReminderVO[] voes = voList.toArray(new ReminderVO[voList.size()]); + return Response.ok(voes).build(); + } + + /** + * Create or update a reminder. + * + * @response.representation.200.qname {http://www.example.com}reminderVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The updated reminder + * @response.representation.200.example {@link org.olat.modules.reminder.restapi.Examples#SAMPLE_REMINDERVO} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course or repository entry not found + * @param reminder The reminder + * @param httpRequest The HTTP request + * @return It returns the updated / created reminder. + */ + @PUT + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response putReminder(ReminderVO reminder, @Context HttpServletRequest httpRequest) { + if(!administrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Reminder updatedReminder = saveReminder(reminder, httpRequest); + return Response.ok(ReminderVO.valueOf(updatedReminder, entry.getKey())).build(); + } + + /** + * Create or update a reminder. + * + * @response.representation.200.qname {http://www.example.com}reminderVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The updated reminder + * @response.representation.200.example {@link org.olat.modules.lecture.restapi.Examples#SAMPLE_REMINDERVO} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course or repository entry not found + * @param reminder The reminder + * @param httpRequest The HTTP request + * @return It returns the updated / created reminder. + */ + @POST + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response postReminder(ReminderVO reminder, @Context HttpServletRequest httpRequest) { + if(!administrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Reminder updatedReminder = saveReminder(reminder, httpRequest); + return Response.ok(ReminderVO.valueOf(updatedReminder, entry.getKey())).build(); + } + + private Reminder saveReminder(ReminderVO reminderVo, HttpServletRequest httpRequest) { + Identity creator = getIdentity(httpRequest); + + Reminder reminder; + if(reminderVo.getKey() == null) { + reminder = reminderService.createReminder(entry, creator); + } else { + reminder = reminderService.loadByKey(reminderVo.getKey()); + } + + reminder.setDescription(reminderVo.getDescription()); + reminder.setEmailSubject(reminderVo.getEmailSubject()); + reminder.setEmailBody(reminderVo.getEmailBody()); + + if(reminderVo.getRules() != null && !reminderVo.getRules().isEmpty()) { + ReminderRules rules = new ReminderRules(); + for(ReminderRuleVO ruleVo:reminderVo.getRules()) { + ReminderRuleImpl rule = new ReminderRuleImpl(); + rule.setType(ruleVo.getType()); + rule.setLeftOperand(ruleVo.getLeftOperand()); + rule.setOperator(ruleVo.getOperator()); + rule.setRightOperand(ruleVo.getRightOperand()); + rule.setRightUnit(ruleVo.getRightUnit()); + rules.getRules().add(rule); + } + String configuration = ReminderRulesXStream.toXML(rules); + reminder.setConfiguration(configuration); + } + return reminderService.save(reminder); + } + + /** + * Delete a specific reminder. + * @response.representation.200.doc Reminder deleted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course or repository entry not found + * @param reminderKey The reminder primary key + * @return Nothing + */ + @DELETE + @Path("{reminderKey}") + public Response deleteReminder(@PathParam("reminderKey") Long reminderKey) { + if(!administrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Reminder reminder = reminderService.loadByKey(reminderKey); + if(reminder == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + reminderService.delete(reminder); + return Response.ok().build(); + } +} diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java index 6001d059306d225166bd401112e25fda56cd28cf..b0ef004cc93a355d4d120121d39bb61ce29649b0 100644 --- a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java +++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java @@ -81,6 +81,7 @@ import org.olat.modules.curriculum.CurriculumElement; import org.olat.modules.curriculum.CurriculumService; import org.olat.modules.curriculum.restapi.CurriculumElementVO; import org.olat.modules.lecture.restapi.LectureBlocksWebService; +import org.olat.modules.reminder.restapi.RemindersWebService; import org.olat.modules.taxonomy.TaxonomyLevel; import org.olat.modules.taxonomy.TaxonomyService; import org.olat.modules.taxonomy.model.TaxonomyLevelRefImpl; @@ -203,6 +204,19 @@ public class RepositoryEntryWebService { return service; } + /** + * To get the web service for the reminders of a specific course. + * + * @return The web service for reminders. + */ + @Path("reminders") + public RemindersWebService getRemindersWebService(@Context HttpServletRequest request) { + boolean administrator = isAuthorEditor(request); + RemindersWebService service = new RemindersWebService(entry, administrator); + CoreSpringFactory.autowireObject(service); + return service; + } + @GET @Path("curriculum/elements") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java index 4e68808cae7e888c599c99183d220163015c7495..2e97a0511dc07881d44deff288af766afbc0daac 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java @@ -80,6 +80,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.modules.gotomeeting.restapi.GoToTrainingWebService; import org.olat.modules.lecture.restapi.LectureBlocksWebService; +import org.olat.modules.reminder.restapi.RemindersWebService; import org.olat.modules.vitero.restapi.ViteroBookingWebService; import org.olat.repository.ErrorList; import org.olat.repository.RepositoryEntry; @@ -236,6 +237,20 @@ public class CourseWebService { CoreSpringFactory.autowireObject(service); return service; } + + /** + * To get the web service for the reminders of a specific course. + * + * @return The web service for reminders. + */ + @Path("reminders") + public RemindersWebService getRemindersWebService(@Context HttpServletRequest request) { + RepositoryEntry courseRe = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); + boolean administrator = isManager(request); + RemindersWebService service = new RemindersWebService(courseRe, administrator); + CoreSpringFactory.autowireObject(service); + return service; + } /** * Publish the course. diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1387ed3aed7cd6cad8e5391b03181fe1a8df9a77 --- /dev/null +++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRulesXStreamTest.java @@ -0,0 +1,67 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.reminder.manager; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.modules.reminder.model.ImportExportReminders; +import org.olat.modules.reminder.model.ReminderRules; + +/** + * + * Initial date: 26 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ReminderRulesXStreamTest { + + private static final OLog log = Tracing.createLoggerFor(ReminderRulesXStreamTest.class); + + @Test + public void readReminderRulesXml() { + ReminderRules reminderRules = null; + try(InputStream input=ReminderRulesXStreamTest.class.getResourceAsStream("reminder_rules_1.xml")) { + reminderRules = ReminderRulesXStream.toRules(input); + } catch(IOException e) { + log.error("", e); + } + + Assert.assertNotNull(reminderRules); + Assert.assertNotNull(reminderRules.getRules()); + Assert.assertEquals(3, reminderRules.getRules().size()); + } + + @Test + public void readImportedReminderRulesXml() { + ImportExportReminders reminders = null; + try(InputStream input=ReminderRulesXStreamTest.class.getResourceAsStream("import_reminders.xml")) { + reminders = ReminderRulesXStream.fromXML(input); + } catch(IOException e) { + log.error("", e); + } + + Assert.assertNotNull(reminders); + } +} diff --git a/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml b/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml new file mode 100644 index 0000000000000000000000000000000000000000..36232b121198f1c41f6417a535b64ef1ca668df1 --- /dev/null +++ b/src/test/java/org/olat/modules/reminder/manager/import_reminders.xml @@ -0,0 +1,28 @@ +<reminders> + <reminders> + <reminder> + <description>XML Reminder</description> + <configuration><rules> + <rules> + <rule> + <type>DateRuleSPI</type> + <operator>&gt;</operator> + <rightOperand>2020-03-01T00:00:00</rightOperand> + </rule> + <rule> + <type>BeforeDateRuleSPI</type> + <operator>&lt;</operator> + <rightOperand>2020-03-26T00:00:00</rightOperand> + </rule> + <rule> + <type>RepositoryEntryRoleRuleSPI</type> + <operator>=</operator> + <rightOperand>coach</rightOperand> + </rule> + </rules> +</rules></configuration> + <emailSubject>E-mail subject</emailSubject> + <emailBody><p>E-mail body</p></emailBody> + </reminder> + </reminders> +</reminders> \ No newline at end of file diff --git a/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml b/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..f6afabd98f4c271a49830eb157954d3dbc1710ff --- /dev/null +++ b/src/test/java/org/olat/modules/reminder/manager/reminder_rules_1.xml @@ -0,0 +1,20 @@ +<rules> + <rules> + <rule> + <type>DateRuleSPI</type> + <operator>></operator> + <rightOperand>2015-05-13T00:00:00</rightOperand> + </rule> + <rule> + <type>BusinessGroupRoleRuleSPI</type> + <operator>=</operator> + <rightOperand>128286721</rightOperand> + </rule> + <rule> + <type>PassedRuleSPI</type> + <leftOperand>91610795686842</leftOperand> + <operator>=</operator> + <rightOperand>passed</rightOperand> + </rule> + </rules> +</rules> \ No newline at end of file diff --git a/src/test/java/org/olat/restapi/RemindersWebServiceTest.java b/src/test/java/org/olat/restapi/RemindersWebServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..022f8684555de30718bc854bfa35df3514e594c3 --- /dev/null +++ b/src/test/java/org/olat/restapi/RemindersWebServiceTest.java @@ -0,0 +1,338 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.restapi; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.course.nodes.gta.rule.AssignTaskRuleSPI; +import org.olat.modules.reminder.Reminder; +import org.olat.modules.reminder.ReminderRule; +import org.olat.modules.reminder.ReminderService; +import org.olat.modules.reminder.manager.ReminderDAO; +import org.olat.modules.reminder.manager.ReminderRuleEngine; +import org.olat.modules.reminder.manager.ReminderRulesXStream; +import org.olat.modules.reminder.model.ReminderImpl; +import org.olat.modules.reminder.model.ReminderRuleImpl; +import org.olat.modules.reminder.model.ReminderRules; +import org.olat.modules.reminder.restapi.ReminderRuleVO; +import org.olat.modules.reminder.restapi.ReminderVO; +import org.olat.modules.reminder.rule.DateRuleSPI; +import org.olat.repository.RepositoryEntry; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatJerseyTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * + * Initial date: 25 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RemindersWebServiceTest extends OlatJerseyTestCase { + + private static final OLog log = Tracing.createLoggerFor(RemindersWebServiceTest.class); + + @Autowired + private DB dbInstance; + @Autowired + private ReminderDAO reminderDao; + @Autowired + private DateRuleSPI dateRuleSpi; + @Autowired + private ReminderService reminderService; + + @Test + public void getReminders_repo() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login("administrator", "openolat")); + + Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1"); + RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry(); + Reminder transientReminder = reminderService.createReminder(entry, creator); + transientReminder.setDescription("Hello"); + Reminder reminder = reminderService.save(transientReminder); + + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries") + .path(entry.getKey().toString()).path("reminders").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + List<ReminderVO> reminderVoes = parseReminderArray(response.getEntity()); + Assert.assertNotNull(reminderVoes); + Assert.assertEquals(1, reminderVoes.size()); + ReminderVO reminderVo = reminderVoes.get(0); + Assert.assertNotNull(reminderVo); + Assert.assertEquals(reminder.getKey(), reminderVo.getKey()); + } + + @Test + public void getReminders_course() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login("administrator", "openolat")); + + Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1"); + RepositoryEntry courseEntry = JunitTestHelper.deployBasicCourse(creator); + Reminder transientReminder = reminderService.createReminder(courseEntry, creator); + transientReminder.setDescription("Hello"); + Reminder reminder = reminderService.save(transientReminder); + + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses") + .path(courseEntry.getOlatResource().getResourceableId().toString()).path("reminders").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + List<ReminderVO> reminderVoes = parseReminderArray(response.getEntity()); + Assert.assertNotNull(reminderVoes); + Assert.assertEquals(1, reminderVoes.size()); + ReminderVO reminderVo = reminderVoes.get(0); + Assert.assertNotNull(reminderVo); + Assert.assertEquals(reminder.getKey(), reminderVo.getKey()); + } + + @Test + public void putNewReminder() + throws IOException, URISyntaxException { + Identity creator = JunitTestHelper.createAndPersistIdentityAsRndAdmin("rest-rem-1"); + RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry(); + dbInstance.commitAndCloseSession(); + + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login(creator.getName(), JunitTestHelper.PWD)); + + ReminderVO reminderVo = new ReminderVO(); + reminderVo.setDescription("Hello, I'm a reminder"); + reminderVo.setEmailSubject("Remind me"); + reminderVo.setEmailBody("<p>To remind you</p>"); + + List<ReminderRuleVO> rulesVo = new ArrayList<>(); + reminderVo.setRules(rulesVo); + ReminderRuleVO ruleVo = new ReminderRuleVO(); + ruleVo.setType("DateRuleSPI"); + ruleVo.setOperator(">"); + ruleVo.setRightOperand("2015-05-13T00:00:00"); + rulesVo.add(ruleVo); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries") + .path(entry.getKey().toString()).path("reminders").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, reminderVo); + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + // check the return value + ReminderVO savedReminderVo = conn.parse(response, ReminderVO.class); + Assert.assertNotNull(savedReminderVo); + Assert.assertNotNull(savedReminderVo.getKey()); + Assert.assertEquals(entry.getKey(), savedReminderVo.getRepoEntryKey()); + Assert.assertEquals("Hello, I'm a reminder", savedReminderVo.getDescription()); + Assert.assertEquals("Remind me", savedReminderVo.getEmailSubject()); + Assert.assertEquals("<p>To remind you</p>", savedReminderVo.getEmailBody()); + Assert.assertEquals(1, savedReminderVo.getRules().size()); + + // check the reminder on the database + List<Reminder> reminders = reminderService.getReminders(entry); + Assert.assertNotNull(reminders); + Assert.assertEquals(1, reminders.size()); + Reminder reminder = reminders.get(0); + Assert.assertEquals(savedReminderVo.getKey(), reminder.getKey()); + Assert.assertEquals("Hello, I'm a reminder", reminder.getDescription()); + Assert.assertEquals("Remind me", reminder.getEmailSubject()); + Assert.assertEquals("<p>To remind you</p>", reminder.getEmailBody()); + Assert.assertEquals(creator, ((ReminderImpl)reminder).getCreator()); + + // check rule configuration + String configuration = reminder.getConfiguration(); + ReminderRules rules = reminderService.toRules(configuration); + List<ReminderRule> ruleList = rules.getRules(); + Assert.assertEquals(1, ruleList.size()); + ReminderRule rule = ruleList.get(0); + Assert.assertEquals(ReminderRuleEngine.DATE_RULE_TYPE, rule.getType()); + + // check if the rule works + boolean ok = dateRuleSpi.evaluate(rule); + Assert.assertTrue(ok); + } + + @Test + public void postReminder() + throws IOException, URISyntaxException { + Identity creator = JunitTestHelper.createAndPersistIdentityAsRndAdmin("rest-rem-3"); + RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry(); + + Reminder reminder = reminderService.createReminder(entry, creator); + reminder.setDescription("Hello, I'm a reminder"); + reminder.setEmailSubject("Remind me"); + reminder.setEmailBody("<p>To remind you</p>"); + + ReminderRules rules = new ReminderRules(); + ReminderRuleImpl rule = new ReminderRuleImpl(); + rule.setType("DateRuleSPI"); + rule.setOperator("<"); + rule.setRightOperand("2015-05-13T00:00:00"); + rules.getRules().add(rule); + String configuration = ReminderRulesXStream.toXML(rules); + reminder.setConfiguration(configuration); + reminder = reminderService.save(reminder); + + dbInstance.commitAndCloseSession(); + + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login(creator.getName(), JunitTestHelper.PWD)); + + ReminderVO reminderVo = new ReminderVO(); + reminderVo.setKey(reminder.getKey()); + reminderVo.setRepoEntryKey(entry.getKey()); + reminderVo.setDescription("I forgot"); + reminderVo.setEmailSubject("I forgot the subject"); + reminderVo.setEmailBody("<p>I forgot the body</p>"); + + List<ReminderRuleVO> rulesVo = new ArrayList<>(); + reminderVo.setRules(rulesVo); + ReminderRuleVO rule1Vo = new ReminderRuleVO(); + rule1Vo.setType("AssignTaskRuleSPI"); + rule1Vo.setLeftOperand("937539759"); + rule1Vo.setOperator("<"); + rule1Vo.setRightOperand("1"); + rule1Vo.setRightUnit("day"); + rulesVo.add(rule1Vo); + + ReminderRuleVO rule2Vo = new ReminderRuleVO(); + rule2Vo.setType("DateRuleSPI"); + rule2Vo.setOperator(">"); + rule2Vo.setRightOperand("2019-05-15T00:00:00"); + rulesVo.add(rule2Vo); + + reminderVo.setRules(rulesVo); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries") + .path(entry.getKey().toString()).path("reminders").build(); + HttpPost method = conn.createPost(request, MediaType.APPLICATION_JSON); + conn.addJsonEntity(method, reminderVo); + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + // check the return value + ReminderVO savedReminderVo = conn.parse(response, ReminderVO.class); + Assert.assertNotNull(savedReminderVo); + Assert.assertNotNull(savedReminderVo.getKey()); + Assert.assertEquals(entry.getKey(), savedReminderVo.getRepoEntryKey()); + Assert.assertEquals("I forgot", savedReminderVo.getDescription()); + Assert.assertEquals("I forgot the subject", savedReminderVo.getEmailSubject()); + Assert.assertEquals("<p>I forgot the body</p>", savedReminderVo.getEmailBody()); + Assert.assertEquals(2, savedReminderVo.getRules().size()); + + // check the reminder on the database + List<Reminder> reminders = reminderService.getReminders(entry); + Assert.assertNotNull(reminders); + Assert.assertEquals(1, reminders.size()); + Reminder updatedReminder = reminders.get(0); + Assert.assertEquals(savedReminderVo.getKey(), updatedReminder.getKey()); + Assert.assertEquals("I forgot", updatedReminder.getDescription()); + Assert.assertEquals("I forgot the subject", updatedReminder.getEmailSubject()); + Assert.assertEquals("<p>I forgot the body</p>", updatedReminder.getEmailBody()); + + // check rule configuration + String updatedConfiguration = updatedReminder.getConfiguration(); + ReminderRules updatedRules = reminderService.toRules(updatedConfiguration); + List<ReminderRule> updatedRuleList = updatedRules.getRules(); + Assert.assertEquals(2, updatedRuleList.size()); + ReminderRuleImpl updatedRule1 = (ReminderRuleImpl)updatedRuleList.get(0); + Assert.assertEquals(AssignTaskRuleSPI.class.getSimpleName(), updatedRule1.getType()); + Assert.assertEquals("937539759", updatedRule1.getLeftOperand()); + Assert.assertEquals("<", updatedRule1.getOperator()); + Assert.assertEquals("1", updatedRule1.getRightOperand()); + Assert.assertEquals("day", updatedRule1.getRightUnit()); + + ReminderRuleImpl updatedRule2 = (ReminderRuleImpl)updatedRuleList.get(1); + Assert.assertEquals(DateRuleSPI.class.getSimpleName(), updatedRule2.getType()); + Assert.assertEquals(">", updatedRule2.getOperator()); + Assert.assertEquals("2019-05-15T00:00:00", updatedRule2.getRightOperand()); + } + + @Test + public void deleteReminder() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login("administrator", "openolat")); + + Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1"); + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-rem-1"); + RepositoryEntry courseEntry = JunitTestHelper.deployBasicCourse(creator); + Reminder transientReminder = reminderService.createReminder(courseEntry, creator); + transientReminder.setDescription("Hello"); + Reminder reminder = reminderService.save(transientReminder); + + //mark as sent + reminderDao.markAsSend(reminder, id, "ok"); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("entries") + .path(courseEntry.getKey().toString()).path("reminders") + .path(reminder.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + + Reminder deletedReminder = reminderService.loadByKey(reminder.getKey()); + Assert.assertNull(deletedReminder); + } + + + private List<ReminderVO> parseReminderArray(HttpEntity entity) { + try(InputStream content=entity.getContent()) { + ObjectMapper mapper = new ObjectMapper(jsonFactory); + return mapper.readValue(content, new TypeReference<List<ReminderVO>>(){/* */}); + } catch (Exception e) { + log.error("", e); + return null; + } + } +} diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index dd6a333b5db4c298837dd6be78894d5c39ca91d8..090a9d137cec0fc6b041e4e557225e68888c260f 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -263,6 +263,7 @@ import org.junit.runners.Suite; org.olat.modules.reminder.ReminderModuleTest.class, org.olat.modules.reminder.manager.ReminderDAOTest.class, org.olat.modules.reminder.manager.ReminderRuleEngineTest.class, + org.olat.modules.reminder.manager.ReminderRulesXStreamTest.class, org.olat.modules.taxonomy.manager.TaxonomyDAOTest.class, org.olat.modules.taxonomy.manager.TaxonomyLevelDAOTest.class, org.olat.modules.taxonomy.manager.TaxonomyLevelTypeDAOTest.class, @@ -391,6 +392,7 @@ import org.junit.runners.Suite; org.olat.restapi.RepositoryEntryLifecycleTest.class, org.olat.restapi.RepositoryEntriesTest.class, org.olat.restapi.RepositoryEntryWebServiceTest.class, + org.olat.restapi.RemindersWebServiceTest.class, org.olat.restapi.RestApiLoginFilterTest.class, org.olat.restapi.UserAuthenticationMgmtTest.class, org.olat.restapi.UserFoldersTest.class,