From e59dac874048962c316c0f51575fa34db97e6453 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Wed, 23 Nov 2022 09:47:20 -0500 Subject: [PATCH 1/7] Update for 24-SHAPSHOT --- .github/workflows/maven.yml | 6 ++++-- api/pom.xml | 13 +++++++------ .../model/AttendanceUserGroupStats.java | 4 ++-- impl/pom.xml | 17 +++++++---------- .../attendance/logic/SakaiProxyImpl.java | 2 +- pom.xml | 11 ++++++----- tool/pom.xml | 11 ++++++----- 7 files changed, 33 insertions(+), 31 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b573abd4..d343cfa7 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -11,12 +11,14 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Git Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: JDK 11 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: java-version: 11 + distribution: temurin architecture: x64 + cache: maven - name: Build with Maven env: MAVEN_OPTS: -Djava.awt.headless=true -Dorg.slf4j.simpleLogger.defaultLogLevel=info -Dmaven.wagon.http.retryHandler.count=2 -Dmaven.wagon.http.pool=true diff --git a/api/pom.xml b/api/pom.xml index 16a6776a..f8717d90 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -18,10 +18,11 @@ 4.0.0 - attendance - org.sakaiproject.attendance - 23-SNAPSHOT - + attendance + org.sakaiproject.attendance + 24-SNAPSHOT + ../pom.xml + attendance - API attendance-api @@ -45,8 +46,8 @@ hibernate-core - commons-lang - commons-lang + org.apache.commons + commons-lang3 diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java index b6daee30..212c8e88 100644 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java +++ b/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java @@ -19,8 +19,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; /** * Created by james on 7/11/17. diff --git a/impl/pom.xml b/impl/pom.xml index 5b281a71..cb76ee02 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -18,10 +18,11 @@ 4.0.0 - attendance - org.sakaiproject.attendance - 23-SNAPSHOT - + attendance + org.sakaiproject.attendance + 24-SNAPSHOT + ../pom.xml + attendance - Implementation attendance-impl @@ -58,12 +59,8 @@ ehcache-core - commons-lang - commons-lang - - - commons-configuration - commons-configuration + org.apache.commons + commons-lang3 org.hibernate diff --git a/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java b/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java index 934998a0..9cf9a53d 100644 --- a/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java @@ -20,7 +20,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.sakaiproject.authz.api.*; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.entity.api.ResourceProperties; diff --git a/pom.xml b/pom.xml index 74b79493..30a46e27 100644 --- a/pom.xml +++ b/pom.xml @@ -24,12 +24,13 @@ attendance pom - + - org.sakaiproject - master - 23-SNAPSHOT - + org.sakaiproject + master + 24-SNAPSHOT + ../master/pom.xml + diff --git a/tool/pom.xml b/tool/pom.xml index d4f06826..496e85fe 100644 --- a/tool/pom.xml +++ b/tool/pom.xml @@ -18,12 +18,13 @@ 4.0.0 - + - attendance - org.sakaiproject.attendance - 23-SNAPSHOT - + attendance + org.sakaiproject.attendance + 24-SNAPSHOT + ../pom.xml + attendance - Tool attendance-tool From 7d412ff154fe65d5ac5589df4fe7ef6828404320 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 19 Aug 2022 01:07:30 -0400 Subject: [PATCH 2/7] Modernize attendance tool backend Migrate from hbm xml to JPA annotations Reduce bloat from data model Reorganize api packages Remove stats from the database Remove stats calc job Add ignite caches --- README.md | 6 - api/pom.xml | 8 +- .../api/AttendanceGradebookProvider.java | 4 +- .../{ => api}/export/PDFEventExporter.java | 4 +- .../{ => api}/logic/AttendanceLogic.java | 55 +- .../{ => api}/logic/SakaiProxy.java | 2 +- .../attendance/api/model/AttendanceEvent.java | 100 +++ .../attendance/api/model/AttendanceGrade.java | 94 +++ .../api/model/AttendanceRecord.java | 101 +++ .../attendance/api/model/AttendanceSite.java | 107 +++ .../api/model/AttendanceStatus.java | 88 +++ .../attendance/api/model/GradingRule.java | 82 +++ .../{ => api}/model/ImportConfirmList.java | 7 +- .../attendance/{ => api}/model/Status.java | 2 +- .../model/stats}/AttendanceItemStats.java | 9 +- .../model/stats}/AttendanceStats.java | 37 +- .../model/stats}/AttendanceUserStats.java | 11 +- .../api/model/stats/StatusCount.java | 12 + .../repository/AttendanceEventRepository.java | 14 + .../repository/AttendanceGradeRepository.java | 14 + .../AttendanceRecordRepository.java | 12 + .../repository/AttendanceSiteRepository.java | 13 + .../AttendanceStatusRepository.java | 13 + .../api/repository/GradingRuleRepository.java | 12 + .../{ => api}/util/AttendanceConstants.java | 2 +- .../attendance/cache/CacheManager.java | 26 - .../attendance/hbm/AttendanceEvent.hbm.xml | 61 -- .../attendance/hbm/AttendanceGrade.hbm.xml | 52 -- .../hbm/AttendanceItemStats.hbm.xml | 46 -- .../attendance/hbm/AttendanceRecord.hbm.xml | 47 -- .../attendance/hbm/AttendanceSite.hbm.xml | 74 --- .../attendance/hbm/AttendanceStatus.hbm.xml | 50 -- .../hbm/AttendanceUserStats.hbm.xml | 52 -- .../attendance/hbm/GradingRule.hbm.xml | 46 -- .../attendance/model/AttendanceEvent.java | 63 -- .../attendance/model/AttendanceGrade.java | 48 -- .../attendance/model/AttendanceRecord.java | 49 -- .../attendance/model/AttendanceSite.java | 96 --- .../attendance/model/AttendanceStatus.java | 54 -- .../model/AttendanceUserGroupStats.java | 77 --- .../attendance/model/GradingRule.java | 45 -- .../attendance/types/StatusUserType.java | 31 - docs/sql/sakai23-conversion-mysql.sql | 27 + docs/sql/sakai23-conversion-oracle.sql | 29 + impl/pom.xml | 34 +- .../attendance/cache/CacheManagerImpl.java | 39 -- .../attendance/dao/AttendanceDao.java | 325 --------- .../dao/impl/AttendanceDaoImpl.java | 627 ------------------ .../impl/AttendanceGradebookProviderImpl.java | 11 +- .../export/PDFEventExporterImpl.java | 34 +- .../export/util/SortNameUserComparator.java | 2 +- .../{ => impl}/logic/AttendanceLogicImpl.java | 360 +++------- .../{ => impl}/logic/SakaiProxyImpl.java | 9 +- .../AttendanceEventRepositoryImpl.java | 40 ++ .../AttendanceGradeRepositoryImpl.java | 40 ++ .../AttendanceRecordRepositoryImpl.java | 27 + .../AttendanceSiteRepositoryImpl.java | 42 ++ .../AttendanceStatusRepositoryImpl.java | 39 ++ .../repository/GradingRuleRepositoryImpl.java | 27 + .../services/AttendanceStatCalc.java | 202 ------ .../services/AttendanceStatCalcJob.java | 142 ---- impl/src/webapp/WEB-INF/components.xml | 119 ++-- .../AttendanceRecordProvider.java | 4 +- .../AttendanceStatusProvider.java | 11 +- .../tool/dataproviders/BaseProvider.java | 4 +- .../tool/dataproviders/EventDataProvider.java | 3 +- .../DetachableAttendanceRecordModel.java | 6 +- .../DetachableAttendanceStatusModel.java | 6 +- .../tool/models/DetachableEventModel.java | 4 +- .../tool/models/DetachableUserModel.java | 2 +- .../attendance/tool/pages/BasePage.java | 15 +- .../attendance/tool/pages/EventInputPage.java | 20 +- .../attendance/tool/pages/EventView.java | 15 +- .../attendance/tool/pages/ExportPage.java | 9 +- .../tool/pages/ImportConfirmation.java | 7 +- .../attendance/tool/pages/Overview.java | 36 +- .../attendance/tool/pages/SettingsPage.java | 2 +- .../tool/pages/StudentOverview.java | 8 +- .../attendance/tool/pages/StudentView.java | 5 +- .../panels/AttendanceCommentFormPanel.java | 6 +- .../tool/panels/AttendanceGradeFormPanel.java | 10 +- .../tool/panels/AttendanceGradePanel.java | 30 +- .../panels/AttendanceRecordFormDataPanel.java | 26 +- .../AttendanceRecordFormHeaderPanel.java | 2 +- .../panels/AttendanceStatusFormPanel.java | 12 +- .../attendance/tool/panels/BasePanel.java | 8 +- .../tool/panels/EventInputPanel.java | 12 +- .../tool/panels/GradingRulesListPanel.java | 10 +- .../tool/panels/GradingRulesPanel.java | 6 +- .../attendance/tool/panels/PrintPanel.java | 2 +- .../tool/panels/StatisticsPanel.java | 9 +- .../util/GradebookItemNameValidator.java | 2 +- 92 files changed, 1326 insertions(+), 2867 deletions(-) rename api/src/java/org/sakaiproject/attendance/{ => api}/export/PDFEventExporter.java (92%) rename api/src/java/org/sakaiproject/attendance/{ => api}/logic/AttendanceLogic.java (86%) rename api/src/java/org/sakaiproject/attendance/{ => api}/logic/SakaiProxy.java (99%) create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/AttendanceEvent.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/AttendanceGrade.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/AttendanceRecord.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/AttendanceSite.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/AttendanceStatus.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/GradingRule.java rename api/src/java/org/sakaiproject/attendance/{ => api}/model/ImportConfirmList.java (91%) rename api/src/java/org/sakaiproject/attendance/{ => api}/model/Status.java (95%) rename api/src/java/org/sakaiproject/attendance/{model => api/model/stats}/AttendanceItemStats.java (78%) rename api/src/java/org/sakaiproject/attendance/{model => api/model/stats}/AttendanceStats.java (64%) rename api/src/java/org/sakaiproject/attendance/{model => api/model/stats}/AttendanceUserStats.java (78%) create mode 100644 api/src/java/org/sakaiproject/attendance/api/model/stats/StatusCount.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/AttendanceEventRepository.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/AttendanceGradeRepository.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/AttendanceRecordRepository.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/AttendanceSiteRepository.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/AttendanceStatusRepository.java create mode 100644 api/src/java/org/sakaiproject/attendance/api/repository/GradingRuleRepository.java rename api/src/java/org/sakaiproject/attendance/{ => api}/util/AttendanceConstants.java (96%) delete mode 100644 api/src/java/org/sakaiproject/attendance/cache/CacheManager.java delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceEvent.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceGrade.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceItemStats.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceRecord.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/hbm/GradingRule.hbm.xml delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceEvent.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceGrade.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceRecord.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceSite.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceStatus.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java delete mode 100644 api/src/java/org/sakaiproject/attendance/model/GradingRule.java delete mode 100644 api/src/java/org/sakaiproject/attendance/types/StatusUserType.java create mode 100644 docs/sql/sakai23-conversion-mysql.sql create mode 100644 docs/sql/sakai23-conversion-oracle.sql delete mode 100644 impl/src/java/org/sakaiproject/attendance/cache/CacheManagerImpl.java delete mode 100644 impl/src/java/org/sakaiproject/attendance/dao/AttendanceDao.java delete mode 100644 impl/src/java/org/sakaiproject/attendance/dao/impl/AttendanceDaoImpl.java rename impl/src/java/org/sakaiproject/attendance/{ => impl}/export/PDFEventExporterImpl.java (87%) rename impl/src/java/org/sakaiproject/attendance/{ => impl}/export/util/SortNameUserComparator.java (94%) rename impl/src/java/org/sakaiproject/attendance/{ => impl}/logic/AttendanceLogicImpl.java (62%) rename impl/src/java/org/sakaiproject/attendance/{ => impl}/logic/SakaiProxyImpl.java (97%) create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceEventRepositoryImpl.java create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceGradeRepositoryImpl.java create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceRecordRepositoryImpl.java create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceSiteRepositoryImpl.java create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceStatusRepositoryImpl.java create mode 100644 impl/src/java/org/sakaiproject/attendance/impl/repository/GradingRuleRepositoryImpl.java delete mode 100644 impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalc.java delete mode 100644 impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalcJob.java diff --git a/README.md b/README.md index 83757780..cfc27e22 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,6 @@ # Attendance A simple [Sakai](https://github.com/sakaiproject/sakai) tool for tracking attendance that integrates with the Gradebook. -## Performance Improvements - MUST READ -With the release of 20170215, statistics are now stored in a table. As such, a job was created to calculate these stats. -This job should be run once after the deployment of 20170215; afterwards it may be run as needed or at regular interval -as determined by the administrators. The job **MUST BE** run at least once to calculate & save the statistics to begin with, afterwards the job is only needed to be run to sync up the stats to the current roster (in -the case of users attending an item and then later leaving the site). This job is titled "Attendance Stat Calc - SEE DOCS". - ## Resources Pages: http://sakaicontrib.github.io/attendance/ diff --git a/api/pom.xml b/api/pom.xml index f8717d90..6df5cebc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -37,10 +37,6 @@ - - org.projectlombok - lombok - org.hibernate hibernate-core @@ -49,6 +45,10 @@ org.apache.commons commons-lang3 + + org.springframework.data + spring-data-jpa + diff --git a/api/src/java/org/sakaiproject/attendance/api/AttendanceGradebookProvider.java b/api/src/java/org/sakaiproject/attendance/api/AttendanceGradebookProvider.java index 058b7e5c..09b4965f 100644 --- a/api/src/java/org/sakaiproject/attendance/api/AttendanceGradebookProvider.java +++ b/api/src/java/org/sakaiproject/attendance/api/AttendanceGradebookProvider.java @@ -16,8 +16,8 @@ package org.sakaiproject.attendance.api; -import org.sakaiproject.attendance.model.AttendanceGrade; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceSite; /** * A Provider which sends grades to the Gradebook diff --git a/api/src/java/org/sakaiproject/attendance/export/PDFEventExporter.java b/api/src/java/org/sakaiproject/attendance/api/export/PDFEventExporter.java similarity index 92% rename from api/src/java/org/sakaiproject/attendance/export/PDFEventExporter.java rename to api/src/java/org/sakaiproject/attendance/api/export/PDFEventExporter.java index 5ba9195f..fc9d5e23 100644 --- a/api/src/java/org/sakaiproject/attendance/export/PDFEventExporter.java +++ b/api/src/java/org/sakaiproject/attendance/api/export/PDFEventExporter.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.sakaiproject.attendance.export; +package org.sakaiproject.attendance.api.export; -import org.sakaiproject.attendance.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceEvent; import org.sakaiproject.user.api.User; import java.io.OutputStream; diff --git a/api/src/java/org/sakaiproject/attendance/logic/AttendanceLogic.java b/api/src/java/org/sakaiproject/attendance/api/logic/AttendanceLogic.java similarity index 86% rename from api/src/java/org/sakaiproject/attendance/logic/AttendanceLogic.java rename to api/src/java/org/sakaiproject/attendance/api/logic/AttendanceLogic.java index 2f72066b..5c62f794 100644 --- a/api/src/java/org/sakaiproject/attendance/logic/AttendanceLogic.java +++ b/api/src/java/org/sakaiproject/attendance/api/logic/AttendanceLogic.java @@ -14,13 +14,16 @@ * limitations under the License. */ -package org.sakaiproject.attendance.logic; +package org.sakaiproject.attendance.api.logic; -import java.io.Serializable; import java.util.List; import java.util.Map; +import java.util.Optional; -import org.sakaiproject.attendance.model.*; +import org.sakaiproject.attendance.api.model.*; +import org.sakaiproject.attendance.api.model.stats.AttendanceItemStats; +import org.sakaiproject.attendance.api.model.stats.AttendanceStats; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; /** * The brains of the operation. @@ -36,7 +39,7 @@ public interface AttendanceLogic { * * @param siteID, sakai Site ID * @return the Attendance Site - */ + */ AttendanceSite getAttendanceSite(String siteID); /** @@ -44,8 +47,8 @@ public interface AttendanceLogic { * * @param aS, the AttendanceSite to update (must not be null) * @return success of the operation - */ - boolean updateAttendanceSite(AttendanceSite aS) throws IllegalArgumentException; + */ + AttendanceSite updateAttendanceSite(AttendanceSite aS) throws IllegalArgumentException; /** * Get's the current AttendanceSite @@ -81,32 +84,31 @@ public interface AttendanceLogic { * * @param e, the AttendanceEvent to add * @return the Long ID of the AttendanceEvent added - */ - Serializable addAttendanceEventNow(AttendanceEvent e); + */ + AttendanceEvent addAttendanceEventNow(AttendanceEvent e); /** * Updates an AttendanceEvent * * @param aE, the event to update (must not be null) * @return success of the operation - */ - boolean updateAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException; + */ + AttendanceEvent updateAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException; /** * Deletes an AttendanceEvent * * @param aE, the event to delete (must not be null) // though this can probably be changed - * @return success of the operation - */ - boolean deleteAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException; + */ + void deleteAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException; /** * Get's an AttendanceRecord by ID * * @param id, the id of the attendanceRecord * @return the attendanceRecord - */ - AttendanceRecord getAttendanceRecord(Long id); + */ + Optional getAttendanceRecord(Long id); /** * get AttendanceRecords For a User in the current site @@ -153,16 +155,16 @@ public interface AttendanceLogic { * * @param id, the id of the AttendanceStatus * @return the AttendanceStatus - */ - AttendanceStatus getAttendanceStatusById(Long id); + */ + Optional getAttendanceStatusById(Long id); /** * Update an AttendanceRecord * * @param aR, the AttendanceRecord to update (must not be null) * @return the success of the operation - */ - boolean updateAttendanceRecord(AttendanceRecord aR, Status oldStatus) throws IllegalArgumentException; + */ + AttendanceRecord updateAttendanceRecord(AttendanceRecord aR, Status oldStatus) throws IllegalArgumentException; /** * Update all AttendanceRecords for an AttendanceEvent @@ -179,7 +181,7 @@ public interface AttendanceLogic { * @param aE, the AttendanceEvent * @param s, the Status to use (if null, use the Site's default status) * @param groupId, only update the AttendanceRecords for members of the groupID (if null or empty calls - * {@link org.sakaiproject.attendance.logic.AttendanceLogic#updateAttendanceRecordsForEvent(AttendanceEvent, Status)}) + * {@link AttendanceLogic#updateAttendanceRecordsForEvent(AttendanceEvent, Status)}) */ void updateAttendanceRecordsForEvent(AttendanceEvent aE, Status s, String groupId); @@ -239,8 +241,8 @@ public interface AttendanceLogic { * * @param id, the ID (must not be null) * @return the AttendanceGrade - */ - AttendanceGrade getAttendanceGrade(Long id) throws IllegalArgumentException; + */ + Optional getAttendanceGrade(Long id) throws IllegalArgumentException; /** * Get's the AttendanceGrade for user in current site @@ -270,8 +272,8 @@ public interface AttendanceLogic { * * @param aG, the AG to update (must not be null) * @return the success of the operation - */ - boolean updateAttendanceGrade(AttendanceGrade aG) throws IllegalArgumentException; + */ + AttendanceGrade updateAttendanceGrade(AttendanceGrade aG) throws IllegalArgumentException; /** * Returns the stats for a specified Status from an AttendanceStats object @@ -287,15 +289,14 @@ public interface AttendanceLogic { * @param gradingRule, The GradingRule to be added. * @return the success of the operation */ - boolean addGradingRule(GradingRule gradingRule); + GradingRule addGradingRule(GradingRule gradingRule); /** * Deletes a grading rule. * * @param gradingRule, The GradingRule to be deleted. - * @return the success of the operation */ - boolean deleteGradingRule(GradingRule gradingRule); + void deleteGradingRule(GradingRule gradingRule); /** * Get a list of Grading Rules that have been created for a given diff --git a/api/src/java/org/sakaiproject/attendance/logic/SakaiProxy.java b/api/src/java/org/sakaiproject/attendance/api/logic/SakaiProxy.java similarity index 99% rename from api/src/java/org/sakaiproject/attendance/logic/SakaiProxy.java rename to api/src/java/org/sakaiproject/attendance/api/logic/SakaiProxy.java index 0521d94a..6d4bafd6 100644 --- a/api/src/java/org/sakaiproject/attendance/logic/SakaiProxy.java +++ b/api/src/java/org/sakaiproject/attendance/api/logic/SakaiProxy.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.logic; +package org.sakaiproject.attendance.api.logic; import org.sakaiproject.user.api.User; diff --git a/api/src/java/org/sakaiproject/attendance/api/model/AttendanceEvent.java b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceEvent.java new file mode 100644 index 00000000..d68a1cf9 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceEvent.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.Type; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + * Represents an AttendanceEvent, such as a class meeting or seminar + * + * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu]) + * @author David Bauer [dbauer1 (at) udayton (dot) edu] + * @author Steve Swinsburg (steve.swinsburg@gmail.com) + */ +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_EVENT_T") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceEvent implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "A_EVENT_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "attendance_event_id_sequence") + @SequenceGenerator(name = "attendance_event_id_sequence", sequenceName = "ATTENDANCE_EVENT_S") + private Long id; + + @Column(name = "NAME") + private String name; + + @Type(type = "org.hibernate.type.InstantType") + @Column(name = "START_DATE_TIME") + private Instant startDateTime; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "A_SITE_ID") + private AttendanceSite attendanceSite; + + @OneToMany(mappedBy = "attendanceEvent", cascade = CascadeType.ALL, orphanRemoval = true) + private Set records = new HashSet<>(0); + + // Copy constructor + public AttendanceEvent(AttendanceEvent attendanceEvent) { + this.name = attendanceEvent.name; + this.startDateTime = attendanceEvent.startDateTime; + this.attendanceSite = attendanceEvent.attendanceSite; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + AttendanceEvent that = (AttendanceEvent) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "(" + + "id = " + id + ", " + + "name = " + name + ", " + + "startDateTime = " + startDateTime + ")"; + } +} diff --git a/api/src/java/org/sakaiproject/attendance/api/model/AttendanceGrade.java b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceGrade.java new file mode 100644 index 00000000..2023a8b4 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceGrade.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +/** + * The AttendanceGrade earned for the all AttendanceItems + * + * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu]au) + * @author Steve Swinsburg (steve.swinsburg@gmail.com) + */ + +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_GRADE_T") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceGrade implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "A_GRADE_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "attendance_grade_id_sequence") + @SequenceGenerator(name = "attendance_grade_id_sequence", sequenceName = "ATTENDANCE_GRADE_S") + private Long id; + + @Column(name = "GRADE") + private Double grade; + + @Column(name = "USER_ID", length = 99) + private String userID; + + @Column(name = "OVERRIDE") + private Boolean override; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "A_SITE_ID") + private AttendanceSite attendanceSite; + + public AttendanceGrade(AttendanceSite aS, String userId) { + this.attendanceSite = aS; + this.userID = userId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + AttendanceGrade that = (AttendanceGrade) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "(" + + "id = " + id + ", " + + "grade = " + grade + ", " + + "userID = " + userID + ", " + + "override = " + override + ")"; + } +} diff --git a/api/src/java/org/sakaiproject/attendance/api/model/AttendanceRecord.java b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceRecord.java new file mode 100644 index 00000000..2ad96b71 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceRecord.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +/** + * An AttendanceRecord for a specific user for a specific AttendanceEvent + * + * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] + * @author David Bauer [dbauer1 (at) udayton (dot) edu] + * @author Steve Swinsburg (steve.swinsburg@gmail.com) + */ +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_RECORD_T", + indexes = { + @Index(name = "ATTEN_EVENT_STATUS_I", columnList = "A_EVENT_ID, STATUS"), + @Index(name = "ATTEN_EVENT_USER_STATUS_I", columnList = "A_EVENT_ID, USER_ID, STATUS") + }) +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceRecord implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "A_RECORD_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "attendance_record_id_sequence") + @SequenceGenerator(name = "attendance_record_id_sequence", sequenceName = "ATTENDANCE_RECORD_S") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "A_EVENT_ID") + private AttendanceEvent attendanceEvent; + + @Column(name = "USER_ID", length = 99) + private String userID; + + @Enumerated(value = EnumType.STRING) + @Column(name = "STATUS", nullable = false, length = 20) + private Status status = Status.UNKNOWN; + + @Lob + @Column(name = "RECORD_COMMENT", length = 4000) + private String comment; + + public AttendanceRecord(AttendanceEvent e, String uId, Status s) { + this.attendanceEvent = e; + this.userID = uId; + this.status = s; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + AttendanceRecord that = (AttendanceRecord) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "(" + + "id = " + id + ", " + + "userID = " + userID + ", " + + "status = " + status + ", " + + "comment = " + comment + ")"; + } +} diff --git a/api/src/java/org/sakaiproject/attendance/api/model/AttendanceSite.java b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceSite.java new file mode 100644 index 00000000..81a368dc --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceSite.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.sakaiproject.attendance.api.util.AttendanceConstants; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + * An AttendanceSite represents all the Attendance related data for a specific Sakai Site. + * + * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] + * @author David Bauer [dbauer1 (at) udayton (dot) edu] + * @author Steve Swinsburg (steve.swinsburg@gmail.com) + */ + +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_SITE_T") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceSite implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "A_SITE_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "attendance_site_id_sequence") + @SequenceGenerator(name = "attendance_site_id_sequence", sequenceName = "ATTENDANCE_SITE_S") + private Long id; + + @Column(name = "SITE_ID", length = 99, nullable = false) + private String siteID; + + @Enumerated(value = EnumType.STRING) + @Column(name = "DEFAULT_STATUS", nullable = false, length = 20) + private Status defaultStatus = Status.UNKNOWN; + + @Column(name = "MAXIMUM_GRADE") + private Double maximumGrade; + + @Column(name = "IS_GRADE_SHOWN") + private Boolean isGradeShown = Boolean.FALSE; + + @Column(name = "SEND_TO_GRADEBOOK") + private Boolean sendToGradebook = Boolean.FALSE; + + @Column(name = "AUTO_GRADING") + private Boolean useAutoGrading = Boolean.FALSE; + + @Column(name = "GRADE_BY_SUBTRACTION") + private Boolean autoGradeBySubtraction = Boolean.TRUE; + + @Column(name = "GRADEBOOK_ITEM_NAME") + private String gradebookItemName; + + @Column(name = "SHOW_COMMENTS") + private Boolean showCommentsToStudents = Boolean.FALSE; + + @OneToMany(mappedBy = "attendanceSite", cascade = CascadeType.ALL, orphanRemoval = true) + private Set attendanceStatuses = new HashSet<>(0); + + public AttendanceSite(String siteID) { + this.siteID = siteID; + this.gradebookItemName = AttendanceConstants.GRADEBOOK_ITEM_NAME; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + AttendanceSite that = (AttendanceSite) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/api/src/java/org/sakaiproject/attendance/api/model/AttendanceStatus.java b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceStatus.java new file mode 100644 index 00000000..d6c4c33b --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/AttendanceStatus.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +/** + * An AttendanceStatus is a wrapper around the Status enum type defining meta information on individual Statuses. + * + * @author David Bauer [dbauer1 (at) udayton (dot) edu] + * @author Steve Swinsburg (steve.swinsburg@gmail.com) + */ +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_STATUS_T") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AttendanceStatus implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "A_STATUS_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "attendance_status_id_sequence") + @SequenceGenerator(name = "attendance_status_id_sequence", sequenceName = "ATTENDANCE_STATUS_S") + private Long id; + + @Column(name = "IS_ACTIVE") + private Boolean isActive = Boolean.TRUE; + + @Enumerated(value = EnumType.STRING) + @Column(name = "STATUS", nullable = false, length = 20) + private Status status; + + @Column(name = "SORT_ORDER") + private int sortOrder; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "A_SITE_ID") + private AttendanceSite attendanceSite; + + // Create a copy constructor + public AttendanceStatus(AttendanceStatus attendanceStatus) { + this.isActive = attendanceStatus.getIsActive(); + this.status = attendanceStatus.getStatus(); + this.sortOrder = attendanceStatus.getSortOrder(); + this.attendanceSite = attendanceStatus.getAttendanceSite(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + AttendanceStatus that = (AttendanceStatus) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/api/src/java/org/sakaiproject/attendance/api/model/GradingRule.java b/api/src/java/org/sakaiproject/attendance/api/model/GradingRule.java new file mode 100644 index 00000000..4de71438 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/GradingRule.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, University of Dayton + * + * Licensed under the Educational Community License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/ecl2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sakaiproject.attendance.api.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.sakaiproject.springframework.data.PersistableEntity; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +/** + * @author David P. Bauer [dbauer1 (at) udayton (dot) edu] + */ +@Entity +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@Table(name = "ATTENDANCE_RULE_T") +@Getter +@Setter +@NoArgsConstructor +public class GradingRule implements Serializable, PersistableEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "GRADING_RULE_ID", length = 19) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "grading_rule_id_sequence") + @SequenceGenerator(name = "grading_rule_id_sequence", sequenceName = "ATTENDANCE_GRADING_RULE_S") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "A_SITE_ID") + private AttendanceSite attendanceSite; + + @Enumerated(value = EnumType.STRING) + @Column(name = "STATUS", nullable = false, length = 20) + private Status status; + + @Column(name = "START_RANGE", nullable = false) + private Integer startRange = 0; + + @Column(name = "END_RANGE") + private Integer endRange; + + @Column(name = "POINTS", nullable = false) + private Double points = 0D; + + public GradingRule(AttendanceSite attendanceSite) { + this.attendanceSite = attendanceSite; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + GradingRule that = (GradingRule) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/api/src/java/org/sakaiproject/attendance/model/ImportConfirmList.java b/api/src/java/org/sakaiproject/attendance/api/model/ImportConfirmList.java similarity index 91% rename from api/src/java/org/sakaiproject/attendance/model/ImportConfirmList.java rename to api/src/java/org/sakaiproject/attendance/api/model/ImportConfirmList.java index cd0f75e4..f0d005a5 100644 --- a/api/src/java/org/sakaiproject/attendance/model/ImportConfirmList.java +++ b/api/src/java/org/sakaiproject/attendance/api/model/ImportConfirmList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.model; +package org.sakaiproject.attendance.api.model; import lombok.AllArgsConstructor; import lombok.Getter; @@ -22,10 +22,7 @@ import lombok.Setter; import java.io.Serializable; -import java.util.Date; -import java.util.HashSet; import java.util.Objects; -import java.util.Set; /** * Holds the records that are being changed by the Import function. @@ -60,7 +57,7 @@ public ImportConfirmList(AttendanceEvent e, String uId, Status newStatus) { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - final org.sakaiproject.attendance.model.ImportConfirmList that = (org.sakaiproject.attendance.model.ImportConfirmList) o; + final ImportConfirmList that = (ImportConfirmList) o; return Objects.equals(id, that.id) && Objects.equals(attendanceEvent, that.attendanceEvent) && Objects.equals(userID, that.userID) && diff --git a/api/src/java/org/sakaiproject/attendance/model/Status.java b/api/src/java/org/sakaiproject/attendance/api/model/Status.java similarity index 95% rename from api/src/java/org/sakaiproject/attendance/model/Status.java rename to api/src/java/org/sakaiproject/attendance/api/model/Status.java index d76dc35d..66cfeb3b 100644 --- a/api/src/java/org/sakaiproject/attendance/model/Status.java +++ b/api/src/java/org/sakaiproject/attendance/api/model/Status.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.model; +package org.sakaiproject.attendance.api.model; /** * The Different Statuses defined within the Tool diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceItemStats.java b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceItemStats.java similarity index 78% rename from api/src/java/org/sakaiproject/attendance/model/AttendanceItemStats.java rename to api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceItemStats.java index 14472696..7913ec15 100644 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceItemStats.java +++ b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceItemStats.java @@ -14,12 +14,15 @@ * limitations under the License. */ -package org.sakaiproject.attendance.model; +package org.sakaiproject.attendance.api.model.stats; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.sakaiproject.attendance.api.model.AttendanceEvent; + +import java.util.List; /** * Created by Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] @@ -38,4 +41,8 @@ public AttendanceItemStats(AttendanceEvent attendanceEvent) { this.attendanceEvent = attendanceEvent; } + public AttendanceItemStats(AttendanceEvent attendanceEvent, List statusCounts) { + this.attendanceEvent = attendanceEvent; + super.setTotalsFromCounts(statusCounts); + } } diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceStats.java b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceStats.java similarity index 64% rename from api/src/java/org/sakaiproject/attendance/model/AttendanceStats.java rename to api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceStats.java index b820e63c..cc2d9be0 100644 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceStats.java +++ b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceStats.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.sakaiproject.attendance.model; +package org.sakaiproject.attendance.api.model.stats; import lombok.Getter; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import java.io.Serializable; +import java.util.List; /** * Created by Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] @@ -27,18 +28,40 @@ @Slf4j @EqualsAndHashCode public class AttendanceStats implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; @Getter - private int present = 0; + private int present = 0; @Getter - private int unexcused = 0; + private int unexcused = 0; @Getter - private int excused = 0; + private int excused = 0; @Getter - private int late = 0; + private int late = 0; @Getter - private int leftEarly = 0; + private int leftEarly = 0; + + void setTotalsFromCounts(List statusCounts) { + for (StatusCount statusCount : statusCounts) { + switch (statusCount.getStatus()) { + case LATE: + this.setLate(statusCount.getTotal().intValue()); + break; + case LEFT_EARLY: + this.setLeftEarly(statusCount.getTotal().intValue()); + break; + case EXCUSED_ABSENCE: + this.setExcused(statusCount.getTotal().intValue()); + break; + case PRESENT: + this.setPresent(statusCount.getTotal().intValue()); + break; + case UNEXCUSED_ABSENCE: + this.setUnexcused((statusCount.getTotal().intValue())); + break; + } + } + } public void setPresent(int present) { if(present < 0) { diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserStats.java b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceUserStats.java similarity index 78% rename from api/src/java/org/sakaiproject/attendance/model/AttendanceUserStats.java rename to api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceUserStats.java index 86b188a1..8c92fc92 100644 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserStats.java +++ b/api/src/java/org/sakaiproject/attendance/api/model/stats/AttendanceUserStats.java @@ -14,12 +14,15 @@ * limitations under the License. */ -package org.sakaiproject.attendance.model; +package org.sakaiproject.attendance.api.model.stats; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.sakaiproject.attendance.api.model.AttendanceSite; + +import java.util.List; /** * Created by Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] @@ -40,4 +43,10 @@ public AttendanceUserStats(String userID, AttendanceSite attendanceSite) { this.attendanceSite = attendanceSite; } + public AttendanceUserStats(String userId, AttendanceSite attendanceSite, List statusCounts) { + this.userID = userId; + this.attendanceSite = attendanceSite; + super.setTotalsFromCounts(statusCounts); + } + } diff --git a/api/src/java/org/sakaiproject/attendance/api/model/stats/StatusCount.java b/api/src/java/org/sakaiproject/attendance/api/model/stats/StatusCount.java new file mode 100644 index 00000000..fd8316e2 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/model/stats/StatusCount.java @@ -0,0 +1,12 @@ +package org.sakaiproject.attendance.api.model.stats; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.sakaiproject.attendance.api.model.Status; + +@AllArgsConstructor +public class StatusCount { + @Getter @Setter private Status status; + @Getter @Setter private Long total; +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceEventRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceEventRepository.java new file mode 100644 index 00000000..7e421094 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceEventRepository.java @@ -0,0 +1,14 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.stats.AttendanceItemStats; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; + +public interface AttendanceEventRepository extends SpringCrudRepository { + + List findAllByAttendanceSite(AttendanceSite attendanceSite); + AttendanceItemStats calculateStatsForEvent(AttendanceEvent event); +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceGradeRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceGradeRepository.java new file mode 100644 index 00000000..d3d46795 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceGradeRepository.java @@ -0,0 +1,14 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; +import java.util.Optional; + +public interface AttendanceGradeRepository extends SpringCrudRepository { + + List findAllByAttendanceSite(AttendanceSite attendanceSite); + Optional findByAttendanceSiteAndUserId(AttendanceSite attendanceSite, String userId); +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceRecordRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceRecordRepository.java new file mode 100644 index 00000000..73f647d8 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceRecordRepository.java @@ -0,0 +1,12 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; + +public interface AttendanceRecordRepository extends SpringCrudRepository { + + List findAllByAttendanceEvent(AttendanceEvent attendanceEvent); +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceSiteRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceSiteRepository.java new file mode 100644 index 00000000..9f3a3675 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceSiteRepository.java @@ -0,0 +1,13 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; + +public interface AttendanceSiteRepository extends SpringCrudRepository { + + AttendanceSite findBySiteId(String siteId); + AttendanceUserStats calculateAttendanceUserStats(String userId, AttendanceSite attendanceSite); +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceStatusRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceStatusRepository.java new file mode 100644 index 00000000..d4290622 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/AttendanceStatusRepository.java @@ -0,0 +1,13 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; + +public interface AttendanceStatusRepository extends SpringCrudRepository { + + List findAllByAttendanceSite(AttendanceSite attendanceSite); + List findAllActiveByAttendanceSite(AttendanceSite attendanceSite); +} diff --git a/api/src/java/org/sakaiproject/attendance/api/repository/GradingRuleRepository.java b/api/src/java/org/sakaiproject/attendance/api/repository/GradingRuleRepository.java new file mode 100644 index 00000000..665a1e26 --- /dev/null +++ b/api/src/java/org/sakaiproject/attendance/api/repository/GradingRuleRepository.java @@ -0,0 +1,12 @@ +package org.sakaiproject.attendance.api.repository; + +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.GradingRule; +import org.sakaiproject.springframework.data.SpringCrudRepository; + +import java.util.List; + +public interface GradingRuleRepository extends SpringCrudRepository { + + List findAllByAttendanceSite(AttendanceSite attendanceSite); +} diff --git a/api/src/java/org/sakaiproject/attendance/util/AttendanceConstants.java b/api/src/java/org/sakaiproject/attendance/api/util/AttendanceConstants.java similarity index 96% rename from api/src/java/org/sakaiproject/attendance/util/AttendanceConstants.java rename to api/src/java/org/sakaiproject/attendance/api/util/AttendanceConstants.java index cc26763e..407f02a6 100644 --- a/api/src/java/org/sakaiproject/attendance/util/AttendanceConstants.java +++ b/api/src/java/org/sakaiproject/attendance/api/util/AttendanceConstants.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.util; +package org.sakaiproject.attendance.api.util; /** * Class to hold constants (defaults, etc) for Attendance. diff --git a/api/src/java/org/sakaiproject/attendance/cache/CacheManager.java b/api/src/java/org/sakaiproject/attendance/cache/CacheManager.java deleted file mode 100644 index 44666c20..00000000 --- a/api/src/java/org/sakaiproject/attendance/cache/CacheManager.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.cache; - -import org.sakaiproject.memory.api.Cache; - -/** - * Created by Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - */ -public interface CacheManager { - Cache createCache(String cacheName); -} diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceEvent.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceEvent.hbm.xml deleted file mode 100644 index 2eef4b95..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceEvent.hbm.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_EVENT_S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceGrade.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceGrade.hbm.xml deleted file mode 100644 index b798a42a..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceGrade.hbm.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_GRADE_S - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceItemStats.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceItemStats.hbm.xml deleted file mode 100644 index cfb4a3f3..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceItemStats.hbm.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - attendanceEvent - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceRecord.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceRecord.hbm.xml deleted file mode 100644 index af612019..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceRecord.hbm.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_RECORD_S - - - - - - - - - - - - - - - - - - diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml deleted file mode 100644 index 8940dfa3..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_SITE_S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :id - ORDER BY id ASC - ]]> - - - - - - - - - - diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml deleted file mode 100644 index 559a872a..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_STATUS_S - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml deleted file mode 100644 index a436a4ef..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_USER_STATS_S - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/java/org/sakaiproject/attendance/hbm/GradingRule.hbm.xml b/api/src/java/org/sakaiproject/attendance/hbm/GradingRule.hbm.xml deleted file mode 100644 index 689b11b2..00000000 --- a/api/src/java/org/sakaiproject/attendance/hbm/GradingRule.hbm.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - ATTENDANCE_GRADING_RULE_S - - - - - - - - - - - - - - - - - diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceEvent.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceEvent.java deleted file mode 100644 index fef9b37b..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceEvent.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.*; - -import java.io.Serializable; -import java.util.*; - -/** - * Represents an AttendanceEvent, such as a class meeting or seminar - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu]) - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(exclude={"records","stats"}) -public class AttendanceEvent implements Serializable { - private static final long serialVersionUID = 1L; - - @Getter @Setter private Long id; - @Getter @Setter private String name; - @Getter @Setter private Date startDateTime; - @Getter @Setter private Date endDateTime; - @Getter @Setter private Boolean isReoccurring; - @Getter @Setter private Long reoccurringID; - @Getter @Setter private Boolean isRequired; - @Getter @Setter private String releasedTo; - @Getter @Setter private AttendanceSite attendanceSite; - @Getter @Setter private String location; - @Getter @Setter private Set records = new HashSet(0); - @Getter @Setter private AttendanceItemStats stats; - - // Copy constructor - public AttendanceEvent(AttendanceEvent attendanceEvent){ - this.name = attendanceEvent.name; - this.startDateTime = attendanceEvent.startDateTime; - this.endDateTime = attendanceEvent.endDateTime; - this.isReoccurring = attendanceEvent.isReoccurring; - this.reoccurringID = attendanceEvent.reoccurringID; - this.isRequired = attendanceEvent.isRequired; - this.releasedTo = attendanceEvent.releasedTo; - this.attendanceSite = attendanceEvent.attendanceSite; - this.location = attendanceEvent.location; - } - -} diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceGrade.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceGrade.java deleted file mode 100644 index 8ec14dbc..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceGrade.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; - -/** - * The AttendanceGrade earned for the all AttendanceItems - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu]au) - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class AttendanceGrade implements Serializable { - private static final long serialVersionUID = 1L; - - private Long id; - private Double grade; - private String userID; - private Boolean override; - - private AttendanceSite attendanceSite; - - public AttendanceGrade(AttendanceSite aS, String userId){ - this.attendanceSite = aS; - this.userID = userId; - } -} diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceRecord.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceRecord.java deleted file mode 100644 index 0541a328..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceRecord.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.*; - -import java.io.Serializable; -import java.util.Objects; - -/** - * An AttendanceRecord for a specific user for a specific AttendanceEvent - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode -public class AttendanceRecord implements Serializable { - private static final long serialVersionUID = 1L; - - @Getter @Setter private Long id; - @Getter @Setter private AttendanceEvent attendanceEvent; - @Getter @Setter private String userID; - @Getter @Setter private Status status; - @Getter @Setter private String comment; - - public AttendanceRecord(AttendanceEvent e, String uId, Status s) { - this.attendanceEvent = e; - this.userID = uId; - this.status = s; - } - -} diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceSite.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceSite.java deleted file mode 100644 index 0383ff17..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceSite.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.*; -import org.sakaiproject.attendance.util.AttendanceConstants; - -import java.io.Serializable; -import java.util.*; - -/** - * An AttendanceSite represents all the Attendance related data for a specific Sakai Site. - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(exclude="attendanceStatuses") -public class AttendanceSite implements Serializable { - private static final long serialVersionUID = 1L; - - @Getter @Setter private Long id; - @Getter @Setter private String siteID; - @Getter @Setter private Status defaultStatus; - @Getter @Setter private Double maximumGrade; - @Getter @Setter private Boolean isGradeShown; - @Setter private Boolean sendToGradebook; - @Setter private Boolean useAutoGrading; - @Setter private Boolean autoGradeBySubtraction; - @Getter @Setter private String gradebookItemName; - @Getter @Setter private Boolean showCommentsToStudents; - @Setter private Boolean isSyncing; - @Getter @Setter private Date syncTime; - @Getter @Setter private Set attendanceStatuses = new HashSet<>(0); - - public AttendanceSite(String siteID){ - this.siteID = siteID; - this.defaultStatus = Status.UNKNOWN; - this.isGradeShown = false; - this.sendToGradebook = false; - this.useAutoGrading = false; - this.autoGradeBySubtraction = true; - this.gradebookItemName = AttendanceConstants.GRADEBOOK_ITEM_NAME; - this.showCommentsToStudents = false; - this.isSyncing = false; - } - - public Boolean getSendToGradebook() { - if(this.sendToGradebook == null) { - return false; - } - - return this.sendToGradebook; - } - - public Boolean getIsSyncing() { - if(this.isSyncing == null) { - return false; - } - - return this.isSyncing; - } - - public Boolean getUseAutoGrading() { - if(this.useAutoGrading == null) { - return false; - } - - return this.useAutoGrading; - } - - public Boolean getAutoGradeBySubtraction() { - if(this.autoGradeBySubtraction == null) { - return true; - } - - return this.autoGradeBySubtraction; - } - -} diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceStatus.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceStatus.java deleted file mode 100644 index 0d5fe6b0..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceStatus.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.io.Serializable; -import java.util.Objects; - -/** - * An AttendanceStatus is a wrapper around the Status enum type defining meta information on individual Statuses. - * - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(of = {"id"}) -public class AttendanceStatus implements Serializable { - private static final long serialVersionUID = 1L; - - @Getter @Setter private Long id; - @Getter @Setter private Boolean isActive; - @Getter @Setter private Status status; - @Getter @Setter private int sortOrder; - @Getter @Setter private AttendanceSite attendanceSite; - - // Create a copy constructor - public AttendanceStatus(AttendanceStatus attendanceStatus) { - this.isActive = attendanceStatus.getIsActive(); - this.status = attendanceStatus.getStatus(); - this.sortOrder = attendanceStatus.getSortOrder(); - this.attendanceSite = attendanceStatus.getAttendanceSite(); - } - -} diff --git a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java b/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java deleted file mode 100644 index 212c8e88..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/AttendanceUserGroupStats.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - -/** - * Created by james on 7/11/17. - */ - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class AttendanceUserGroupStats { - private static final long serialVersionUID = 1L; - - private String userID; - private String groupId; - private AttendanceSite attendanceSite; - - - public AttendanceUserGroupStats(String userID, AttendanceSite attendanceSite) { - this.userID = userID; - this.attendanceSite = attendanceSite; - } - - @Override - public boolean equals (final Object obj) { - if(obj == null) { - return false; - } - - if(obj == this) { - return true; - } - - if(obj.getClass() != getClass()) { - return false; - } - - final AttendanceUserGroupStats other = (AttendanceUserGroupStats) obj; - return new EqualsBuilder() - .appendSuper(super.equals(obj)) - .append(this.userID, other.userID) - .append(this.groupId, other.groupId) - .append(this.attendanceSite, other.attendanceSite) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder() - .appendSuper(super.hashCode()) - .append(this.userID) - .append(this.groupId) - .append(this.attendanceSite.getId()) - .toHashCode(); - } -} diff --git a/api/src/java/org/sakaiproject/attendance/model/GradingRule.java b/api/src/java/org/sakaiproject/attendance/model/GradingRule.java deleted file mode 100644 index 727811c5..00000000 --- a/api/src/java/org/sakaiproject/attendance/model/GradingRule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.model; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -import java.io.Serializable; - -/** - * @author David P. Bauer [dbauer1 (at) udayton (dot) edu] - */ -@Data -@EqualsAndHashCode(of = "id") -@NoArgsConstructor -public class GradingRule implements Serializable { - private static final long serialVersionUID = 1L; - - private Long id; - private AttendanceSite attendanceSite; - private Status status; - private Integer startRange; - private Integer endRange; - private Double points; - - public GradingRule(AttendanceSite attendanceSite) { - this.attendanceSite = attendanceSite; - } - -} diff --git a/api/src/java/org/sakaiproject/attendance/types/StatusUserType.java b/api/src/java/org/sakaiproject/attendance/types/StatusUserType.java deleted file mode 100644 index c991a6c8..00000000 --- a/api/src/java/org/sakaiproject/attendance/types/StatusUserType.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.types; - -import org.sakaiproject.attendance.model.Status; -import org.sakaiproject.springframework.orm.hibernate.EnumUserType; - -/** - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - * @author Duffy Gillman - * Modeled after org.sakaiproject.scheduler.events.hibernate.TriggerEventEnumUserType.java - */ -public class StatusUserType extends EnumUserType { - public StatusUserType(){ - super(Status.class); - } -} diff --git a/docs/sql/sakai23-conversion-mysql.sql b/docs/sql/sakai23-conversion-mysql.sql new file mode 100644 index 00000000..c3ad095d --- /dev/null +++ b/docs/sql/sakai23-conversion-mysql.sql @@ -0,0 +1,27 @@ +ALTER TABLE ATTENDANCE_EVENT_T + DROP END_DATE_TIME, + DROP IS_REOCCURRING, + DROP REOCCURRING_ID, + DROP IS_REQUIRED, + DROP RELEASED_TO, + DROP LOCATION; + +ALTER TABLE ATTENDANCE_GRADE_T CHANGE USER_ID USER_ID VARCHAR(99) NULL DEFAULT NULL; + +DROP TABLE ATTENDANCE_ITEM_STATS_T; + +ALTER TABLE ATTENDANCE_SITE_T CHANGE IS_GRADE_SHOWN IS_GRADE_SHOWN BIT(1) NULL DEFAULT b'0', CHANGE SEND_TO_GRADEBOOK SEND_TO_GRADEBOOK BIT(1) NULL DEFAULT b'0', CHANGE AUTO_GRADING AUTO_GRADING BIT(1) NULL DEFAULT b'0', CHANGE GRADE_BY_SUBTRACTION GRADE_BY_SUBTRACTION BIT(1) NULL DEFAULT b'1', CHANGE SHOW_COMMENTS SHOW_COMMENTS BIT(1) NULL DEFAULT b'0'; + +ALTER TABLE ATTENDANCE_SITE_T + DROP SYNC, + DROP SYNC_TIME; + +ALTER TABLE ATTENDANCE_RULE_T CHANGE START_RANGE START_RANGE INT(11) NOT NULL DEFAULT '0'; + +ALTER TABLE ATTENDANCE_RULE_T CHANGE POINTS POINTS DOUBLE NOT NULL DEFAULT '0'; + +ALTER TABLE ATTENDANCE_STATUS_T CHANGE IS_ACTIVE IS_ACTIVE BIT(1) NULL DEFAULT b'1'; + +ALTER TABLE ATTENDANCE_STATUS_T CHANGE STATUS STATUS VARCHAR(20) NULL DEFAULT NULL; + +DROP TABLE ATTENDANCE_USER_STATS_T; \ No newline at end of file diff --git a/docs/sql/sakai23-conversion-oracle.sql b/docs/sql/sakai23-conversion-oracle.sql new file mode 100644 index 00000000..8a040e03 --- /dev/null +++ b/docs/sql/sakai23-conversion-oracle.sql @@ -0,0 +1,29 @@ +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN END_DATE_TIME; +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN IS_REOCCURRING; +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN REOCCURRING_ID; +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN IS_REQUIRED; +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN RELEASED_TO; +ALTER TABLE ATTENDANCE_EVENT_T DROP COLUMN LOCATION; + +ALTER TABLE ATTENDANCE_GRADE_T MODIFY USER_ID VARCHAR2(99) NULL DEFAULT NULL; + +DROP TABLE ATTENDANCE_ITEM_STATS_T; + +ALTER TABLE ATTENDANCE_SITE_T MODIFY IS_GRADE_SHOWN NUMBER(1) NULL DEFAULT 0; +ALTER TABLE ATTENDANCE_SITE_T MODIFY SEND_TO_GRADEBOOK NUMBER(1,0) NULL DEFAULT 0; +ALTER TABLE ATTENDANCE_SITE_T MODIFY AUTO_GRADING NUMBER(1,0) NULL DEFAULT 0; +ALTER TABLE ATTENDANCE_SITE_T MODIFY GRADE_BY_SUBTRACTION NUMBER(1,0) NULL DEFAULT 1; +ALTER TABLE ATTENDANCE_SITE_T MODIFY SHOW_COMMENTS NUMBER(1,0) NULL DEFAULT 0; + +ALTER TABLE ATTENDANCE_SITE_T DROP COLUMN SYNC; +ALTER TABLE ATTENDANCE_SITE_T DROP COLUMN SYNC_TIME; + +ALTER TABLE ATTENDANCE_RULE_T MODIFY START_RANGE NUMBER(11, 0) NOT NULL DEFAULT '0'; + +ALTER TABLE ATTENDANCE_RULE_T MODIFY POINTS NUMBER(19,4) NOT NULL DEFAULT '0'; + +ALTER TABLE ATTENDANCE_STATUS_T MODIFY IS_ACTIVE NUMBER(1,0) NULL DEFAULT 1; + +ALTER TABLE ATTENDANCE_STATUS_T MODIFY STATUS VARCHAR2(20) NULL DEFAULT NULL; + +DROP TABLE ATTENDANCE_USER_STATS_T; \ No newline at end of file diff --git a/impl/pom.xml b/impl/pom.xml index cb76ee02..2ff34082 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -43,20 +43,24 @@ - org.projectlombok - lombok + org.springframework + spring-core + + + org.springframework.data + spring-data-jpa org.springframework - spring-core + spring-context org.springframework spring-orm - net.sf.ehcache - ehcache-core + org.springframework + spring-tx org.apache.commons @@ -75,21 +79,17 @@ quartz - - org.sakaiproject.kernel - sakai-kernel-api - - - org.sakaiproject.kernel - sakai-component-manager - - + org.sakaiproject.kernel - sakai-kernel-util + sakai-kernel-api - org.sakaiproject.genericdao - generic-dao + org.sakaiproject.kernel + sakai-kernel-util + + + org.sakaiproject.kernel + sakai-component-manager org.sakaiproject.grading diff --git a/impl/src/java/org/sakaiproject/attendance/cache/CacheManagerImpl.java b/impl/src/java/org/sakaiproject/attendance/cache/CacheManagerImpl.java deleted file mode 100644 index 84b15e44..00000000 --- a/impl/src/java/org/sakaiproject/attendance/cache/CacheManagerImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.cache; - -import lombok.Setter; -import org.sakaiproject.memory.api.Cache; -import org.sakaiproject.memory.api.MemoryService; - -/** - * A shell to eventually implement caching - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - */ -public class CacheManagerImpl implements CacheManager { - - /** - * {@inheritDoc} - */ - public Cache createCache(String cacheName) { - return memoryService.newCache(cacheName); - } - - @Setter - private MemoryService memoryService; -} diff --git a/impl/src/java/org/sakaiproject/attendance/dao/AttendanceDao.java b/impl/src/java/org/sakaiproject/attendance/dao/AttendanceDao.java deleted file mode 100644 index e46ad97b..00000000 --- a/impl/src/java/org/sakaiproject/attendance/dao/AttendanceDao.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.dao; - -import org.sakaiproject.attendance.model.*; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -/** - * DAO interface for the Attendance Tool - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -public interface AttendanceDao { - /** - * Get an AttendanceSite - * - * @param siteId, the Sakai SiteID - * @return the AttendanceSite - */ - AttendanceSite getAttendanceSite(String siteId); - - /** - * Return attendanceSite by ID - * @param id, the attendance Site ID - * @return {@link AttendanceSite} - */ - AttendanceSite getAttendanceSite(Long id); - - /** - * Add a new AttendanceSite record to the database - * - * @param as, the AttendanceSite to add - * @return success of the operation - */ - boolean addAttendanceSite(AttendanceSite as); - - /** - * Updates an attendanceSite - * - * @param aS, the AttendanceSite with updated values - * @return success of the operation - */ - boolean updateAttendanceSite(AttendanceSite aS); - - /** - * Gets a single AttendanceEvent from the db - * - * @return the AttendanceEvent, may be null - */ - AttendanceEvent getAttendanceEvent(long id); - - /** - * get all the events by attendanceSite - * - * @param aS, the AttendanceSite - * @return a list of events or empty if no items. - */ - List getAttendanceEventsForSite(AttendanceSite aS); - - /** - * Serializable function used to save an AttendanceEvent as part of the "Take Attendance Now" feature - * - * @param e, the AttendanceEvent - * @return the Long ID of the newly added AttendanceEvent - */ - Serializable addAttendanceEventNow(AttendanceEvent e); - - /** - * Update an AttendanceEvent - * - * @param aE, the AttendanceEvent - * @return success of the operation - */ - boolean updateAttendanceEvent(AttendanceEvent aE); - - /** - * Deletes an AttendanceEvent - * - * @param aE, the AttendanceEvent - * @return success of the operation - */ - boolean deleteAttendanceEvent(AttendanceEvent aE); - - /** - * Get Status Record by ID - * - * @param id, the id of the status record - * @return the status record (may be null if DB operation fails) - */ - AttendanceRecord getStatusRecord(long id); - - /** - * Add an AttendanceRecord - * - * @param aR, the AttendanceRecord to add - * @return true if success, false if not - */ - boolean addAttendanceRecord(AttendanceRecord aR); - - /** - * Updates an AttendanceRecord - * - * @param aR, the AttendanceRecord to update with new values - * @return success of the operation - */ - boolean updateAttendanceRecord(AttendanceRecord aR); - - /** - * Update a set of AttendanceRecords - * - * @param aRs, a List of AttendanceRecords - * @return success of the operation - */ - void updateAttendanceRecords(List aRs); - - /** - * Update a set of AttendanceStatuses - * - * @param attendanceStatusList, a List of AttendanceStatuses - * @return success of the operation - */ - void updateAttendanceStatuses(List attendanceStatusList); - - /** - * Get a list of the active statuses in an Attendance Site - * - * @param attendanceSite, the AttendanceSite - * @return List of Active AttendanceStatuses, null if DB issues - */ - List getActiveStatusesForSite(AttendanceSite attendanceSite); - - /** - * Get a lit of all of the attendance statuses for a site - * - * @param attendanceSite, the AttendanceSite - * @return list of all AttendanceStatuses, null if DB issues - */ - List getAllStatusesForSite(AttendanceSite attendanceSite); - - /** - * Get an attendance status record by its id - * - * @param id, the ID of the AttendanceStatus - * @return the AttendanceStatus (null if DB issues) - */ - AttendanceStatus getAttendanceStatusById(Long id); - - /** - * Get AttendanceGrade by ID - * - * @param id, the AttendanceGrade ID - * @return the AttendanceGrade (null if DB issues) - */ - AttendanceGrade getAttendanceGrade(Long id); - - /** - * Get an AttendanceGrade - * - * @param userID, the userID of owner of Grade - * @param aS, the site the Grade is present in - * @return the AttendanceGrade, null if DB issues - */ - AttendanceGrade getAttendanceGrade(String userID, AttendanceSite aS); - - /** - * Get a list of AttendanceGrades - * - * @param aS, the AttendanceSite to get the AGs for. - * @return List of AttendanceGrades, null if DB issues - */ - List getAttendanceGrades(AttendanceSite aS); - - /** - * Add an AttendanceGrade to DB - * - * @param aG, AttendanceGrade to add - * @return success of operation - */ - boolean addAttendanceGrade(AttendanceGrade aG); - - /** - * Updates an AttendanceGrade - * - * @param aG, the AG to update - * @return success of operation - */ - boolean updateAttendanceGrade(AttendanceGrade aG); - - /** - * Get the AttendanceUserStats for a User and Site - * @param userId - * @param aS - * @return - */ - AttendanceUserStats getAttendanceUserStats(String userId, AttendanceSite aS); - - /** - * Return the AttendanceUserStats for a Site - * @param aS, the AttendanceSite to get UserStats for - * @return a List of {@link AttendanceUserStats} - */ - List getAttendanceUserStatsForSite(AttendanceSite aS); - - /** - * Update the AttendanceUserStats - * @param aUS, the AttendanceUserStats to update - * @return success or failure of the operation - */ - boolean updateAttendanceUserStats(AttendanceUserStats aUS); - - /** - * Get the AttendanceItemStats for an AttendanceEvent - * @param aE, the AttendanceEvent to get the stats for - * @return the AttendanceItemStats, null if DB issue - */ - AttendanceItemStats getAttendanceItemStats(AttendanceEvent aE); - - /** - * Update the AttendanceItemStats - * @param aIS, the AttendanceItemStats to update - * @return success or failure of the operation - */ - boolean updateAttendanceItemStats(AttendanceItemStats aIS); - - /** - * Return a batch of AttendanceSites - * @return a List of AttendanceSite IDs (max 5) - */ - List getAttendanceSiteBatch(Date syncTime, Long lastId); - - /** - * Return a list of all AttendanceSites In Sync - * @return List of IDs - */ - List getAttendanceSitesInSync(); - - /** - * Mark a set of AttendanceSites as currently syncing - * @param ids, a list of IDs to mark - * @return boolean value of success - */ - boolean markAttendanceSiteForSync(List ids, Date syncTime); - - /** - * Returns a list containing all of the grading rules for a given AttendanceSite. - * - * @param attendanceSite, An existing attendance site. - * @return A list of all of the GradingRules for the provided attendance site. - */ - List getGradingRulesForSite(AttendanceSite attendanceSite); - - /** - * Add a new GradingRule. - * - * @param gradingRule, The GradingRule to be added. - * @return The success of the save operation. - */ - boolean addGradingRule(GradingRule gradingRule); - - /** - * Delete an existing GradingRule. - * - * @param gradingRule, The GradingRule to be deleted. - * @return The success of the delete operation. - */ - boolean deleteGradingRule(GradingRule gradingRule); - - // Hibernate Query Constants - String QUERY_GET_ATTENDANCE_EVENT = "getAttendanceEvent"; - String QUERY_GET_ATTENDANCE_EVENTS_FOR_SITE = "getAttendanceEventsForSite"; - String QUERY_GET_ATTENDANCE_EVENTS = "getAttendanceEvents"; - - String QUERY_GET_SITE_BY_SITE_ID = "getSiteBySiteID"; - String QUERY_GET_SITE_BY_ID = "getSiteByID"; - - String QUERY_GET_ATTENDANCE_RECORD = "getAttendanceRecord"; - String QUERY_GET_ATTENDANCE_RECORDS_FOR_ATTENDANCE_EVENT = "getRecordsForAttendanceEvent"; - - String QUERY_GET_ATTENDANCE_STATUS = "getAttendanceStatus"; - String QUERY_GET_ACTIVE_ATTENDANCE_STATUSES_FOR_SITE = "getActiveAttendanceStatusesForSite"; - String QUERY_GET_ALL_ATTENDANCE_STATUSES_FOR_SITE = "getAllAttendanceStatusesForSite"; - - String QUERY_GET_ATTENDANCE_GRADES_FOR_SITE = "getAttendanceGradesForSite"; - String QUERY_GET_ATTENDANCE_GRADE_BY_ID = "getAttendanceGradeByID"; - String QUERY_GET_ATTENDANCE_GRADE = "getAttendanceGrade"; - - String QUERY_GET_ATTENDANCE_USER_STATS = "getAttendanceUserStats"; - String QUERY_GET_ATTENDANCE_USER_STATS_FOR_SITE = "getAttendanceUserStatsForSite"; - String QUERY_GET_ATTENDANCE_ITEM_STATS = "getAttendanceItemStats"; - - // Attendance Sync for Statistics Queries - String QUERY_GET_ATTENDANCE_SITE_BATCH = "getAttendanceSiteBatch"; - String QUERY_GET_ATTENDANCE_SITES_IN_SYNC = "getAttendanceSitesInSync"; - String QUERY_MARK_ATTENDANCE_SITE_IN_SYNC = "markAttendanceSiteForSync"; - - String QUERY_GET_GRADING_RULES_FOR_SITE = "getGradingRulesForSite"; - - // Hibernate Object Fields - String ID = "id"; - String IDS = "ids"; - String USER_ID = "userID"; - String SITE_ID = "siteID"; - String ATTENDANCE_SITE = "attendanceSite"; - String ATTENDANCE_EVENT = "attendanceEvent"; - String SYNC_TIME = "syncTime"; -} diff --git a/impl/src/java/org/sakaiproject/attendance/dao/impl/AttendanceDaoImpl.java b/impl/src/java/org/sakaiproject/attendance/dao/impl/AttendanceDaoImpl.java deleted file mode 100644 index 5591d5c5..00000000 --- a/impl/src/java/org/sakaiproject/attendance/dao/impl/AttendanceDaoImpl.java +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.dao.impl; - -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.query.Query; -import org.hibernate.type.LongType; -import org.hibernate.type.StringType; -import org.sakaiproject.attendance.dao.AttendanceDao; -import org.sakaiproject.attendance.model.*; -import org.springframework.dao.DataAccessException; -import org.springframework.orm.hibernate5.HibernateCallback; -import org.springframework.orm.hibernate5.support.HibernateDaoSupport; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; - -import lombok.extern.slf4j.Slf4j; - -/** - * Implementation of AttendanceDao - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - * @author David Bauer [dbauer1 (at) udayton (dot) edu] - * @author Steve Swinsburg (steve.swinsburg@gmail.com) - */ -@Slf4j -public class AttendanceDaoImpl extends HibernateDaoSupport implements AttendanceDao { - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public AttendanceSite getAttendanceSite(final String siteID) { - if(log.isDebugEnabled()){ - log.debug("getSiteBySite_ID "); - } - - HibernateCallback hcb = new HibernateCallback() { - @Override - public Object doInHibernate(Session session) throws HibernateException { - Query q = session.getNamedQuery(QUERY_GET_SITE_BY_SITE_ID); - q.setParameter(SITE_ID, siteID, new StringType()); - return q.uniqueResult(); - } - }; - - return (AttendanceSite) getHibernateTemplate().execute(hcb); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public AttendanceSite getAttendanceSite(final Long id) { - log.debug("getAttendanceSite by ID: " + id); - - return (AttendanceSite) getByIDHelper(id, QUERY_GET_SITE_BY_ID); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public boolean addAttendanceSite(AttendanceSite aS) { - if(log.isDebugEnabled()) { - log.debug("addAttendanceSite ( " + aS.toString() + ")"); - } - - try { - getHibernateTemplate().save(aS); - return true; - } catch (DataAccessException de) { - log.error("addAttendanceSite failed", de); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceSite(AttendanceSite aS) { - try{ - getHibernateTemplate().saveOrUpdate(aS); - return true; - } catch (DataAccessException e) { - log.error("updateAttendanceSite aS '" + aS.getSiteID() + "' failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public AttendanceEvent getAttendanceEvent(final long id) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceEvent()" + String.valueOf(id)); - } - - return (AttendanceEvent) getByIDHelper(id, QUERY_GET_ATTENDANCE_EVENT); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAttendanceEventsForSite(final AttendanceSite aS) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceEventsForSite(AttendanceSite id)"); - } - - return getEventsForAttendanceSiteHelper(aS); - } - - /** - * {@inheritDoc} - */ - public Serializable addAttendanceEventNow(AttendanceEvent attendanceEvent) { - - if(log.isDebugEnabled()) { - log.debug("addAttendanceEventNow( " + attendanceEvent.toString() + ")"); - } - - try{ - return getHibernateTemplate().save(attendanceEvent); - } catch (DataAccessException de) { - log.error("addAttendanceEventNow failed.", de); - return null; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceEvent(AttendanceEvent aE) { - if(log.isDebugEnabled()) { - log.debug("updateAttendanceEvent aE: " + aE.getName()); - } - - try{ - getHibernateTemplate().saveOrUpdate(aE); - return true; - } catch (DataAccessException e){ - log.error("updateAttendanceEvent failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean deleteAttendanceEvent(AttendanceEvent aE) { - if(log.isDebugEnabled()) { - log.debug("deleteAttendanceEvent aE: " + aE.getName()); - } - - if(aE.getStats() !=null && aE.getStats().getId() == null){ - aE.setStats(null); - } - - try { - getHibernateTemplate().delete(getHibernateTemplate().merge(aE)); - return true; - } catch (DataAccessException e) { - log.error("deleteAttendanceEvent, " + aE.getId() + ", failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - public AttendanceRecord getStatusRecord(final long id) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceRecord()" + String.valueOf(id)); - } - - return (AttendanceRecord) getByIDHelper(id, QUERY_GET_ATTENDANCE_RECORD); - } - - /** - * {@inheritDoc} - */ - public boolean addAttendanceRecord(AttendanceRecord aR) { - if(log.isDebugEnabled()){ - log.debug("addAttendanceRecord sR for User '" + aR.getUserID() + "' event " + aR.getAttendanceEvent().getName() + " with Status " + aR.getStatus().toString()); - } - - try { - getHibernateTemplate().save(aR); - return true; - } catch (DataAccessException de) { - log.error("addAttendanceRecord failed.", de); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceRecord(AttendanceRecord aR) { - try { - getHibernateTemplate().saveOrUpdate(aR); - return true; - } catch (Exception e) { - log.error("update attendanceRecord failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - public void updateAttendanceRecords(List aRs) { - for(AttendanceRecord aR : aRs) { - try { - getHibernateTemplate().saveOrUpdate(aR); - log.debug("save attendanceRecord id: " + aR.getId()); - } catch (Exception e) { - log.error("update attendanceRecords failed.", e); - } - } - } - - /** - * {@inheritDoc} - */ - public void updateAttendanceStatuses(List attendanceStatusList) { - for(AttendanceStatus aS : attendanceStatusList) { - try { - getHibernateTemplate().saveOrUpdate(aS); - log.debug("AttendanceStatus saved, id: " + aS.getId()); - } catch (Exception e) { - log.error("update attendanceStatuses failed.", e); - } - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getActiveStatusesForSite(final AttendanceSite attendanceSite) { - if(log.isDebugEnabled()){ - log.debug("getActiveStatusesForSite(AttendanceSite " + attendanceSite.getSiteID() + " )"); - } - - try { - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ACTIVE_ATTENDANCE_STATUSES_FOR_SITE) - .setParameter(ATTENDANCE_SITE, attendanceSite) - .getResultList()); - } catch (DataAccessException e) { - log.error("getActiveStatusesForSite failed", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAllStatusesForSite(final AttendanceSite attendanceSite) { - if(log.isDebugEnabled()){ - log.debug("getAllStatusesForSite(AttendanceSite attendanceSite)"); - } - - try { - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ALL_ATTENDANCE_STATUSES_FOR_SITE) - .setParameter(ATTENDANCE_SITE, attendanceSite) - .getResultList()); - } catch (DataAccessException e) { - log.error("getAllStatusesForSite failed", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - public AttendanceStatus getAttendanceStatusById(final Long id) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceStatus()" + String.valueOf(id)); - } - - return (AttendanceStatus) getByIDHelper(id, QUERY_GET_ATTENDANCE_STATUS); - } - - /** - * {@inheritDoc} - */ - public AttendanceGrade getAttendanceGrade(final Long id) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceGrade, id: " + id.toString()); - } - - return (AttendanceGrade) getByIDHelper(id, QUERY_GET_ATTENDANCE_GRADE_BY_ID); - } - - /** - * {@inheritDoc} - */ - public AttendanceGrade getAttendanceGrade(final String userID, final AttendanceSite aS) { - if(log.isDebugEnabled()) { - log.debug("getAttendanceGrades for user " + userID + " in site " + aS.getSiteID()); - } - - try{ - return (AttendanceGrade) getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_GRADE) - .setParameter(ATTENDANCE_SITE, aS) - .setParameter(USER_ID, userID) - .uniqueResult()); - } catch (DataAccessException e) { - log.error("Failed to get AttendanceGrade for " + userID + " in " + aS.getSiteID()); - return null; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAttendanceGrades(final AttendanceSite aS) { - if(log.isDebugEnabled()){ - log.debug("getAttendanceGrades for: " + aS.getSiteID()); - } - - try{ - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_GRADES_FOR_SITE) - .setParameter(ATTENDANCE_SITE, aS) - .getResultList()); - } catch (DataAccessException e) { - log.error("DataAccessException getting AttendanceGrades for " + aS.getSiteID() + ". E:", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - public boolean addAttendanceGrade(AttendanceGrade aG) { - if(log.isDebugEnabled()){ - log.debug("addAttendanceGrade for User '" + aG.getUserID() + "' grade " + aG.getGrade() + " for site " + aG.getAttendanceSite().getSiteID()); - } - - try { - getHibernateTemplate().save(aG); - return true; - } catch (DataAccessException de) { - log.error("addAttendanceGrade failed.", de); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceGrade(AttendanceGrade aG) { - if(log.isDebugEnabled()){ - log.debug("updateAttendanceGrade for User '" + aG.getUserID() + "' grade " + aG.getGrade() + " for site " + aG.getAttendanceSite().getSiteID()); - } - - try { - getHibernateTemplate().saveOrUpdate(aG); - return true; - } catch (DataAccessException de) { - log.error("updateAttendanceGrade failed.", de); - return false; - } - } - - /** - * {@inheritDoc} - */ - public AttendanceUserStats getAttendanceUserStats(final String userId, final AttendanceSite aS) { - log.debug("getAttendanceUserStats for User '" + userId + "' and Site: '" + aS.getSiteID() + "'."); - - try{ - return (AttendanceUserStats) getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_USER_STATS) - .setParameter(ATTENDANCE_SITE, aS) - .setParameter(USER_ID, userId) - .uniqueResult()); - } catch (DataAccessException e) { - log.error("DataAccessException getting AttendanceUserStats for User '" + userId + "' and Site: '" + aS.getSiteID() + "'.", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAttendanceUserStatsForSite(final AttendanceSite aS) { - log.debug("getAttendanceUserStatsForSite for site: " + aS.getSiteID()); - - try{ - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_USER_STATS_FOR_SITE) - .setParameter(ATTENDANCE_SITE, aS) - .getResultList()); - } catch (DataAccessException e) { - log.error("DataAccessException getting AttendanceUserStats for Site: " + aS.getSiteID() + ".", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceUserStats(AttendanceUserStats aUS) { - log.debug("updateAttendanceUserStats for User '" + aUS.getUserID() + "' and Site: '" + aUS.getAttendanceSite().getSiteID() + "'."); - - try { - getHibernateTemplate().saveOrUpdate(aUS); - return true; - } catch (DataAccessException e) { - log.error("updateAttendanceUserStats, id: '" + aUS.getId() + "' failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean addGradingRule(GradingRule gradingRule) { - if (log.isDebugEnabled()) { - log.debug("add grading rule to site " + gradingRule.getAttendanceSite().getSiteID() + - " status: " + gradingRule.getStatus() + - " range: " + gradingRule.getStartRange() + - " - " + gradingRule.getEndRange() + - " points: " + gradingRule.getPoints()); - } - try { - getHibernateTemplate().save(gradingRule); - return true; - } catch (DataAccessException dae) { - log.error("addGradingRule failed.", dae); - return false; - } - } - - /** - * {@inheritDoc} - */ - public boolean deleteGradingRule(GradingRule gradingRule) { - log.debug("Delete grading rule from site " + gradingRule.getAttendanceSite().getSiteID() + " grading rule: " + gradingRule.getId()); - - try { - getHibernateTemplate().delete(getHibernateTemplate().merge(gradingRule)); - return true; - } catch (DataAccessException e) { - log.error("deleteGradingRule, " + gradingRule.getId() + ", failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - public AttendanceItemStats getAttendanceItemStats(AttendanceEvent aE) { - log.debug("getAttendanceUserStats for Event '" + aE.getName() + "' and Site: '" + aE.getAttendanceSite().getSiteID() + "'."); - - try{ - return (AttendanceItemStats) getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_ITEM_STATS) - .setParameter(ATTENDANCE_EVENT, aE) - .uniqueResult()); - } catch (DataAccessException e) { - log.error("DataAccessException getting AttendanceItemStats for Event '" + aE.getName() + "' and Site: '" + aE.getAttendanceSite().getSiteID() + "'.", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - public boolean updateAttendanceItemStats(AttendanceItemStats aIS) { - log.debug("updateAttendanceItemStats, '" + aIS.getId() + "', for Event '" + aIS.getAttendanceEvent().getName() + "' and site: '" + aIS.getAttendanceEvent().getAttendanceSite().getSiteID() + "'."); - - try { - getHibernateTemplate().saveOrUpdate(aIS); - return true; - } catch (DataAccessException e) { - log.error("updateAttendanceItemStats, '" + aIS.getId() + "' failed.", e); - return false; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getGradingRulesForSite(AttendanceSite attendanceSite) { - if(log.isDebugEnabled()){ - log.debug("getGradingRulesForSite(AttendanceSite " + attendanceSite.getSiteID() + " )"); - } - - try { - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_GRADING_RULES_FOR_SITE) - .setParameter(ATTENDANCE_SITE, attendanceSite) - .getResultList()); - } catch (DataAccessException e) { - log.error("getGradingRulesForSite failed", e); - return null; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAttendanceSiteBatch(final Date syncTime, final Long lastId) { - final HibernateCallback> hcb = new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query q = session.getNamedQuery(QUERY_GET_ATTENDANCE_SITE_BATCH); - q.setTimestamp(SYNC_TIME, syncTime); - q.setLong(ID, lastId); - q.setMaxResults(5); - return q.list(); - } - }; - - return getHibernateTemplate().execute(hcb); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getAttendanceSitesInSync() { - final HibernateCallback> hcb = new HibernateCallback>() { - @Override - public List doInHibernate(Session session) throws HibernateException { - Query q = session.getNamedQuery(QUERY_GET_ATTENDANCE_SITES_IN_SYNC); - return q.list(); - } - }; - - return getHibernateTemplate().execute(hcb); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public boolean markAttendanceSiteForSync(final List ids, final Date syncTime) { - final HibernateCallback hcb = new HibernateCallback() { - @Override - public Integer doInHibernate(Session session) throws HibernateException { - Query q = session.getNamedQuery(QUERY_MARK_ATTENDANCE_SITE_IN_SYNC); - q.setParameterList(IDS, ids); - q.setTimestamp(SYNC_TIME, syncTime); - return q.executeUpdate(); - } - }; - - return getHibernateTemplate().execute(hcb).equals(ids.size()); - } - - /** - * init - */ - public void init() { - log.debug("AttendanceDaoImpl init()"); - } - - @SuppressWarnings("unchecked") - private List getEventsForAttendanceSiteHelper(final AttendanceSite aS){ - if(log.isDebugEnabled()){ - log.debug("getAttendanceEventsForSiteHelper()"); - } - - try { - return getHibernateTemplate().execute(session -> session - .getNamedQuery(QUERY_GET_ATTENDANCE_EVENTS_FOR_SITE) - .setParameter(ATTENDANCE_SITE, aS) - .getResultList()); - - } catch (DataAccessException e) { - log.error("getEventsForAttendanceSiteHelper failed", e); - return null; - } - } - - // Generic Function to get something by it's ID. - private Object getByIDHelper(final long id, final String queryString) { - if(log.isDebugEnabled()) { - log.debug("getByIDHelper() id: '" + String.valueOf(id) + "' String: " + queryString); - } - - try { - return getHibernateTemplate().execute(session -> session - .getNamedQuery(queryString) - .setParameter(ID, id, new LongType()) - .setMaxResults(1) - .uniqueResult()); - - } catch (DataAccessException e) { - log.error("getByIDHelper for " + queryString + " failed", e); - return null; - } - } - -} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/AttendanceGradebookProviderImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/AttendanceGradebookProviderImpl.java index 2833deba..89fbf99b 100644 --- a/impl/src/java/org/sakaiproject/attendance/impl/AttendanceGradebookProviderImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/AttendanceGradebookProviderImpl.java @@ -19,15 +19,14 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.sakaiproject.attendance.api.AttendanceGradebookProvider; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.AttendanceGrade; -import org.sakaiproject.attendance.model.AttendanceSite; -import org.sakaiproject.attendance.util.AttendanceConstants; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.util.AttendanceConstants; import org.sakaiproject.grading.api.AssessmentNotFoundException; import org.sakaiproject.grading.api.ConflictingAssignmentNameException; import org.sakaiproject.grading.api.GradingService; -import org.sakaiproject.tool.api.Tool; import org.sakaiproject.tool.api.ToolManager; import java.util.Map; diff --git a/impl/src/java/org/sakaiproject/attendance/export/PDFEventExporterImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/export/PDFEventExporterImpl.java similarity index 87% rename from impl/src/java/org/sakaiproject/attendance/export/PDFEventExporterImpl.java rename to impl/src/java/org/sakaiproject/attendance/impl/export/PDFEventExporterImpl.java index 1d48c3d8..062b4837 100644 --- a/impl/src/java/org/sakaiproject/attendance/export/PDFEventExporterImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/export/PDFEventExporterImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.export; +package org.sakaiproject.attendance.impl.export; import com.lowagie.text.*; import com.lowagie.text.pdf.PdfPCell; @@ -22,23 +22,26 @@ import com.lowagie.text.pdf.PdfWriter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.sakaiproject.attendance.export.util.SortNameUserComparator; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.export.PDFEventExporter; +import org.sakaiproject.attendance.impl.export.util.SortNameUserComparator; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; +import org.sakaiproject.time.api.UserTimeService; import org.sakaiproject.user.api.User; import java.awt.Color; import java.io.OutputStream; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.util.Collections; -import java.util.Date; import java.util.List; /** - * Implementation of PDFEventExporter, {@link org.sakaiproject.attendance.export.PDFEventExporter} + * Implementation of PDFEventExporter, {@link PDFEventExporter} * * @author David Bauer [dbauer1 (at) udayton (dot) edu] */ @@ -84,10 +87,10 @@ public void createAttendanceSheetPdf(AttendanceEvent event, OutputStream outputS private void buildDocumentShell(OutputStream outputStream, boolean isSignInSheet) { String eventName = event.getName(); - Date eventDate = event.getStartDateTime(); + Instant eventDate = event.getStartDateTime(); - - SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, MMM d, yyyy h:mm a"); + DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT) + .withZone(userTimeService.getLocalTimeZone().toZoneId()); try { PdfWriter.getInstance(document, outputStream); @@ -101,7 +104,7 @@ private void buildDocumentShell(OutputStream outputStream, boolean isSignInSheet document.add(title); - String eventDateString = eventDate==null?"":" (" + dateFormat.format(eventDate) + ")"; + String eventDateString = eventDate==null?"":" (" + formatter.format(eventDate) + ")"; Paragraph eventHeader = new Paragraph(eventName + eventDateString, h3); eventHeader.setSpacingBefore(14); @@ -250,4 +253,7 @@ private String getStatusString(Status s, int numStatuses) { @Setter private AttendanceLogic attendanceLogic; + @Setter + private UserTimeService userTimeService; + } diff --git a/impl/src/java/org/sakaiproject/attendance/export/util/SortNameUserComparator.java b/impl/src/java/org/sakaiproject/attendance/impl/export/util/SortNameUserComparator.java similarity index 94% rename from impl/src/java/org/sakaiproject/attendance/export/util/SortNameUserComparator.java rename to impl/src/java/org/sakaiproject/attendance/impl/export/util/SortNameUserComparator.java index cf7cc9e3..ab888f28 100644 --- a/impl/src/java/org/sakaiproject/attendance/export/util/SortNameUserComparator.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/export/util/SortNameUserComparator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.sakaiproject.attendance.export.util; +package org.sakaiproject.attendance.impl.export.util; import org.sakaiproject.user.api.User; import java.util.Comparator; diff --git a/impl/src/java/org/sakaiproject/attendance/logic/AttendanceLogicImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java similarity index 62% rename from impl/src/java/org/sakaiproject/attendance/logic/AttendanceLogicImpl.java rename to impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java index 55a34908..cc0badfd 100644 --- a/impl/src/java/org/sakaiproject/attendance/logic/AttendanceLogicImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java @@ -14,18 +14,23 @@ * limitations under the License. */ -package org.sakaiproject.attendance.logic; +package org.sakaiproject.attendance.impl.logic; -import java.io.Serializable; import java.util.*; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.sakaiproject.attendance.api.AttendanceGradebookProvider; -import org.sakaiproject.attendance.dao.AttendanceDao; -import org.sakaiproject.attendance.model.*; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; +import org.sakaiproject.attendance.api.model.*; +import org.sakaiproject.attendance.api.model.stats.AttendanceItemStats; +import org.sakaiproject.attendance.api.model.stats.AttendanceStats; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; +import org.sakaiproject.attendance.api.repository.*; import org.sakaiproject.user.api.User; /** @@ -36,43 +41,53 @@ * @author Steve Swinsburg (steve.swinsburg@gmail.com) */ @Slf4j +@Setter public class AttendanceLogicImpl implements AttendanceLogic { + + private AttendanceEventRepository attendanceEventRepository; + + private AttendanceGradeRepository attendanceGradeRepository; + + private AttendanceRecordRepository attendanceRecordRepository; + + private AttendanceSiteRepository attendanceSiteRepository; + + private AttendanceStatusRepository attendanceStatusRepository; + + private GradingRuleRepository gradingRuleRepository; + + private SakaiProxy sakaiProxy; + + private AttendanceGradebookProvider attendanceGradebookProvider; + /** * {@inheritDoc} - */ + */ public AttendanceSite getAttendanceSite(String siteID) { - return dao.getAttendanceSite(siteID); + return attendanceSiteRepository.findBySiteId(siteID); } /** * {@inheritDoc} */ - public boolean updateAttendanceSite(AttendanceSite aS) throws IllegalArgumentException { + public AttendanceSite updateAttendanceSite(AttendanceSite aS) throws IllegalArgumentException { if(aS == null) { throw new IllegalArgumentException("AttendanceSite must not be null"); } - - return dao.updateAttendanceSite(aS); + return attendanceSiteRepository.save(aS); } /** * {@inheritDoc} */ public AttendanceSite getCurrentAttendanceSite() { - String currentSiteID = sakaiProxy.getCurrentSiteId(); + final String currentSiteID = sakaiProxy.getCurrentSiteId(); AttendanceSite currentAttendanceSite = getAttendanceSite(currentSiteID); - // is this the best way to do this? - if(currentAttendanceSite == null) { - currentAttendanceSite = new AttendanceSite(currentSiteID); - if(!addSite(currentAttendanceSite)){ - return null; - } + if (currentAttendanceSite == null) { + currentAttendanceSite = addSite(new AttendanceSite(currentSiteID)); } - generateMissingAttendanceStatusesForSite(currentAttendanceSite); - currentAttendanceSite = getAttendanceSite(currentSiteID); - return currentAttendanceSite; } @@ -80,73 +95,60 @@ public AttendanceSite getCurrentAttendanceSite() { * {@inheritDoc} */ public AttendanceEvent getAttendanceEvent(long id) { - return dao.getAttendanceEvent(id); + return attendanceEventRepository.findById(id).orElseThrow( + () -> new IllegalArgumentException("No event for id " + id) + ); } /** * {@inheritDoc} */ public List getAttendanceEventsForSite(AttendanceSite aS) { - return safeAttendanceEventListReturn(dao.getAttendanceEventsForSite(aS)); + return attendanceEventRepository.findAllByAttendanceSite(aS); } /** * {@inheritDoc} */ public List getAttendanceEventsForCurrentSite(){ - return getAttendanceEventsForSite(getCurrentAttendanceSite()); + return attendanceEventRepository.findAllByAttendanceSite(getCurrentAttendanceSite()); } /** * {@inheritDoc} */ - public Serializable addAttendanceEventNow(AttendanceEvent e) { - return dao.addAttendanceEventNow(e); + public AttendanceEvent addAttendanceEventNow(AttendanceEvent e) { + return attendanceEventRepository.save(e); } /** * {@inheritDoc} */ - public boolean updateAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException { + public AttendanceEvent updateAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException { if(aE == null) { throw new IllegalArgumentException("AttendanceEvent is null"); } - - return dao.updateAttendanceEvent(aE); + return attendanceEventRepository.save(aE); } /** * {@inheritDoc} */ - public boolean deleteAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException { + public void deleteAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentException { if(aE == null) { throw new IllegalArgumentException("AttendanceEvent is null"); } - - Set records = aE.getRecords(); - AttendanceSite site = aE.getAttendanceSite(); - for(AttendanceRecord record : records) { - AttendanceUserStats userStats = dao.getAttendanceUserStats(record.getUserID(), site); - if(userStats != null) { - Status recordStatus = record.getStatus(); - removeStatusFromStats(userStats, recordStatus); - - dao.updateAttendanceUserStats(userStats); - } - } - - return dao.deleteAttendanceEvent(aE); + attendanceEventRepository.delete(aE); } /** * {@inheritDoc} */ - public AttendanceRecord getAttendanceRecord(Long id) { + public Optional getAttendanceRecord(Long id) { if(id == null) { - return null; + return Optional.empty(); } - - return dao.getStatusRecord(id); + return attendanceRecordRepository.findById(id); } /** @@ -174,34 +176,32 @@ public List getActiveStatusesForCurrentSite() { * {@inheritDoc} */ public List getActiveStatusesForSite(AttendanceSite attendanceSite) { - return safeAttendanceStatusListReturn(dao.getActiveStatusesForSite(attendanceSite)); + return attendanceStatusRepository.findAllActiveByAttendanceSite(attendanceSite); } /** * {@inheritDoc} */ public List getAllStatusesForSite(AttendanceSite attendanceSite) { - return safeAttendanceStatusListReturn(dao.getAllStatusesForSite(attendanceSite)); + return attendanceStatusRepository.findAllByAttendanceSite(attendanceSite); } /** * {@inheritDoc} */ - public AttendanceStatus getAttendanceStatusById(Long id) { - return dao.getAttendanceStatusById(id); + public Optional getAttendanceStatusById(Long id) { + return attendanceStatusRepository.findById(id); } /** * {@inheritDoc} */ - public boolean updateAttendanceRecord(AttendanceRecord aR, Status oldStatus) throws IllegalArgumentException { + public AttendanceRecord updateAttendanceRecord(AttendanceRecord aR, Status oldStatus) throws IllegalArgumentException { if(aR == null) { throw new IllegalArgumentException("AttendanceRecord cannot be null"); } - - updateStats(aR, oldStatus); regradeForAttendanceRecord(aR); - return dao.updateAttendanceRecord(aR); + return attendanceRecordRepository.save(aR); } /** @@ -210,18 +210,12 @@ public boolean updateAttendanceRecord(AttendanceRecord aR, Status oldStatus) thr public List updateAttendanceRecordsForEvent(AttendanceEvent aE, Status s) { aE = getAttendanceEvent(aE.getId()); List records = new ArrayList<>(aE.getRecords()); - if(records.isEmpty()) { return generateAttendanceRecords(aE, s); } - - Status oldStatus; for(AttendanceRecord aR : records) { - oldStatus = aR.getStatus(); aR.setStatus(s); - updateStats(aR, oldStatus); } - return records; } @@ -232,7 +226,6 @@ public void updateAttendanceRecordsForEvent(AttendanceEvent aE, Status s, String aE = getAttendanceEvent(aE.getId()); //why are we getting this as a new event when it's a parameter passed in already? List allRecords = new ArrayList<>(aE.getRecords()); List recordsToUpdate = new ArrayList<>(); - if(allRecords.isEmpty()) { allRecords = generateAttendanceRecords(aE, null); } else { @@ -240,7 +233,6 @@ public void updateAttendanceRecordsForEvent(AttendanceEvent aE, Status s, String allRecords.forEach(record -> ids.remove(record.getUserID())); allRecords.addAll(updateMissingRecordsForEvent(aE, null, ids)); } - if(groupId == null || groupId.isEmpty()) { recordsToUpdate.addAll(allRecords); } else { @@ -254,48 +246,11 @@ public void updateAttendanceRecordsForEvent(AttendanceEvent aE, Status s, String } } } - - Status oldStatus; - int present =0, unexcused =0, excused =0, late=0, leftEarly =0; for(AttendanceRecord aR : recordsToUpdate) { - oldStatus = aR.getStatus(); - if (oldStatus == Status.PRESENT) { - present++; - } else if (oldStatus == Status.UNEXCUSED_ABSENCE) { - unexcused++; - } else if (oldStatus == Status.EXCUSED_ABSENCE) { - excused++; - } else if (oldStatus == Status.LATE) { - late++; - } else if (oldStatus == Status.LEFT_EARLY ) { - leftEarly++; - } aR.setStatus(s); - updateUserStats(aR, oldStatus); regradeForAttendanceRecord(aR); - dao.updateAttendanceRecord(aR); //change the actual data for the student we've just iterated past. This saves looping through it again as part of dao.updateAttendanceRecords on a whole array. } - - AttendanceItemStats itemStats = getStatsForEvent(aE); - itemStats.setPresent(itemStats.getPresent() - present); - itemStats.setUnexcused(itemStats.getUnexcused() - unexcused); - itemStats.setExcused(itemStats.getExcused() - excused); - itemStats.setLate(itemStats.getLate() - late); - itemStats.setLeftEarly(itemStats.getLeftEarly() - leftEarly); - - if (s == Status.PRESENT) { - itemStats.setPresent(itemStats.getPresent()+ recordsToUpdate.size()); - } else if (s == Status.UNEXCUSED_ABSENCE) { - itemStats.setUnexcused(itemStats.getUnexcused() + recordsToUpdate.size()); - } else if (s == Status.EXCUSED_ABSENCE) { - itemStats.setExcused(itemStats.getExcused() + recordsToUpdate.size()); - } else if (s == Status.LATE) { - itemStats.setLate(itemStats.getLate() + recordsToUpdate.size()); - } else if (s == Status.LEFT_EARLY) { - itemStats.setLeftEarly(itemStats.getLeftEarly() + recordsToUpdate.size()); - } - - dao.updateAttendanceItemStats(itemStats); + attendanceRecordRepository.saveAll(recordsToUpdate); } /** @@ -327,14 +282,7 @@ public List updateMissingRecordsForEvent(AttendanceEvent atten * {@inheritDoc} */ public AttendanceItemStats getStatsForEvent(AttendanceEvent event) { - AttendanceItemStats itemStats = dao.getAttendanceItemStats(event); - - if(itemStats == null) { - itemStats = new AttendanceItemStats(event); - } - event.setStats(itemStats); - - return itemStats; + return attendanceEventRepository.calculateStatsForEvent(event); } /** @@ -348,13 +296,7 @@ public AttendanceUserStats getStatsForUser(String userId) { * {@inheritDoc} */ public AttendanceUserStats getStatsForUser(String userId, AttendanceSite aS) { - AttendanceUserStats userStats = dao.getAttendanceUserStats(userId, aS); - - if(userStats == null) { - userStats = new AttendanceUserStats(userId, aS); - } - - return userStats; + return attendanceSiteRepository.calculateAttendanceUserStats(userId, aS); } /** @@ -368,67 +310,40 @@ public List getUserStatsForCurrentSite(String group) { * {@inheritDoc} */ public List getUserStatsForSite(AttendanceSite aS, String group) { - List userStatsList = dao.getAttendanceUserStatsForSite(aS); List users; if(group == null || group.isEmpty()) { users = sakaiProxy.getCurrentSiteMembershipIds(); } else { users = sakaiProxy.getGroupMembershipIds(aS.getSiteID(), group); } - List missingUsers = new ArrayList<>(); List returnList = new ArrayList<>(users.size()); - - if(userStatsList != null && !userStatsList.isEmpty()) { - users.forEach(user -> { - boolean found = false; - for(AttendanceUserStats userStat : userStatsList) { - if(user.equals(userStat.getUserID())) { - found = true; - returnList.add(userStat); - } - } - if(!found) { - missingUsers.add(user); - } - }); - } else { - missingUsers.addAll(users); - } - - if (!missingUsers.isEmpty()) { - missingUsers.forEach(user -> returnList.add(new AttendanceUserStats(user, aS))); - } - + users.forEach(user -> { + returnList.add(attendanceSiteRepository.calculateAttendanceUserStats(user, aS)); + }); return returnList; } /** * {@inheritDoc} */ - public AttendanceGrade getAttendanceGrade(Long id) throws IllegalArgumentException { + public Optional getAttendanceGrade(Long id) throws IllegalArgumentException { if(id == null) { throw new IllegalArgumentException("ID must not be null"); } - - return dao.getAttendanceGrade(id); + return attendanceGradeRepository.findById(id); } /** * {@inheritDoc} */ - public AttendanceGrade getAttendanceGrade(String uID) throws IllegalArgumentException { - if(uID == null || uID.isEmpty()) { + public AttendanceGrade getAttendanceGrade(String userId) throws IllegalArgumentException { + if(StringUtils.isBlank(userId)) { throw new IllegalArgumentException("uID must not be null or empty."); } - final AttendanceSite currentSite = getCurrentAttendanceSite(); - final AttendanceGrade grade = dao.getAttendanceGrade(uID, currentSite); - - if(grade == null) { - return new AttendanceGrade(currentSite, uID); - } - - return grade; + return attendanceGradeRepository.findByAttendanceSiteAndUserId(currentSite, userId).orElse( + new AttendanceGrade(currentSite, userId) + ); } /** @@ -437,7 +352,7 @@ public AttendanceGrade getAttendanceGrade(String uID) throws IllegalArgumentExce public Map getAttendanceGrades() { Map aGHashMap = new HashMap<>(); AttendanceSite aS = getCurrentAttendanceSite(); - List aGs = dao.getAttendanceGrades(aS); + List aGs = attendanceGradeRepository.findAllByAttendanceSite(aS); if(aGs == null || aGs.isEmpty()) { aGs = generateAttendanceGrades(aS); } else { @@ -481,18 +396,19 @@ public Map getAttendanceGradeScores() { /** * {@inheritDoc} */ - public boolean updateAttendanceGrade(AttendanceGrade aG) throws IllegalArgumentException { + public AttendanceGrade updateAttendanceGrade(AttendanceGrade aG) throws IllegalArgumentException { if(aG == null) { throw new IllegalArgumentException("AttendanceGrade cannot be null"); } - boolean saved = dao.updateAttendanceGrade(aG); + AttendanceGrade savedGrade = attendanceGradeRepository.save(aG); - if(saved && aG.getAttendanceSite().getSendToGradebook()) { - return attendanceGradebookProvider.sendToGradebook(aG); + if(aG.getAttendanceSite().getSendToGradebook()) { + if (!attendanceGradebookProvider.sendToGradebook(aG)) { + log.warn("Unable to send attendance grade to the Gradebook in site " + aG.getAttendanceSite().getSiteID()); + } } - - return saved; + return savedGrade; } /** @@ -519,22 +435,22 @@ public int getStatsForStatus(AttendanceStats stats, Status status) { /** * {@inheritDoc} */ - public boolean addGradingRule(GradingRule gradingRule) { - return gradingRule != null && dao.addGradingRule(gradingRule); + public GradingRule addGradingRule(GradingRule gradingRule) { + return gradingRuleRepository.save(gradingRule); } /** * {@inheritDoc} */ - public boolean deleteGradingRule(GradingRule gradingRule) { - return gradingRule != null && dao.deleteGradingRule(gradingRule); + public void deleteGradingRule(GradingRule gradingRule) { + gradingRuleRepository.delete(gradingRule); } /** * {@inheritDoc} */ public List getGradingRulesForSite(AttendanceSite attendanceSite) { - return dao.getGradingRulesForSite(attendanceSite); + return gradingRuleRepository.findAllByAttendanceSite(attendanceSite); } /** @@ -565,15 +481,8 @@ public Double regrade(AttendanceGrade attendanceGrade, boolean saveGrade) { return grade; } - /** - * init - perform any actions required here for when this bean starts up - */ - public void init() { - log.debug("AttendanceLogicImpl init()"); - } - - private boolean addSite(AttendanceSite s) { - return dao.addAttendanceSite(s); + private AttendanceSite addSite(AttendanceSite s) { + return attendanceSiteRepository.save(s); } private List generateAttendanceGrades(AttendanceSite aS) { @@ -675,7 +584,7 @@ private void generateMissingAttendanceStatusesForSite(AttendanceSite attendanceS } } - dao.updateAttendanceStatuses(statusesToBeAdded); + attendanceStatusRepository.saveAll(statusesToBeAdded); } private int getNextSortOrder(List attendanceStatusList) { @@ -690,92 +599,6 @@ private int getNextSortOrder(List attendanceStatusList) { return maxSortOrder + 1; } - private List safeAttendanceEventListReturn(List l) { - if(l == null) { - return new ArrayList<>(); - } - - return l; - } - - private List safeAttendanceStatusListReturn(List l) { - if(l == null) { - return new ArrayList<>(); - } - - return l; - } - - private void updateStats(AttendanceRecord aR, Status oldStatus) { - if(aR.getStatus() == oldStatus) { - return; - } - - updateUserStats(aR, oldStatus); - - AttendanceEvent aE = aR.getAttendanceEvent(); - AttendanceItemStats itemStats = getStatsForEvent(aE); - updateStats(null, itemStats, oldStatus, aR.getStatus()); - } - - private boolean updateUserStats(AttendanceRecord record, Status oldStatus) { - AttendanceUserStats userStats = dao.getAttendanceUserStats(record.getUserID(), record.getAttendanceEvent().getAttendanceSite()); - if(userStats == null) { // assume null userStats means stats haven't been calculated yet - userStats = new AttendanceUserStats(record.getUserID(), record.getAttendanceEvent().getAttendanceSite()); - } - return updateStats(userStats, null, oldStatus, record.getStatus()); - } - - private boolean updateStats(AttendanceUserStats userStats, AttendanceItemStats itemStats, Status oldStatus, Status newStatus) { - AttendanceStats stats; - if(userStats != null) { - stats = userStats; - } else { - stats = itemStats; - } - - if(oldStatus != newStatus) { - removeStatusFromStats(stats, oldStatus); - - if (newStatus == Status.PRESENT) { - stats.setPresent(stats.getPresent() + 1); - } else if (newStatus == Status.UNEXCUSED_ABSENCE) { - stats.setUnexcused(stats.getUnexcused() + 1); - } else if (newStatus == Status.EXCUSED_ABSENCE) { - stats.setExcused(stats.getExcused() + 1); - } else if (newStatus == Status.LATE) { - stats.setLate(stats.getLate() + 1); - } else if (newStatus == Status.LEFT_EARLY) { - stats.setLeftEarly(stats.getLeftEarly() + 1); - } - } - - boolean returnVariable; - if(userStats != null) { - returnVariable = dao.updateAttendanceUserStats((AttendanceUserStats) stats); - } else { - returnVariable = dao.updateAttendanceItemStats((AttendanceItemStats) stats); - } - - return returnVariable; - } - - private void removeStatusFromStats(AttendanceStats stats, Status status) { - if (status != Status.UNKNOWN) { - if (status == Status.PRESENT) { - stats.setPresent(stats.getPresent() - 1); - } else if (status == Status.UNEXCUSED_ABSENCE) { - stats.setUnexcused(stats.getUnexcused() - 1); - } else if (status == Status.EXCUSED_ABSENCE) { - stats.setExcused(stats.getExcused() - 1); - } else if (status == Status.LATE) { - stats.setLate(stats.getLate() - 1); - } else if (status == Status.LEFT_EARLY) { - stats.setLeftEarly(stats.getLeftEarly() - 1); - } - } - } - private void regradeForAttendanceRecord(AttendanceRecord attendanceRecord) { final AttendanceSite currentSite = getCurrentAttendanceSite(); // Auto grade if valid record, maximum points is set, and auto grade is enabled @@ -795,7 +618,7 @@ private Double grade(String userId, AttendanceSite attendanceSite) { final List rules = getGradingRulesForSite(attendanceSite); final AttendanceUserStats userStats = getStatsForUser(userId); - Double totalPoints = 0D; + double totalPoints = 0D; Double maximumGrade = attendanceSite.getMaximumGrade(); if (attendanceSite.getAutoGradeBySubtraction() && maximumGrade != null) { totalPoints = maximumGrade; @@ -828,19 +651,6 @@ private Double grade(String userId, AttendanceSite attendanceSite) { } // Don't allow negative total points - if (totalPoints < 0D) { - return 0D; - } else { - return totalPoints; - } + return Math.max(totalPoints, 0D); } - - @Setter - private AttendanceDao dao; - - @Setter - private SakaiProxy sakaiProxy; - - @Setter - private AttendanceGradebookProvider attendanceGradebookProvider; } diff --git a/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/logic/SakaiProxyImpl.java similarity index 97% rename from impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java rename to impl/src/java/org/sakaiproject/attendance/impl/logic/SakaiProxyImpl.java index 9cf9a53d..1ce762f1 100644 --- a/impl/src/java/org/sakaiproject/attendance/logic/SakaiProxyImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/logic/SakaiProxyImpl.java @@ -14,30 +14,25 @@ * limitations under the License. */ -package org.sakaiproject.attendance.logic; +package org.sakaiproject.attendance.impl.logic; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.sakaiproject.attendance.api.logic.SakaiProxy; import org.sakaiproject.authz.api.*; import org.sakaiproject.component.api.ServerConfigurationService; -import org.sakaiproject.entity.api.ResourceProperties; -import org.sakaiproject.entity.api.ResourcePropertiesEdit; import org.sakaiproject.event.api.EventTrackingService; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SiteService; -import org.sakaiproject.time.api.Time; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.api.SessionManager; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.user.api.*; -import org.sakaiproject.util.ResourceLoader; -import org.w3c.dom.Document; -import org.w3c.dom.Element; import java.util.*; diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceEventRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceEventRepositoryImpl.java new file mode 100644 index 00000000..7e1062f7 --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceEventRepositoryImpl.java @@ -0,0 +1,40 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.stats.AttendanceItemStats; +import org.sakaiproject.attendance.api.model.stats.StatusCount; +import org.sakaiproject.attendance.api.repository.AttendanceEventRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.Query; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class AttendanceEventRepositoryImpl extends SpringCrudRepositoryImpl implements AttendanceEventRepository { + + @Transactional(readOnly = true) + public List findAllByAttendanceSite(AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceEvent.class); + Root event = query.from(AttendanceEvent.class); + query.where(cb.equal(event.get("attendanceSite"), attendanceSite)); + + return session.createQuery(query).list(); + } + + @Transactional(readOnly = true) + public AttendanceItemStats calculateStatsForEvent(AttendanceEvent event) { + Session session = sessionFactory.getCurrentSession(); + Query query = session.createQuery("SELECT new org.sakaiproject.attendance.api.model.stats.StatusCount(r.status, COUNT(r.status)) " + + "FROM AttendanceRecord AS r WHERE r.attendanceEvent = :attendanceEvent GROUP BY r.status"); + query.setParameter("attendanceEvent", event); + List statusCounts = query.getResultList(); + return new AttendanceItemStats(event, statusCounts); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceGradeRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceGradeRepositoryImpl.java new file mode 100644 index 00000000..652c078b --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceGradeRepositoryImpl.java @@ -0,0 +1,40 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.repository.AttendanceGradeRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; +import java.util.Optional; + +public class AttendanceGradeRepositoryImpl extends SpringCrudRepositoryImpl implements AttendanceGradeRepository { + + @Transactional(readOnly = true) + public List findAllByAttendanceSite(AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceGrade.class); + Root record = query.from(AttendanceGrade.class); + query.where(cb.equal(record.get("attendanceSite"), attendanceSite)); + + return session.createQuery(query).list(); + } + + @Transactional(readOnly = true) + public Optional findByAttendanceSiteAndUserId(AttendanceSite attendanceSite, String userId) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceGrade.class); + Root grade = query.from(AttendanceGrade.class); + query.where(cb.and(cb.equal(grade.get("attendanceSite"), attendanceSite), + cb.equal(grade.get("userID"), userId))); + + return session.createQuery(query).uniqueResultOptional(); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceRecordRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceRecordRepositoryImpl.java new file mode 100644 index 00000000..ae188d27 --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceRecordRepositoryImpl.java @@ -0,0 +1,27 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.attendance.api.repository.AttendanceRecordRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class AttendanceRecordRepositoryImpl extends SpringCrudRepositoryImpl implements AttendanceRecordRepository { + + @Transactional(readOnly = true) + public List findAllByAttendanceEvent(AttendanceEvent attendanceEvent) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceRecord.class); + Root record = query.from(AttendanceRecord.class); + query.where(cb.equal(record.get("attendanceEvent"), attendanceEvent)); + + return session.createQuery(query).list(); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceSiteRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceSiteRepositoryImpl.java new file mode 100644 index 00000000..cf885bd8 --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceSiteRepositoryImpl.java @@ -0,0 +1,42 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; +import org.sakaiproject.attendance.api.model.stats.StatusCount; +import org.sakaiproject.attendance.api.repository.AttendanceSiteRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.Query; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class AttendanceSiteRepositoryImpl extends SpringCrudRepositoryImpl implements AttendanceSiteRepository { + + @Transactional(readOnly = true) + public AttendanceSite findBySiteId(String siteId) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceSite.class); + Root site = query.from(AttendanceSite.class); + query.where(cb.equal(site.get("siteID"), siteId)); + + return session.createQuery(query).uniqueResult(); + } + + @Transactional(readOnly = true) + public AttendanceUserStats calculateAttendanceUserStats(String userId, AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + Query query = session.createQuery("SELECT new org.sakaiproject.attendance.api.model.stats.StatusCount(r.status, COUNT(r.status)) " + + "FROM AttendanceRecord AS r JOIN AttendanceEvent AS e ON r.attendanceEvent = e " + + "WHERE e.attendanceSite = :attendanceSite AND r.userID = :userId GROUP BY r.status"); + query.setParameter("attendanceSite", attendanceSite); + query.setParameter("userId", userId); + List statusCounts = query.getResultList(); + + return new AttendanceUserStats(userId, attendanceSite, statusCounts); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceStatusRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceStatusRepositoryImpl.java new file mode 100644 index 00000000..29d2b573 --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/AttendanceStatusRepositoryImpl.java @@ -0,0 +1,39 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.repository.AttendanceStatusRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class AttendanceStatusRepositoryImpl extends SpringCrudRepositoryImpl implements AttendanceStatusRepository { + + @Transactional(readOnly = true) + public List findAllByAttendanceSite(AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceStatus.class); + Root status = query.from(AttendanceStatus.class); + query.where(cb.equal(status.get("attendanceSite"), attendanceSite)); + + return session.createQuery(query).list(); + } + + @Transactional(readOnly = true) + public List findAllActiveByAttendanceSite(AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(AttendanceStatus.class); + Root status = query.from(AttendanceStatus.class); + query.where(cb.and(cb.equal(status.get("attendanceSite"), attendanceSite), + cb.equal(status.get("isActive"), Boolean.TRUE))); + + return session.createQuery(query).list(); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/impl/repository/GradingRuleRepositoryImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/repository/GradingRuleRepositoryImpl.java new file mode 100644 index 00000000..ddefa4c3 --- /dev/null +++ b/impl/src/java/org/sakaiproject/attendance/impl/repository/GradingRuleRepositoryImpl.java @@ -0,0 +1,27 @@ +package org.sakaiproject.attendance.impl.repository; + +import org.hibernate.Session; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.GradingRule; +import org.sakaiproject.attendance.api.repository.GradingRuleRepository; +import org.sakaiproject.springframework.data.SpringCrudRepositoryImpl; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.List; + +public class GradingRuleRepositoryImpl extends SpringCrudRepositoryImpl implements GradingRuleRepository { + + @Transactional(readOnly = true) + public List findAllByAttendanceSite(AttendanceSite attendanceSite) { + Session session = sessionFactory.getCurrentSession(); + CriteriaBuilder cb = session.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(GradingRule.class); + Root rule = query.from(GradingRule.class); + query.where(cb.equal(rule.get("attendanceSite"), attendanceSite)); + + return session.createQuery(query).list(); + } +} diff --git a/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalc.java b/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalc.java deleted file mode 100644 index 021ffd79..00000000 --- a/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalc.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.services; - -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.sakaiproject.attendance.dao.AttendanceDao; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.*; - -import java.util.*; - -/** - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - */ -@Slf4j -public class AttendanceStatCalc { - private int sitesProcessed = 0; - private int sitesNotMarked = 0; - private int sitesInError = 0; - private int sitesWithNoUsers = 0; - - public void init() { - log.debug("AttendanceStatCalc init()"); - } - - public void destroy() { - log.debug("AttendanceStatCalc destroy()"); - } - - public void execute() { - log.debug("AttendanceStatCalc execute()"); - Date syncTime = new Date(); - Long lastId = 0L; - - List ids = dao.getAttendanceSiteBatch(syncTime, lastId); - if(ids.isEmpty()) { - String summary = getOverallSummary(); - if("".equals(summary)) { - log.info("AttendanceStatCalc no sites left to sync"); - } else { - log.info("AttendanceStatCalc done, but there are errors\n" + summary); - } - } else { - while(!ids.isEmpty()) { - dao.markAttendanceSiteForSync(ids, syncTime); - for (Long id : ids) { - calculateStats(id); - lastId = id > lastId ? id : lastId++; // never-ending loop protection - } - log.info("AttendanceStatCalc in progress " + getSummary()); - ids = dao.getAttendanceSiteBatch(syncTime, lastId); - } - log.info("AttendanceStatCalc finished " + getSummary()); - log.info(getOverallSummary()); - } - - resetCounters(); - } - - private void calculateStats(Long id) { - try { - AttendanceSite attendanceSite = dao.getAttendanceSite(id); - - if(attendanceSite.getIsSyncing()) { - List userIds = sakaiProxy.getSiteMembershipIds(attendanceSite.getSiteID()); - if(!userIds.isEmpty()) { // only calculate stats for sites still available - Map userStatsList = new HashMap<>(userIds.size()); - - userIds.forEach(userId -> { - int[] array = {0, 0, 0, 0, 0}; // present, unexcused, excused, late, leftEarly - userStatsList.put(userId, array); - }); - - List events = attendanceLogic.getAttendanceEventsForSite(attendanceSite); - if (!events.isEmpty()) { - events.forEach(attendanceEvent -> calculateEventStats(attendanceEvent, userStatsList)); - - for (String key : userStatsList.keySet()) { - AttendanceUserStats userStat = attendanceLogic.getStatsForUser(key, attendanceSite); - int[] userRecordStats = userStatsList.get(key); - userStat.setPresent(userRecordStats[0]); - userStat.setUnexcused(userRecordStats[1]); - userStat.setExcused(userRecordStats[2]); - userStat.setLate(userRecordStats[3]); - userStat.setLeftEarly(userRecordStats[4]); - - dao.updateAttendanceUserStats(userStat); - } - } - } else { - sitesWithNoUsers++; - log.debug("AttendanceSite, id: '" + id +"' has no users or Site, id: '" - + attendanceSite.getSiteID() +"' no longer exists."); - } - - attendanceSite.setIsSyncing(false); - attendanceLogic.updateAttendanceSite(attendanceSite); - - log.debug("AttendanceSite synced with id: " + id); - sitesProcessed++; - } else { - log.debug("AttendanceSite not marked as in progress" + id); - sitesNotMarked++; - } - } catch (Exception e) { - sitesInError++; - log.warn("Error syncing AttendanceSite id: " + id, e); - } - } - - private void calculateEventStats(AttendanceEvent event, Map userStats) { - Set records = event.getRecords(); - AttendanceItemStats itemStats = attendanceLogic.getStatsForEvent(event); - - int present = 0, unexcused = 0, excused = 0, late = 0, leftEarly = 0; - boolean recordsPresent = false; - for(AttendanceRecord record : records) { - recordsPresent = true; - Status recordStatus = record.getStatus(); - int[] array = userStats.get(record.getUserID()); - if(array != null) { - if (recordStatus == Status.PRESENT) { - present++; - array[0] = array[0] + 1; - } else if (recordStatus == Status.UNEXCUSED_ABSENCE) { - unexcused++; - array[1] = array[1] + 1; - } else if (recordStatus == Status.EXCUSED_ABSENCE) { - excused++; - array[2] = array[2] + 1; - } else if (recordStatus == Status.LATE) { - late++; - array[3] = array[3] + 1; - } else if (recordStatus == Status.LEFT_EARLY) { - leftEarly++; - array[4] = array[4] + 1; - } - - userStats.put(record.getUserID(), array); - } else { - log.debug("AttendanceRecord user no longer present in course, record id: '" + record.getId() - + "' and userID: " + record.getUserID()); - } - } - - if(recordsPresent) { - itemStats.setPresent(present); - itemStats.setUnexcused(unexcused); - itemStats.setExcused(excused); - itemStats.setLate(late); - itemStats.setLeftEarly(leftEarly); - - dao.updateAttendanceItemStats(itemStats); - } - } - - private String getSummary() { - return String.format("%d Attendance Sites synced, %d Attendance Sites with no users, %d Attendance Sites unsuccessfully synced", - sitesProcessed, sitesWithNoUsers, sitesInError + sitesNotMarked); - } - - private String getOverallSummary() { - List inProgress = dao.getAttendanceSitesInSync(); - if(inProgress.size() > 0) { - String message = "%d AttendanceSite(s) currently marked in sync. IDs marked in sync: %s"; - return String.format(message, inProgress.size(), inProgress); - } - return ""; - } - - private void resetCounters() { - this.sitesInError = 0; - this.sitesNotMarked = 0; - this.sitesProcessed = 0; - this.sitesWithNoUsers = 0; - } - - @Setter - private AttendanceDao dao; - - @Setter - private SakaiProxy sakaiProxy; - - @Setter - private AttendanceLogic attendanceLogic; -} diff --git a/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalcJob.java b/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalcJob.java deleted file mode 100644 index 6b42e3f0..00000000 --- a/impl/src/java/org/sakaiproject/attendance/services/AttendanceStatCalcJob.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2017, University of Dayton - * - * Licensed under the Educational Community License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://opensource.org/licenses/ecl2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sakaiproject.attendance.services; - -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.quartz.DisallowConcurrentExecution; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.sakaiproject.authz.api.AuthzGroupService; -import org.sakaiproject.component.cover.ServerConfigurationService; -import org.sakaiproject.event.api.EventTrackingService; -import org.sakaiproject.event.api.UsageSession; -import org.sakaiproject.event.api.UsageSessionService; -import org.sakaiproject.tool.api.Session; -import org.sakaiproject.tool.api.SessionManager; - -import java.util.Date; - -/** - * The AttendanceStatCalc Job calculates all AttendanceUserStats and all AttendanceItemStats - * for each AttendanceSite in batches of 5 Attendance Sites. - * - * The job should be run once after upgrading past Attendance 1.0. Afterwards, it should be run - * only in cases where the statistics got out of sync (very very rare). - * - * @author Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] - */ -@Slf4j -@DisallowConcurrentExecution -public class AttendanceStatCalcJob implements Job { - private String serverName = "N/A"; - final private String jobName = "AttendanceStatCalcJob"; - final private String jobError = "attend.calc.job.error"; - - public AttendanceStatCalcJob() { - super(); - } - - public void init() { - log.info(jobName + " init."); - serverName = ServerConfigurationService.getServerName(); - } - - public void destroy() { - log.info(jobName +" D E S T R O Y E D."); - } - - public void execute(JobExecutionContext context) { - log.debug(jobName + "execute()"); - loginToSakai("admin", jobName, jobError); - - String jobName = context.getJobDetail().getKey().getName(); - String triggerName = context.getTrigger().getKey().getName(); - Date requestedFire = context.getScheduledFireTime(); - Date actualFire = context.getFireTime(); - - StringBuffer whoAmI = new StringBuffer(jobName + " $"); - whoAmI.append(" Job: "); - whoAmI.append(jobName); - whoAmI.append(" Trigger: "); - whoAmI.append(triggerName); - - if (requestedFire != null) { - whoAmI.append(" Fire scheduled: "); - whoAmI.append(requestedFire.toString()); - } - - if (actualFire != null) { - whoAmI.append(" Fire actual: "); - whoAmI.append(actualFire.toString()); - } - - eventTrackingService.post(eventTrackingService.newEvent("attend.calc.job", safeEventLength(whoAmI.toString()), true)); - - log.info("Start Job: " + whoAmI.toString()); - attendanceStatCalc.execute(); - - logoutFromSakai(); - - } - - public void loginToSakai(String whoAs, String jobName, String jobError) { - log.debug(jobName + " loginToSakai()"); - - UsageSession session = usageSessionService.startSession(whoAs, serverName, jobName); - if (session == null) { - eventTrackingService.post(eventTrackingService.newEvent(jobError, whoAs + " unable to log into " + serverName, true)); - return; - } - - Session sakaiSession = sessionManager.getCurrentSession(); - sakaiSession.setUserId(whoAs); - sakaiSession.setUserEid(whoAs); - - // update the user's externally provided realm definitions - authzGroupService.refreshUser(whoAs); - - // post the login events - eventTrackingService.post(eventTrackingService.newEvent(UsageSessionService.EVENT_LOGIN, whoAs + " running " + serverName, true)); - } - - public void logoutFromSakai() { - log.debug(jobName + " Logging out of Sakai on " + serverName); - eventTrackingService.post(eventTrackingService.newEvent(UsageSessionService.EVENT_LOGOUT, null, true)); - usageSessionService.logout(); // safe to logout? what if other jobs are running? - } - - static public String safeEventLength(final String target) - { - return (target.length() > 255 ? target.substring(0, 255) : target); - } - - @Setter - private AttendanceStatCalc attendanceStatCalc; - - @Setter - private EventTrackingService eventTrackingService; - - @Setter - private UsageSessionService usageSessionService; - - @Setter - private AuthzGroupService authzGroupService; - - @Setter - private SessionManager sessionManager; -} diff --git a/impl/src/webapp/WEB-INF/components.xml b/impl/src/webapp/WEB-INF/components.xml index 0e821185..e0948191 100644 --- a/impl/src/webapp/WEB-INF/components.xml +++ b/impl/src/webapp/WEB-INF/components.xml @@ -14,13 +14,22 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + + + + @@ -36,42 +45,28 @@ - - - - - - - - - - - - PROPAGATION_REQUIRED - - - - - - + class="org.sakaiproject.attendance.impl.logic.AttendanceLogicImpl"> + + + + + + + + @@ -86,55 +81,49 @@ - - + - + + - org/sakaiproject/attendance/hbm/AttendanceEvent.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceGrade.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceItemStats.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceRecord.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml - org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml - org/sakaiproject/attendance/hbm/GradingRule.hbm.xml + org.sakaiproject.attendance.api.model.AttendanceEvent + org.sakaiproject.attendance.api.model.AttendanceGrade + org.sakaiproject.attendance.api.model.AttendanceRecord + org.sakaiproject.attendance.api.model.AttendanceStatus + org.sakaiproject.attendance.api.model.AttendanceSite + org.sakaiproject.attendance.api.model.GradingRule + + + - - - + + - - - - - - - + + - - - - + + - - - - + + + + + + diff --git a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceRecordProvider.java b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceRecordProvider.java index b61588f4..13738c9c 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceRecordProvider.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceRecordProvider.java @@ -18,8 +18,8 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.model.AttendanceRecord; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceRecord; import java.util.ArrayList; import java.util.Comparator; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceStatusProvider.java b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceStatusProvider.java index 4f5760c5..5c40d1f8 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceStatusProvider.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/AttendanceStatusProvider.java @@ -18,10 +18,9 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; -import org.sakaiproject.attendance.model.AttendanceSite; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; -import org.sakaiproject.attendance.tool.models.DetachableAttendanceStatusModel; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import java.util.ArrayList; import java.util.Collections; @@ -55,8 +54,10 @@ public AttendanceStatusProvider(String siteId, String filter) { AttendanceSite attendanceSite = attendanceLogic.getAttendanceSite(siteId); if(attendanceSite != null) { List attendanceStatuses = attendanceLogic.getAllStatusesForSite(attendanceSite); - this.list = new ArrayList(); + this.list = new ArrayList<>(); filterStatuses(attendanceStatuses, filter); + } else { + throw new IllegalArgumentException("Unable to get attendance site for site id " + siteId); } } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/BaseProvider.java b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/BaseProvider.java index 89f0f6a8..2e3f1b8e 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/BaseProvider.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/BaseProvider.java @@ -19,8 +19,8 @@ import org.apache.wicket.injection.Injector; import org.apache.wicket.markup.repeater.data.IDataProvider; import org.apache.wicket.spring.injection.annot.SpringBean; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; import java.util.Iterator; import java.util.List; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/EventDataProvider.java b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/EventDataProvider.java index c53d6e48..a6e26d8a 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/EventDataProvider.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/dataproviders/EventDataProvider.java @@ -18,8 +18,7 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.tool.models.DetachableEventModel; +import org.sakaiproject.attendance.api.model.AttendanceEvent; import java.util.Collections; import java.util.List; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceRecordModel.java b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceRecordModel.java index 63b9b40b..474b6d4f 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceRecordModel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceRecordModel.java @@ -19,8 +19,8 @@ import org.apache.wicket.injection.Injector; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.spring.injection.annot.SpringBean; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.model.AttendanceRecord; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.model.AttendanceRecord; /** * DetachableAttendanceRecordModel @@ -85,6 +85,6 @@ else if (obj instanceof DetachableAttendanceRecordModel) { protected AttendanceRecord load(){ Injector.get().inject(this); // get the thing - return attendanceLogic.getAttendanceRecord(id); + return attendanceLogic.getAttendanceRecord(id).orElseThrow( () -> { throw new IllegalArgumentException("Unable to get attendance record for id " + id); }); } } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceStatusModel.java b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceStatusModel.java index 6a9653ae..054ef9cb 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceStatusModel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableAttendanceStatusModel.java @@ -19,8 +19,8 @@ import org.apache.wicket.injection.Injector; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.spring.injection.annot.SpringBean; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.model.AttendanceStatus; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.model.AttendanceStatus; /** * DetachableAttendanceStatusModel @@ -85,6 +85,6 @@ else if (obj instanceof DetachableAttendanceStatusModel) { protected AttendanceStatus load(){ Injector.get().inject(this); // get the thing - return attendanceLogic.getAttendanceStatusById(id); + return attendanceLogic.getAttendanceStatusById(id).orElseThrow( () -> { throw new IllegalArgumentException("Unable to get attendance status by id " + id); }); } } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableEventModel.java b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableEventModel.java index 769f2c81..4ddb8016 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableEventModel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableEventModel.java @@ -19,8 +19,8 @@ import org.apache.wicket.injection.Injector; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.spring.injection.annot.SpringBean; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.model.AttendanceEvent; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.model.AttendanceEvent; /** * DetachableAttendanceEventModel diff --git a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableUserModel.java b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableUserModel.java index ae2190c2..8f0e83ef 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableUserModel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/models/DetachableUserModel.java @@ -19,7 +19,7 @@ import org.apache.wicket.injection.Injector; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.spring.injection.annot.SpringBean; -import org.sakaiproject.attendance.logic.SakaiProxy; +import org.sakaiproject.attendance.api.logic.SakaiProxy; import org.sakaiproject.user.api.User; /** diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java index 9ed8f108..8c8cb14e 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java @@ -20,13 +20,10 @@ import lombok.extern.slf4j.Slf4j; import org.apache.wicket.AttributeModifier; -import org.apache.wicket.Component; -import org.apache.wicket.Session; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; -import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.markup.head.*; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.WebPage; @@ -38,10 +35,10 @@ import org.apache.wicket.model.ResourceModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.sakaiproject.attendance.api.AttendanceGradebookProvider; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.panels.EventInputPanel; import org.sakaiproject.attendance.tool.util.AttendanceFeedbackPanel; import org.sakaiproject.component.cover.ServerConfigurationService; @@ -167,10 +164,6 @@ public void onClick() { feedbackPanel = new AttendanceFeedbackPanel("feedback"); add(feedbackPanel); - if(attendanceLogic.getCurrentAttendanceSite().getIsSyncing()) { - getSession().error((new ResourceModel("attendance.site.syncing.error")).getObject()); - } - this.addOrEditItemWindow = new ModalWindow("addOrEditItemWindow"); this.addOrEditItemWindow.showUnloadConfirmation(false); this.addOrEditItemWindow.setInitialHeight(400); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.java index ebd89a17..88f71339 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.java @@ -1,6 +1,5 @@ package org.sakaiproject.attendance.tool.pages; import org.apache.commons.codec.binary.StringUtils; -import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; @@ -11,11 +10,7 @@ import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.*; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.tool.pages.EventView; -import org.sakaiproject.attendance.tool.pages.Overview; -import org.sakaiproject.attendance.tool.util.AttendanceFeedbackPanel; -import org.sakaiproject.attendance.tool.util.ConfirmationLink; +import org.sakaiproject.attendance.api.model.AttendanceEvent; import org.sakaiproject.attendance.tool.util.PlaceholderBehavior; public class EventInputPage extends BasePage{ @@ -88,11 +83,11 @@ protected void onInitialize(){ private void processSave(AjaxRequestTarget target, Form form, boolean addAnother) { AttendanceEvent e = (AttendanceEvent) form.getModelObject(); e.setAttendanceSite(attendanceLogic.getCurrentAttendanceSite()); - boolean result = attendanceLogic.updateAttendanceEvent(e); - if(result){ - StringResourceModel temp = new StringResourceModel("attendance.add.success", null, new String[]{e.getName()}); + StringResourceModel temp = new StringResourceModel("attendance.add.success", null, new String[]{e.getName()}); + try { + e = attendanceLogic.updateAttendanceEvent(e); getSession().success(temp.getString()); - } else { + } catch (Exception ex) { error(getString("attendance.add.failure")); target.addChildren(form, FeedbackPanel.class); } @@ -111,11 +106,6 @@ protected void onSubmit(AjaxRequestTarget target, Form form) { processSave(target, form, createAnother); } - @Override - public boolean isEnabled() { - return !attendanceLogic.getCurrentAttendanceSite().getIsSyncing(); - } - @Override protected void onError(AjaxRequestTarget target, Form form) { target.addChildren(form, FeedbackPanel.class); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventView.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventView.java index a733d5a7..54c3a313 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventView.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventView.java @@ -33,20 +33,18 @@ import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.navigation.paging.PagingNavigator; import org.apache.wicket.markup.repeater.Item; -import org.apache.wicket.markup.repeater.ReuseIfModelsEqualStrategy; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.model.AttendanceRecord; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.dataproviders.AttendanceRecordProvider; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.attendance.tool.models.ProfileImage; import org.sakaiproject.attendance.tool.panels.AttendanceRecordFormDataPanel; -import org.sakaiproject.attendance.tool.panels.AttendanceRecordFormHeaderPanel; import org.sakaiproject.attendance.tool.panels.PrintPanel; import org.sakaiproject.attendance.tool.panels.StatisticsPanel; @@ -137,11 +135,6 @@ protected void onSubmit() { getSession().info("All attendance records " + who + " for " + attendanceEvent.getName() + " set to " + setAllStatus.getModelObject()); setResponsePage(new EventView(attendanceEvent.getId(), returnPage, selectedGroup)); } - - @Override - public boolean isEnabled() { - return !attendanceEvent.getAttendanceSite().getIsSyncing(); - } }; List activeAttendanceStatuses = attendanceLogic.getActiveStatusesForCurrentSite(); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/ExportPage.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/ExportPage.java index e7f67118..342f62b4 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/ExportPage.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/ExportPage.java @@ -18,12 +18,11 @@ import org.apache.commons.codec.binary.StringUtils; import org.apache.wicket.model.StringResourceModel; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.*; +import org.sakaiproject.attendance.api.model.*; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; import org.sakaiproject.user.api.User; import org.apache.wicket.RestartResponseException; -import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.SubmitLink; import org.apache.wicket.model.LoadableDetachableModel; @@ -136,9 +135,7 @@ private File buildExcelFile(boolean blankSheet, boolean commentsOnOff){ final ArrayList eventHolder = new ArrayList(); AttendanceSite attendanceSite = attendanceLogic.getAttendanceSite(siteID); List groupIds = sakaiProxy.getAvailableGroupsForCurrentSite(); - List finalUserStatsList = new ArrayList(); - List fullUserList = attendanceLogic.getUserStatsForSite(attendanceLogic.getAttendanceSite(siteID), null); - AttendanceUserGroupStats finalUserStatsListholder = new AttendanceUserGroupStats(); + List fullUserList = attendanceLogic.getUserStatsForSite(attendanceSite, null); HSSFRow headerRow = mainSheet.createRow(0); //create blank header row HSSFCellStyle boldStyle = wb.createCellStyle(); //cell styling HSSFFont boldFont = wb.createFont(); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/ImportConfirmation.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/ImportConfirmation.java index c79dd8b5..5432057c 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/ImportConfirmation.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/ImportConfirmation.java @@ -16,8 +16,11 @@ package org.sakaiproject.attendance.tool.pages; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.ImportConfirmList; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; -import org.sakaiproject.attendance.model.*; import java.util.*; import java.util.List; @@ -190,7 +193,7 @@ public UploadForm(final String id) { SubmitLink completeImport = new SubmitLink("submitLink") { public void onSubmit() { for (int i = 0; i < uploadICLList.size(); i++){ - boolean updated = attendanceLogic.updateAttendanceRecord(uploadICLList.get(i).getAttendanceRecord(), uploadICLList.get(i).getOldStatus()); + attendanceLogic.updateAttendanceRecord(uploadICLList.get(i).getAttendanceRecord(), uploadICLList.get(i).getOldStatus()); attendanceLogic.updateAttendanceSite(uploadICLList.get(i).getAttendanceSite()); } getSession().success(getString("attendance.export.confirmation.import.save.success")); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/Overview.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/Overview.java index b15b4bda..1e92f054 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/Overview.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/Overview.java @@ -20,35 +20,30 @@ import org.apache.wicket.Page; import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.extensions.markup.html.form.select.Select; -import org.apache.wicket.extensions.markup.html.form.select.SelectOption; -import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.SubmitLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.Model; -import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.StringResourceModel; -import org.sakaiproject.attendance.model.AttendanceEvent; -import org.sakaiproject.attendance.model.AttendanceItemStats; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.stats.AttendanceItemStats; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.attendance.tool.dataproviders.EventDataProvider; import org.sakaiproject.attendance.tool.panels.EventInputPanel; import org.sakaiproject.attendance.tool.panels.PrintPanel; import org.sakaiproject.attendance.tool.util.ConfirmationLink; -import java.util.*; +import java.time.Instant; /** * The overview page which lists AttendanceEvents and basic statistics of each @@ -144,7 +139,7 @@ public void onClick() { item.add(eventLink); Label eventDate = new Label("event-date", modelObject.getStartDateTime()); - eventDate.add(new AttributeModifier("data-text", modelObject.getStartDateTime() != null ? modelObject.getStartDateTime().getTime() : 0)); + eventDate.add(new AttributeModifier("data-text", modelObject.getStartDateTime() != null ? modelObject.getStartDateTime() : 0)); item.add(eventDate); DataView activeStatusStats = new DataView("active-status-stats", attendanceStatusProvider) { @@ -176,9 +171,10 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { @Override public void onClick(AjaxRequestTarget ajaxRequestTarget) { final String name = modelObject.getName(); - if(attendanceLogic.deleteAttendanceEvent(modelObject)) { + try { + attendanceLogic.deleteAttendanceEvent(modelObject); getSession().info(name + " deleted successfully."); - } else { + } catch (Exception ex) { getSession().error("Failed to delete " + name); } Class currentPageClass = getPage().getPageClass(); @@ -189,11 +185,6 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { setResponsePage(currentPageClass); } } - - @Override - public boolean isEnabled() { - return !attendanceLogic.getCurrentAttendanceSite().getIsSyncing(); - } }; item.add(deleteLink); } @@ -218,11 +209,10 @@ protected void onSubmit() { AttendanceEvent newEvent = new AttendanceEvent(); newEvent.setAttendanceSite(attendanceLogic.getCurrentAttendanceSite()); newEvent.setName(new ResourceModel("attendance.now.name").getObject()); - newEvent.setStartDateTime(new Date()); - Long newEventId = (Long) attendanceLogic.addAttendanceEventNow(newEvent); - if(newEventId != null) { - newEvent = attendanceLogic.getAttendanceEvent(newEventId); - setResponsePage(new EventView(newEvent, BasePage.OVERVIEW_PAGE)); + newEvent.setStartDateTime(Instant.now()); + AttendanceEvent savedEvent = attendanceLogic.addAttendanceEventNow(newEvent); + if(savedEvent != null) { + setResponsePage(new EventView(savedEvent, BasePage.OVERVIEW_PAGE)); } else { error(new ResourceModel("attendance.now.error").getObject()); } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/SettingsPage.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/SettingsPage.java index 57717279..d1221060 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/SettingsPage.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/SettingsPage.java @@ -24,7 +24,7 @@ import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceSite; import org.sakaiproject.attendance.tool.panels.AttendanceCommentFormPanel; import org.sakaiproject.attendance.tool.panels.AttendanceStatusFormPanel; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentOverview.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentOverview.java index cdaa691b..ee508113 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentOverview.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentOverview.java @@ -33,10 +33,10 @@ import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.AttendanceGrade; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.AttendanceUserStats; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.stats.AttendanceUserStats; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.attendance.tool.models.ProfileImage; import org.sakaiproject.attendance.tool.panels.AttendanceGradePanel; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentView.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentView.java index 2c8f15b9..a383d3e6 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentView.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/StudentView.java @@ -25,13 +25,12 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.AttendanceRecord; -import org.sakaiproject.attendance.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.attendance.api.model.AttendanceStatus; import org.sakaiproject.attendance.tool.dataproviders.AttendanceRecordProvider; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.attendance.tool.panels.AttendanceGradePanel; import org.sakaiproject.attendance.tool.panels.AttendanceRecordFormDataPanel; -import org.sakaiproject.attendance.tool.panels.AttendanceRecordFormHeaderPanel; import org.sakaiproject.attendance.tool.panels.StatisticsPanel; /** diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceCommentFormPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceCommentFormPanel.java index 06618afa..bcf6d028 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceCommentFormPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceCommentFormPanel.java @@ -21,7 +21,7 @@ import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.*; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceSite; /** * Created by Leonardo Canessa [lcanessa1 (at) udayton (dot) edu] @@ -53,9 +53,9 @@ private void init(FeedbackPanel panel) { @Override protected void onSubmit() { final AttendanceSite aS = (AttendanceSite) getDefaultModelObject(); - boolean result = attendanceLogic.updateAttendanceSite(aS); + AttendanceSite result = attendanceLogic.updateAttendanceSite(aS); - if(result) { + if(result != null) { getSession().success(getString("attendance.settings.edit.comment.save.success")); } else { getSession().error(getString("attendance.settings.edit.comment.save.error")); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradeFormPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradeFormPanel.java index 1c1d8f4f..4b1a3293 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradeFormPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradeFormPanel.java @@ -29,7 +29,7 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceSite; import org.sakaiproject.attendance.tool.panels.util.GradebookItemNameValidator; /** @@ -96,9 +96,8 @@ public void onSubmit() { aS.setUseAutoGrading(false); } - boolean result = attendanceLogic.updateAttendanceSite(aS); - - if (result) { + try { + aS = attendanceLogic.updateAttendanceSite(aS); if(aS.getSendToGradebook()){ if(previousSendToGradebook) { // if previously true, see if any relevant values have changed if(!previousName.equals(aS.getGradebookItemName()) || !previousMaxGrade.equals(aS.getMaximumGrade())){ @@ -124,10 +123,9 @@ public void onSubmit() { } getSession().info(getString("attendance.settings.grading.success")); - } else { + } catch (Exception exception) { getSession().error(getString("attendance.settings.grading.failure")); } - } }; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradePanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradePanel.java index af0a0172..8def834f 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradePanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceGradePanel.java @@ -26,8 +26,8 @@ import org.apache.wicket.markup.html.form.NumberTextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.*; -import org.sakaiproject.attendance.model.AttendanceGrade; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceGrade; +import org.sakaiproject.attendance.api.model.AttendanceSite; /** * AttendanceGradePanel allows for inputting of AttendanceGrades @@ -64,24 +64,20 @@ private Form createGradeForm() { @Override public void onSubmit() { AttendanceGrade aG = (AttendanceGrade) getDefaultModelObject(); - - boolean result; - - if (Boolean.TRUE.equals(attendanceSite.getUseAutoGrading()) && Boolean.FALSE.equals(aG.getOverride())) { - result = attendanceLogic.regrade(aG, true) != null; - } else { - result = attendanceLogic.updateAttendanceGrade(aG); - } - String displayName = sakaiProxy.getUserSortName(aG.getUserID()); - if (result) { - String grade = aG.getGrade() == null ? "null" : aG.getGrade().toString(); - getSession().info(new StringResourceModel("attendance.grade.update.success", null, new String[]{grade, displayName}).getString()); - } else { - getSession().error(new StringResourceModel("attendance.grade.update.failure", null, new String[]{displayName}).getString()); + try { + Double grade; + if (Boolean.TRUE.equals(attendanceSite.getUseAutoGrading()) && Boolean.FALSE.equals(aG.getOverride())) { + grade = attendanceLogic.regrade(aG, true); + } else { + aG = attendanceLogic.updateAttendanceGrade(aG); + grade = aG.getGrade(); + } + getSession().info(new StringResourceModel("attendance.grade.update.success", null, (Object) new String[]{String.valueOf(grade), displayName}).getString()); + } catch (Exception ex) { + getSession().error(new StringResourceModel("attendance.grade.update.failure", null, (Object) new String[]{displayName}).getString()); } - } }; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormDataPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormDataPanel.java index e934f415..2ca3e0ed 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormDataPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormDataPanel.java @@ -31,9 +31,9 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.*; -import org.sakaiproject.attendance.model.AttendanceRecord; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceRecord; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.component.cover.ServerConfigurationService; @@ -79,23 +79,15 @@ protected void onSubmit() { if(aR.getStatus() == null) { aR.setStatus(Status.UNKNOWN); } - boolean result = attendanceLogic.updateAttendanceRecord(aR, oldStatus); - String[] resultMsgVars = new String[]{sakaiProxy.getUserSortName(aR.getUserID()), aR.getAttendanceEvent().getName(), getStatusString(aR.getStatus())}; - StringResourceModel temp; - if(result){ - temp = new StringResourceModel("attendance.record.save.success", null, resultMsgVars); - getSession().info(temp.getString()); + try { + aR = attendanceLogic.updateAttendanceRecord(aR, oldStatus); + String[] resultMsgVars = new String[]{sakaiProxy.getUserSortName(aR.getUserID()), aR.getAttendanceEvent().getName(), getStatusString(aR.getStatus())}; + getSession().info(new StringResourceModel("attendance.record.save.success", null, (Object) resultMsgVars).getString()); oldStatus = aR.getStatus(); - } else { - temp = new StringResourceModel("attendance.record.save.failure", null, resultMsgVars); - getSession().error(temp.getString()); + } catch (Exception ex) { + getSession().error(new StringResourceModel("attendance.record.save.failure", null, (Object) new String[]{sakaiProxy.getUserSortName(aR.getUserID()), aR.getAttendanceEvent().getName(), getStatusString(aR.getStatus())}).getString()); } } - - @Override - public boolean isEnabled() { - return !recordIModel.getObject().getAttendanceEvent().getAttendanceSite().getIsSyncing(); - } }; createStatusRadio(recordForm); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormHeaderPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormHeaderPanel.java index 7362f635..8c6b9168 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormHeaderPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceRecordFormHeaderPanel.java @@ -20,7 +20,7 @@ import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; -import org.sakaiproject.attendance.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.AttendanceStatus; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; /** diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceStatusFormPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceStatusFormPanel.java index f8375756..f134f519 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceStatusFormPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/AttendanceStatusFormPanel.java @@ -29,9 +29,9 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; -import org.sakaiproject.attendance.model.AttendanceSite; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import java.util.*; @@ -71,10 +71,10 @@ private void init(FeedbackPanel panel) { @Override protected void onSubmit() { AttendanceSite aS = (AttendanceSite) getDefaultModelObject(); - boolean result = attendanceLogic.updateAttendanceSite(aS); - if(result){ + try { + aS = attendanceLogic.updateAttendanceSite(aS); getSession().info(getString("attendance.settings.edit.status.save.success")); - } else { + } catch (Exception ex) { getSession().error(getString("attendance.settings.edit.status.save.error")); } } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/BasePanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/BasePanel.java index 8a66958b..56db41d1 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/BasePanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/BasePanel.java @@ -22,10 +22,10 @@ import org.apache.wicket.model.ResourceModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.sakaiproject.attendance.api.AttendanceGradebookProvider; -import org.sakaiproject.attendance.export.PDFEventExporter; -import org.sakaiproject.attendance.logic.AttendanceLogic; -import org.sakaiproject.attendance.logic.SakaiProxy; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.export.PDFEventExporter; +import org.sakaiproject.attendance.api.logic.AttendanceLogic; +import org.sakaiproject.attendance.api.logic.SakaiProxy; +import org.sakaiproject.attendance.api.model.Status; import lombok.extern.slf4j.Slf4j; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/EventInputPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/EventInputPanel.java index f3b469ff..9720ffe8 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/EventInputPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/EventInputPanel.java @@ -27,11 +27,10 @@ import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.*; -import org.sakaiproject.attendance.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceEvent; import org.sakaiproject.attendance.tool.pages.EventView; import org.sakaiproject.attendance.tool.pages.Overview; import org.sakaiproject.attendance.tool.util.AttendanceFeedbackPanel; -import org.sakaiproject.attendance.tool.util.ConfirmationLink; import org.sakaiproject.attendance.tool.util.PlaceholderBehavior; @@ -106,9 +105,9 @@ public void onSubmit(final AjaxRequestTarget target, final Form form) { private void processSave(AjaxRequestTarget target, Form form, boolean addAnother) { AttendanceEvent e = (AttendanceEvent) form.getModelObject(); e.setAttendanceSite(attendanceLogic.getCurrentAttendanceSite()); - boolean result = attendanceLogic.updateAttendanceEvent(e); + e = attendanceLogic.updateAttendanceEvent(e); - if(result){ + if(e != null){ StringResourceModel temp = new StringResourceModel("attendance.add.success", null, new String[]{e.getName()}); getSession().success(temp.getString()); } else { @@ -146,11 +145,6 @@ protected void onSubmit(AjaxRequestTarget target, Form form) { processSave(target, form, createAnother); } - @Override - public boolean isEnabled() { - return !attendanceLogic.getCurrentAttendanceSite().getIsSyncing(); - } - @Override protected void onError(AjaxRequestTarget target, Form form) { target.addChildren(form, FeedbackPanel.class); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesListPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesListPanel.java index 404cbfd9..b6e197ec 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesListPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesListPanel.java @@ -16,6 +16,7 @@ package org.sakaiproject.attendance.tool.panels; +import org.apache.commons.collections4.functors.ExceptionClosure; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.basic.Label; @@ -24,7 +25,7 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; -import org.sakaiproject.attendance.model.GradingRule; +import org.sakaiproject.attendance.api.model.GradingRule; import java.text.MessageFormat; import java.util.List; @@ -76,12 +77,11 @@ protected void populateItem(Item item) { protected void onSubmit(AjaxRequestTarget target, Form form) { super.onSubmit(target, form); - final boolean result = attendanceLogic.deleteGradingRule((GradingRule) form.getModelObject()); - - if (result) { + try { + attendanceLogic.deleteGradingRule((GradingRule) form.getModelObject()); setNeedRegrade(true); target.add(GradingRulesListPanel.this.regradeForm); - } else { + } catch (Exception ex) { GradingRulesListPanel.this.pageFeedbackPanel.error(getString("attendance.grading.delete.rule.error")); target.add(GradingRulesListPanel.this.pageFeedbackPanel); } diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesPanel.java index d7dc1a13..e8cf1301 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/GradingRulesPanel.java @@ -25,9 +25,9 @@ import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; -import org.sakaiproject.attendance.model.AttendanceStatus; -import org.sakaiproject.attendance.model.GradingRule; -import org.sakaiproject.attendance.model.Status; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.GradingRule; +import org.sakaiproject.attendance.api.model.Status; import java.util.*; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/PrintPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/PrintPanel.java index 7e8e4785..29883ce5 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/PrintPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/PrintPanel.java @@ -24,7 +24,7 @@ import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler; import org.apache.wicket.util.resource.AbstractResourceStreamWriter; -import org.sakaiproject.attendance.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.AttendanceEvent; import org.sakaiproject.user.api.User; import java.io.IOException; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/StatisticsPanel.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/StatisticsPanel.java index 1e2cbe4f..277f5d24 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/StatisticsPanel.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/StatisticsPanel.java @@ -22,7 +22,10 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.ResourceModel; -import org.sakaiproject.attendance.model.*; +import org.sakaiproject.attendance.api.model.AttendanceEvent; +import org.sakaiproject.attendance.api.model.stats.AttendanceStats; +import org.sakaiproject.attendance.api.model.AttendanceStatus; +import org.sakaiproject.attendance.api.model.Status; import org.sakaiproject.attendance.tool.dataproviders.AttendanceStatusProvider; import org.sakaiproject.attendance.tool.pages.EventView; import org.sakaiproject.attendance.tool.pages.StudentView; @@ -37,12 +40,12 @@ public class StatisticsPanel extends BasePanel { private static final long serialVersionUID = 1L; - private AttendanceEvent attendanceEvent; + private AttendanceEvent attendanceEvent; private String userId; private String fromPage; private Long previousEventId; - private AttendanceStats stats; + private AttendanceStats stats; public StatisticsPanel(String id, String fromPage, AttendanceEvent aE) { super(id); diff --git a/tool/src/java/org/sakaiproject/attendance/tool/panels/util/GradebookItemNameValidator.java b/tool/src/java/org/sakaiproject/attendance/tool/panels/util/GradebookItemNameValidator.java index 36fee9e4..2e5bb6cc 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/panels/util/GradebookItemNameValidator.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/panels/util/GradebookItemNameValidator.java @@ -22,7 +22,7 @@ import org.apache.wicket.validation.IValidator; import org.apache.wicket.validation.ValidationError; import org.sakaiproject.attendance.api.AttendanceGradebookProvider; -import org.sakaiproject.attendance.model.AttendanceSite; +import org.sakaiproject.attendance.api.model.AttendanceSite; /** * GradebookItemNameValidator is used to ensure the Gradebook Item Name is not all ready present in the gradebook From 45c2b90e3b943ec2ae36a83f2f7391850d0efee4 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Wed, 24 Aug 2022 13:47:33 -0400 Subject: [PATCH 3/7] Fix issues with converting start date to instant This also addresses #76 by converting to use sakai's datepicker --- .../impl/logic/AttendanceLogicImpl.java | 4 +- tool/pom.xml | 6 +- .../attendance/tool/pages/BasePage.java | 36 ++++++-- .../attendance/tool/pages/EventInputPage.html | 6 +- .../attendance/tool/pages/EventInputPage.java | 68 +++++++++------ .../attendance/tool/pages/EventView.html | 33 +++---- .../attendance/tool/pages/EventView.java | 18 ++-- .../attendance/tool/pages/Overview.html | 12 +-- .../attendance/tool/pages/Overview.java | 33 ++----- .../attendance/tool/pages/StudentView.java | 10 ++- .../tool/panels/EventInputPanel.html | 2 +- .../tool/panels/EventInputPanel.java | 86 +++++++++++++------ tool/src/webapp/css/attendance.css | 42 +-------- 13 files changed, 198 insertions(+), 158 deletions(-) diff --git a/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java b/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java index cc0badfd..e35ed34c 100644 --- a/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java +++ b/impl/src/java/org/sakaiproject/attendance/impl/logic/AttendanceLogicImpl.java @@ -138,7 +138,7 @@ public void deleteAttendanceEvent(AttendanceEvent aE) throws IllegalArgumentExce if(aE == null) { throw new IllegalArgumentException("AttendanceEvent is null"); } - attendanceEventRepository.delete(aE); + attendanceEventRepository.deleteById(aE.getId()); } /** @@ -443,7 +443,7 @@ public GradingRule addGradingRule(GradingRule gradingRule) { * {@inheritDoc} */ public void deleteGradingRule(GradingRule gradingRule) { - gradingRuleRepository.delete(gradingRule); + gradingRuleRepository.deleteById(gradingRule.getId()); } /** diff --git a/tool/pom.xml b/tool/pom.xml index 496e85fe..d9fe14be 100644 --- a/tool/pom.xml +++ b/tool/pom.xml @@ -105,7 +105,11 @@ org.sakaiproject.kernel sakai-kernel-util - + + org.sakaiproject.wicket + wicket-tool-6 + + diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java b/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java index 8c8cb14e..b5f4e01e 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/BasePage.java @@ -42,9 +42,12 @@ import org.sakaiproject.attendance.tool.panels.EventInputPanel; import org.sakaiproject.attendance.tool.util.AttendanceFeedbackPanel; import org.sakaiproject.component.cover.ServerConfigurationService; +import org.sakaiproject.portal.util.PortalUtils; +import org.sakaiproject.time.api.UserTimeService; import org.sakaiproject.util.ResourceLoader; import javax.servlet.http.HttpServletRequest; +import java.time.format.DateTimeFormatter; /** @@ -69,6 +72,9 @@ public class BasePage extends WebPage implements IHeaderContributor { @SpringBean(name="org.sakaiproject.attendance.api.AttendanceGradebookProvider") protected AttendanceGradebookProvider attendanceGradebookProvider; + @SpringBean(name="org.sakaiproject.time.api.UserTimeService") + protected UserTimeService userTimeService; + protected String role; Link addLink; @@ -176,20 +182,40 @@ public void onClick() { * Add to this any additional CSS or JS references that you need. * */ + @Override public void renderHead(IHeaderResponse response) { + super.renderHead(response); + + final String version = PortalUtils.getCDNQuery(); + //get the Sakai skin header fragment from the request attribute HttpServletRequest request = (HttpServletRequest)getRequest().getContainerRequest(); + + response.render(new PriorityHeaderItem(JavaScriptHeaderItem + .forReference(getApplication().getJavaScriptLibrarySettings().getJQueryReference()))); response.render(StringHeaderItem.forString((String)request.getAttribute("sakai.html.head"))); response.render(OnLoadHeaderItem.forScript("setMainFrameHeight( window.name )")); + //add Attendance.css as the css class response.render(CssHeaderItem.forUrl("css/attendance.css")); + //Tool additions (at end so we can override if isRequired) response.render(StringHeaderItem.forString("")); - //response.renderCSSReference("css/my_tool_styles.css"); - //response.renderJavascriptReference("js/my_tool_javascript.js"); + + // Shared JavaScript and stylesheets + // Force Wicket to use Sakai's version of jQuery + response.render( + new PriorityHeaderItem( + JavaScriptHeaderItem + .forUrl(String.format("/library/webjars/jquery/1.12.4/jquery.min.js%s", version)))); + // And pair this instance of jQuery with a Bootstrap version we've tested with + response.render( + new PriorityHeaderItem( + JavaScriptHeaderItem + .forUrl(String.format("/library/webjars/bootstrap/3.3.7/js/bootstrap.min.js%s", version)))); + // tablesorter - final String version = ServerConfigurationService.getString("portal.cdn.version", ""); response.render(JavaScriptHeaderItem.forUrl(String.format("javascript/jquery.tablesorter.min.js?version=%s", version))); response.render(JavaScriptHeaderItem.forUrl(String.format("javascript/jquery.tablesorter.widgets.min.js?version=%s", version))); } @@ -225,7 +251,7 @@ protected String getStatusString(Status s) { } } - protected AjaxLink getAddEditWindowAjaxLink(final AttendanceEvent obj, final String id) { + protected AjaxLink getAddEditWindowAjaxLink(Long attendanceEventId, final String id) { return new AjaxLink(id) { private static final long serialVersionUID = 1L; @@ -233,7 +259,7 @@ public void onClick(AjaxRequestTarget target) { final ModalWindow window = getAddOrEditItemWindow(); window.setTitle(new ResourceModel("attendance.add.edit.header")); window.setCssClassName(window.getCssClassName() + " editItemModal"); - window.setContent(new EventInputPanel(window.getContentId(), window, new CompoundPropertyModel<>(obj))); + window.setContent(new EventInputPanel(window.getContentId(), window, Model.of(attendanceEventId))); window.show(target); } }; diff --git a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.html b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.html index 4314c585..bbf07c61 100644 --- a/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.html +++ b/tool/src/java/org/sakaiproject/attendance/tool/pages/EventInputPage.html @@ -32,10 +32,12 @@

-