diff --git a/src/main/java/org/olat/commons/calendar/CalendarUtils.java b/src/main/java/org/olat/commons/calendar/CalendarUtils.java index bee66d68fb7f9f43a834994a805aa22ae2eb1cfe..d5da7238248006c6b21b2a6f9d2cf555fa68d7fc 100644 --- a/src/main/java/org/olat/commons/calendar/CalendarUtils.java +++ b/src/main/java/org/olat/commons/calendar/CalendarUtils.java @@ -82,6 +82,15 @@ public class CalendarUtils { return cal; } + + + public static Date endOfDay(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal = getEndOfDay(cal); + return cal.getTime(); + } + public static Calendar getEndOfDay(Calendar cal) { cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); diff --git a/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java b/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java index 9df1fb79ce329d53af4e518a623d55b8706b2cc9..001f7bd92e8a05c6c51a40a4d5c2afa4c7d5d0e5 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java +++ b/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java @@ -1,4 +1,6 @@ /** + + * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> @@ -21,12 +23,9 @@ package org.olat.core.commons.services.notifications.restapi; import static org.olat.restapi.security.RestSecurityHelper.isAdmin; +import static org.olat.restapi.security.RestSecurityHelper.parseDate; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; @@ -241,49 +240,4 @@ public class NotificationsWebService { } return infoVO; } - - private Date parseDate(String date, Locale locale) { - if(StringHelper.containsNonWhitespace(date)) { - if(date.indexOf('T') > 0) { - if(date.indexOf('.') > 0) { - try { - return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.S").parse(date); - } catch (ParseException e) { - //fail silently - } - } else { - try { - return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss").parse(date); - } catch (ParseException e) { - //fail silently - } - } - } - - //try with the locale - if(date.length() > 10) { - //probably date time - try { - DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); - format.setLenient(true); - return format.parse(date); - } catch (ParseException e) { - //fail silently - } - } else { - try { - DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM, locale); - format.setLenient(true); - return format.parse(date); - } catch (ParseException e) { - //fail silently - } - } - } - - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); - cal.add(Calendar.MONTH, -1); - return cal.getTime(); - } } diff --git a/src/main/java/org/olat/modules/lecture/LectureBlockRollCallSearchParameters.java b/src/main/java/org/olat/modules/lecture/LectureBlockRollCallSearchParameters.java index 65ad1e5d7befb9686cc4f69bdfc4e1e40abbb2bb..744841a6e77f91e564921aa78de81d9dd7e06a41 100644 --- a/src/main/java/org/olat/modules/lecture/LectureBlockRollCallSearchParameters.java +++ b/src/main/java/org/olat/modules/lecture/LectureBlockRollCallSearchParameters.java @@ -32,6 +32,7 @@ public class LectureBlockRollCallSearchParameters { private Boolean hasSupervisorNotificationDate; private Long rollCallKey; + private Long lectureBlockKey; public Boolean getClosed() { return closed; @@ -64,4 +65,12 @@ public class LectureBlockRollCallSearchParameters { public void setRollCallKey(Long rollCallKey) { this.rollCallKey = rollCallKey; } + + public Long getLectureBlockKey() { + return lectureBlockKey; + } + + public void setLectureBlockKey(Long lectureBlockKey) { + this.lectureBlockKey = lectureBlockKey; + } } diff --git a/src/main/java/org/olat/modules/lecture/LectureService.java b/src/main/java/org/olat/modules/lecture/LectureService.java index 64ca0c2a64ed7a6dfd10c35714766bbf4332a69c..78d0c7cf89b4b7e2b625898641706f68ba924422 100644 --- a/src/main/java/org/olat/modules/lecture/LectureService.java +++ b/src/main/java/org/olat/modules/lecture/LectureService.java @@ -360,6 +360,14 @@ public interface LectureService { */ public List<LectureBlock> getLectureBlocks(RepositoryEntryRef entry); + /** + * Search lecture blocks. + * + * @param searchParams The search parameters + * @return A list of lecture blocks + */ + public List<LectureBlock> getLectureBlocks(LecturesBlockSearchParameters searchParams); + /** * Return the list of lecture blocks of a course with the teachers. * diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java b/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java index 4f40aae29cd93a4ab9b794f1009cea33264a3794..fd446dff6137c674928a4271ad7fde9d44783579 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java @@ -152,6 +152,21 @@ public class LectureBlockDAO { .getResultList(); } + public List<LectureBlock> searchLectureBlocks(LecturesBlockSearchParameters searchParams) { + StringBuilder sb = new StringBuilder(); + sb.append("select block from lectureblock block") + .append(" inner join block.teacherGroup tGroup") + .append(" inner join tGroup.members membership") + .append(" inner join fetch block.entry entry"); + boolean where = false; + where = addSearchParametersToQuery(sb, where, searchParams); + + TypedQuery<LectureBlock> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), LectureBlock.class); + addSearchParametersToQuery(query, searchParams); + return query.getResultList(); + } + public List<LectureBlock> loadByTeacher(IdentityRef identityRef, LecturesBlockSearchParameters searchParams) { StringBuilder sb = new StringBuilder(); sb.append("select block from lectureblock block") @@ -159,7 +174,7 @@ public class LectureBlockDAO { .append(" inner join tGroup.members membership") .append(" inner join fetch block.entry entry") .append(" where membership.identity.key=:teacherKey"); - addSearchParametersToQuery(sb, searchParams); + addSearchParametersToQuery(sb, true, searchParams); TypedQuery<LectureBlock> query = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), LectureBlock.class) @@ -224,7 +239,7 @@ public class LectureBlockDAO { .append(" inner join membership.identity coach") .append(" inner join fetch coach.user usercoach") .append(" where membership.role='").append("teacher").append("' and block.entry.key=:repoEntryKey"); - addSearchParametersToQuery(sc, searchParams); + addSearchParametersToQuery(sc, true, searchParams); if(teacher != null) { sc.append(" and exists (select teachership.key from bgroupmember teachership where") .append(" teachership.group.key=tGroup.key and teachership.identity.key=:teacherKey") @@ -256,10 +271,11 @@ public class LectureBlockDAO { return new ArrayList<>(blockMap.values()); } - private void addSearchParametersToQuery(StringBuilder sb, LecturesBlockSearchParameters searchParams) { - if(searchParams == null) return; + private boolean addSearchParametersToQuery(StringBuilder sb, boolean where, LecturesBlockSearchParameters searchParams) { + if(searchParams == null) return where; if(StringHelper.containsNonWhitespace(searchParams.getSearchString())) { + where = PersistenceHelper.appendAnd(sb, where); sb.append(" and (entry.externalRef=:searchString or "); PersistenceHelper.appendFuzzyLike(sb, "entry.displayname", "fuzzySearchString", dbInstance.getDbVendor()); sb.append(" or "); @@ -268,11 +284,14 @@ public class LectureBlockDAO { } if(searchParams.getStartDate() != null) { - sb.append(" and block.startDate>=:startDate"); + where = PersistenceHelper.appendAnd(sb, where); + sb.append(" block.startDate>=:startDate"); } if(searchParams.getEndDate() != null) { - sb.append(" and block.endDate<=:endDate"); + where = PersistenceHelper.appendAnd(sb, where); + sb.append(" block.endDate<=:endDate"); } + return where; } private void addSearchParametersToQuery(TypedQuery<?> query, LecturesBlockSearchParameters searchParams) { diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java index a54266d1b1d9a73b27060a4e0aff28ceb14abee1..81725e833a08dc687d26018d857911d1f63a9fef 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java @@ -300,12 +300,21 @@ public class LectureBlockRollCallDAO { where = PersistenceHelper.appendAnd(sb, where); sb.append("rollcall.key=:rollCallKey"); } + + if(searchParams.getLectureBlockKey() != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append("rollcall.lectureBlock.key=:lectureBlockKey"); + } TypedQuery<LectureBlockRollCall> query = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), LectureBlockRollCall.class); if(searchParams.getRollCallKey() != null) { query.setParameter("rollCallKey", searchParams.getRollCallKey()); } + if(searchParams.getLectureBlockKey() != null) { + query.setParameter("lectureBlockKey", searchParams.getLectureBlockKey()); + } + return query.getResultList(); } diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java index 6e994b64faf633e679b47d7f7a0f38e5523ecbb5..ee6e3ecba6ae0b069a0a247bb075ca0fa8fb98ab 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java @@ -680,6 +680,11 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable { return lectureBlockDao.getLectureBlocks(entry); } + @Override + public List<LectureBlock> getLectureBlocks(LecturesBlockSearchParameters searchParams) { + return lectureBlockDao.searchLectureBlocks(searchParams); + } + @Override public List<LectureBlock> getLectureBlocks(IdentityRef teacher, LecturesBlockSearchParameters searchParams) { return lectureBlockDao.loadByTeacher(teacher, searchParams); diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockRollCallWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockRollCallWebService.java index 35bee5d17424f1f7ba246a4e097f8981cecc47fc..9da864ffe1b58001788a5d3c2acab81efce845ab 100644 --- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockRollCallWebService.java +++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockRollCallWebService.java @@ -1,5 +1,6 @@ /** + * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> @@ -51,7 +52,6 @@ import org.olat.modules.lecture.LectureService; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -@Path("repo/lectures/rollcalls") public class LectureBlockRollCallWebService { /** @@ -69,9 +69,11 @@ public class LectureBlockRollCallWebService { * @return The roll calls */ @GET + @Path("/") @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public Response getRollCalls(@QueryParam("closed") Boolean closed, @QueryParam("hasAbsence") Boolean hasAbsence, @QueryParam("hasSupervisorNotificationDate") Boolean hasSupervisorNotificationDate, + @QueryParam("lectureBlockKey") Long lectureBlockKey, @Context HttpServletRequest httpRequest) { Roles roles = getRoles(httpRequest); if(!roles.isOLATAdmin()) { @@ -89,6 +91,9 @@ public class LectureBlockRollCallWebService { if(closed != null) { searchParams.setClosed(closed); } + if(lectureBlockKey != null) { + searchParams.setLectureBlockKey(lectureBlockKey); + } List<LectureBlockRollCall> rollCalls = lectureService.getRollCalls(searchParams); List<LectureBlockRollCallVO> voList = new ArrayList<>(rollCalls.size()); @@ -149,6 +154,7 @@ public class LectureBlockRollCallWebService { * @return The updated roll call */ @PUT + @Path("/") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response updateRollCallPut(LectureBlockRollCallVO rollCallVo, @Context HttpServletRequest httpRequest) { @@ -171,6 +177,7 @@ public class LectureBlockRollCallWebService { * @return The updated roll call */ @POST + @Path("/") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response updateRollCall(LectureBlockRollCallVO rollCallVo, @Context HttpServletRequest httpRequest) { diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksRootWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksRootWebService.java new file mode 100644 index 0000000000000000000000000000000000000000..84b8e3df8ae15e04b55e2592a49e44286480410a --- /dev/null +++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksRootWebService.java @@ -0,0 +1,98 @@ +/** + * <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.lecture.restapi; + +import static org.olat.restapi.security.RestSecurityHelper.getRoles; +import static org.olat.restapi.security.RestSecurityHelper.parseDate; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +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.commons.calendar.CalendarUtils; +import org.olat.core.CoreSpringFactory; +import org.olat.core.id.Roles; +import org.olat.modules.lecture.LectureBlock; +import org.olat.modules.lecture.LectureService; +import org.olat.modules.lecture.model.LecturesBlockSearchParameters; + +/** + * + * Initial date: 8 juin 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Path("repo/lectures") +public class LectureBlocksRootWebService { + + + /** + * Return the lecture blocks of the specified course or repository entry. + * @response.representation.200.qname {http://www.example.com}lectureBlocksVO + * @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.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 + * @param httpRequest The HTTP request + * @return The lecture blocks + */ + @GET + @Path("") + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public Response searchLectureBlocks(@QueryParam("date") String date, @Context HttpServletRequest httpRequest) { + Roles roles = getRoles(httpRequest); + if(!roles.isOLATAdmin()) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + LecturesBlockSearchParameters searchParams = new LecturesBlockSearchParameters(); + if(date != null) { + Date d = parseDate(date, Locale.ENGLISH); + Date startDate = CalendarUtils.removeTime(d); + Date endDate = CalendarUtils.endOfDay(d); + searchParams.setStartDate(startDate); + searchParams.setEndDate(endDate); + } + List<LectureBlock> blockList = CoreSpringFactory.getImpl(LectureService.class).getLectureBlocks(searchParams); + List<LectureBlockVO> voList = new ArrayList<>(blockList.size()); + for(LectureBlock block:blockList) { + voList.add(new LectureBlockVO(block, block.getEntry().getKey())); + } + LectureBlockVO[] voes = voList.toArray(new LectureBlockVO[voList.size()]); + return Response.ok(voes).build(); + } + + @Path("rollcalls") + public LectureBlockRollCallWebService getLectureBlockRollCallWebService() { + return new LectureBlockRollCallWebService(); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/restapi/_spring/restApiContext.xml b/src/main/java/org/olat/restapi/_spring/restApiContext.xml index 9addf2bf980d20b7563b14638fac0020c5921b4e..5240c1a4d6d5f39339902892133f78b7b93ea085 100644 --- a/src/main/java/org/olat/restapi/_spring/restApiContext.xml +++ b/src/main/java/org/olat/restapi/_spring/restApiContext.xml @@ -40,7 +40,7 @@ <value>org.olat.modules.fo.restapi.ForumImportWebService</value> <value>org.olat.modules.fo.restapi.ForumCourseNodeWebService</value> <value>org.olat.modules.fo.restapi.MyForumsWebService</value> - <value>org.olat.modules.lecture.restapi.LectureBlockRollCallWebService</value> + <value>org.olat.modules.lecture.restapi.LectureBlocksRootWebService</value> <value>org.olat.modules.openmeetings.restapi.OpenMeetingsWebService</value> <value>org.olat.modules.vitero.restapi.ViteroWebService</value> <value>org.olat.core.commons.services.notifications.restapi.NotificationsWebService</value> diff --git a/src/main/java/org/olat/restapi/security/RestSecurityHelper.java b/src/main/java/org/olat/restapi/security/RestSecurityHelper.java index 6de4d7ae762bb19375e619523542b760b67a119f..4ca6e30f5e5eda429165042034fab13825603a0a 100644 --- a/src/main/java/org/olat/restapi/security/RestSecurityHelper.java +++ b/src/main/java/org/olat/restapi/security/RestSecurityHelper.java @@ -19,6 +19,11 @@ */ package org.olat.restapi.security; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; import java.util.Locale; import java.util.UUID; @@ -31,6 +36,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; +import org.olat.core.util.StringHelper; import org.olat.core.util.i18n.I18nModule; import org.olat.course.ICourse; import org.olat.course.groupsandrights.CourseGroupManager; @@ -195,4 +201,49 @@ public class RestSecurityHelper { if(ureq == null) return I18nModule.getDefaultLocale(); return LocaleNegotiator.getPreferedLocale(ureq); } + + public static Date parseDate(String date, Locale locale) { + if(StringHelper.containsNonWhitespace(date)) { + if(date.indexOf('T') > 0) { + if(date.indexOf('.') > 0) { + try { + return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.S").parse(date); + } catch (ParseException e) { + //fail silently + } + } else { + try { + return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss").parse(date); + } catch (ParseException e) { + //fail silently + } + } + } + + //try with the locale + if(date.length() > 10) { + //probably date time + try { + DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); + format.setLenient(true); + return format.parse(date); + } catch (ParseException e) { + //fail silently + } + } else { + try { + DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM, locale); + format.setLenient(true); + return format.parse(date); + } catch (ParseException e) { + //fail silently + } + } + } + + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + cal.add(Calendar.MONTH, -1); + return cal.getTime(); + } }