diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsDataModel.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsDataModel.java index 7037208b65f6d672366ee528568b50760e9c4bad..6cc9c805ea6b1812ab692b133a59b44aeb421d8a 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsDataModel.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsDataModel.java @@ -68,10 +68,9 @@ public class CurriculumElementWithViewsDataModel extends DefaultFlexiTreeTableDa if(row.isCurriculumElementOnly() || row.isCurriculumElementWithEntry()) { active = row.getCurriculumElementStatus() == CurriculumElementStatus.active; } - if(active) { for(CurriculumElementWithViewsRow parent=row.getParent(); parent != null; parent=parent.getParent()) { - if(row.isCurriculumElementOnly() || row.isCurriculumElementWithEntry()) { + if(parent.isCurriculumElementOnly() || parent.isCurriculumElementWithEntry()) { active &= row.getCurriculumElementStatus() == CurriculumElementStatus.active; } } diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsRow.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsRow.java index a35d20f0a7cadd1dd898e5963b2211ff02348cb8..082274ab59e72f60889b4da3923a7e34ecf3945d 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsRow.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementWithViewsRow.java @@ -406,6 +406,18 @@ public class CurriculumElementWithViewsRow implements CurriculumElementWithView, public void setAccessTypes(List<PriceMethod> accessTypes) { this.accessTypes = accessTypes; } + + public boolean isClosedOrInactive() { + if(isCurriculumElementOnly()) { + return element.getElementStatus() == CurriculumElementStatus.inactive || element.getElementStatus() == CurriculumElementStatus.deleted; + } + if(isRepositoryEntryOnly()) { + return status != null && status.decommissioned(); + } + return (status != null && status.decommissioned()) + || (element != null && element.getElementStatus() != null + && (element.getElementStatus() == CurriculumElementStatus.inactive || element.getElementStatus() == CurriculumElementStatus.deleted)); + } @Override public CurriculumElementWithViewsRow getParent() { diff --git a/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparator.java b/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparator.java index 28d0469cca3795d1443d76f5b05085b52aceb3cc..07a39346aa7705330b3d7d7ae7850dbb592a0345 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparator.java +++ b/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparator.java @@ -78,13 +78,7 @@ public class CurriculumElementViewsRowComparator extends FlexiTreeNodeComparator int c = 0; if((c1.isCurriculumElementOnly() || c1.isCurriculumElementWithEntry()) && (c2.isCurriculumElementOnly() || c2.isCurriculumElementWithEntry())) { // compare by position - Long pos1 = c1.getCurriculumElementPos(); - Long pos2 = c2.getCurriculumElementPos(); - if(pos1 == null || pos2 == null) { - c = compareNullObjects(pos1, pos2); - } else { - c = Long.compare(pos1.longValue(), pos2.longValue()); - } + c = compareCurriculumElements(c1, c2); } else if(c1.isCurriculumElementOnly() || c1.isCurriculumElementWithEntry()) { c = 1; } else if(c2.isCurriculumElementOnly() || c2.isCurriculumElementWithEntry()) { @@ -96,11 +90,14 @@ public class CurriculumElementViewsRowComparator extends FlexiTreeNodeComparator } private int compareCurriculumElements(CurriculumElementWithViewsRow c1, CurriculumElementWithViewsRow c2) { - int c = 0; - if(c1.getCurriculumElementBeginDate() == null || c2.getCurriculumElementBeginDate() == null) { - c = compareNullObjects(c1.getCurriculumElementBeginDate(), c2.getCurriculumElementBeginDate()); - } else { - c = c1.getCurriculumElementBeginDate().compareTo(c2.getCurriculumElementBeginDate()); + int c = compareClosed(c1, c2); + + if(c == 0) { + if(c1.getCurriculumElementBeginDate() == null || c2.getCurriculumElementBeginDate() == null) { + c = compareNullObjects(c1.getCurriculumElementBeginDate(), c2.getCurriculumElementBeginDate()); + } else { + c = c1.getCurriculumElementBeginDate().compareTo(c2.getCurriculumElementBeginDate()); + } } if(c == 0) { @@ -126,11 +123,14 @@ public class CurriculumElementViewsRowComparator extends FlexiTreeNodeComparator } private int compareRepositoryEntry(CurriculumElementWithViewsRow c1, CurriculumElementWithViewsRow c2) { - int c = 0; - if(c1.getRepositoryEntryDisplayName() == null || c2.getRepositoryEntryDisplayName() == null) { - c = compareNullObjects(c1.getRepositoryEntryDisplayName(), c2.getRepositoryEntryDisplayName()); - } else { - c = collator.compare(c1.getRepositoryEntryDisplayName(), c2.getRepositoryEntryDisplayName()); + int c = compareClosed(c1, c2); + + if(c == 0) { + if(c1.getRepositoryEntryDisplayName() == null || c2.getRepositoryEntryDisplayName() == null) { + c = compareNullObjects(c1.getRepositoryEntryDisplayName(), c2.getRepositoryEntryDisplayName()); + } else { + c = collator.compare(c1.getRepositoryEntryDisplayName(), c2.getRepositoryEntryDisplayName()); + } } if(c == 0) { @@ -147,17 +147,23 @@ public class CurriculumElementViewsRowComparator extends FlexiTreeNodeComparator return c; } + private int compareClosed(CurriculumElementWithViewsRow c1, CurriculumElementWithViewsRow c2) { + int c = 0; + if(c1.isClosedOrInactive() && !c2.isClosedOrInactive()) { + c = 1; + } else if(!c1.isClosedOrInactive() && c2.isClosedOrInactive()) { + c = -1; + } + return c; + } + private int compareDisplayName(CurriculumElementWithViewsRow c1, CurriculumElementWithViewsRow c2) { String d1 = getDisplayName(c1); String d2 = getDisplayName(c2); if(d1 == null || d2 == null) { return compareNullObjects(d1, d2); } - int c = d1.compareTo(d2); - if(c == 0) { - - } - return c; + return d1.compareTo(d2); } private String getDisplayName(CurriculumElementWithViewsRow row) { 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/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties index 732fad5d61389e3b65f58c9c74155f8bb70422a6..38019be6acf3e6585788a9c22f830181a6650f2f 100644 --- a/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties @@ -16,7 +16,7 @@ export.url=Link zu Daten export.user.data.explain=W\u00E4hlen Sie die Elemente, welche f\u00FCr diesen Benutzer exportiert werden sollen. Der Export kann mehrere Stunden in Anspruch nehmen. Sobald der Export beendet ist, werden Sie per Email informiert. export.user.data.none=Sie k\u00F6nnen sich eine \u00DCbersicht \u00FCber ihre in OpenOLAT gespeicherten Daten nach Artikel 15 DSGVO beim Betreiber anfordern. Schreiben Sie hierzu eine entsprechende E-Mail mit ihrem Anliegen an den <a href\="mailto\:{0}">Support</a>. export.user.data.notReady=Der Benutzer kann den Export mit dem folgenden Link herunterladen. -export.user.data.processing=Der Export ist gerade bearbeitet. +export.user.data.processing=Der Export ist gerade in Bearbeitung. export.user.data.ready=Der Benutzer kann den Export mit dem folgenden Link herunterladen. Sie k\u00F6nnen auch ein en neuen Export erfordern. export.user.data.ready.subject=Export von "{0}" ist fertig export.user.data.ready.text=<p>Sie haben als Benutzerverwalter in OpenOLAT f\u00FCr den Benutzer "{0}" den Export der pers\u00F6nlichen Daten durchgef\u00FChrt. Die Daten sind nun generiert und stehen dem Benutzer im pers\u00F6nlichen Bereich in OpenOLAT zur Verf\u00FCgung.</p><p>Mit folgendem Link hat der Benutzer direkten Zugriff auf den Export: <a href="{1}">{1}</a><br>Sie k\u00F6nnen diesen Link an den Benutzer weiterleiten.</p><p>Wichtig: Diese Daten sind NUR f\u00FCr den Benutzer einsehbar, nicht aber f\u00FCr andere Benutzer des Systems. Auch Sie in der Rolle des Benutzerverwalters haben keinen Zugriff auf die pers\u00F6nlichen Daten des Benutzers.</p> diff --git a/src/test/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparatorTest.java b/src/test/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9e099d5e85c1c0b6ed6e1f5b1bdfc5ec5152b331 --- /dev/null +++ b/src/test/java/org/olat/modules/curriculum/ui/component/CurriculumElementViewsRowComparatorTest.java @@ -0,0 +1,249 @@ +/** + * <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.curriculum.ui.component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.modules.curriculum.Curriculum; +import org.olat.modules.curriculum.CurriculumCalendars; +import org.olat.modules.curriculum.CurriculumElement; +import org.olat.modules.curriculum.CurriculumElementStatus; +import org.olat.modules.curriculum.CurriculumLectures; +import org.olat.modules.curriculum.CurriculumService; +import org.olat.modules.curriculum.manager.CurriculumDAO; +import org.olat.modules.curriculum.manager.CurriculumElementDAO; +import org.olat.modules.curriculum.ui.CurriculumElementWithViewsRow; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryEntryStatusEnum; +import org.olat.repository.model.RepositoryEntryMyCourseImpl; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + + + +/** + * + * Initial date: 26 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class CurriculumElementViewsRowComparatorTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private CurriculumDAO curriculumDao; + @Autowired + private CurriculumService curriculumService; + @Autowired + private CurriculumElementDAO curriculumElementDao; + + @Test + public void testCurriculumElementActiveInactive() { + Curriculum curriculum = curriculumDao.createAndPersist("Cur-for-el-1", "Curriculum for element", "Curriculum", null); + CurriculumElement element1 = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element2 = curriculumElementDao.createCurriculumElement("Element-1", "2. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element3 = curriculumElementDao.createCurriculumElement("Element-1", "3. Element", CurriculumElementStatus.active, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element4 = curriculumElementDao.createCurriculumElement("Element-1", "4. Element", CurriculumElementStatus.active, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + dbInstance.commitAndCloseSession(); + + CurriculumElementWithViewsRow row1 = new CurriculumElementWithViewsRow(element1, null, 0); + CurriculumElementWithViewsRow row2 = new CurriculumElementWithViewsRow(element2, null, 0); + CurriculumElementWithViewsRow row3 = new CurriculumElementWithViewsRow(element3, null, 0); + CurriculumElementWithViewsRow row4 = new CurriculumElementWithViewsRow(element4, null, 0); + + List<CurriculumElementWithViewsRow> rows = new ArrayList<>(); + rows.add(row1); + rows.add(row2); + rows.add(row3); + rows.add(row4); + + Collections.sort(rows, new CurriculumElementViewsRowComparator(Locale.ENGLISH)); + + Assert.assertEquals(element3.getKey(), rows.get(0).getCurriculumElementKey()); + Assert.assertEquals(element4.getKey(), rows.get(1).getCurriculumElementKey()); + Assert.assertEquals(element1.getKey(), rows.get(2).getCurriculumElementKey()); + Assert.assertEquals(element2.getKey(), rows.get(3).getCurriculumElementKey()); + } + + /** + * Simulate a list of repository entries under the same curriculum element. + * + */ + @Test + public void testRepositoryEntryActiveInactive() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("sort-cur-el"); + + Curriculum curriculum = curriculumDao.createAndPersist("Cur-for-el-1", "Curriculum for element", "Curriculum", null); + CurriculumElement element = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + dbInstance.commitAndCloseSession(); + + RepositoryEntry entry1 = JunitTestHelper.deployBasicCourse(author, "1 course", RepositoryEntryStatusEnum.closed, false, false); + RepositoryEntry entry2 = JunitTestHelper.deployBasicCourse(author, "2 course", RepositoryEntryStatusEnum.trash, false, false); + RepositoryEntry entry3 = JunitTestHelper.deployBasicCourse(author, "3 course", RepositoryEntryStatusEnum.published, false, false); + RepositoryEntry entry4 = JunitTestHelper.deployBasicCourse(author, "4 course", RepositoryEntryStatusEnum.published, false, false); + // add the course and a participant to the curriculum + curriculumService.addRepositoryEntry(element, entry1, false); + curriculumService.addRepositoryEntry(element, entry2, false); + curriculumService.addRepositoryEntry(element, entry3, false); + curriculumService.addRepositoryEntry(element, entry4, false); + dbInstance.commitAndCloseSession(); + + CurriculumElementWithViewsRow row1 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry1, null, false, 0, 0), false); + CurriculumElementWithViewsRow row2 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry2, null, false, 0, 0), false); + CurriculumElementWithViewsRow row3 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry3, null, false, 0, 0), false); + CurriculumElementWithViewsRow row4 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry4, null, false, 0, 0), false); + + List<CurriculumElementWithViewsRow> rows = new ArrayList<>(); + rows.add(row1); + rows.add(row2); + rows.add(row3); + rows.add(row4); + + Collections.sort(rows, new CurriculumElementViewsRowComparator(Locale.ENGLISH)); + + Assert.assertEquals(entry3.getKey(), rows.get(0).getRepositoryEntryKey()); + Assert.assertEquals(entry4.getKey(), rows.get(1).getRepositoryEntryKey()); + Assert.assertEquals(entry1.getKey(), rows.get(2).getRepositoryEntryKey()); + Assert.assertEquals(entry2.getKey(), rows.get(3).getRepositoryEntryKey()); + } + + @Test + public void testRepositoryEntryClosed_underParent() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("sort-cur-el"); + + Curriculum curriculum = curriculumDao.createAndPersist("Cur-for-el-1", "Curriculum for element", "Curriculum", null); + CurriculumElement element = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + dbInstance.commitAndCloseSession(); + + RepositoryEntry entry1 = JunitTestHelper.deployBasicCourse(author, "1 course", RepositoryEntryStatusEnum.closed, false, false); + RepositoryEntry entry2 = JunitTestHelper.deployBasicCourse(author, "2 course", RepositoryEntryStatusEnum.trash, false, false); + RepositoryEntry entry3 = JunitTestHelper.deployBasicCourse(author, "3 course", RepositoryEntryStatusEnum.published, false, false); + RepositoryEntry entry4 = JunitTestHelper.deployBasicCourse(author, "4 course", RepositoryEntryStatusEnum.published, false, false); + // add the course and a participant to the curriculum + curriculumService.addRepositoryEntry(element, entry1, false); + curriculumService.addRepositoryEntry(element, entry2, false); + curriculumService.addRepositoryEntry(element, entry3, false); + curriculumService.addRepositoryEntry(element, entry4, false); + dbInstance.commitAndCloseSession(); + + + CurriculumElementWithViewsRow parent = new CurriculumElementWithViewsRow(element, null, 4); + + CurriculumElementWithViewsRow row1 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry1, null, false, 0, 0), false); + row1.setParent(parent); + CurriculumElementWithViewsRow row2 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry2, null, false, 0, 0), false); + row2.setParent(parent); + CurriculumElementWithViewsRow row3 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry3, null, false, 0, 0), false); + row3.setParent(parent); + CurriculumElementWithViewsRow row4 = new CurriculumElementWithViewsRow(element, null, + new RepositoryEntryMyCourseImpl(entry4, null, false, 0, 0), false); + row4.setParent(parent); + + List<CurriculumElementWithViewsRow> rows = new ArrayList<>(); + rows.add(parent); + rows.add(row1); + rows.add(row2); + rows.add(row3); + rows.add(row4); + + Collections.sort(rows, new CurriculumElementViewsRowComparator(Locale.ENGLISH)); + + Assert.assertEquals(entry3.getKey(), rows.get(1).getRepositoryEntryKey()); + Assert.assertEquals(entry4.getKey(), rows.get(2).getRepositoryEntryKey()); + Assert.assertEquals(entry1.getKey(), rows.get(3).getRepositoryEntryKey()); + Assert.assertEquals(entry2.getKey(), rows.get(4).getRepositoryEntryKey()); + } + + /** + * Simulate a list of repository entries under their own curriculum element. + * + */ + @Test + public void testActiveInactiveClosedOrNot() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("sort-cur-el"); + + Curriculum curriculum = curriculumDao.createAndPersist("Cur-for-el-1", "Curriculum for element", "Curriculum", null); + CurriculumElement element1 = curriculumElementDao.createCurriculumElement("Element-1", "1. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element2 = curriculumElementDao.createCurriculumElement("Element-2", "2. Element", CurriculumElementStatus.inactive, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, curriculum); + CurriculumElement element3 = curriculumElementDao.createCurriculumElement("Element-3", "3. Element", CurriculumElementStatus.active, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.enabled, curriculum); + CurriculumElement element4 = curriculumElementDao.createCurriculumElement("Element-4", "4. Element", CurriculumElementStatus.active, + new Date(), new Date(), null, null, CurriculumCalendars.disabled, CurriculumLectures.enabled, curriculum); + dbInstance.commitAndCloseSession(); + + RepositoryEntry entry1 = JunitTestHelper.deployBasicCourse(author, "1 course", RepositoryEntryStatusEnum.closed, false, false); + RepositoryEntry entry2 = JunitTestHelper.deployBasicCourse(author, "2 course", RepositoryEntryStatusEnum.published, false, false); + RepositoryEntry entry3 = JunitTestHelper.deployBasicCourse(author, "3 course", RepositoryEntryStatusEnum.closed, false, false); + RepositoryEntry entry4 = JunitTestHelper.deployBasicCourse(author, "4 course", RepositoryEntryStatusEnum.published, false, false); + // add the course and a participant to the curriculum + curriculumService.addRepositoryEntry(element1, entry1, false); + curriculumService.addRepositoryEntry(element2, entry2, false); + curriculumService.addRepositoryEntry(element3, entry3, false); + curriculumService.addRepositoryEntry(element4, entry4, false); + dbInstance.commitAndCloseSession(); + + CurriculumElementWithViewsRow row1 = new CurriculumElementWithViewsRow(element1, null, + new RepositoryEntryMyCourseImpl(entry1, null, false, 0, 0), true); + CurriculumElementWithViewsRow row2 = new CurriculumElementWithViewsRow(element2, null, + new RepositoryEntryMyCourseImpl(entry2, null, false, 0, 0), true); + CurriculumElementWithViewsRow row3 = new CurriculumElementWithViewsRow(element3, null, + new RepositoryEntryMyCourseImpl(entry3, null, false, 0, 0), true); + CurriculumElementWithViewsRow row4 = new CurriculumElementWithViewsRow(element4, null, + new RepositoryEntryMyCourseImpl(entry4, null, false, 0, 0), true); + + List<CurriculumElementWithViewsRow> rows = new ArrayList<>(); + rows.add(row1); + rows.add(row2); + rows.add(row3); + rows.add(row4); + + Collections.sort(rows, new CurriculumElementViewsRowComparator(Locale.ENGLISH)); + + Assert.assertEquals(entry4.getKey(), rows.get(0).getRepositoryEntryKey()); + Assert.assertEquals(entry1.getKey(), rows.get(1).getRepositoryEntryKey()); + Assert.assertEquals(entry2.getKey(), rows.get(2).getRepositoryEntryKey()); + Assert.assertEquals(entry3.getKey(), rows.get(3).getRepositoryEntryKey()); + } +} 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 ddb8225e42480f46b5a82adfbbfa84ce20c12e4f..51e9a830d844d5179db0efeacc12f1577c370625 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -267,6 +267,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, @@ -395,6 +396,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,