Index: lams_admin/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r394f403c289f0fd7808c228840bead5c4e7d5d32 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_admin/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 394f403c289f0fd7808c228840bead5c4e7d5d32) +++ lams_admin/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -1,655 +1,660 @@ -appName = admin -#language code: en -#locale code: AU - - # Exported from the LAMS Community by Ernie Ghiglione on Wed Jan 16 14:38:11 CST 2019 - -#=================== labels for LAMS Administration =================# - -audit.organisation.change =Changed {0} for organisation: {1} from: {2} to: {3} -audit.organisation.create =Created organisation: {0} of type: {1} -audit.user.disable =Disabled account userId: {0} -audit.user.delete =Deleted userId: {0} -label.yes =Yes -label.no =No -label.or =Or -title.job.list =Jobs -lable.job.name =Job name -lable.job.start.date =Job start date -lable.job.description =Job description -error.system =Oops! An unexpected exception thrown by the system. Contact your system administrator. -error.org.invalid =Invalid organisation Id. {0} -error.orgtype.invalid =Invalid operation for this type of organisation. -error.name.required =Name is required. -error.login.required =Login is required. -error.login.unique =Login is already taken. {0} -error.password.required =Password is required. -error.authorisation =You are not authorised to do this. -error.newpassword.mismatch =Your new password does not match. -error.oldpassword.mismatch =Your old password is not correct. -error.img.format =The file you uploaded looks not an image. An image file usually has .jpg, .gif, .png or .bmp extension. -error.img.size =The file size exceeds the maximum 4096k limit. -error.need.sysadmin =You need to have the sys admin role to do this. -error.roles.empty =You need to assign at least one role. -error.userid.invalid =Invalid User Id. -error.firstname.required =First name is required. -error.lastname.required =Last name is required. -error.email.required =Email address is required. -error.valid.email.required =Valid email address is required. -error.required ={0} is required. -error.not.unique ={0} is not unique. -error.roles.invalid =One or more roles are invalid. {0} -error.fail.add =Failed to add user. -error.authmethod.invalid =Invalid authentication method. {0} -error.locale.invalid =Invalid locale. {0} -msg.user.add.to.parent.group =User/s marked with a '*' will be automatically added to the parent course with the same roles. -msg.add.to.org =User will be added to {0}. -msg.results.none =No results matched your query. -msg.users.added ={0} users were added to course/subcourse. -msg.disable.user.1 =This user has lesson and/or sequence data associated with it and cannot be deleted. -msg.disable.user.2 =User account will be disabled instead, maintaining their data, but the account will be treated as deleted. -msg.disable.user.3 =It will not appear in course/subcourse lists, nor will the user be able to login. -msg.disable.user.4 =You can enable the user account again by editing the user's profile. -msg.delete.user.1 =User has no associated data and can be safely removed. -msg.delete.user.2 =Are you sure you want to delete this account? -msg.edit.tool.content.1 =This page contains a list of installed tools. -msg.edit.tool.content.2 =Changes to a tool's content using this screen will affect the tool's default appearance for all authors. -msg.edit.tool.content.3 =Note that you cannot upload files to a tool's default content, only edit the default text. -msg.roles.mandatory =You must assign at least one role. -msg.roles.mandatory.users =You must assign at least one role for each user. -organisation.state.ACTIVE =Active -organisation.state.HIDDEN =Hidden -organisation.state.ARCHIVED =Archived -organisation.state.REMOVED =Removed -admin.user.management =User management -admin.user.entry =User entry -admin.user.userid =User ID -admin.user.login =Login -admin.user.password =Password -admin.user.password.confirm =Confirm password -admin.user.name =Name -admin.user.title =Title -admin.user.first_name =First name -admin.user.last_name =Last name -admin.user.address_line_1 =Address line 1 -admin.user.address_line_2 =Address line 2 -admin.user.address_line_3 =Address line 3 -admin.user.city =City -admin.user.state =State -admin.user.postcode =Postcode -admin.user.country =Country -admin.user.day_phone =Work phone -admin.user.evening_phone =Home phone -admin.user.mobile_phone =Mobile phone -admin.user.fax =Fax -admin.user.email =Email -admin.user.roles =Roles -admin.user.manage =Manage users -admin.user.delete =Delete -admin.user.add =Add/Remove users -admin.user.create =Create user -admin.user.assign.roles =Assign roles -admin.user.find =Find users -admin.user.edit =Edit user details -admin.user.disable =Disable user -admin.user.actions =Actions -admin.user.import =Import users -admin.list.disabled.users =List disabled accounts -label.excel.spreadsheet =File -label.spreadsheet =spreadsheet -label.download.template =Download the template -role.AUTHOR =Author -role.AUTHOR.ADMIN =Author Admin -role.GROUP.MANAGER =Course Manager -role.LEARNER =Learner -role.MONITOR =Monitor -role.SYSADMIN =System Admin -label.member.of =Member of -label.with.roles =With roles -admin.organisation.management =Course/Subcourse management -admin.organisation.entry =Course/Subcourse entry -admin.organisation.name =Name -admin.organisation.code =Code -admin.organisation.description =Description -admin.organisation.locale =Locale -admin.organisation.status =Status -admin.can.add.user =Course managers can add new users -admin.can.browse.user =Course managers can browse all users in the system -admin.can.change.status =Course managers can change status of course -admin.organisation =Course/Subcourse -admin.course =Course -admin.class =Subcourse -admin.course.manage =Manage courses -admin.class.manage =Manage subcourses -admin.class.add =Create subcourse -admin.course.add =Create course -admin.global.roles.manage =Manage global roles -admin.number =No. -admin.in =In -admin.error =Oops! -admin.save =Save -admin.create =Create -admin.edit =Edit -admin.reset =Reset -admin.delete =Delete -admin.cancel =Cancel -admin.search =Search -admin.enable =Enable -admin.disable =Disable -sysadmin.maintain =Maintain LAMS -sysadmin.maintain.loginpage =Maintain login page -sysadmin.maintain.external.servers =Maintain integrated servers -sysadmin.maintain.server.edit =Edit integrated server -sysadmin.serverid =Id -sysadmin.serverkey =Key -sysadmin.servername =Name -sysadmin.serverdesc =Description -sysadmin.prefix =Prefix -sysadmin.disabled =Disabled -sysadmin.organisation =Organisation -sysadmin.userinfoUrl =User information URL -sysadmin.timeoutUrl =Timeout URL -sysadmin.integrated.servers =integrated server(s) in total -sysadmin.server.add =Add new server -sysadmin.organisation.create =Create one -sysadmin.organisation.select =Please select... -sysadmin.login.text =Update login page text: -sysadmin.headline =System Administration -sysadmin.config.settings.edit =Edit configuration settings -sysadmin.batch.temp.file.delete =Delete old temporary files -sysadmin.job.list =Job list -sysadmin.list.job =List scheduled jobs in Quartz queue -sysadmin.edit.default.tool.content =Edit default tool content -cache.maintain =Maintain LAMS cache -cache.title =Cache management -cache.entries.title =Cache nodes -cache.explanation1 =Listed below are the current nodes in the cache. This keeps certain common objects in memory to speed up LAMS. It is managed automatically and should not require any intervention. However, if the system appears to be keeping "old values" e.g. an old first name, try clearing all the nodes in the cache. Once cleared, LAMS will reload the objects from the database. -cache.explanation2 =Warning: Removing nodes will reduce the performance of the LAMS server. After a while, the cache will build up again and LAMS will run as usual. -cache.explanation3 =Warning: If you remove a node, you will remove the node and all its child nodes. -cache.button.remove =Remove -admin.config.key =Key -admin.config.value =Value -label.show.all.users =Show all users -msg.group.organisation_id =The organisation_id of this course is -msg.subgroup.organisation_id =The organisation_id of this subcourse is -msg.remove.from.subgroups =Removed users will also be removed from subcourse. -label.global.roles =Global roles -label.import =Import -msg.import.intro =Use this screen to bulk import users using an Excel spreadsheet. -msg.import.1 =In the spreadsheet, columns marked with a (*) are mandatory. -msg.import.2 =Download the user template to create users. -msg.import.conclusion =Click the help icon above for more information. -label.results.per.page =Results per page -msg.import.3 =Download the roles template to add users to course/subcourse and assign their roles. -error.user.does.not.exist =User does not exist {0} -msg.users.created ={0} users were created successfully. -error.no.sysadmin.priviledge =You do not have the required privileges to perform this action. -sysadmin.library.management =Learning library management -sysadmin.library.totals =learning libraries in total -sysadmin.library.activity.title =Title -sysadmin.library.activity.description =Description -sysadmin.library.createtim =Create time -sysadmin.function =Function -msg.cleanup.files.deleted ={0} files were deleted. -msg.cleanup.warning =Warning: calculating the size of LAMS' temporary files may incur a performance hit on your server if it hasn't been cleaned out for a while. -label.unknown =unknown -msg.cleanup.actual.space =Depending on your server's file system, the actual space occupied may differ from the above. -msg.cleanup.recommended =It's recommended to leave at least 1 day of temporary files in order not to remove anything that's currently in use. -label.cleanup.delete =Delete temporary files older than this number of days -label.can.join.joint.lessons =Can join joint lessons -label.can.offer.joint.lessons =Can offer joint lessons -error.cant.write.login.jsp =Couldn''t write value of {0} to {1}, please check your {2} configuration. -label.login.as =Login as -sysadmin.import.groups.title =Import courses -heading.import.results =Import results -table.heading.organisation.id =Organisation ID -import.groups.intro =Use this screen to bulk import courses and subcourses using an Excel spreadsheet. -import.groups.instructions =When creating a course, make sure the row above it is empty. When creating a subcourse, place it directly under it's parent course. -import.groups.download =Download the courses template to create courses and subcourse. -msg.please.wait =Please wait... -sysadmin.ldap.configuration =LDAP configuration -label.synchronise =Synchronise -msg.num.ldap.users =There are {0} LDAP users in LAMS. -msg.ldap.synchronise.intro =This feature allows you to synchronise LAMS' database with your LDAP server. This includes updating existing users' profile and adding them to the LAMS course which matches their attributes. -msg.ldap.synchronise.warning =Note that this process may take some time depending on the number of users contained in your LDAP tree; it's best to perform this operation when the LAMS server will not be under load. -heading.ldap.synchronise =Synchronise with LDAP -msg.done =...done! -msg.tool.management =Tool management -sysadmin.tool.management =Tool management -msg.ldap.synchronise.wait =Please wait while synchronisation completes... -msg.ldap.synchronise.errors =The following errors were encountered: -msg.num.search.results.users =LDAP server returned {0} users. -msg.num.created.users ={0} user accounts were created in LAMS. -msg.num.updated.users ={0} user accounts already existed in LAMS and were updated. -msg.num.disabled.users ={0} user accounts were disabled in LAMS. -config.header.system =System configuration -config.header.email =Email -config.header.uploads =Uploaded files -config.header.chat =Chat server -config.header.ldap =LDAP -config.header.ldap.attributes =LDAP attribute mapping -config.header.features =Features -config.header.look.feel =Look and feel -config.header.versions =Versions -config.header.antivirus =Antivirus -config.header.qb =Question bank -config.server.url =Server URL -config.server.url.context.path =Server URL context path -config.version =Version -config.temp.dir =Temporary files directory -config.ear.dir =EAR directory -config.smtp.server =SMTP server -config.lams.support.email =LAMS support email -config.content.repository.path =Content repository directory -config.upload.file.max.size =Maximum upload size -config.upload.large.file.max.size =Maximum large upload size -config.upload.file.max.memory.size =Maximum memory used when uploading -config.executable.extensions =Executable extensions -config.user.inactive.timeout =Inactive user timeout -config.use.cache.debug.listener =Cache debug listener -config.cleanup.preview.older.than.days =Number of days to keep preview -config.authoring.client.version =Authoring client version -config.monitor.client.version =Monitoring client version -config.learner.client.version =Learner client version -config.server.version.number =Server version number -config.server.language =Locale -config.server.page.direction =Locale page direction -config.dictionary.date.created =Language pack install date -config.help.url =Help URL -config.xmpp.domain =Chat server domain -config.xmpp.conference =Chat server conference -config.xmpp.admin =Chat server admin username -config.xmpp.password =Chat server admin password -config.allow.direct.lesson.launch =Allow direct lesson launch -config.allow.live.edit =Allow Live Edit -config.ldap.provisioning.enabled =Enable provisioning -config.ldap.provider.url =LDAP server URL -config.ldap.security.authentication =Authentication mechanism -config.ldap.principal.dn.prefix =User's distinguished name prefix -config.ldap.principal.dn.suffix =User's distinguished name suffix -config.ldap.security.protocol =Security protocol -config.ldap.truststore.path =SSL certificate path -config.ldap.truststore.password =SSL certificate password -config.ldap.learner.map =Learner role map -config.ldap.monitor.map =Monitor role map -config.ldap.author.map =Author role map -config.ldap.group.manager.map =Course Manager role map -config.ldap.update.on.login =Update on login -config.ldap.org.field =Course field map -config.ldap.only.one.org =Only one course -config.ldap.encrypt.password.from.browser =Encrypt password in browser -config.ldap.search.results.page.size =Search results page size -error.numeric ={0} only accepts numeric characters -label.users.in.system ={0} users in system. -label.users.in.group ={0} users in course. -label.show =Show -label.groups =courses -label.subgroups =subcourses -heading.manage.group.users =Manage Users of {0} -label.learners =Learners -label.monitors =Monitors -label.authors =Authors -label.group.managers =Course Managers -label.sysadmins =Sysadmins -label.author.admins =Author Administrators -heading.users =Users -label.number.of.users ={0} users. -heading.potential.users =Potential users -label.number.of.potential.users ={0} potential users. -msg.click.remove.user =Click a user to remove them. -msg.click.add.user =Click a user to add them. -msg.show.all.potential.users =Show all potential users. -label.next =Next -audit.user.create =Created user {0}, named {1} -audit.spreadsheet.error =Error processing spreadsheet row {0}: {1} -audit.successful.user.import =Successfully imported {0} users. -audit.successful.role.import =Successfully imported {0} role memberships. -audit.successful.organisation.import =Successfully imported {0} organisations. -config.forgot.password.allow.email =Allow forgot password email link in front page? -config.forgot.password.email =Email address from which the forgotten password emails will be sent -config.custom.tab.link =Custom tab URL -config.custom.tab.title =Custom tab title -config.authoring.screen.size =Authoring screen size -config.monitor.screen.size =Monitor screen size -config.learner.screen.size =Learner screen size -config.admin.screen.size =System Admin screen size -label.tool =Tool -label.tool.version =Tool version -label.database.version =Database version -config.ldap.search.filter =Search filter -config.ldap.base.dn =Base distinguished name -config.ldap.bind.user.dn =Bind user distinguished name -config.ldap.bind.user.password =Bind user password -admin.user.authentication.method =Authentication method -config.smtp.user =SMTP user -config.smtp.password =SMTP password -config.header.red5 =Media server -config.red5.server.url =Media server URL -config.red5.recordings.url =Media server recordings URL -admin.gradebook.learner.enable =Enable Gradebook for learners -sysadmin.serverUrl =External server URL -admin.statistics.title =Server statistics -admin.statistics.overall =Overall statistics -admin.statistics.totalUsers =Total users: -admin.statistics.groups =Total courses: -admin.statistics.subGroups =Total subcourses: -admin.statistics.learningDesigns =Total learning designs: -admin.statistics.lessons =Total lessons: -admin.statistics.activities =Total activities: -admin.statistics.completedActivities =Total completed activities: -admin.statistics.title.byGroup =Statistics by course -admin.statistics.group.learners =Total Learners: -admin.statistics.group.monitors =Total Monitors: -admin.statistics.group.authors =Total Authors: -admin.themes.title =Theme management -admin.themes.theme =Theme -admin.themes.description =Description -admin.themes.imageDir =CSS image directory -admin.themes.defaultTheme =Current default theme -admin.themes.remove =Remove -admin.themes.edit =Edit -admin.themes.addNew =Add/Edit theme -admin.themes.name =Name -admin.themes.makeThemeDefault =Make this theme the server default -admin.themes.makeDefault =Make default -admin.themes.deleteConfirm =Are you sure you want to delete this theme? -admin.themes.nameAlreadyExists =Please enter a new unused theme name, or click the edit icon to edit. -config.use.internal.smtp.server =Use internal SMTP server -label.email =Email -title.clone.lessons =Clone lessons -label.ok =OK -title.clone.lessons.for =Clone lessons for {0} -title.choose.group =Choose course to clone lessons from -label.choose =Choose -title.select.lessons =Select lessons -title.select.staff =Select staff -message.add.all.monitors =Add all monitors in this course to each lesson? -label.configure.staff =Configure staff -title.select.learners =Select learners -message.add.all.learners =Add all learners in this course to each lesson? -label.configure.learners =Configure learners -label.clone =Clone -message.cloned.lessons =Cloned {0} lessons. -message.no.lessons =There are no lessons to clone. -message.check.to.clone.lesson =Check the box for each lesson to clone it. -message.no.lesson.description =No lesson description -message.no.learners =This course has no learners! Please add some via the Add/Remove users screen. -message.check.to.add.learner =Check the box of each learner to add to each of the new lessons. -message.no.monitors =This course has no monitors! Please add some via the Add/Remove users screen. -message.check.to.add.monitor =Check the box of each monitor to add as staff to each of the new lessons. -label.return.to.group =Return to course -admin.timezone.title =Timezone management -admin.timezone.available.timezones =Available timezones -admin.timezone.select.timezones.you.want.users.choose =Select the timezones you want the users for choose from. The server timezone is: {0} -admin.timezone.select =Select -admin.timezone.time.zone.id =Time zone ID -admin.timezone.raw.offset =Raw offset (Hours : Minutes) -admin.timezone.dst.offset =DST offset (Minutes) -admin.timezone.display.name =Display name -admin.user.enable.flash.for.learner.window =Enable Flash for learner window -admin.user.time.zone =Time Zone -config.show.all.my.lesson.link =Show "All my lessons" link in User's profile -config.display.print.button =Display a print button when the lesson is completed -sysadmin.lessonFinishUrl =Lesson finish callback URL -admin.servertimezone.server.timezone.management =Server timezone management -admin.servertimezone.title =Server timezone management -admin.servertimezone.select.server.timezone =Please, select server timezone -admin.servertimezone.raw.offset =Raw offset: {0} -admin.servertimezone.dst.offset =DST offset: {0} -admin.servertimezone.name =Name: {0} -admin.servertimezone.select =Select -config.profile.edit.enable =Enable profile editing -config.profile.partial.edit.enable =Enable partial profile editing (only email and contact number can be changed) -config.server2server.registration.enable =Enable remote server user registration -admin.enable.course.notifications =Enable organisation notifications -cache.entries.title2 =Cacheable entities -cache.explanation4 =Listed below are cacheable classes and collections. This keeps certain common objects in memory to speed up LAMS. It is managed automatically and should not require any intervention. However, if the system appears to be keeping "old values" e.g. an old first name, try clearing all the nodes in the cache. Once cleared, LAMS will reload the objects from the database. -cache.button.remove.all =Clear all cached objects -cache.removed =Objects bound with entity name {0} were removed -cache.removed.all =All cached objects were removed -admin.add.edit.signup.page =Add/edit new signup page -admin.signup.title =Signup pages -admin.group =Course -admin.lessons =Add to lessons? -admin.staff =Add as staff/monitor? -admin.course.key =Course Key -admin.confirm.course.key =Confirm course key -admin.description.txt =Description -admin.disable.option =Disabled? -admin.context.path =Path to sign up -admin.submit =Submit -admin.actions =Actions -admin.group.code =Course access code -admin.added.on =Added on -admin.add.new.signup.page =Add a new signup page -admin.list.signup.pages =List of signup pages -error.course.keys.unequal =Course keys did not match -error.context.exists =This URL context is taken -config.authoring.suffix =Add unique suffix when importing Learning Designs -config.authoring.single.activity =Enable single activity lessons -error.name.invalid.characters =Name cannot contain any of these characters < > ^ * @ % $ -admin.login.tab =Display login tab as default -error.firstname.invalid.characters =First name contains invalid characters -error.lastname.invalid.characters =Last name contains invalid characters -error.username.invalid.characters =Username can only contain alphanumeric characters and no spaces -config.header.user.validation =User data validation -config.user.validation.username =Enforce username validation (only alphanumeric, hyphen (-), underscore (_), period (.), at sign (@) and single quote (') allowed) -config.user.validation.first.last.name =Enforce first and last name validation (only letters, hypen (-), space ( ) and single quote (') characters allowed) -config.user.validation.emails =Enforce properly formatted emails -config.cache.refresh =Configuration cache refresh interval (minutes) -error.login.request.ttl.negative =Login request time to live should be a positive number. -sysadmin.login.request.ttl =Time to live for integration requests (in minutes) -sysadmin.login.request.ttl.enable =Enforce time limitation for integration requests -tool.groups.open.button =Manage tool groups -tool.groups.open.button.tooltip =Assign tools to groups for later use in Authoring -tool.groups.dialog.title =Tool groups management -tool.groups.dialog.instructions =Manage groups by dragging and dropping tools -tool.groups.add.group.button =Add group -tool.groups.remove.group.button.tooltip =Remove group -tool.groups.group.default.name =Untitled -tool.groups.remove.confirm =Are you sure you want to remove this group? -tool.groups.group.name.error =A group name can not be blank -tool.groups.save.error =Error while saving groups -config.live.edit =Enable live edit -sysadmin.extGroupsUrl =External groups URL -server.config.title =Server configuration -server.monitor.title =Server monitoring -user.course.title =User and course configuration -config.site.name =Site name -label.create.lesson =Create lesson -label.manage.tool.consumers =Maintain LTI Tool Consumers -label.edit.tool.consumer =Edit tool consumer details -label.add.tool.consumer =Add new tool consumer -sysadmin.serversecret =Secret -label.tool.consumers.count =LTI Tool Consumers(s) in total -config.stacktrace.error =Show full error message (stack trace) -config.password.minimum.characters =Minimum number of characters -config.password.uppercase =Must contain uppercase letter(s) -config.password.lowercase =Must contain lowercase letter(s) -config.header.password.policy =Password policy -config.password.numerics =Must contain at least a number -config.password.symbols =Must contain at least one symbol(s) -error.password.mismatch =Your passwords does not match. -error.password.empty =Password cannot be empty. -admin.user.change.password =Force password change -label.password.max.length =must be less than 25 characters -label.password.min.length =must be at least {0} characters long -label.password.old.must.entered =Old password must be entered -label.password.symbols.allowed =Only these symbols are allowed -label.password.restrictions =Password must follow the restrictions shown -label.password.must.contain =Password must contain -label.password.must.ucase =at least 1 upper case letter -label.password.must.number =at least 1 number -label.password.must.symbol =at least 1 symbol -sysadmin.batch.preview.lesson.delete =Delete old preview lessons -msg.cleanup.preview.lesson.confirm =Are you sure you want to delete all preview lessons? -msg.cleanup.preview.lesson.error =Error while deleting preview lessons -label.cleanup.preview.lesson.count =Number of preview/all lessons: -label.cleanup.preview.lesson.progress =Deleting... -error.theme.invalid =Invalid theme -label.theme =Theme -config.default.theme =Default theme -label.2FA.property.enable =Enable two-factor authentication -sysadmin.lti.consumer.monitor.roles =Comma-separated list of monitor roles -config.failed.attempts =Number of failed logins before locking account -config.lock.out.time =Number of minutes to lock account for -config.default.html.theme =Default theme -admin.user.changePassword =Change password -config.show.timezone.warning =Show warning when user's LAMS timezone does not match their computer/device. -label.password.must.lcase =at least 1 lower case letter -button.select.importfile =Select file to import -label.upload.info =Uploaded file must be an Excel file and not exceed size of {0} -errors.maxfilesize =Uploaded file exceeded maximum size: {0} -error.attachment.not.xls =File is not an Excel .xls file. -sysadmin.maintain.session =Logged in users -sysadmin.maintain.session.login =Login -sysadmin.maintain.session.id =Session ID -error.portrait.removal.failed =Unable to delete portrait. See error file for details -label.delete.portrait =Delete portrait -sysadmin.maintain.session.delete =Delete -config.display.portrait =Display learner's portrait in a progress bar -config.allow.kumalive =Enable Kumalive -admin.organisation.create.date =Creation date -admin.org.password.change.title =Reset password for course members -admin.org.password.change.button =Password reset -admin.org.password.change.is.staff =Authors/monitors -admin.org.password.change.is.learner =Students -admin.org.password.change.generate =Generate new password -admin.org.password.change.email =Email new password -admin.org.password.change.force =Force change password after login -admin.org.password.change.custom =Enter own password or generate one -admin.org.password.change.grid.login =Login -admin.org.password.change.grid.name =Name -admin.org.password.change.grid.email =Email -admin.org.password.change.grid.error.load =Error while loading users into grid -admin.org.password.change.choose =Change password for -admin.org.password.change.submit =Change password -admin.org.password.change.error.prefix.staff =Authors/monitors password -admin.org.password.change.error.prefix.learners =Authors/monitors password -admin.org.password.change.success =Passwords successfully changed -admin.org.password.change.email.subject =LAMS password change -admin.org.password.change.email.body =Your password has been changed to: {0}\n\n-- email sent automatically by LAMS -label.event.log =Event (Audit) Log -label.event.topic =Topic -label.event.type =Type of Event -label.select.topic =Select topic... -label.select.type =Select type... -label.date =Date -label.between.dates =Between dates -label.lesson.with.name =Lesson: {0} ({1}) -label.activity.with.name =Activity: {0} ({1}) -label.type.teacher.learning.design.create =Learning Design Created -label.type.teacher.lesson.create =Lesson Created -label.type.teacher.lesson.start =Lesson Started -label.type.teacher.lesson.change.state =Lesson State Changed -label.type.learner.activity.start =Activity Started -label.type.learner.activity.finish =Activity Finished -label.type.learner.lesson.complete =Lesson Complete -label.type.learner.lesson.mark.submit =Mark Submitted -label.type.activity.edit =Activity Edited -label.type.force.complete =Learner Force Completed -label.type.user.org.admin =Organisation or User Changed -label.type.login.as =Sysadmin Logged In As -label.type.password.change =Password Change -label.type.role.failure =Action Attempted With Wrong Roles -label.type.account.locked =Account Locked -label.type.notification =Notification -label.type.mark.updated =Mark Updated -label.type.mark.released =Mark Released -label.type.learner.content.updated =Learner's Entry Modified -label.type.learner.content.show.hide =Learner's Entry Shown/Hidden -label.type.unknown =Unknown -label.area.lesson =Lesson -label.area.security =Security -label.area.notification =Notification -label.area.marks =Marks -label.area.learner.content =Learner Entry -label.area.unknown =Unknown -audit.change.made.by =Changes Made By -audit.change.made.to =Changes Made To -admin.delete.lessons =Delete all lessons -msg.delete.all.lesson.confirm.1 =You are about to PERMANENTLY delete ALL lessons from course "{0}". Are you ABSOLUTELY sure that you want to do this? There will be no turning back! -msg.delete.all.lesson.confirm.2 =ALL lessons will be deleted, including active ones with learners in them. NO lessons will be left in the course. Are you sure you want to continue? -msg.delete.all.lesson.error =Error while deleting course lessons lessons -label.delete.all.lesson.count =Number of remaining / total lessons: -label.delete.all.lesson.progress =Deleting... -sysadmin.lesson.delete.title =Delete all lessons from course -label.type.live.edit =Live Edit -label.no.data.found =No data found -msg.delete.organisation.confirm =You are about to permanently remove a course. Are you sure want to do this? -msg.delete.organisation.delete.lessons.confirm =The course or one of its subcourses still contains lessons. They need to be permanently deleted first. You will be redirected to a page where you can do it. -config.kumalive.enable =Enable Kumalive -audit.remarks =Remarks -config.allow.direct.access.for.integration.learners =Allow direct access to main LAMS page for integration learners. -label.type.tool.mark.released =Tool Marks Released -label.policy.minor.change.hint =Minor changes are meant to be wording changes that do not affect the meaning of the policy. If this option is not checked, then a new version of the policy will be created and users will be required to consent to this new policy version. -label.select.country =Select a country -error.country.required =Country is required. -admin.policies.title =Policies and consents -admin.add.edit.policy =Add/edit new policy -label.name =Name -label.policy.type =Policy type -label.policy.status =Policy status -label.version =Version -label.last.modified =Last modified -label.consents =Consents -label.add.new.policy =Add a new policy -label.policy.status.hint =An active policy will require consent from new users. Existing users will need to consent to this policy on their next log in. -label.policy.status.active =Active -label.policy.status.inactive =Inactive -label.policy.type.site =Site policy -label.policy.type.privacy =Privacy policy -label.policy.type.third.party =Third party policy -label.policy.type.other =Other policy -label.summary =Summary -label.full.policy =Full policy -label.view.previous.versions =View previous versions -label.activate =Activate -label.deactivate =Deactivate -label.minor.change =Minor change -label.policy.consents =Policy consents -label.consented =Consented? -label.consented.on =Consented on -label.user.consents =User consents -label.user.full.name =Full name -admin.user.create.date =Created on -admin.email.verify =Require email verification? -admin.email.verify.desc =(a verification email will be send before user can log in for the first time) -config.smtp.port =SMTP port -config.smtp.auth.security =SMTP authentication security -config.server.country =Country -sysadmin.lesson.gradebook.complete =Display activity scores on completion -sysadmin.lesson.liveedit =Enable Live Edit -sysadmin.lesson.notification =Enable lesson notifications -sysadmin.lesson.presence =Allow learners to see who is online -sysadmin.lesson.im =Enable Instant Messaging -sysadmin.lesson.force.restart =Learners always start from the first activity -sysadmin.lesson.allow.restart =Learners can restart the lesson -sysadmin.lesson.default =Lesson default settings -config.enable.portrait.editing =Enable profile portrait editing -label.search =Search... -config.enable.forgot.your.password.link =Enable "Forgot your password" link at the login page -admin.outcome.title =Outcomes management -outcome.authoring.title =Learning outcomes -outcome.authoring.input =Search and select by outcome name or code -outcome.authoring.existing =Added outcomes -outcome.authoring.existing.none =none -outcome.authoring.remove.confirm =Are you sure you want to remove this learning outcome? -sysadmin.maintain.session.name =Name -congfig.header.antivirus =Antivirus -config.av.enable =Enable antivirus scanning on file upload -config.av.host =ClamAV server host -config.av.port =ClamAV server port -label.type.login =User login -label.type.logout =User logout -label.type.config.change =Configuration change -config.learning.outcome.add.enable =Enable quick add of learning outcomes in authoring -config.qb.qti.enable =Enable QTI question import/export -config.qb.word.enable =Enable Word question import -config.qb.collections.create.enable =Allow creating custom collections -config.qb.collections.transfer.enable =Allow question transfer between collections -config.qb.monitors.read.only =Force read-only access for monitors -config.qb.stats.min.participants =Minimum test participant number to calculate question indexes -config.qb.stats.group.size =Percent of participants in top/bottom performers group (default: 27) - -#======= End labels: Exported 627 labels for en AU ===== +appName = admin +#language code: en +#locale code: AU + + # Exported from the LAMS Community by Ernie Ghiglione on Wed Jan 16 14:38:11 CST 2019 + +#=================== labels for LAMS Administration =================# + +audit.organisation.change =Changed {0} for organisation: {1} from: {2} to: {3} +audit.organisation.create =Created organisation: {0} of type: {1} +audit.user.disable =Disabled account userId: {0} +audit.user.delete =Deleted userId: {0} +label.yes =Yes +label.no =No +label.or =Or +title.job.list =Jobs +lable.job.name =Job name +lable.job.start.date =Job start date +lable.job.description =Job description +error.system =Oops! An unexpected exception thrown by the system. Contact your system administrator. +error.org.invalid =Invalid organisation Id. {0} +error.orgtype.invalid =Invalid operation for this type of organisation. +error.name.required =Name is required. +error.login.required =Login is required. +error.login.unique =Login is already taken. {0} +error.password.required =Password is required. +error.authorisation =You are not authorised to do this. +error.newpassword.mismatch =Your new password does not match. +error.oldpassword.mismatch =Your old password is not correct. +error.img.format =The file you uploaded looks not an image. An image file usually has .jpg, .gif, .png or .bmp extension. +error.img.size =The file size exceeds the maximum 4096k limit. +error.need.sysadmin =You need to have the sys admin role to do this. +error.roles.empty =You need to assign at least one role. +error.userid.invalid =Invalid User Id. +error.firstname.required =First name is required. +error.lastname.required =Last name is required. +error.email.required =Email address is required. +error.valid.email.required =Valid email address is required. +error.required ={0} is required. +error.not.unique ={0} is not unique. +error.roles.invalid =One or more roles are invalid. {0} +error.fail.add =Failed to add user. +error.authmethod.invalid =Invalid authentication method. {0} +error.locale.invalid =Invalid locale. {0} +msg.user.add.to.parent.group =User/s marked with a '*' will be automatically added to the parent course with the same roles. +msg.add.to.org =User will be added to {0}. +msg.results.none =No results matched your query. +msg.users.added ={0} users were added to course/subcourse. +msg.disable.user.1 =This user has lesson and/or sequence data associated with it and cannot be deleted. +msg.disable.user.2 =User account will be disabled instead, maintaining their data, but the account will be treated as deleted. +msg.disable.user.3 =It will not appear in course/subcourse lists, nor will the user be able to login. +msg.disable.user.4 =You can enable the user account again by editing the user's profile. +msg.delete.user.1 =User has no associated data and can be safely removed. +msg.delete.user.2 =Are you sure you want to delete this account? +msg.edit.tool.content.1 =This page contains a list of installed tools. +msg.edit.tool.content.2 =Changes to a tool's content using this screen will affect the tool's default appearance for all authors. +msg.edit.tool.content.3 =Note that you cannot upload files to a tool's default content, only edit the default text. +msg.roles.mandatory =You must assign at least one role. +msg.roles.mandatory.users =You must assign at least one role for each user. +organisation.state.ACTIVE =Active +organisation.state.HIDDEN =Hidden +organisation.state.ARCHIVED =Archived +organisation.state.REMOVED =Removed +admin.user.management =User management +admin.user.entry =User entry +admin.user.userid =User ID +admin.user.login =Login +admin.user.password =Password +admin.user.password.confirm =Confirm password +admin.user.name =Name +admin.user.title =Title +admin.user.first_name =First name +admin.user.last_name =Last name +admin.user.address_line_1 =Address line 1 +admin.user.address_line_2 =Address line 2 +admin.user.address_line_3 =Address line 3 +admin.user.city =City +admin.user.state =State +admin.user.postcode =Postcode +admin.user.country =Country +admin.user.day_phone =Work phone +admin.user.evening_phone =Home phone +admin.user.mobile_phone =Mobile phone +admin.user.fax =Fax +admin.user.email =Email +admin.user.roles =Roles +admin.user.manage =Manage users +admin.user.delete =Delete +admin.user.add =Add/Remove users +admin.user.create =Create user +admin.user.assign.roles =Assign roles +admin.user.find =Find users +admin.user.edit =Edit user details +admin.user.disable =Disable user +admin.user.actions =Actions +admin.user.import =Import users +admin.list.disabled.users =List disabled accounts +label.excel.spreadsheet =File +label.spreadsheet =spreadsheet +label.download.template =Download the template +role.AUTHOR =Author +role.AUTHOR.ADMIN =Author Admin +role.GROUP.MANAGER =Course Manager +role.LEARNER =Learner +role.MONITOR =Monitor +role.SYSADMIN =System Admin +label.member.of =Member of +label.with.roles =With roles +admin.organisation.management =Course/Subcourse management +admin.organisation.entry =Course/Subcourse entry +admin.organisation.name =Name +admin.organisation.code =Code +admin.organisation.description =Description +admin.organisation.locale =Locale +admin.organisation.status =Status +admin.can.add.user =Course managers can add new users +admin.can.browse.user =Course managers can browse all users in the system +admin.can.change.status =Course managers can change status of course +admin.organisation =Course/Subcourse +admin.course =Course +admin.class =Subcourse +admin.course.manage =Manage courses +admin.class.manage =Manage subcourses +admin.class.add =Create subcourse +admin.course.add =Create course +admin.global.roles.manage =Manage global roles +admin.number =No. +admin.in =In +admin.error =Oops! +admin.save =Save +admin.create =Create +admin.edit =Edit +admin.reset =Reset +admin.delete =Delete +admin.cancel =Cancel +admin.search =Search +admin.enable =Enable +admin.disable =Disable +sysadmin.maintain =Maintain LAMS +sysadmin.maintain.loginpage =Maintain login page +sysadmin.maintain.external.servers =Maintain integrated servers +sysadmin.maintain.server.edit =Edit integrated server +sysadmin.serverid =Id +sysadmin.serverkey =Key +sysadmin.servername =Name +sysadmin.serverdesc =Description +sysadmin.prefix =Prefix +sysadmin.disabled =Disabled +sysadmin.organisation =Organisation +sysadmin.userinfoUrl =User information URL +sysadmin.timeoutUrl =Timeout URL +sysadmin.integrated.servers =integrated server(s) in total +sysadmin.server.add =Add new server +sysadmin.organisation.create =Create one +sysadmin.organisation.select =Please select... +sysadmin.login.text =Update login page text: +sysadmin.headline =System Administration +sysadmin.config.settings.edit =Edit configuration settings +sysadmin.batch.temp.file.delete =Delete old temporary files +sysadmin.job.list =Job list +sysadmin.list.job =List scheduled jobs in Quartz queue +sysadmin.edit.default.tool.content =Edit default tool content +cache.maintain =Maintain LAMS cache +cache.title =Cache management +cache.entries.title =Cache nodes +cache.explanation1 =Listed below are the current nodes in the cache. This keeps certain common objects in memory to speed up LAMS. It is managed automatically and should not require any intervention. However, if the system appears to be keeping "old values" e.g. an old first name, try clearing all the nodes in the cache. Once cleared, LAMS will reload the objects from the database. +cache.explanation2 =Warning: Removing nodes will reduce the performance of the LAMS server. After a while, the cache will build up again and LAMS will run as usual. +cache.explanation3 =Warning: If you remove a node, you will remove the node and all its child nodes. +cache.button.remove =Remove +admin.config.key =Key +admin.config.value =Value +label.show.all.users =Show all users +msg.group.organisation_id =The organisation_id of this course is +msg.subgroup.organisation_id =The organisation_id of this subcourse is +msg.remove.from.subgroups =Removed users will also be removed from subcourse. +label.global.roles =Global roles +label.import =Import +msg.import.intro =Use this screen to bulk import users using an Excel spreadsheet. +msg.import.1 =In the spreadsheet, columns marked with a (*) are mandatory. +msg.import.2 =Download the user template to create users. +msg.import.conclusion =Click the help icon above for more information. +label.results.per.page =Results per page +msg.import.3 =Download the roles template to add users to course/subcourse and assign their roles. +error.user.does.not.exist =User does not exist {0} +msg.users.created ={0} users were created successfully. +error.no.sysadmin.priviledge =You do not have the required privileges to perform this action. +sysadmin.library.management =Learning library management +sysadmin.library.totals =learning libraries in total +sysadmin.library.activity.title =Title +sysadmin.library.activity.description =Description +sysadmin.library.createtim =Create time +sysadmin.function =Function +msg.cleanup.files.deleted ={0} files were deleted. +msg.cleanup.warning =Warning: calculating the size of LAMS' temporary files may incur a performance hit on your server if it hasn't been cleaned out for a while. +label.unknown =unknown +msg.cleanup.actual.space =Depending on your server's file system, the actual space occupied may differ from the above. +msg.cleanup.recommended =It's recommended to leave at least 1 day of temporary files in order not to remove anything that's currently in use. +label.cleanup.delete =Delete temporary files older than this number of days +label.can.join.joint.lessons =Can join joint lessons +label.can.offer.joint.lessons =Can offer joint lessons +error.cant.write.login.jsp =Couldn''t write value of {0} to {1}, please check your {2} configuration. +label.login.as =Login as +sysadmin.import.groups.title =Import courses +heading.import.results =Import results +table.heading.organisation.id =Organisation ID +import.groups.intro =Use this screen to bulk import courses and subcourses using an Excel spreadsheet. +import.groups.instructions =When creating a course, make sure the row above it is empty. When creating a subcourse, place it directly under it's parent course. +import.groups.download =Download the courses template to create courses and subcourse. +msg.please.wait =Please wait... +sysadmin.ldap.configuration =LDAP configuration +label.synchronise =Synchronise +msg.num.ldap.users =There are {0} LDAP users in LAMS. +msg.ldap.synchronise.intro =This feature allows you to synchronise LAMS' database with your LDAP server. This includes updating existing users' profile and adding them to the LAMS course which matches their attributes. +msg.ldap.synchronise.warning =Note that this process may take some time depending on the number of users contained in your LDAP tree; it's best to perform this operation when the LAMS server will not be under load. +heading.ldap.synchronise =Synchronise with LDAP +msg.done =...done! +msg.tool.management =Tool management +sysadmin.tool.management =Tool management +msg.ldap.synchronise.wait =Please wait while synchronisation completes... +msg.ldap.synchronise.errors =The following errors were encountered: +msg.num.search.results.users =LDAP server returned {0} users. +msg.num.created.users ={0} user accounts were created in LAMS. +msg.num.updated.users ={0} user accounts already existed in LAMS and were updated. +msg.num.disabled.users ={0} user accounts were disabled in LAMS. +config.header.system =System configuration +config.header.email =Email +config.header.uploads =Uploaded files +config.header.chat =Chat server +config.header.ldap =LDAP +config.header.ldap.attributes =LDAP attribute mapping +config.header.features =Features +config.header.look.feel =Look and feel +config.header.versions =Versions +config.header.antivirus =Antivirus +config.header.qb =Question bank +config.server.url =Server URL +config.server.url.context.path =Server URL context path +config.version =Version +config.temp.dir =Temporary files directory +config.ear.dir =EAR directory +config.smtp.server =SMTP server +config.lams.support.email =LAMS support email +config.content.repository.path =Content repository directory +config.upload.file.max.size =Maximum upload size +config.upload.large.file.max.size =Maximum large upload size +config.upload.file.max.memory.size =Maximum memory used when uploading +config.executable.extensions =Executable extensions +config.user.inactive.timeout =Inactive user timeout +config.use.cache.debug.listener =Cache debug listener +config.cleanup.preview.older.than.days =Number of days to keep preview +config.authoring.client.version =Authoring client version +config.monitor.client.version =Monitoring client version +config.learner.client.version =Learner client version +config.server.version.number =Server version number +config.server.language =Locale +config.server.page.direction =Locale page direction +config.dictionary.date.created =Language pack install date +config.help.url =Help URL +config.xmpp.domain =Chat server domain +config.xmpp.conference =Chat server conference +config.xmpp.admin =Chat server admin username +config.xmpp.password =Chat server admin password +config.allow.direct.lesson.launch =Allow direct lesson launch +config.allow.live.edit =Allow Live Edit +config.ldap.provisioning.enabled =Enable provisioning +config.ldap.provider.url =LDAP server URL +config.ldap.security.authentication =Authentication mechanism +config.ldap.principal.dn.prefix =User's distinguished name prefix +config.ldap.principal.dn.suffix =User's distinguished name suffix +config.ldap.security.protocol =Security protocol +config.ldap.truststore.path =SSL certificate path +config.ldap.truststore.password =SSL certificate password +config.ldap.learner.map =Learner role map +config.ldap.monitor.map =Monitor role map +config.ldap.author.map =Author role map +config.ldap.group.manager.map =Course Manager role map +config.ldap.update.on.login =Update on login +config.ldap.org.field =Course field map +config.ldap.only.one.org =Only one course +config.ldap.encrypt.password.from.browser =Encrypt password in browser +config.ldap.search.results.page.size =Search results page size +error.numeric ={0} only accepts numeric characters +label.users.in.system ={0} users in system. +label.users.in.group ={0} users in course. +label.show =Show +label.groups =courses +label.subgroups =subcourses +heading.manage.group.users =Manage Users of {0} +label.learners =Learners +label.monitors =Monitors +label.authors =Authors +label.group.managers =Course Managers +label.sysadmins =Sysadmins +label.author.admins =Author Administrators +heading.users =Users +label.number.of.users ={0} users. +heading.potential.users =Potential users +label.number.of.potential.users ={0} potential users. +msg.click.remove.user =Click a user to remove them. +msg.click.add.user =Click a user to add them. +msg.show.all.potential.users =Show all potential users. +label.next =Next +audit.user.create =Created user {0}, named {1} +audit.spreadsheet.error =Error processing spreadsheet row {0}: {1} +audit.successful.user.import =Successfully imported {0} users. +audit.successful.role.import =Successfully imported {0} role memberships. +audit.successful.organisation.import =Successfully imported {0} organisations. +config.forgot.password.allow.email =Allow forgot password email link in front page? +config.forgot.password.email =Email address from which the forgotten password emails will be sent +config.custom.tab.link =Custom tab URL +config.custom.tab.title =Custom tab title +config.authoring.screen.size =Authoring screen size +config.monitor.screen.size =Monitor screen size +config.learner.screen.size =Learner screen size +config.admin.screen.size =System Admin screen size +label.tool =Tool +label.tool.version =Tool version +label.database.version =Database version +config.ldap.search.filter =Search filter +config.ldap.base.dn =Base distinguished name +config.ldap.bind.user.dn =Bind user distinguished name +config.ldap.bind.user.password =Bind user password +admin.user.authentication.method =Authentication method +config.smtp.user =SMTP user +config.smtp.password =SMTP password +config.header.red5 =Media server +config.red5.server.url =Media server URL +config.red5.recordings.url =Media server recordings URL +admin.gradebook.learner.enable =Enable Gradebook for learners +sysadmin.serverUrl =External server URL +admin.statistics.title =Server statistics +admin.statistics.overall =Overall statistics +admin.statistics.totalUsers =Total users: +admin.statistics.groups =Total courses: +admin.statistics.subGroups =Total subcourses: +admin.statistics.learningDesigns =Total learning designs: +admin.statistics.lessons =Total lessons: +admin.statistics.activities =Total activities: +admin.statistics.completedActivities =Total completed activities: +admin.statistics.title.byGroup =Statistics by course +admin.statistics.group.learners =Total Learners: +admin.statistics.group.monitors =Total Monitors: +admin.statistics.group.authors =Total Authors: +admin.themes.title =Theme management +admin.themes.theme =Theme +admin.themes.description =Description +admin.themes.imageDir =CSS image directory +admin.themes.defaultTheme =Current default theme +admin.themes.remove =Remove +admin.themes.edit =Edit +admin.themes.addNew =Add/Edit theme +admin.themes.name =Name +admin.themes.makeThemeDefault =Make this theme the server default +admin.themes.makeDefault =Make default +admin.themes.deleteConfirm =Are you sure you want to delete this theme? +admin.themes.nameAlreadyExists =Please enter a new unused theme name, or click the edit icon to edit. +config.use.internal.smtp.server =Use internal SMTP server +label.email =Email +title.clone.lessons =Clone lessons +label.ok =OK +title.clone.lessons.for =Clone lessons for {0} +title.choose.group =Choose course to clone lessons from +label.choose =Choose +title.select.lessons =Select lessons +title.select.staff =Select staff +message.add.all.monitors =Add all monitors in this course to each lesson? +label.configure.staff =Configure staff +title.select.learners =Select learners +message.add.all.learners =Add all learners in this course to each lesson? +label.configure.learners =Configure learners +label.clone =Clone +message.cloned.lessons =Cloned {0} lessons. +message.no.lessons =There are no lessons to clone. +message.check.to.clone.lesson =Check the box for each lesson to clone it. +message.no.lesson.description =No lesson description +message.no.learners =This course has no learners! Please add some via the Add/Remove users screen. +message.check.to.add.learner =Check the box of each learner to add to each of the new lessons. +message.no.monitors =This course has no monitors! Please add some via the Add/Remove users screen. +message.check.to.add.monitor =Check the box of each monitor to add as staff to each of the new lessons. +label.return.to.group =Return to course +admin.timezone.title =Timezone management +admin.timezone.available.timezones =Available timezones +admin.timezone.select.timezones.you.want.users.choose =Select the timezones you want the users for choose from. The server timezone is: {0} +admin.timezone.select =Select +admin.timezone.time.zone.id =Time zone ID +admin.timezone.raw.offset =Raw offset (Hours : Minutes) +admin.timezone.dst.offset =DST offset (Minutes) +admin.timezone.display.name =Display name +admin.user.enable.flash.for.learner.window =Enable Flash for learner window +admin.user.time.zone =Time Zone +config.show.all.my.lesson.link =Show "All my lessons" link in User's profile +config.display.print.button =Display a print button when the lesson is completed +sysadmin.lessonFinishUrl =Lesson finish callback URL +admin.servertimezone.server.timezone.management =Server timezone management +admin.servertimezone.title =Server timezone management +admin.servertimezone.select.server.timezone =Please, select server timezone +admin.servertimezone.raw.offset =Raw offset: {0} +admin.servertimezone.dst.offset =DST offset: {0} +admin.servertimezone.name =Name: {0} +admin.servertimezone.select =Select +config.profile.edit.enable =Enable profile editing +config.profile.partial.edit.enable =Enable partial profile editing (only email and contact number can be changed) +config.server2server.registration.enable =Enable remote server user registration +admin.enable.course.notifications =Enable organisation notifications +cache.entries.title2 =Cacheable entities +cache.explanation4 =Listed below are cacheable classes and collections. This keeps certain common objects in memory to speed up LAMS. It is managed automatically and should not require any intervention. However, if the system appears to be keeping "old values" e.g. an old first name, try clearing all the nodes in the cache. Once cleared, LAMS will reload the objects from the database. +cache.button.remove.all =Clear all cached objects +cache.removed =Objects bound with entity name {0} were removed +cache.removed.all =All cached objects were removed +admin.add.edit.signup.page =Add/edit new signup page +admin.signup.title =Signup pages +admin.group =Course +admin.lessons =Add to lessons? +admin.staff =Add as staff/monitor? +admin.course.key =Course Key +admin.confirm.course.key =Confirm course key +admin.description.txt =Description +admin.disable.option =Disabled? +admin.context.path =Path to sign up +admin.submit =Submit +admin.actions =Actions +admin.group.code =Course access code +admin.added.on =Added on +admin.add.new.signup.page =Add a new signup page +admin.list.signup.pages =List of signup pages +error.course.keys.unequal =Course keys did not match +error.context.exists =This URL context is taken +config.authoring.suffix =Add unique suffix when importing Learning Designs +config.authoring.single.activity =Enable single activity lessons +error.name.invalid.characters =Name cannot contain any of these characters < > ^ * @ % $ +admin.login.tab =Display login tab as default +error.firstname.invalid.characters =First name contains invalid characters +error.lastname.invalid.characters =Last name contains invalid characters +error.username.invalid.characters =Username can only contain alphanumeric characters and no spaces +config.header.user.validation =User data validation +config.user.validation.username =Enforce username validation (only alphanumeric, hyphen (-), underscore (_), period (.), at sign (@) and single quote (') allowed) +config.user.validation.first.last.name =Enforce first and last name validation (only letters, hypen (-), space ( ) and single quote (') characters allowed) +config.user.validation.emails =Enforce properly formatted emails +config.cache.refresh =Configuration cache refresh interval (minutes) +error.login.request.ttl.negative =Login request time to live should be a positive number. +sysadmin.login.request.ttl =Time to live for integration requests (in minutes) +sysadmin.login.request.ttl.enable =Enforce time limitation for integration requests +tool.groups.open.button =Manage tool groups +tool.groups.open.button.tooltip =Assign tools to groups for later use in Authoring +tool.groups.dialog.title =Tool groups management +tool.groups.dialog.instructions =Manage groups by dragging and dropping tools +tool.groups.add.group.button =Add group +tool.groups.remove.group.button.tooltip =Remove group +tool.groups.group.default.name =Untitled +tool.groups.remove.confirm =Are you sure you want to remove this group? +tool.groups.group.name.error =A group name can not be blank +tool.groups.save.error =Error while saving groups +config.live.edit =Enable live edit +sysadmin.extGroupsUrl =External groups URL +server.config.title =Server configuration +server.monitor.title =Server monitoring +user.course.title =User and course configuration +config.site.name =Site name +label.create.lesson =Create lesson +label.manage.tool.consumers =Maintain LTI Tool Consumers +label.edit.tool.consumer =Edit tool consumer details +label.add.tool.consumer =Add new tool consumer +sysadmin.serversecret =Secret +label.tool.consumers.count =LTI Tool Consumers(s) in total +config.stacktrace.error =Show full error message (stack trace) +config.password.minimum.characters =Minimum number of characters +config.password.uppercase =Must contain uppercase letter(s) +config.password.lowercase =Must contain lowercase letter(s) +config.header.password.policy =Password policy +config.password.numerics =Must contain at least a number +config.password.symbols =Must contain at least one symbol(s) +error.password.mismatch =Your passwords does not match. +error.password.empty =Password cannot be empty. +admin.user.change.password =Force password change +label.password.max.length =must be less than 25 characters +label.password.min.length =must be at least {0} characters long +label.password.old.must.entered =Old password must be entered +label.password.symbols.allowed =Only these symbols are allowed +label.password.restrictions =Password must follow the restrictions shown +label.password.must.contain =Password must contain +label.password.must.ucase =at least 1 upper case letter +label.password.must.number =at least 1 number +label.password.must.symbol =at least 1 symbol +sysadmin.batch.preview.lesson.delete =Delete old preview lessons +msg.cleanup.preview.lesson.confirm =Are you sure you want to delete all preview lessons? +msg.cleanup.preview.lesson.error =Error while deleting preview lessons +label.cleanup.preview.lesson.count =Number of preview/all lessons: +label.cleanup.preview.lesson.progress =Deleting... +error.theme.invalid =Invalid theme +label.theme =Theme +config.default.theme =Default theme +label.2FA.property.enable =Enable two-factor authentication +sysadmin.lti.consumer.monitor.roles =Comma-separated list of monitor roles +config.failed.attempts =Number of failed logins before locking account +config.lock.out.time =Number of minutes to lock account for +config.default.html.theme =Default theme +admin.user.changePassword =Change password +config.show.timezone.warning =Show warning when user's LAMS timezone does not match their computer/device. +label.password.must.lcase =at least 1 lower case letter +button.select.importfile =Select file to import +label.upload.info =Uploaded file must be an Excel file and not exceed size of {0} +errors.maxfilesize =Uploaded file exceeded maximum size: {0} +error.attachment.not.xls =File is not an Excel .xls file. +sysadmin.maintain.session =Logged in users +sysadmin.maintain.session.login =Login +sysadmin.maintain.session.id =Session ID +error.portrait.removal.failed =Unable to delete portrait. See error file for details +label.delete.portrait =Delete portrait +sysadmin.maintain.session.delete =Delete +config.display.portrait =Display learner's portrait in a progress bar +config.allow.kumalive =Enable Kumalive +admin.organisation.create.date =Creation date +admin.org.password.change.title =Reset password for course members +admin.org.password.change.button =Password reset +admin.org.password.change.is.staff =Authors/monitors +admin.org.password.change.is.learner =Students +admin.org.password.change.generate =Generate new password +admin.org.password.change.email =Email new password +admin.org.password.change.force =Force change password after login +admin.org.password.change.custom =Enter own password or generate one +admin.org.password.change.grid.login =Login +admin.org.password.change.grid.name =Name +admin.org.password.change.grid.email =Email +admin.org.password.change.grid.error.load =Error while loading users into grid +admin.org.password.change.choose =Change password for +admin.org.password.change.submit =Change password +admin.org.password.change.error.prefix.staff =Authors/monitors password +admin.org.password.change.error.prefix.learners =Authors/monitors password +admin.org.password.change.success =Passwords successfully changed +admin.org.password.change.email.subject =LAMS password change +admin.org.password.change.email.body =Your password has been changed to: {0}\n\n-- email sent automatically by LAMS +label.event.log =Event (Audit) Log +label.event.topic =Topic +label.event.type =Type of Event +label.select.topic =Select topic... +label.select.type =Select type... +label.date =Date +label.between.dates =Between dates +label.lesson.with.name =Lesson: {0} ({1}) +label.activity.with.name =Activity: {0} ({1}) +label.type.teacher.learning.design.create =Learning Design Created +label.type.teacher.lesson.create =Lesson Created +label.type.teacher.lesson.start =Lesson Started +label.type.teacher.lesson.change.state =Lesson State Changed +label.type.learner.activity.start =Activity Started +label.type.learner.activity.finish =Activity Finished +label.type.learner.lesson.complete =Lesson Complete +label.type.learner.lesson.mark.submit =Mark Submitted +label.type.activity.edit =Activity Edited +label.type.force.complete =Learner Force Completed +label.type.user.org.admin =Organisation or User Changed +label.type.login.as =Sysadmin Logged In As +label.type.password.change =Password Change +label.type.role.failure =Action Attempted With Wrong Roles +label.type.account.locked =Account Locked +label.type.notification =Notification +label.type.mark.updated =Mark Updated +label.type.mark.released =Mark Released +label.type.learner.content.updated =Learner's Entry Modified +label.type.learner.content.show.hide =Learner's Entry Shown/Hidden +label.type.unknown =Unknown +label.area.lesson =Lesson +label.area.security =Security +label.area.notification =Notification +label.area.marks =Marks +label.area.learner.content =Learner Entry +label.area.unknown =Unknown +audit.change.made.by =Changes Made By +audit.change.made.to =Changes Made To +admin.delete.lessons =Delete all lessons +msg.delete.all.lesson.confirm.1 =You are about to PERMANENTLY delete ALL lessons from course "{0}". Are you ABSOLUTELY sure that you want to do this? There will be no turning back! +msg.delete.all.lesson.confirm.2 =ALL lessons will be deleted, including active ones with learners in them. NO lessons will be left in the course. Are you sure you want to continue? +msg.delete.all.lesson.error =Error while deleting course lessons lessons +label.delete.all.lesson.count =Number of remaining / total lessons: +label.delete.all.lesson.progress =Deleting... +sysadmin.lesson.delete.title =Delete all lessons from course +label.type.live.edit =Live Edit +label.no.data.found =No data found +msg.delete.organisation.confirm =You are about to permanently remove a course. Are you sure want to do this? +msg.delete.organisation.delete.lessons.confirm =The course or one of its subcourses still contains lessons. They need to be permanently deleted first. You will be redirected to a page where you can do it. +config.kumalive.enable =Enable Kumalive +audit.remarks =Remarks +config.allow.direct.access.for.integration.learners =Allow direct access to main LAMS page for integration learners. +label.type.tool.mark.released =Tool Marks Released +label.policy.minor.change.hint =Minor changes are meant to be wording changes that do not affect the meaning of the policy. If this option is not checked, then a new version of the policy will be created and users will be required to consent to this new policy version. +label.select.country =Select a country +error.country.required =Country is required. +admin.policies.title =Policies and consents +admin.add.edit.policy =Add/edit new policy +label.name =Name +label.policy.type =Policy type +label.policy.status =Policy status +label.version =Version +label.last.modified =Last modified +label.consents =Consents +label.add.new.policy =Add a new policy +label.policy.status.hint =An active policy will require consent from new users. Existing users will need to consent to this policy on their next log in. +label.policy.status.active =Active +label.policy.status.inactive =Inactive +label.policy.type.site =Site policy +label.policy.type.privacy =Privacy policy +label.policy.type.third.party =Third party policy +label.policy.type.other =Other policy +label.summary =Summary +label.full.policy =Full policy +label.view.previous.versions =View previous versions +label.activate =Activate +label.deactivate =Deactivate +label.minor.change =Minor change +label.policy.consents =Policy consents +label.consented =Consented? +label.consented.on =Consented on +label.user.consents =User consents +label.user.full.name =Full name +admin.user.create.date =Created on +admin.email.verify =Require email verification? +admin.email.verify.desc =(a verification email will be send before user can log in for the first time) +config.smtp.port =SMTP port +config.smtp.auth.security =SMTP authentication security +config.server.country =Country +sysadmin.lesson.gradebook.complete =Display activity scores on completion +sysadmin.lesson.liveedit =Enable Live Edit +sysadmin.lesson.notification =Enable lesson notifications +sysadmin.lesson.presence =Allow learners to see who is online +sysadmin.lesson.im =Enable Instant Messaging +sysadmin.lesson.force.restart =Learners always start from the first activity +sysadmin.lesson.allow.restart =Learners can restart the lesson +sysadmin.lesson.default =Lesson default settings +config.enable.portrait.editing =Enable profile portrait editing +label.search =Search... +config.enable.forgot.your.password.link =Enable "Forgot your password" link at the login page +admin.outcome.title =Outcomes management +outcome.authoring.title =Learning outcomes +outcome.authoring.input =Search and select by outcome name or code +outcome.authoring.existing =Added outcomes +outcome.authoring.existing.none =none +outcome.authoring.remove.confirm =Are you sure you want to remove this learning outcome? +sysadmin.maintain.session.name =Name +congfig.header.antivirus =Antivirus +config.av.enable =Enable antivirus scanning on file upload +config.av.host =ClamAV server host +config.av.port =ClamAV server port +label.type.login =User login +label.type.logout =User logout +label.type.config.change =Configuration change +config.learning.outcome.add.enable =Enable quick add of learning outcomes in authoring +config.qb.qti.enable =Enable QTI question import/export +config.qb.word.enable =Enable Word question import +config.qb.collections.create.enable =Allow creating custom collections +config.qb.collections.transfer.enable =Allow question transfer between collections +config.qb.monitors.read.only =Force read-only access for monitors +config.qb.stats.min.participants =Minimum test participant number to calculate question indexes +config.qb.stats.group.size =Percent of participants in top/bottom performers group (default: 27) + +outcome.authoring.remove.confirm =Are you sure you want to remove this learning outcome? +sysadmin.alternative.user.id.name =Use alternative parameter name "lis_person_sourcedid" to get user id +config.header.privacy.settings =Privacy settings +config.restricted.displaying.user.names.in.groupings =Groupings: only display names for learners within own group + +#======= End labels: Exported 627 labels for en AU ===== Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r0b3c5ce0f18b9e4a4195dc8144dc02784c6e3997 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0b3c5ce0f18b9e4a4195dc8144dc02784c6e3997) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -411,8 +411,8 @@ label.your.new.shared.secret =Your new shared secret: {0} label.2FA.shared.secret =Two-factor authentication shared secret label.2FA.login.panel =Two-factor authentication required -label.remove.org.favorite =Remove organisation from favorite ones -label.mark.org.favorite =Mark organisation as favorite +label.remove.org.favorite =Remove course from favourite list +label.mark.org.favorite =Mark course as favourite label.email.send.me.a.copy =Send me a copy label.password.max.length =must be less than 25 characters label.password.min.length =must be at least {0} characters long @@ -683,7 +683,7 @@ tour.lesson.conditions.content =Set up conditions for starting or ending the lesson. tour.lesson.remove.title =Remove Lesson tour.lesson.remove.content =Remove the lesson completely. This is permanent - it cannot be undone. -tour.end.title =End Of Tour +tour.end.title =End tour.end.content =Thank you for taking the tour. To restart the tour, click the Tour button again. errors.maxfilesize =Uploaded file exceeded maximum size: {0} error.attachment.executable =Uploaded file is executable @@ -696,7 +696,7 @@ authoring.fla.activity.branching.description =branching tour.prev =Prev tour.next =Next -tour.end.tour =End of tour +tour.end.tour =End label.search.for.courses =Search for courses label.save.as.course.grouping =Save as a Course Grouping label.enter.course.grouping.name =Please enter name for the new course grouping @@ -842,15 +842,14 @@ authoring.error.question.correct.num =RAT Questions: One of the answers for Question {0} needs to be correct. authoring.description.application.exercise =Application Exercise (These question(s) will be shown during the analysis phase in the sequence.) authoring.label.grouping =Teams -authoring.label.group.name =Team_{0} authoring.label.grouping.learners.choice =Learner's Choice authoring.label.grouping.teachers.choice =Teacher's Choice authoring.label.grouping.random.allocation =Random Allocation authoring.label.numgroups =Number of teams: authoring.error.numgroups =Number of teams must be 1 to 99. authoring.label.numlearners =Number of learners: authoring.error.numlearners =Number of learners must be 1 to 99. -authoring.error.group.data =Teams settings are not correct. +authoring.error.group.data =Team settings are not correct. authoring.section.lessondetails =Lesson Details authoring.section.questions =RAT Questions authoring.section.applicationexercise =Application Exercises @@ -870,27 +869,30 @@ button.return.to.template.list =Back to Templates authoring.error.content.id =Content ID is missing authoring.error.question.must.have.answer.num =RAT Questions: Question {0} must have at least one answer. -authoring.error.application.exercise.question.must.not.be.blank.num =Application Exercises: {0} Question {1} may not be blank. authoring.error.application.exercise.must.have.answer.num =Application Exercises: {0} Question {1} must have at least one answer. authoring.error.application.exercise.must.have.100.percent =Application Exercises: {0} Question {1} must have at least one answer worth 100%. authoring.error.application.exercise.not.blank.and.grade =Application Exercises: {0} Question {1} may not be blank and must have a grade. -authoring.error.application.exercise.needs.noticeboard.text =Application Exercises: {0} is missing the text for the noticeboard. -authoring.error.rat.not.blank=RAT Questions: There must be at least one question. authoring.label.grade =Grade authoring.label.none =None authoring.tbl.template.title =Team Based Learning authoring.tbl.template.description =Individual and Team Readiness Assessments followed by Application Exercises. authoring.tbl.desc.question =Adding RAT questions. -authoring.tbl.enable.confidence.tooltip =Asks students in the iRAT how confident they are with their choosen answer. Then the confidence level for each student is displayed in the tRAT to all members of their team. authoring.tbl.desc.ae =Adding Application Exercises (AEs). You can create multiple AEs if needed. +outcome.manage.remove.error.in.use =The outcome is mapped to some items. It can not be removed. +scale.manage.remove.error.in.use =The scale is used in some outcomes. It can not be removed. +outcome.authoring.remove.confirm =Are you sure you want to remove this learning outcome? +signup.email.welcome.subject =LAMS: account details +authoring.error.application.exercise.question.must.not.be.blank.num =Application Exercise {0} Question {1} may not be blank. +authoring.error.application.exercise.needs.noticeboard.text =Application Exercises: {0} is missing the text for the noticeboard. +authoring.error.rat.not.blank =RAT Questions: There must be at least one question. authoring.template.basic.import.qti =Import IMS QTI -authoring.tbl.use.noticeboard=Add Noticeboard after AE -authoring.tbl.use.noticeboard.tooltip=After the AE, displays content to students as additional information or as a reflection on the AE topic -authoring.create.application.exercise=Add New Application Exercise -label.marks=Marks -authoring.tbl.delete.appex.prompt=Do you want to delete the Application Exercise {0}? -authoring.tbl.delete.mcq.prompt=Do you want to delete the RAT Question {0}? -authoring.application.exercise.allow.multiple.responses =Allow Multiple Responses +authoring.tbl.use.noticeboard =Add Noticeboard after AE +authoring.create.application.exercise =Add new Application Exercise +authoring.tbl.enable.confidence.tooltip =Asks students in the iRAT how confident they are with their chosen answer. Then the confidence level for each student is displayed in the tRAT to all members of their team. +authoring.tbl.use.noticeboard.tooltip =After the AE, displays content to students as additional information or as a reflection on the AE topic. +authoring.tbl.delete.appex.prompt =Do you want to delete the Application Exercise {0}? +authoring.tbl.delete.mcq.prompt =Do you want to delete the RAT Question {0}? +authoring.application.exercise.allow.multiple.responses =Allow multiple responses authoring.application.exercise.allow.multiple.responses.tooltip =When learners are allowed to select multiple answers the grade is the sum of the grade for all correct responses selected. #QB questions# @@ -977,7 +979,10 @@ label.qb.collection.grid.stats =Stats label.qb.collection.edit =Edit +message.teacher.role.not.recognized =Please wait for a teacher to start the lesson. (You were logged in as a learner, as your current role does not conform LTI specification). +label.multiple.lessons =Multiple lessons +label.add.lessons.to.subgroups =Add lesson to all selected subcourses +label.marks =Marks - -#======= End labels: Exported 872 labels for en AU ===== +#======= End labels: Exported 892 labels for en AU ===== Index: lams_central/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -411,8 +411,8 @@ label.your.new.shared.secret =Your new shared secret: {0} label.2FA.shared.secret =Two-factor authentication shared secret label.2FA.login.panel =Two-factor authentication required -label.remove.org.favorite =Remove organisation from favorite ones -label.mark.org.favorite =Mark organisation as favorite +label.remove.org.favorite =Remove course from favourite list +label.mark.org.favorite =Mark course as favourite label.email.send.me.a.copy =Send me a copy label.password.max.length =must be less than 25 characters label.password.min.length =must be at least {0} characters long @@ -683,7 +683,7 @@ tour.lesson.conditions.content =Set up conditions for starting or ending the lesson. tour.lesson.remove.title =Remove Lesson tour.lesson.remove.content =Remove the lesson completely. This is permanent - it cannot be undone. -tour.end.title =End Of Tour +tour.end.title =End tour.end.content =Thank you for taking the tour. To restart the tour, click the Tour button again. errors.maxfilesize =Uploaded file exceeded maximum size: {0} error.attachment.executable =Uploaded file is executable @@ -696,7 +696,7 @@ authoring.fla.activity.branching.description =branching tour.prev =Prev tour.next =Next -tour.end.tour =End of tour +tour.end.tour =End label.search.for.courses =Search for courses label.save.as.course.grouping =Save as a Course Grouping label.enter.course.grouping.name =Please enter name for the new course grouping @@ -815,7 +815,6 @@ scale.manage.view =View scale scale.manage.remove =Remove scale scale.manage.remove.scale =Error while removing a scale. -scale.manage.remove.error.in.use =The scale is used in some outcomes. It can not be removed. scale.manage.remove.confirm =Are you sure you want to remove this scale? scale.manage.add.value =Values scale.manage.add.value.info =Enter comma separated values in increasing order of value. For example, an A,B,C,D scale must be entered as D,C,B,A. @@ -841,15 +840,14 @@ authoring.error.question.correct.num =RAT Questions: One of the answers for Question {0} needs to be correct. authoring.description.application.exercise =Application Exercise (These question(s) will be shown during the analysis phase in the sequence.) authoring.label.grouping =Teams -authoring.label.group.name =Team_{0} authoring.label.grouping.learners.choice =Learner's Choice authoring.label.grouping.teachers.choice =Teacher's Choice authoring.label.grouping.random.allocation =Random Allocation authoring.label.numgroups =Number of teams: authoring.error.numgroups =Number of teams must be 1 to 99. authoring.label.numlearners =Number of learners: authoring.error.numlearners =Number of learners must be 1 to 99. -authoring.error.group.data =Teams settings are not correct. +authoring.error.group.data =Team settings are not correct. authoring.section.lessondetails =Lesson Details authoring.section.questions =RAT Questions authoring.section.applicationexercise =Application Exercises @@ -869,7 +867,6 @@ button.return.to.template.list =Back to Templates authoring.error.content.id =Content ID is missing authoring.error.question.must.have.answer.num =RAT Questions: Question {0} must have at least one answer. -authoring.error.application.exercise.question.must.not.be.blank.num =Application Exercises: {0} Question {1} may not be blank. authoring.error.application.exercise.must.have.answer.num =Application Exercises: {0} Question {1} must have at least one answer. authoring.error.application.exercise.must.have.100.percent =Application Exercises: {0} Question {1} must have at least one answer worth 100%. authoring.error.application.exercise.not.blank.and.grade =Application Exercises: {0} Question {1} may not be blank and must have a grade. @@ -880,16 +877,22 @@ authoring.tbl.template.title =Team Based Learning authoring.tbl.template.description =Individual and Team Readiness Assessments followed by Application Exercises. authoring.tbl.desc.question =Adding RAT questions. -authoring.tbl.enable.confidence.tooltip =Asks students in the iRAT how confident they are with their choosen answer. Then the confidence level for each student is displayed in the tRAT to all members of their team. authoring.tbl.desc.ae =Adding Application Exercises (AEs). You can create multiple AEs if needed. +outcome.manage.remove.error.in.use =The outcome is mapped to some items. It can not be removed. +scale.manage.remove.error.in.use =The scale is used in some outcomes. It can not be removed. +outcome.authoring.remove.confirm =Are you sure you want to remove this learning outcome? +signup.email.welcome.subject =LAMS: account details +authoring.error.application.exercise.question.must.not.be.blank.num =Application Exercise {0} Question {1} may not be blank. +authoring.error.application.exercise.needs.noticeboard.text =Application Exercises: {0} is missing the text for the noticeboard. +authoring.error.rat.not.blank =RAT Questions: There must be at least one question. authoring.template.basic.import.qti =Import IMS QTI -authoring.tbl.use.noticeboard=Add Noticeboard after AE -authoring.tbl.use.noticeboard.tooltip=After the AE, displays content to students as additional information or as a reflection on the AE topic -authoring.create.application.exercise=Add New Application Exercise -label.marks=Marks -authoring.tbl.delete.appex.prompt=Do you want to delete the Application Exercise {0}? -authoring.tbl.delete.mcq.prompt=Do you want to delete the RAT Question {0}? -authoring.application.exercise.allow.multiple.responses =Allow Multiple Responses +authoring.tbl.use.noticeboard =Add Noticeboard after AE +authoring.create.application.exercise =Add new Application Exercise +authoring.tbl.enable.confidence.tooltip =Asks students in the iRAT how confident they are with their chosen answer. Then the confidence level for each student is displayed in the tRAT to all members of their team. +authoring.tbl.use.noticeboard.tooltip =After the AE, displays content to students as additional information or as a reflection on the AE topic. +authoring.tbl.delete.appex.prompt =Do you want to delete the Application Exercise {0}? +authoring.tbl.delete.mcq.prompt =Do you want to delete the RAT Question {0}? +authoring.application.exercise.allow.multiple.responses =Allow multiple responses authoring.application.exercise.allow.multiple.responses.tooltip =When learners are allowed to select multiple answers the grade is the sum of the grade for all correct responses selected. #QB questions# @@ -981,4 +984,8 @@ label.authoring.basic.none =None error.positive.grade.required =One of the answers should have a positive grade +message.teacher.role.not.recognized =Please wait for a teacher to start the lesson. (You were logged in as a learner, as your current role does not conform LTI specification). +label.multiple.lessons =Multiple lessons +label.add.lessons.to.subgroups =Add lesson to all selected subcourses +label.marks =Marks #======= End labels: Exported 872 labels for en AU ===== Index: lams_central/src/java/org/lamsfoundation/lams/web/outcome/OutcomeController.java =================================================================== diff -u -r0f2b554d8e5dca78a8e936730490d03ecd0357ba -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_central/src/java/org/lamsfoundation/lams/web/outcome/OutcomeController.java (.../OutcomeController.java) (revision 0f2b554d8e5dca78a8e936730490d03ecd0357ba) +++ lams_central/src/java/org/lamsfoundation/lams/web/outcome/OutcomeController.java (.../OutcomeController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -51,11 +51,11 @@ import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; -import org.lamsfoundation.lams.util.ExcelCell; -import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.beans.factory.annotation.Autowired; Index: lams_central/web/main.jsp =================================================================== diff -u -r2128de996e2dddada19946afdcd719bbd7bdbfab -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_central/web/main.jsp (.../main.jsp) (revision 2128de996e2dddada19946afdcd719bbd7bdbfab) +++ lams_central/web/main.jsp (.../main.jsp) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -1,339 +1,336 @@ -<%@ page contentType="text/html; charset=utf-8" language="java"%> -<%@ page import="org.lamsfoundation.lams.util.Configuration"%> -<%@ page import="org.lamsfoundation.lams.util.ConfigurationKeys"%> -<%@ taglib uri="tags-lams" prefix="lams"%> -<%@ taglib uri="tags-fmt" prefix="fmt"%> -<%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-function" prefix="fn"%> - - - - - - <fmt:message key="title.lams"/> :: <fmt:message key="index.welcome" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - -class="offcanvas-hidden"> - - - - - -
- - -
- -
- -
- - - -
- - - -
-
- <%-- -
Important annoucements might be posted here...
- --%> -
- -
-
-
-
-
-
- - - -
-
-

-  <%=Configuration.get(ConfigurationKeys.VERSION)%> - - © - - -

-
-
-
- - -
- - -
+<%@ page contentType="text/html; charset=utf-8" language="java"%> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-fmt" prefix="fmt"%> +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-function" prefix="fn"%> + + + + + + <fmt:message key="title.lams"/> :: <fmt:message key="index.welcome" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + +class="offcanvas-hidden"> + + + + + +
+ + +
+ +
+ +
+ + + +
+ + + +
+
+ <%-- +
Important annoucements might be posted here...
+ --%> +
+ +
+
+
+
+
+
+ + + + + + +
+ + +
Index: lams_central/web/questions/questionChoice.jsp =================================================================== diff -u -r3568517ed841a9c1cfe1b4831ee240929323ca2b -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_central/web/questions/questionChoice.jsp (.../questionChoice.jsp) (revision 3568517ed841a9c1cfe1b4831ee240929323ca2b) +++ lams_central/web/questions/questionChoice.jsp (.../questionChoice.jsp) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -64,7 +64,9 @@ if (returnURL == '') { form.css('visibility', 'hidden'); window.opener.saveQTI(form[0].outerHTML, 'questionForm', callerID); + // needs to be called twice for Chrome to close pop up window window.close(); + window.close(); } else { // this code is not really used at the moment, but it's available $.ajax({ @@ -73,7 +75,9 @@ data: form.serializeArray(), success: function(response) { window.opener.location.reload(); + // needs to be called twice for Chrome to close pop up window window.close(); + window.close(); } }); } Index: lams_common/src/java/org/lamsfoundation/lams/outcome/service/IOutcomeService.java =================================================================== diff -u -r67db3e1b2ada0d59ff98c807a54282783797c5e6 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_common/src/java/org/lamsfoundation/lams/outcome/service/IOutcomeService.java (.../IOutcomeService.java) (revision 67db3e1b2ada0d59ff98c807a54282783797c5e6) +++ lams_common/src/java/org/lamsfoundation/lams/outcome/service/IOutcomeService.java (.../IOutcomeService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -8,7 +8,7 @@ import org.lamsfoundation.lams.outcome.OutcomeMapping; import org.lamsfoundation.lams.outcome.OutcomeResult; import org.lamsfoundation.lams.outcome.OutcomeScale; -import org.lamsfoundation.lams.util.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelCell; import org.springframework.web.multipart.MultipartFile; public interface IOutcomeService { Index: lams_common/src/java/org/lamsfoundation/lams/outcome/service/OutcomeService.java =================================================================== diff -u -r0f2b554d8e5dca78a8e936730490d03ecd0357ba -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_common/src/java/org/lamsfoundation/lams/outcome/service/OutcomeService.java (.../OutcomeService.java) (revision 0f2b554d8e5dca78a8e936730490d03ecd0357ba) +++ lams_common/src/java/org/lamsfoundation/lams/outcome/service/OutcomeService.java (.../OutcomeService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -27,8 +27,8 @@ import org.lamsfoundation.lams.outcome.dao.IOutcomeDAO; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.excel.ExcelCell; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.web.multipart.MultipartFile; Index: lams_common/src/java/org/lamsfoundation/lams/questions/QuestionExporter.java =================================================================== diff -u -r3568517ed841a9c1cfe1b4831ee240929323ca2b -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_common/src/java/org/lamsfoundation/lams/questions/QuestionExporter.java (.../QuestionExporter.java) (revision 3568517ed841a9c1cfe1b4831ee240929323ca2b) +++ lams_common/src/java/org/lamsfoundation/lams/questions/QuestionExporter.java (.../QuestionExporter.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -596,6 +596,7 @@ */ private void appendMaterialElements(Element materialElem, String text) { int index = 0; + text = text.replace("%20", " "); // looks for images stored in LAMS WWW secure folder Matcher imageTagMatcher = QuestionExporter.IMAGE_PATTERN.matcher(text); Index: lams_common/src/java/org/lamsfoundation/lams/util/ConfigurationKeys.java =================================================================== diff -u -r394f403c289f0fd7808c228840bead5c4e7d5d32 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_common/src/java/org/lamsfoundation/lams/util/ConfigurationKeys.java (.../ConfigurationKeys.java) (revision 394f403c289f0fd7808c228840bead5c4e7d5d32) +++ lams_common/src/java/org/lamsfoundation/lams/util/ConfigurationKeys.java (.../ConfigurationKeys.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -1,305 +1,307 @@ -/**************************************************************** - * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) - * ============================================================= - * License Information: http://lamsfoundation.org/licensing/lams/2.0/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2.0 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * http://www.gnu.org/licenses/gpl.txt - * **************************************************************** - */ - -package org.lamsfoundation.lams.util; - -/** - * Known keys for the configuration data. - * - * @author fmalikoff - * - */ -public class ConfigurationKeys { - - public static String ROOT = "Lams"; - - public static String SERVER_URL = "ServerURL"; - - public static String SERVER_URL_CONTEXT_PATH = "ServerURLContextPath"; - - public static String VERSION = "Version"; - - public static String LAMS_TEMP_DIR = "TempDir"; - - /** - * Directory in which lams.ear is deployed. Usually {JBOSS}/server/default/deploy/lams.ear - */ - public static String LAMS_EAR_DIR = "EARDir"; - - public static String SMTP_SERVER = "SMTPServer"; - - public static String SMTP_PORT = "SMTPPort"; - - public static String LAMS_ADMIN_EMAIL = "LamsSupportEmail"; - - public static String CONTENT_REPOSITORY_PATH = "ContentRepositoryPath"; - - public static String UPLOAD_FILE_MAX_SIZE = "UploadFileMaxSize"; - - public static String UPLOAD_FILE_LARGE_MAX_SIZE = "UploadLargeFileMaxSize"; - - public static String UPLOAD_FILE_MAX_MEMORY_SIZE = "UploadFileMaxMemorySize"; - - public static String CHAT_SERVER_NAME = "ChatServerName"; - - public static String CHAT_PORT_NUMBER = "ChatPortNumber"; - - public static String EXE_EXTENSIONS = "ExecutableExtensions"; - - public static String LICENSE_TICKET_FILE = "TicketFile"; - - public static String PREVIEW_CLEANUP_NUM_DAYS = "CleanupPreviewOlderThanDays"; - - /** - * Number of seconds before a user is considered "inactive" and gets logged out. - */ - public static String INACTIVE_TIME = "UserInactiveTimeout"; - - /** - * Allow more than one session to exist for one user. Needed for the test harness Do not set this parameter to true - * in production. - */ - public static String ALLOW_MULTIPLE_LOGIN = "AllowMultipleLogin"; - - /** Values for client updates */ - public static String SERVER_VERSION_NUMBER = "ServerVersionNumber"; - - /** Default locale for the server. Originally en_AU */ - public static String SERVER_LANGUAGE = "ServerLanguage"; - - /** - * Default country for the server. Originally AU - */ - public static String SERVER_COUNTRY = "ServerCountry"; - - /** - * Direction (left to right, right to left) for writing on HTML pages. Originally LTR - */ - public static String SERVER_PAGE_DIRECTION = "ServerPageDirection"; - - /** universal date of dictionary updates */ - public static String DICTIONARY_DATE_CREATED = "DictionaryDateCreated"; - - public static String HELP_URL = "HelpURL"; - - public static String XMPP_DOMAIN = "XmppDomain"; - - public static String XMPP_CONFERENCE = "XmppConference"; - - public static String XMPP_ADMIN = "XmppAdmin"; - - public static String XMPP_PASSWORD = "XmppPassword"; - - public static String DEFAULT_THEME = "DefaultTheme"; - - public static String ALLOW_DIRECT_LESSON_LAUNCH = "AllowDirectLessonLaunch"; - - public static String ALLOW_EDIT_ON_FLY = "AllowLiveEdit"; - - public static String ALLOW_KUMALIVE = "AllowKumalive"; - - public static String DISPLAY_PORTRAIT = "DisplayPortrait"; - - public static String ENABLE_PORTRAIT_EDITING = "EnablePortraitEditing"; - - public static String SHOW_ALL_MY_LESSON_LINK = "ShowAllMyLessonLink"; - - public static String LDAP_PROVISIONING_ENABLED = "LDAPProvisioningEnabled"; - - public static String LDAP_PROVIDER_URL = "LDAPProviderURL"; - - public static String LDAP_SECURITY_AUTHENTICATION = "LDAPSecurityAuthentication"; - - public static String LDAP_SEARCH_FILTER = "LDAPSearchFilter"; - - public static String LDAP_BASE_DN = "LDAPBaseDN"; - - public static String LDAP_BIND_USER_DN = "LDAPBindUserDN"; - - public static String LDAP_BIND_USER_PASSWORD = "LDAPBindUserPassword"; - - public static String LDAP_SECURITY_PROTOCOL = "LDAPSecurityProtocol"; - - public static String LDAP_LOGIN_ATTR = "LDAPLoginAttr"; - - public static String LDAP_FIRST_NAME_ATTR = "LDAPFNameAttr"; - - public static String LDAP_LAST_NAME_ATTR = "LDAPLNameAttr"; - - public static String LDAP_EMAIL_ATTR = "LDAPEmailAttr"; - - public static String LDAP_ADDR1_ATTR = "LDAPAddr1Attr"; - - public static String LDAP_ADDR2_ATTR = "LDAPAddr2Attr"; - - public static String LDAP_ADDR3_ATTR = "LDAPAddr3Attr"; - - public static String LDAP_CITY_ATTR = "LDAPCityAttr"; - - public static String LDAP_STATE_ATTR = "LDAPStateAttr"; - - public static String LDAP_POSTCODE_ATTR = "LDAPPostcodeAttr"; - - public static String LDAP_COUNTRY_ATTR = "LDAPCountryAttr"; - - public static String LDAP_DAY_PHONE_ATTR = "LDAPDayPhoneAttr"; - - public static String LDAP_EVENING_PHONE_ATTR = "LDAPEveningPhoneAttr"; - - public static String LDAP_FAX_ATTR = "LDAPFaxAttr"; - - public static String LDAP_MOBILE_ATTR = "LDAPMobileAttr"; - - public static String LDAP_LOCALE_ATTR = "LDAPLocaleAttr"; - - public static String LDAP_DISABLED_ATTR = "LDAPDisabledAttr"; - - public static String LDAP_ORG_ATTR = "LDAPOrgAttr"; - - public static String LDAP_ROLES_ATTR = "LDAPRolesAttr"; - - public static String LDAP_LEARNER_MAP = "LDAPLearnerMap"; - - public static String LDAP_MONITOR_MAP = "LDAPMonitorMap"; - - public static String LDAP_AUTHOR_MAP = "LDAPAuthorMap"; - - public static String LDAP_GROUP_ADMIN_MAP = "LDAPGroupAdminMap"; - - public static String LDAP_GROUP_MANAGER_MAP = "LDAPGroupManagerMap"; - - public static String LDAP_UPDATE_ON_LOGIN = "LDAPUpdateOnLogin"; - - public static String LDAP_ORG_FIELD = "LDAPOrgField"; - - public static String LDAP_ONLY_ONE_ORG = "LDAPOnlyOneOrg"; - - public static String LDAP_SEARCH_RESULTS_PAGE_SIZE = "LDAPSearchResultsPageSize"; - - /** Custom tab for the main page */ - public static String CUSTOM_TAB_LINK = "CustomTabLink"; - - public static String CUSTOM_TAB_TITLE = "CustomTabTitle"; - - /** - * Configurable screen sizes for authoring, monitor, learner and admin (LDEV-1598) - */ - public static String AUTHORING_SCREEN_SIZE = "AuthoringScreenSize"; - - public static String MONITOR_SCREEN_SIZE = "MonitorScreenSize"; - - public static String LEARNER_SCREEN_SIZE = "LearnerScreenSize"; - - public static String ADMIN_SCREEN_SIZE = "AdminScreenSize"; - - public static String GMAP_KEY = "GmapKey"; - - public static String RED5_SERVER_URL = "Red5ServerUrl"; - - public static String RED5_RECORDINGS_URL = "Red5RecordingsUrl"; - - public static String SMTP_AUTH_USER = "SMTPUser"; - - public static String SMTP_AUTH_PASSWORD = "SMTPPassword"; - - public static String SMTP_AUTH_SECURITY = "SMTPAuthSecurity"; - - public static String PROFILE_EDIT_ENABLE = "ProfileEditEnable"; - - public static String FORGOT_YOUR_PASSWORD_LINK_ENABLE = "EnableForgotYourPasswordLink"; - - public static String PROFILE_PARTIAL_EDIT_ENABLE = "ProfilePartialEditEnable"; - - public static String KALTURA_SERVER = "KalturaServer"; - - public static String KALTURA_PARTNER_ID = "KalturaPartnerId"; - - public static String KALTURA_SUB_PARTNER_ID = "KalturaSubPartnerId"; - - public static String KALTURA_USER_SECRET = "KalturaUserSecret"; - - public static String KALTURA_KCW_UI_CONF_ID = "KalturaKCWUiConfId"; - - public static String KALTURA_KDP_UI_CONF_ID = "KalturaKDPUiConfId"; - - public static String USER_VALIDATION_REQUIRED_USERNAME = "UserValidationUsername"; - - public static String USER_VALIDATION_REQUIRED_FIRST_LAST_NAME = "UserValidationFirstLastName"; - - public static String USER_VALIDATION_REQUIRED_EMAIL = "UserValidationEmail"; - - // LDEV-2747 - public static String ENABLE_SERVER_REGISTRATION = "EnableServerRegistration"; - - // CNG-26 Add to lams_configuration and set to false - // if you don't want imported LD to have __ appended - public static String SUFFIX_IMPORTED_LD = "SuffixImportedLD"; - - // LDEV-3254 - public static String CONFIGURATION_CACHE_REFRESH_INTERVAL = "ConfigCacheRefreshInterval"; - - // LDEV-3961 - public static String SITE_NAME = "SiteName"; - - // LDEV-4023 Password policy - public static String PASSWORD_POLICY_MINIMUM_CHARACTERS = "PasswordPolicyMinChars"; - - public static String PASSWORD_POLICY_UPPERCASE = "PasswordPolicyUppercase"; - - public static String PASSWORD_POLICY_LOWERCASE = "PasswordPolicyLowercase"; - - public static String PASSWORD_POLICY_NUMERICS = "PasswordPolicyNumerics"; - - public static String PASSWORD_POLICY_SYMBOLS = "PasswordPolicySymbols"; - - // LDEV-4049 Option for not displaying stacktraces in config settings - public static String ERROR_STACK_TRACE = "ErrorStackTrace"; - - // LDEV-4030 Disable login for a few minutes after X number of attempts - public static String FAILED_ATTEMPTS = "FailedAttempts"; - - public static String LOCK_OUT_TIME = "LockOutTime"; - - // LDEV-4144 - public static String SHOW_TIMEZONE_WARNING = "ShowTimezoneWarning"; - - // LDEV-4594 / LDEV-4583 Allow/Block access to index.do for integration learners. Default to false - do not allow direct access. - public static String ALLOW_DIRECT_ACCESS_FOR_INTEGRATION_LEARNERS = "AllowDirectAccessIntgrtnLrnr"; - - // LDEV-4755 Antivirus - public static String ANTIVIRUS_ENABLE = "AntivirusEnable"; - public static String ANTIVIRUS_HOST = "AntivirusHost"; - public static String ANTIVIRUS_PORT = "AntivirusPort"; - - // LDEV-4819 - public static String LEARNING_OUTCOME_QUICK_ADD_ENABLE = "LearningOutcomeQuickAddEnable"; - - // LDEV-4827 Question Bank - public static String QB_QTI_ENABLE = "QbQtiEnable"; - public static String QB_WORD_ENABLE = "QbWordEnable"; - public static String QB_COLLECTIONS_CREATE_ALLOW = "QbCollectionsCreateEnable"; - public static String QB_COLLECTIONS_TRANSFER_ALLOW = "QbCollectionsTransferEnable"; - public static String QB_MONITORS_READ_ONLY = "QbMonitorsReadOnly"; - public static String QB_STATS_MIN_PARTICIPANTS = "QbStatsMinParticipants"; - public static String QB_STATS_GROUP_SIZE = "QbStatsGroupSize"; -} +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.util; + +/** + * Known keys for the configuration data. + * + * @author fmalikoff + * + */ +public class ConfigurationKeys { + + public static String ROOT = "Lams"; + + public static String SERVER_URL = "ServerURL"; + + public static String SERVER_URL_CONTEXT_PATH = "ServerURLContextPath"; + + public static String VERSION = "Version"; + + public static String LAMS_TEMP_DIR = "TempDir"; + + /** + * Directory in which lams.ear is deployed. Usually {JBOSS}/server/default/deploy/lams.ear + */ + public static String LAMS_EAR_DIR = "EARDir"; + + public static String SMTP_SERVER = "SMTPServer"; + + public static String SMTP_PORT = "SMTPPort"; + + public static String LAMS_ADMIN_EMAIL = "LamsSupportEmail"; + + public static String CONTENT_REPOSITORY_PATH = "ContentRepositoryPath"; + + public static String UPLOAD_FILE_MAX_SIZE = "UploadFileMaxSize"; + + public static String UPLOAD_FILE_LARGE_MAX_SIZE = "UploadLargeFileMaxSize"; + + public static String UPLOAD_FILE_MAX_MEMORY_SIZE = "UploadFileMaxMemorySize"; + + public static String CHAT_SERVER_NAME = "ChatServerName"; + + public static String CHAT_PORT_NUMBER = "ChatPortNumber"; + + public static String EXE_EXTENSIONS = "ExecutableExtensions"; + + public static String LICENSE_TICKET_FILE = "TicketFile"; + + public static String PREVIEW_CLEANUP_NUM_DAYS = "CleanupPreviewOlderThanDays"; + + /** + * Number of seconds before a user is considered "inactive" and gets logged out. + */ + public static String INACTIVE_TIME = "UserInactiveTimeout"; + + /** + * Allow more than one session to exist for one user. Needed for the test harness Do not set this parameter to true + * in production. + */ + public static String ALLOW_MULTIPLE_LOGIN = "AllowMultipleLogin"; + + /** Values for client updates */ + public static String SERVER_VERSION_NUMBER = "ServerVersionNumber"; + + /** Default locale for the server. Originally en_AU */ + public static String SERVER_LANGUAGE = "ServerLanguage"; + + /** + * Default country for the server. Originally AU + */ + public static String SERVER_COUNTRY = "ServerCountry"; + + /** + * Direction (left to right, right to left) for writing on HTML pages. Originally LTR + */ + public static String SERVER_PAGE_DIRECTION = "ServerPageDirection"; + + /** universal date of dictionary updates */ + public static String DICTIONARY_DATE_CREATED = "DictionaryDateCreated"; + + public static String HELP_URL = "HelpURL"; + + public static String XMPP_DOMAIN = "XmppDomain"; + + public static String XMPP_CONFERENCE = "XmppConference"; + + public static String XMPP_ADMIN = "XmppAdmin"; + + public static String XMPP_PASSWORD = "XmppPassword"; + + public static String DEFAULT_THEME = "DefaultTheme"; + + public static String ALLOW_DIRECT_LESSON_LAUNCH = "AllowDirectLessonLaunch"; + + public static String ALLOW_EDIT_ON_FLY = "AllowLiveEdit"; + + public static String ALLOW_KUMALIVE = "AllowKumalive"; + + public static String DISPLAY_PORTRAIT = "DisplayPortrait"; + + public static String ENABLE_PORTRAIT_EDITING = "EnablePortraitEditing"; + + public static String SHOW_ALL_MY_LESSON_LINK = "ShowAllMyLessonLink"; + + public static String LDAP_PROVISIONING_ENABLED = "LDAPProvisioningEnabled"; + + public static String LDAP_PROVIDER_URL = "LDAPProviderURL"; + + public static String LDAP_SECURITY_AUTHENTICATION = "LDAPSecurityAuthentication"; + + public static String LDAP_SEARCH_FILTER = "LDAPSearchFilter"; + + public static String LDAP_BASE_DN = "LDAPBaseDN"; + + public static String LDAP_BIND_USER_DN = "LDAPBindUserDN"; + + public static String LDAP_BIND_USER_PASSWORD = "LDAPBindUserPassword"; + + public static String LDAP_SECURITY_PROTOCOL = "LDAPSecurityProtocol"; + + public static String LDAP_LOGIN_ATTR = "LDAPLoginAttr"; + + public static String LDAP_FIRST_NAME_ATTR = "LDAPFNameAttr"; + + public static String LDAP_LAST_NAME_ATTR = "LDAPLNameAttr"; + + public static String LDAP_EMAIL_ATTR = "LDAPEmailAttr"; + + public static String LDAP_ADDR1_ATTR = "LDAPAddr1Attr"; + + public static String LDAP_ADDR2_ATTR = "LDAPAddr2Attr"; + + public static String LDAP_ADDR3_ATTR = "LDAPAddr3Attr"; + + public static String LDAP_CITY_ATTR = "LDAPCityAttr"; + + public static String LDAP_STATE_ATTR = "LDAPStateAttr"; + + public static String LDAP_POSTCODE_ATTR = "LDAPPostcodeAttr"; + + public static String LDAP_COUNTRY_ATTR = "LDAPCountryAttr"; + + public static String LDAP_DAY_PHONE_ATTR = "LDAPDayPhoneAttr"; + + public static String LDAP_EVENING_PHONE_ATTR = "LDAPEveningPhoneAttr"; + + public static String LDAP_FAX_ATTR = "LDAPFaxAttr"; + + public static String LDAP_MOBILE_ATTR = "LDAPMobileAttr"; + + public static String LDAP_LOCALE_ATTR = "LDAPLocaleAttr"; + + public static String LDAP_DISABLED_ATTR = "LDAPDisabledAttr"; + + public static String LDAP_ORG_ATTR = "LDAPOrgAttr"; + + public static String LDAP_ROLES_ATTR = "LDAPRolesAttr"; + + public static String LDAP_LEARNER_MAP = "LDAPLearnerMap"; + + public static String LDAP_MONITOR_MAP = "LDAPMonitorMap"; + + public static String LDAP_AUTHOR_MAP = "LDAPAuthorMap"; + + public static String LDAP_GROUP_ADMIN_MAP = "LDAPGroupAdminMap"; + + public static String LDAP_GROUP_MANAGER_MAP = "LDAPGroupManagerMap"; + + public static String LDAP_UPDATE_ON_LOGIN = "LDAPUpdateOnLogin"; + + public static String LDAP_ORG_FIELD = "LDAPOrgField"; + + public static String LDAP_ONLY_ONE_ORG = "LDAPOnlyOneOrg"; + + public static String LDAP_SEARCH_RESULTS_PAGE_SIZE = "LDAPSearchResultsPageSize"; + + /** Custom tab for the main page */ + public static String CUSTOM_TAB_LINK = "CustomTabLink"; + + public static String CUSTOM_TAB_TITLE = "CustomTabTitle"; + + /** + * Configurable screen sizes for authoring, monitor, learner and admin (LDEV-1598) + */ + public static String AUTHORING_SCREEN_SIZE = "AuthoringScreenSize"; + + public static String MONITOR_SCREEN_SIZE = "MonitorScreenSize"; + + public static String LEARNER_SCREEN_SIZE = "LearnerScreenSize"; + + public static String ADMIN_SCREEN_SIZE = "AdminScreenSize"; + + public static String GMAP_KEY = "GmapKey"; + + public static String RED5_SERVER_URL = "Red5ServerUrl"; + + public static String RED5_RECORDINGS_URL = "Red5RecordingsUrl"; + + public static String SMTP_AUTH_USER = "SMTPUser"; + + public static String SMTP_AUTH_PASSWORD = "SMTPPassword"; + + public static String SMTP_AUTH_SECURITY = "SMTPAuthSecurity"; + + public static String PROFILE_EDIT_ENABLE = "ProfileEditEnable"; + + public static String FORGOT_YOUR_PASSWORD_LINK_ENABLE = "EnableForgotYourPasswordLink"; + + public static String PROFILE_PARTIAL_EDIT_ENABLE = "ProfilePartialEditEnable"; + + public static String KALTURA_SERVER = "KalturaServer"; + + public static String KALTURA_PARTNER_ID = "KalturaPartnerId"; + + public static String KALTURA_SUB_PARTNER_ID = "KalturaSubPartnerId"; + + public static String KALTURA_USER_SECRET = "KalturaUserSecret"; + + public static String KALTURA_KCW_UI_CONF_ID = "KalturaKCWUiConfId"; + + public static String KALTURA_KDP_UI_CONF_ID = "KalturaKDPUiConfId"; + + public static String USER_VALIDATION_REQUIRED_USERNAME = "UserValidationUsername"; + + public static String USER_VALIDATION_REQUIRED_FIRST_LAST_NAME = "UserValidationFirstLastName"; + + public static String USER_VALIDATION_REQUIRED_EMAIL = "UserValidationEmail"; + + public static String RESTRICTED_DISPLAYING_OF_USER_NAMES_IN_GROUPS = "RestrictedGroupUserNames"; + + // LDEV-2747 + public static String ENABLE_SERVER_REGISTRATION = "EnableServerRegistration"; + + // CNG-26 Add to lams_configuration and set to false + // if you don't want imported LD to have __ appended + public static String SUFFIX_IMPORTED_LD = "SuffixImportedLD"; + + // LDEV-3254 + public static String CONFIGURATION_CACHE_REFRESH_INTERVAL = "ConfigCacheRefreshInterval"; + + // LDEV-3961 + public static String SITE_NAME = "SiteName"; + + // LDEV-4023 Password policy + public static String PASSWORD_POLICY_MINIMUM_CHARACTERS = "PasswordPolicyMinChars"; + + public static String PASSWORD_POLICY_UPPERCASE = "PasswordPolicyUppercase"; + + public static String PASSWORD_POLICY_LOWERCASE = "PasswordPolicyLowercase"; + + public static String PASSWORD_POLICY_NUMERICS = "PasswordPolicyNumerics"; + + public static String PASSWORD_POLICY_SYMBOLS = "PasswordPolicySymbols"; + + // LDEV-4049 Option for not displaying stacktraces in config settings + public static String ERROR_STACK_TRACE = "ErrorStackTrace"; + + // LDEV-4030 Disable login for a few minutes after X number of attempts + public static String FAILED_ATTEMPTS = "FailedAttempts"; + + public static String LOCK_OUT_TIME = "LockOutTime"; + + // LDEV-4144 + public static String SHOW_TIMEZONE_WARNING = "ShowTimezoneWarning"; + + // LDEV-4594 / LDEV-4583 Allow/Block access to index.do for integration learners. Default to false - do not allow direct access. + public static String ALLOW_DIRECT_ACCESS_FOR_INTEGRATION_LEARNERS = "AllowDirectAccessIntgrtnLrnr"; + + // LDEV-4755 Antivirus + public static String ANTIVIRUS_ENABLE = "AntivirusEnable"; + public static String ANTIVIRUS_HOST = "AntivirusHost"; + public static String ANTIVIRUS_PORT = "AntivirusPort"; + + // LDEV-4819 + public static String LEARNING_OUTCOME_QUICK_ADD_ENABLE = "LearningOutcomeQuickAddEnable"; + + // LDEV-4827 Question Bank + public static String QB_QTI_ENABLE = "QbQtiEnable"; + public static String QB_WORD_ENABLE = "QbWordEnable"; + public static String QB_COLLECTIONS_CREATE_ALLOW = "QbCollectionsCreateEnable"; + public static String QB_COLLECTIONS_TRANSFER_ALLOW = "QbCollectionsTransferEnable"; + public static String QB_MONITORS_READ_ONLY = "QbMonitorsReadOnly"; + public static String QB_STATS_MIN_PARTICIPANTS = "QbStatsMinParticipants"; + public static String QB_STATS_GROUP_SIZE = "QbStatsGroupSize"; +} Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java =================================================================== diff -u -r67db3e1b2ada0d59ff98c807a54282783797c5e6 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 67db3e1b2ada0d59ff98c807a54282783797c5e6) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -95,10 +95,12 @@ import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.DateUtil; -import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelRow; +import org.lamsfoundation.lams.util.excel.ExcelSheet; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.web.context.WebApplicationContext; @@ -118,8 +120,6 @@ public class GradebookService implements IGradebookFullService { private static Logger logger = Logger.getLogger(GradebookService.class); - private static final ExcelCell[] EMPTY_ROW = new ExcelCell[4]; - private static final String TOOL_SIGNATURE_ASSESSMENT = "laasse10"; public static final String TOOL_SIGNATURE_SCRATCHIE = "lascrt11"; public static final String TOOL_SIGNATURE_MCQ = "lamc11"; @@ -141,7 +141,7 @@ @Override public List getGBActivityRowsForLearner(Long lessonId, Integer userId, TimeZone userTimezone) { - GradebookService.logger.debug("Getting gradebook user data for lesson: " + lessonId + ". For user: " + userId); + logger.debug("Getting gradebook user data for lesson: " + lessonId + ". For user: " + userId); Lesson lesson = lessonService.getLesson(lessonId); User learner = (User) userService.findById(User.class, userId); @@ -235,7 +235,7 @@ @Override public List getGBActivityArchiveRowsForLearner(Long activityId, Integer userId, TimeZone userTimezone) { - GradebookService.logger + logger .debug("Getting archive gradebook user data for activity: " + activityId + ". For user: " + userId); Activity activity = getActivityById(activityId); @@ -279,7 +279,7 @@ @Override public List getGBLessonComplete(Long lessonId, Integer userId) { - GradebookService.logger + logger .debug("Getting lesson complete gradebook user data for lesson: " + lessonId + ". For user: " + userId); Lesson lesson = lessonService.getLesson(lessonId); @@ -319,7 +319,7 @@ @Override public List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone, boolean escapeTitles) { - GradebookService.logger.debug("Getting gradebook data for lesson: " + lessonId); + logger.debug("Getting gradebook data for lesson: " + lessonId); Lesson lesson = lessonService.getLesson(lessonId); List gradebookActivityDTOs = new ArrayList<>(); @@ -729,7 +729,7 @@ } } catch (ToolException e) { - GradebookService.logger.debug( + logger.debug( "Runtime exception when attempted to get outputs for activity: " + toolActivity.getActivityId(), e); } } @@ -821,7 +821,7 @@ } } catch (ToolException e) { - GradebookService.logger.debug( + logger.debug( "Runtime exception when attempted to get outputs for activity: " + toolActivity.getActivityId(), e); } } @@ -1040,7 +1040,7 @@ } } else { - GradebookService.logger.error("Request for gradebook grid with a null organisation"); + logger.error("Request for gradebook grid with a null organisation"); } return lessonRows; @@ -1129,94 +1129,91 @@ @Override @SuppressWarnings("unchecked") - public LinkedHashMap exportLessonGradebook(Lesson lesson) { - + public List exportLessonGradebook(Lesson lesson) { boolean isWeighted = toolService.isWeightedMarks(lesson.getLearningDesign()); - LinkedHashMap dataToExport = new LinkedHashMap<>(); + List sheets = new LinkedList(); // -------------------- process summary excel page -------------------------------- + + ExcelSheet summarySheet = new ExcelSheet(getMessage("gradebook.export.lesson.summary")); + sheets.add(summarySheet); - // The entire data list - List rowList = new LinkedList<>(); - // Adding the lesson average data to the summary Double lessonAverageMarkValue = getAverageMarkForLesson(lesson.getLessonId()); - ExcelCell[] lessonAverageMark = new ExcelCell[2]; - lessonAverageMark[0] = new ExcelCell(getMessage("gradebook.export.average.lesson.mark"), true); - ExcelCell markCell = isWeighted ? GradebookUtil.createPercentageCell(lessonAverageMarkValue, true) - : new ExcelCell(lessonAverageMarkValue, false); - lessonAverageMark[1] = markCell; + ExcelRow lessonAverageMark = summarySheet.initRow(); + lessonAverageMark.addCell(getMessage("gradebook.export.average.lesson.mark"), true); + if (isWeighted) { + lessonAverageMark.addPercentageCell(lessonAverageMarkValue / 100.0); + } else { + lessonAverageMark.addCell(lessonAverageMarkValue); + } - ExcelCell[] lessonMedianTimeTaken = new ExcelCell[2]; - lessonMedianTimeTaken[0] = new ExcelCell(getMessage("gradebook.export.average.lesson.time.taken"), true); - lessonMedianTimeTaken[1] = new ExcelCell(gradebookDAO.getMedianTimeTakenLesson(lesson.getLessonId()) / 1000, + ExcelRow lessonMedianTimeTaken = summarySheet.initRow(); + lessonMedianTimeTaken.addCell(getMessage("gradebook.export.average.lesson.time.taken"), true); + lessonMedianTimeTaken.addCell(gradebookDAO.getMedianTimeTakenLesson(lesson.getLessonId()) / 1000, false); - rowList.add(lessonMedianTimeTaken); - rowList.add(GradebookService.EMPTY_ROW); + summarySheet.addEmptyRow(); // Adding the activity average data to the summary List activityRows = getGBActivityRowsForLesson(lesson.getLessonId(), null, false); - ExcelCell[] activityAverageTitle = new ExcelCell[1]; - activityAverageTitle[0] = new ExcelCell(getMessage("gradebook.export.activities"), true); - rowList.add(activityAverageTitle); + ExcelRow activityAverageTitle = summarySheet.initRow(); + activityAverageTitle.addCell(getMessage("gradebook.export.activities"), true); // Setting up the activity summary table - ExcelCell[] activityAverageRow = new ExcelCell[6]; - activityAverageRow[0] = new ExcelCell(getMessage("gradebook.export.activity"), true); - activityAverageRow[1] = new ExcelCell(getMessage("gradebook.columntitle.competences"), true); - activityAverageRow[2] = new ExcelCell(getMessage("gradebook.export.average.time.taken.seconds"), true); - activityAverageRow[3] = new ExcelCell(getMessage("gradebook.columntitle.averageMark"), true); - activityAverageRow[4] = new ExcelCell(getMessage("gradebook.export.min.time.taken.seconds"), true); - activityAverageRow[5] = new ExcelCell(getMessage("gradebook.export.max.time.taken.seconds"), true); - rowList.add(activityAverageRow); + ExcelRow activityAverageRow = summarySheet.initRow(); + activityAverageRow.addCell(getMessage("gradebook.export.activity"), true); + activityAverageRow.addCell(getMessage("gradebook.columntitle.competences"), true); + activityAverageRow.addCell(getMessage("gradebook.export.average.time.taken.seconds"), true); + activityAverageRow.addCell(getMessage("gradebook.columntitle.averageMark"), true); + activityAverageRow.addCell(getMessage("gradebook.export.min.time.taken.seconds"), true); + activityAverageRow.addCell(getMessage("gradebook.export.max.time.taken.seconds"), true); Iterator it = activityRows.iterator(); while (it.hasNext()) { GBActivityGridRowDTO activityRow = (GBActivityGridRowDTO) it.next(); // Add the activity average data - ExcelCell[] activityDataRow = new ExcelCell[6]; - activityDataRow[0] = new ExcelCell(activityRow.getRowName(), false); // this is the problem entry - activityDataRow[1] = new ExcelCell(activityRow.getCompetences(), false); - activityDataRow[2] = new ExcelCell(activityRow.getMedianTimeTakenSeconds(), false); - activityDataRow[3] = new ExcelCell(activityRow.getAverageMark(), false); - activityDataRow[4] = new ExcelCell(activityRow.getMinTimeTakenSeconds(), false); - activityDataRow[5] = new ExcelCell(activityRow.getMaxTimeTakenSeconds(), false); - rowList.add(activityDataRow); + ExcelRow activityDataRow = summarySheet.initRow(); + activityDataRow.addCell(activityRow.getRowName()); // this is the problem entry + activityDataRow.addCell(activityRow.getCompetences()); + activityDataRow.addCell(activityRow.getMedianTimeTakenSeconds()); + activityDataRow.addCell(activityRow.getAverageMark()); + activityDataRow.addCell(activityRow.getMinTimeTakenSeconds()); + activityDataRow.addCell(activityRow.getMaxTimeTakenSeconds()); } - rowList.add(GradebookService.EMPTY_ROW); + summarySheet.addEmptyRow(); // Adding the user lesson marks to the summary - ExcelCell[] userMarksTitle = new ExcelCell[1]; - userMarksTitle[0] = new ExcelCell(getMessage("gradebook.export.total.marks.for.lesson"), true); - rowList.add(userMarksTitle); + ExcelRow userMarksTitle = summarySheet.initRow(); + userMarksTitle.addCell(getMessage("gradebook.export.total.marks.for.lesson"), true); // Fetching the user data ArrayList userRows = getGBUserRowsForLesson(lesson, null); // Setting up the user marks table - ExcelCell[] userTitleRow = new ExcelCell[6]; - userTitleRow[0] = new ExcelCell(getMessage("gradebook.export.last.name"), true); - userTitleRow[1] = new ExcelCell(getMessage("gradebook.export.first.name"), true); - userTitleRow[2] = new ExcelCell(getMessage("gradebook.export.login"), true); - userTitleRow[3] = new ExcelCell(getMessage("gradebook.exportcourse.progress"), true); - userTitleRow[4] = new ExcelCell(getMessage("gradebook.export.time.taken.seconds"), true); - userTitleRow[5] = new ExcelCell(getMessage("gradebook.export.total.mark"), true); - rowList.add(userTitleRow); + ExcelRow userTitleRow = summarySheet.initRow(); + userTitleRow.addCell(getMessage("gradebook.export.last.name"), true); + userTitleRow.addCell(getMessage("gradebook.export.first.name"), true); + userTitleRow.addCell(getMessage("gradebook.export.login"), true); + userTitleRow.addCell(getMessage("gradebook.exportcourse.progress"), true); + userTitleRow.addCell(getMessage("gradebook.export.time.taken.seconds"), true); + userTitleRow.addCell(getMessage("gradebook.export.total.mark"), true); for (GBUserGridRowDTO userRow : userRows) { // Adding the user data for the lesson - ExcelCell[] userDataRow = new ExcelCell[6]; - userDataRow[0] = new ExcelCell(userRow.getLastName(), false); - userDataRow[1] = new ExcelCell(userRow.getFirstName(), false); - userDataRow[2] = new ExcelCell(userRow.getLogin(), false); - userDataRow[3] = new ExcelCell(getProgressMessage(userRow), false); - userDataRow[4] = new ExcelCell(userRow.getTimeTakenSeconds(), false); - userDataRow[5] = isWeighted ? GradebookUtil.createPercentageCell(userRow.getMark(), true) - : new ExcelCell(userRow.getMark(), false); - rowList.add(userDataRow); + ExcelRow userDataRow = summarySheet.initRow(); + userDataRow.addCell(userRow.getLastName()); + userDataRow.addCell(userRow.getFirstName()); + userDataRow.addCell(userRow.getLogin()); + userDataRow.addCell(getProgressMessage(userRow)); + userDataRow.addCell(userRow.getTimeTakenSeconds()); + if (isWeighted) { + userDataRow.addPercentageCell(userRow.getMark() / 100.0); + } else { + userDataRow.addCell(userRow.getMark()); + } } - rowList.add(GradebookService.EMPTY_ROW); + summarySheet.addEmptyRow(); // -- Summary for activity marks (simplified) --- @@ -1233,33 +1230,30 @@ } //add header - ExcelCell[] headerRow = new ExcelCell[1]; - headerRow[0] = new ExcelCell(getMessage("gradebook.summary.activity.marks"), true); - rowList.add(headerRow); - headerRow = new ExcelCell[3 + filteredActivityToUserDTOMap.keySet().size()]; - int count = 3; + ExcelRow headerRow = summarySheet.initRow(); + headerRow.addCell(getMessage("gradebook.summary.activity.marks"), true); + + headerRow = summarySheet.initRow(); + headerRow.addEmptyCells(3); for (Activity activity : filteredActivityToUserDTOMap.keySet()) { - headerRow[count++] = new ExcelCell(activity.getTitle(), true); // this one works + headerRow.addCell(activity.getTitle(), true); // this one works } - rowList.add(headerRow); - headerRow = new ExcelCell[4 + filteredActivityToUserDTOMap.keySet().size()]; - count = 0; - headerRow[count++] = new ExcelCell(getMessage("gradebook.export.last.name"), true); - headerRow[count++] = new ExcelCell(getMessage("gradebook.export.first.name"), true); - headerRow[count++] = new ExcelCell(getMessage("gradebook.export.login"), true); + + headerRow = summarySheet.initRow(); + headerRow.addCell(getMessage("gradebook.export.last.name"), true); + headerRow.addCell(getMessage("gradebook.export.first.name"), true); + headerRow.addCell(getMessage("gradebook.export.login"), true); for (Activity activity : filteredActivityToUserDTOMap.keySet()) { - headerRow[count++] = new ExcelCell(getMessage("gradebook.columntitle.mark"), true); + headerRow.addCell(getMessage("gradebook.columntitle.mark"), true); } - headerRow[count] = new ExcelCell(getMessage("gradebook.export.total.mark"), true); - rowList.add(headerRow); + headerRow.addCell(getMessage("gradebook.export.total.mark"), true); //iterating through all users in a lesson for (GBUserGridRowDTO userRow : userRows) { - ExcelCell[] userDataRow = new ExcelCell[4 + filteredActivityToUserDTOMap.keySet().size()]; - count = 0; - userDataRow[count++] = new ExcelCell(userRow.getLastName(), false); - userDataRow[count++] = new ExcelCell(userRow.getFirstName(), false); - userDataRow[count++] = new ExcelCell(userRow.getLogin(), false); + ExcelRow userDataRow = summarySheet.initRow(); + userDataRow.addCell(userRow.getLastName()); + userDataRow.addCell(userRow.getFirstName()); + userDataRow.addCell(userRow.getLogin()); for (Activity activity : filteredActivityToUserDTOMap.keySet()) { @@ -1272,35 +1266,32 @@ break; } } - userDataRow[count++] = new ExcelCell(userActivityMark, false); + userDataRow.addCell(userActivityMark); } - userDataRow[count] = isWeighted ? GradebookUtil.createPercentageCell(userRow.getMark(), true) - : new ExcelCell(userRow.getMark(), false); - rowList.add(userDataRow); + if (isWeighted) { + userDataRow.addPercentageCell(userRow.getMark() / 100.0); + } else { + userDataRow.addCell(userRow.getMark()); + } } - ExcelCell[][] summaryData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("gradebook.export.lesson.summary"), summaryData); - // -------------------- process activity excel page -------------------------------- - List rowList1 = new LinkedList<>(); + ExcelSheet activitySheet = new ExcelSheet(getMessage("gradebook.gridtitle.activitygrid")); + sheets.add(activitySheet); for (Activity activity : activityToUserDTOMap.keySet()) { - ExcelCell[] activityTitleRow = new ExcelCell[7]; - activityTitleRow[0] = new ExcelCell(activity.getTitle(), true); - rowList1.add(activityTitleRow); + ExcelRow activityTitleRow = activitySheet.initRow(); + activityTitleRow.addCell(activity.getTitle(), true); - count = 0; - ExcelCell[] titleRow = new ExcelCell[7]; - titleRow[count++] = new ExcelCell(getMessage("gradebook.export.last.name"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.export.first.name"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.export.login"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.columntitle.startDate"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.columntitle.completeDate"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.export.time.taken.seconds"), true); - titleRow[count++] = new ExcelCell(getMessage("gradebook.columntitle.mark"), true); - rowList1.add(titleRow); + ExcelRow titleRow = activitySheet.initRow(); + titleRow.addCell(getMessage("gradebook.export.last.name"), true); + titleRow.addCell(getMessage("gradebook.export.first.name"), true); + titleRow.addCell(getMessage("gradebook.export.login"), true); + titleRow.addCell(getMessage("gradebook.columntitle.startDate"), true); + titleRow.addCell(getMessage("gradebook.columntitle.completeDate"), true); + titleRow.addCell(getMessage("gradebook.export.time.taken.seconds"), true); + titleRow.addCell(getMessage("gradebook.columntitle.mark"), true); // Get the rest of the data List userDtos = activityToUserDTOMap.get(activity); @@ -1311,45 +1302,40 @@ String finishDate = (userDto.getFinishDate() == null) ? "" : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(userDto.getFinishDate()); - count = 0; - ExcelCell[] userDataRow = new ExcelCell[7]; - userDataRow[count++] = new ExcelCell(userDto.getLastName(), false); - userDataRow[count++] = new ExcelCell(userDto.getFirstName(), false); - userDataRow[count++] = new ExcelCell(userDto.getLogin(), false); - userDataRow[count++] = new ExcelCell(startDate, false); - userDataRow[count++] = new ExcelCell(finishDate, false); - userDataRow[count++] = new ExcelCell(userDto.getTimeTakenSeconds(), false); - userDataRow[count++] = new ExcelCell(userDto.getMark(), false); - rowList1.add(userDataRow); + ExcelRow userDataRow = activitySheet.initRow(); + userDataRow.addCell(userDto.getLastName()); + userDataRow.addCell(userDto.getFirstName()); + userDataRow.addCell(userDto.getLogin()); + userDataRow.addCell(startDate); + userDataRow.addCell(finishDate); + userDataRow.addCell(userDto.getTimeTakenSeconds()); + userDataRow.addCell(userDto.getMark()); } - rowList1.add(GradebookService.EMPTY_ROW); + activitySheet.addEmptyRow(); } - ExcelCell[][] activityData = rowList1.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("gradebook.gridtitle.activitygrid"), activityData); - // -------------------- process Learner View page -------------------------------- + ExcelSheet learnerViewSheet = new ExcelSheet(getMessage("gradebook.export.learner.view")); + sheets.add(learnerViewSheet); + Set learners = new TreeSet(new LastNameAlphabeticComparator()); if (lesson.getAllLearners() != null) { learners.addAll(lesson.getAllLearners()); } - - rowList = new LinkedList<>(); + for (User learner : learners) { - userTitleRow = new ExcelCell[4]; - userTitleRow[0] = new ExcelCell(learner.getFullName() + " (" + learner.getLogin() + ")", true); - rowList.add(userTitleRow); + userTitleRow = learnerViewSheet.initRow(); + userTitleRow.addCell(learner.getFullName() + " (" + learner.getLogin() + ")", true); - ExcelCell[] titleRow = new ExcelCell[5]; - titleRow[0] = new ExcelCell(getMessage("gradebook.export.activity"), true); - titleRow[1] = new ExcelCell(getMessage("gradebook.columntitle.startDate"), true); - titleRow[2] = new ExcelCell(getMessage("gradebook.columntitle.completeDate"), true); - titleRow[3] = new ExcelCell(getMessage("gradebook.export.time.taken.seconds"), true); - titleRow[4] = new ExcelCell(getMessage("gradebook.columntitle.mark"), true); - rowList.add(titleRow); + ExcelRow titleRow = learnerViewSheet.initRow(); + titleRow.addCell(getMessage("gradebook.export.activity"), true); + titleRow.addCell(getMessage("gradebook.columntitle.startDate"), true); + titleRow.addCell(getMessage("gradebook.columntitle.completeDate"), true); + titleRow.addCell(getMessage("gradebook.export.time.taken.seconds"), true); + titleRow.addCell(getMessage("gradebook.columntitle.mark"), true); Map activityIdToName = new HashMap<>(); @@ -1386,37 +1372,34 @@ String finishDate = (userDto.getFinishDate() == null) ? "" : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(userDto.getFinishDate()); - ExcelCell[] activityDataRow = new ExcelCell[5]; - activityDataRow[0] = new ExcelCell(activityRowName, false); - activityDataRow[1] = new ExcelCell(startDate, false); - activityDataRow[2] = new ExcelCell(finishDate, false); - activityDataRow[3] = new ExcelCell(userDto.getTimeTakenSeconds(), false); - activityDataRow[4] = new ExcelCell(userDto.getMark(), false); - rowList.add(activityDataRow); + ExcelRow activityDataRow = learnerViewSheet.initRow(); + activityDataRow.addCell(activityRowName); + activityDataRow.addCell(startDate); + activityDataRow.addCell(finishDate); + activityDataRow.addCell(userDto.getTimeTakenSeconds()); + activityDataRow.addCell(userDto.getMark()); } } // check if learner has restarted the lesson and has archived marks boolean hasArchivedMarks = gradebookDAO.hasArchivedMarks(lesson.getLessonId(), learner.getUserId()); if (hasArchivedMarks) { // "Previous attempts" row - ExcelCell[] attemptsRow = new ExcelCell[1]; - attemptsRow[0] = new ExcelCell(getMessage("gradebook.columntitle.attempts"), true); - rowList.add(attemptsRow); + ExcelRow attemptsRow = learnerViewSheet.initRow(); + attemptsRow.addCell(getMessage("gradebook.columntitle.attempts"), true); List lessonArchives = gradebookDAO .getArchivedLessonMarks(lesson.getLessonId(), learner.getUserId()); int attemptOrder = lessonArchives.size(); // go through each lesson attempt for (GradebookUserLessonArchive lessonArchive : lessonArchives) { // lesson attempt header - ExcelCell[] attemptRow = new ExcelCell[4]; - attemptRow[0] = new ExcelCell(getMessage("gradebook.columntitle.attempt"), true); - attemptRow[1] = new ExcelCell(attemptOrder, true); - attemptRow[1].setAlignment(ExcelCell.ALIGN_LEFT); - attemptRow[2] = new ExcelCell(getMessage("gradebook.columntitle.lesson.mark"), true); - attemptRow[3] = new ExcelCell(lessonArchive.getMark(), false); - rowList.add(attemptRow); + ExcelRow attemptRow = learnerViewSheet.initRow(); + attemptRow.addCell(getMessage("gradebook.columntitle.attempt"), true); + ExcelCell cell = attemptRow.addCell(attemptOrder, true); + cell.setAlignment(ExcelCell.ALIGN_LEFT); + attemptRow.addCell(getMessage("gradebook.columntitle.lesson.mark"), true); + attemptRow.addCell(lessonArchive.getMark()); Date archiveDate = lessonArchive.getArchiveDate(); LearnerProgressArchive learnerProgress = learnerProgressDAO @@ -1435,83 +1418,71 @@ } } - ExcelCell[] activityDataRow = new ExcelCell[5]; - activityDataRow[0] = new ExcelCell(activityIdToName.get(activity.getActivityId()), false); + ExcelRow activityDataRow = learnerViewSheet.initRow(); + activityDataRow.addCell(activityIdToName.get(activity.getActivityId())); Date startDate = getActivityStartDate(learnerProgress, activity, null); - activityDataRow[1] = new ExcelCell(startDate == null ? "" - : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(startDate), false); + activityDataRow.addCell(startDate == null ? "" + : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(startDate)); Date finishDate = getActivityFinishDate(learnerProgress, activity, null); - activityDataRow[2] = new ExcelCell(finishDate == null ? "" - : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(finishDate), false); + activityDataRow.addCell(finishDate == null ? "" + : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT.format(finishDate)); Long duration = getActivityDuration(learnerProgress, activity); - activityDataRow[3] = new ExcelCell(duration == null ? "" : duration / 1000, false); - activityDataRow[4] = new ExcelCell(activityArchive == null ? "" : activityArchive.getMark(), + activityDataRow.addCell(duration == null ? "" : duration / 1000); + activityDataRow.addCell(activityArchive == null ? "" : activityArchive.getMark(), false); - - rowList.add(activityDataRow); } attemptOrder--; } } - - rowList.add(GradebookService.EMPTY_ROW); + learnerViewSheet.addEmptyRow(); } - ExcelCell[][] userData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("gradebook.export.learner.view"), userData); - - return dataToExport; + return sheets; } @Override @SuppressWarnings("unchecked") - public LinkedHashMap exportCourseGradebook(Integer userId, Integer organisationId) { - LinkedHashMap dataToExport = new LinkedHashMap<>(); + public List exportCourseGradebook(Integer userId, Integer organisationId) { + List sheets = new LinkedList(); // The entire data list - List rowList = new LinkedList<>(); + ExcelSheet sheet = new ExcelSheet(getMessage("gradebook.exportcourse.course.summary")); + sheets.add(sheet); Set lessons = new TreeSet<>(new LessonComparator()); lessons.addAll(lessonService.getLessonsByGroupAndUser(userId, organisationId)); Map isWeightedLessonMap = new HashMap<>(); if ((lessons != null) && (lessons.size() > 0)) { - - int numberOfCellsInARow = 3 + (lessons.size() * 6); - // Adding the user lesson marks to the summary---------------------- - ExcelCell[] lessonsNames = new ExcelCell[numberOfCellsInARow]; - int i = 0; - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); + ExcelRow lessonsNames = sheet.initRow(); + lessonsNames.addCell(""); + lessonsNames.addCell(""); + lessonsNames.addCell(""); for (Lesson lesson : lessons) { - lessonsNames[i++] = new ExcelCell(messageService.getMessage("gradebook.exportcourse.lesson", + lessonsNames.addCell(messageService.getMessage("gradebook.exportcourse.lesson", new Object[] { lesson.getLessonName() }), true); - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); - lessonsNames[i++] = new ExcelCell("", false); + lessonsNames.addCell(""); + lessonsNames.addCell(""); + lessonsNames.addCell(""); + lessonsNames.addCell(""); + lessonsNames.addCell(""); } - rowList.add(lessonsNames); // Setting up the user marks table - ExcelCell[] headerRow = new ExcelCell[numberOfCellsInARow]; - i = 0; - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.last.name"), true); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.first.name"), true); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.login"), true); + ExcelRow headerRow = sheet.initRow(); + headerRow.addCell(getMessage("gradebook.export.last.name"), true); + headerRow.addCell(getMessage("gradebook.export.first.name"), true); + headerRow.addCell(getMessage("gradebook.export.login"), true); for (Lesson lesson : lessons) { - headerRow[i++] = new ExcelCell(getMessage("gradebook.exportcourse.progress"), true); - headerRow[i++] = new ExcelCell(getMessage("gradebook.columntitle.startDate"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.columntitle.completeDate"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.time.taken.seconds"), true); - headerRow[i++] = new ExcelCell(getMessage("gradebook.exportcourse.lessonFeedback"), true); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.total.mark"), true); + headerRow.addCell(getMessage("gradebook.exportcourse.progress"), true); + headerRow.addCell(getMessage("gradebook.columntitle.startDate")); + headerRow.addCell(getMessage("gradebook.columntitle.completeDate")); + headerRow.addCell(getMessage("gradebook.export.time.taken.seconds"), true); + headerRow.addCell(getMessage("gradebook.exportcourse.lessonFeedback"), true); + headerRow.addCell(getMessage("gradebook.export.total.mark"), true); } - rowList.add(headerRow); // collect users from all lessons & check if lesson uses weightings LinkedHashSet allLearners = new LinkedHashSet<>(); @@ -1537,11 +1508,10 @@ sortedLearners.addAll(allLearners); for (User learner : sortedLearners) { - i = 0; - ExcelCell[] userDataRow = new ExcelCell[numberOfCellsInARow]; - userDataRow[i++] = new ExcelCell(learner.getLastName(), false); - userDataRow[i++] = new ExcelCell(learner.getFirstName(), false); - userDataRow[i++] = new ExcelCell(learner.getLogin(), false); + ExcelRow userDataRow = sheet.initRow(); + userDataRow.addCell(learner.getLastName()); + userDataRow.addCell(learner.getFirstName()); + userDataRow.addCell(learner.getLogin()); for (Lesson lesson : lessons) { GBUserGridRowDTO userDto = new GBUserGridRowDTO(learner); @@ -1607,35 +1577,31 @@ } //all of GBUserGridRowDTOs will be displayed on 1 line on course export. - userDataRow[i++] = new ExcelCell(getProgressMessage(userDto), false); - userDataRow[i++] = new ExcelCell(startDate, false); - userDataRow[i++] = new ExcelCell(finishDate, false); - userDataRow[i++] = new ExcelCell(timeTakenSeconds, false); - userDataRow[i++] = new ExcelCell(feedback, false); - userDataRow[i++] = isWeightedLessonMap.get(lesson.getLessonId()) - ? GradebookUtil.createPercentageCell(mark, true) - : new ExcelCell(mark, false); + userDataRow.addCell(getProgressMessage(userDto)); + userDataRow.addCell(startDate); + userDataRow.addCell(finishDate); + userDataRow.addCell(timeTakenSeconds); + userDataRow.addCell(feedback); + if (isWeightedLessonMap.get(lesson.getLessonId())) { + userDataRow.addPercentageCell(mark / 100.0); + } else { + userDataRow.addCell(mark); + } } - - rowList.add(userDataRow); } } - - ExcelCell[][] summaryData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("gradebook.exportcourse.course.summary"), summaryData); - return dataToExport; + return sheets; } @Override - public LinkedHashMap exportSelectedLessonsGradebook(Integer userId, Integer organisationId, + public List exportSelectedLessonsGradebook(Integer userId, Integer organisationId, String[] lessonIds, boolean simplified) { - LinkedHashMap dataToExport = new LinkedHashMap<>(); + List sheets = new LinkedList(); + ExcelSheet sheet = new ExcelSheet(getMessage("gradebook.exportcourse.course.summary")); + sheets.add(sheet); Organisation organisation = (Organisation) userService.findById(Organisation.class, organisationId); - // The entire data list - List rowList = new LinkedList<>(); - User user = (User) userService.findById(User.class, userId); Set selectedLessons = new TreeSet<>(new LessonComparator()); Map isWeightedLessonMap = new HashMap<>(); @@ -1671,7 +1637,6 @@ } if (!selectedLessons.isEmpty()) { - // Fetching the user data List lessonIdLongs = new LinkedList<>(); for (String lessonId : lessonIds) { @@ -1696,52 +1661,90 @@ String weightedMessage = messageService.getMessage("label.activity.marks.weighted"); // Lesson names row---------------------- - ExcelCell[] lessonsNames = new ExcelCell[numberCellsPerRow]; + ExcelRow lessonsNames = sheet.initRow(); if (simplified) { - int i = 3; + lessonsNames.addEmptyCells(3); for (Lesson lesson : selectedLessons) { - lessonsNames[i++] = new ExcelCell(lesson.getLessonName(), true) + lessonsNames.addCell(lesson.getLessonName(), true) .setAlignment(ExcelCell.ALIGN_CENTER); } - lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_LEFT_THICK); - lessonsNames[i++] = new ExcelCell(getMessage("label.overall.totals"), true) + lessonsNames.addCell("", ExcelCell.BORDER_STYLE_LEFT_THICK); + lessonsNames.addCell(getMessage("label.overall.totals"), true) .setAlignment(ExcelCell.ALIGN_CENTER); - lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); + lessonsNames.addCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); } else { - int i = 4; + lessonsNames.addEmptyCells(4); for (Lesson lesson : selectedLessons) { - List lessonActivities = lessonActivitiesMap.get(lesson.getLessonId()); - int numberActivities = lessonActivities.size(); String lessonName = isWeightedLessonMap.get(lesson.getLessonId()) ? new StringBuilder(lesson.getLessonName()).append(" ").append(weightedMessage).toString() : lesson.getLessonName(); - lessonsNames[i + numberActivities] = new ExcelCell(lessonName, true); - i += 9 + (numberActivities * 2); + + List lessonActivities = lessonActivitiesMap.get(lesson.getLessonId()); + int numberActivities = lessonActivities.size(); + lessonsNames.addEmptyCells(numberActivities); + lessonsNames.addCell(lessonName, true); + lessonsNames.addEmptyCells(9 + (numberActivities * 2)); } - i -= 2; - lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_LEFT_THIN); - lessonsNames[i++] = new ExcelCell(getMessage("label.overall.totals"), true); - lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); +// i -= 2; + lessonsNames.addCell("", ExcelCell.BORDER_STYLE_LEFT_THIN); + lessonsNames.addCell(getMessage("label.overall.totals"), true); + lessonsNames.addCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); } - rowList.add(lessonsNames); // Headers row---------------------- + ExcelRow headerRow = sheet.initRow(); if (simplified) { - rowList.add(createSelectedLessonsHeaderSimplified(selectedLessons, numberCellsPerRow)); + // Simplified shows the learner's name once at the far left of the spreadsheet. + headerRow.addCell(getMessage("gradebook.export.last.name")); + headerRow.addCell(getMessage("gradebook.export.first.name")); + headerRow.addCell(getMessage("gradebook.export.login")); + + for (Lesson lesson : selectedLessons) { + headerRow.addCell(getMessage("label.total.actuals"), false, ExcelCell.BORDER_STYLE_LEFT_THIN) + .setAlignment(ExcelCell.ALIGN_CENTER); + } + + headerRow.addCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THICK) + .setAlignment(ExcelCell.ALIGN_CENTER); + headerRow.addCell(getMessage("label.max")).setAlignment(ExcelCell.ALIGN_CENTER); + headerRow.addCell("%", false, ExcelCell.BORDER_STYLE_RIGHT_THICK) + .setAlignment(ExcelCell.ALIGN_CENTER); } else { - rowList.add(createSelectedLessonsHeaderFull(selectedLessons, lessonActivitiesMap, numberCellsPerRow)); + //create Selected Lessons Header Full + for (Lesson lesson : selectedLessons) { + headerRow.addCell(getMessage("gradebook.export.last.name")); + headerRow.addCell(getMessage("gradebook.export.first.name")); + headerRow.addCell(getMessage("gradebook.export.login")); + headerRow.addCell(getMessage("label.group")); + headerRow.addCell(getMessage("gradebook.columntitle.startDate")); + headerRow.addCell(getMessage("gradebook.columntitle.completeDate")); + + List activities = lessonActivitiesMap.get(lesson.getLessonId()); + for (Activity activity : activities) { + headerRow.addCell(activity.getTitle(), true); + headerRow.addCell(getMessage("label.max.possible")); + } + + headerRow.addCell(getMessage("label.total.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THIN); + headerRow.addCell(getMessage("label.max.mark")); + headerRow.addCell("%", ExcelCell.BORDER_STYLE_RIGHT_THICK); + } + + headerRow.addEmptyCells(2); + headerRow.addCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THIN); + headerRow.addCell(getMessage("label.max"), true); + headerRow.addCell("%", true, ExcelCell.BORDER_STYLE_RIGHT_THICK); } // Actual data rows---------------------- for (User learner : allLearners) { Double overallTotal = 0d; Double overallMaxMark = 0d; - ExcelCell[] userRow = new ExcelCell[numberCellsPerRow]; - int i = 0; + ExcelRow userRow = sheet.initRow(); if (simplified) { - i = addUsernameCells(learner, userRow, i); + addUsernameCells(learner, userRow); } for (Lesson lesson : selectedLessons) { @@ -1752,14 +1755,14 @@ Boolean weighted = isWeightedLessonMap.get(lesson.getLessonId()); if (!simplified) { - i = addUsernameCells(learner, userRow, i); + addUsernameCells(learner, userRow); // check if learner is participating in this lesson if (!lesson.getAllLearners().contains(learner)) { - i += 3 + (activities.size() * 2); - userRow[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_LEFT_THIN); - userRow[i++] = new ExcelCell("", false); - userRow[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); + userRow.addEmptyCells(3 + (activities.size() * 2)); + userRow.addCell("", ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow.addCell(""); + userRow.addCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); continue; } @@ -1771,7 +1774,7 @@ break; } } - userRow[i++] = new ExcelCell(groupName, false); + userRow.addCell(groupName); //start and complete dates LearnerProgress learnerProgress = null; @@ -1784,11 +1787,11 @@ String startDate = (learnerProgress == null || learnerProgress.getStartDate() == null) ? "" : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT .format(learnerProgress.getStartDate()); - userRow[i++] = new ExcelCell(startDate, false); + userRow.addCell(startDate); String finishDate = (learnerProgress == null || learnerProgress.getFinishDate() == null) ? "" : FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT .format(learnerProgress.getFinishDate()); - userRow[i++] = new ExcelCell(finishDate, false); + userRow.addCell(finishDate); } for (ToolActivity activity : activities) { @@ -1813,19 +1816,19 @@ mark = doWeightedMarkCalc(mark, activity, weight, rawActivityTotalMarks); } if (!simplified) { - userRow[i++] = new ExcelCell(mark, false); + userRow.addCell(mark); } } else { if (!simplified) { - userRow[i++] = new ExcelCell("", false); + userRow.addCell(""); } } if (!simplified) { if (weightedActivityTotalMarks > 0) { - userRow[i++] = new ExcelCell(weightedActivityTotalMarks, false); + userRow.addCell(weightedActivityTotalMarks); } else { - userRow[i++] = new ExcelCell("", false); + userRow.addCell(""); } } @@ -1837,107 +1840,44 @@ if (simplified) { if (weighted) { - userRow[i++] = GradebookUtil.createPercentageCell(lessonTotal, true, false, - ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow.addPercentageCell(lessonTotal / 100.0, false, ExcelCell.BORDER_STYLE_LEFT_THIN); } else { - userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow.addCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); } } else { - userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); - userRow[i++] = new ExcelCell(lessonMaxMark, false); + userRow.addCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow.addCell(lessonMaxMark); Double percentage = (lessonMaxMark != 0) ? lessonTotal / lessonMaxMark : 0d; - userRow[i++] = GradebookUtil.createPercentageCell(percentage, false, false, - ExcelCell.BORDER_STYLE_RIGHT_THICK); + userRow.addPercentageCell(percentage, false, ExcelCell.BORDER_STYLE_RIGHT_THICK); } } Double percentage = (overallMaxMark != 0) ? overallTotal / overallMaxMark : 0d; if (simplified) { - userRow[i++] = new ExcelCell(overallTotal, ExcelCell.BORDER_STYLE_LEFT_THICK); - userRow[i++] = new ExcelCell(overallMaxMark, false); - userRow[i++] = GradebookUtil.createPercentageCell(percentage, false, false, - ExcelCell.BORDER_STYLE_RIGHT_THICK); + userRow.addCell(overallTotal, ExcelCell.BORDER_STYLE_LEFT_THICK); + userRow.addCell(overallMaxMark); + userRow.addPercentageCell(percentage, false, ExcelCell.BORDER_STYLE_RIGHT_THICK); } else { - i += 2; - userRow[i++] = new ExcelCell(overallTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); - userRow[i++] = new ExcelCell(overallMaxMark, false); - userRow[i++] = GradebookUtil.createPercentageCell(percentage, false, true, - ExcelCell.BORDER_STYLE_RIGHT_THICK); + userRow.addEmptyCells(2); + userRow.addCell(overallTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow.addCell(overallMaxMark); + userRow.addPercentageCell(percentage, true, ExcelCell.BORDER_STYLE_RIGHT_THICK); } - - rowList.add(userRow); } } - - ExcelCell[][] summaryData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("gradebook.exportcourse.course.summary"), summaryData); - return dataToExport; + return sheets; } - private int addUsernameCells(User learner, ExcelCell[] userRow, int i) { + private void addUsernameCells(User learner, ExcelRow userRow) { //first, last names and login String lastName = (learner.getLastName() == null) ? "" : learner.getLastName().toUpperCase(); - userRow[i++] = new ExcelCell(lastName, false); + userRow.addCell(lastName); String firstName = (learner.getFirstName() == null) ? "" : learner.getFirstName().toUpperCase(); - userRow[i++] = new ExcelCell(firstName, false); - userRow[i++] = new ExcelCell(learner.getLogin(), false); - return i; + userRow.addCell(firstName); + userRow.addCell(learner.getLogin()); } - private ExcelCell[] createSelectedLessonsHeaderFull(Set selectedLessons, - Map> lessonActivitiesMap, int numberCellsPerRow) { - int i; - ExcelCell[] headerRow = new ExcelCell[numberCellsPerRow]; - i = 0; - - for (Lesson lesson : selectedLessons) { - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.last.name"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.first.name"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.login"), false); - headerRow[i++] = new ExcelCell(getMessage("label.group"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.columntitle.startDate"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.columntitle.completeDate"), false); - - List activities = lessonActivitiesMap.get(lesson.getLessonId()); - for (Activity activity : activities) { - headerRow[i++] = new ExcelCell(activity.getTitle(), true); - headerRow[i++] = new ExcelCell(getMessage("label.max.possible"), false); - } - - headerRow[i++] = new ExcelCell(getMessage("label.total.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THIN); - headerRow[i++] = new ExcelCell(getMessage("label.max.mark"), false); - headerRow[i++] = new ExcelCell("%", ExcelCell.BORDER_STYLE_RIGHT_THICK); - } - i += 2; - headerRow[i++] = new ExcelCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THIN); - headerRow[i++] = new ExcelCell(getMessage("label.max"), true); - headerRow[i++] = new ExcelCell("%", true, ExcelCell.BORDER_STYLE_RIGHT_THICK); - return headerRow; - } - - private ExcelCell[] createSelectedLessonsHeaderSimplified(Set selectedLessons, int numberCellsPerRow) { - int i = 0; - ExcelCell[] headerRow = new ExcelCell[numberCellsPerRow]; - - // Simplified shows the learner's name once at the far left of the spreadsheet. - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.last.name"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.first.name"), false); - headerRow[i++] = new ExcelCell(getMessage("gradebook.export.login"), false); - - for (Lesson lesson : selectedLessons) { - headerRow[i++] = new ExcelCell(getMessage("label.total.actuals"), false, ExcelCell.BORDER_STYLE_LEFT_THIN) - .setAlignment(ExcelCell.ALIGN_CENTER); - } - - headerRow[i++] = new ExcelCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THICK) - .setAlignment(ExcelCell.ALIGN_CENTER); - headerRow[i++] = new ExcelCell(getMessage("label.max"), false).setAlignment(ExcelCell.ALIGN_CENTER); - headerRow[i++] = new ExcelCell("%", false, ExcelCell.BORDER_STYLE_RIGHT_THICK) - .setAlignment(ExcelCell.ALIGN_CENTER); - return headerRow; - } - @Override public void updateGradebookUserActivityMark(Double mark, String feedback, Integer userID, Long toolSessionID, Boolean markedInGradebook) { @@ -2328,10 +2268,10 @@ if (startDate != null) { if (timeZone == null) { - GradebookService.logger.warn("No user time zone provided, leaving server default"); + logger.warn("No user time zone provided, leaving server default"); } else { - if (GradebookService.logger.isTraceEnabled()) { - GradebookService.logger.trace("Adjusting time according to zone \"" + timeZone + "\""); + if (logger.isTraceEnabled()) { + logger.trace("Adjusting time according to zone \"" + timeZone + "\""); } startDate = DateUtil.convertToTimeZoneFromDefault(timeZone, startDate); } @@ -2368,10 +2308,10 @@ if (finishDate != null) { if (timeZone == null) { - GradebookService.logger.warn("No user time zone provided, leaving server default"); + logger.warn("No user time zone provided, leaving server default"); } else { - if (GradebookService.logger.isTraceEnabled()) { - GradebookService.logger.trace("Adjusting time according to zone \"" + timeZone + "\""); + if (logger.isTraceEnabled()) { + logger.trace("Adjusting time according to zone \"" + timeZone + "\""); } finishDate = DateUtil.convertToTimeZoneFromDefault(timeZone, finishDate); } Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/util/GradebookUtil.java =================================================================== diff -u -r43d88e533dd5666feeaeab4368982ad8028bfae3 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/util/GradebookUtil.java (.../GradebookUtil.java) (revision 43d88e533dd5666feeaeab4368982ad8028bfae3) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/util/GradebookUtil.java (.../GradebookUtil.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -1,318 +1,297 @@ -/**************************************************************** - * Copyright (C) 2008 LAMS Foundation (http://lamsfoundation.org) - * ============================================================= - * License Information: http://lamsfoundation.org/licensing/lams/2.0/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2.0 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA - * - * http://www.gnu.org/licenses/gpl.txt - * **************************************************************** - */ - -package org.lamsfoundation.lams.gradebook.util; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.lamsfoundation.lams.gradebook.dto.GradebookGridRowDTO; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBAverageMarkComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBIDComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBMarkComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBMedianTimeTakenComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBRowNameComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBStartDateComparator; -import org.lamsfoundation.lams.gradebook.dto.comparators.GBTimeTakenComparator; -import org.lamsfoundation.lams.util.CommonConstants; -import org.lamsfoundation.lams.util.ExcelCell; -import org.lamsfoundation.lams.util.WebUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -public class GradebookUtil { - - /** - * Wrapper method for printing the xml for grid rows - * - * It takes the list of rows along with the grid parameter and returns the - * xml for the altered set - * - * - * @param gridRows - * @param view - * @param sortBy - * @param isSearch - * @param searchField - * @param searchOper - * @param searchString - * @param sortOrder - * @param rowLimit - * @param page - * @return - */ - public static String toGridXML(List gridRows, GBGridView view, String sortBy, boolean isSearch, String searchField, - String searchOper, String searchString, String sortOrder, int rowLimit, int page) { - - // Alter the set based on the parameters - gridRows = GradebookUtil.makeGridRowAlterations(gridRows, sortBy, isSearch, searchField, searchOper, - searchString, sortOrder, rowLimit, page); - // Work out the sublist to fetch based on rowlimit and current page. - int totalPages = 1; - if (rowLimit < gridRows.size()) { - - totalPages = new Double( - Math.ceil(new Integer(gridRows.size()).doubleValue() / new Integer(rowLimit).doubleValue())) - .intValue(); - int firstRow = (page - 1) * rowLimit; - int lastRow = firstRow + rowLimit; - - if (lastRow > gridRows.size()) { - gridRows = gridRows.subList(firstRow, gridRows.size()); - } else { - gridRows = gridRows.subList(firstRow, lastRow); - } - - } - - return GradebookUtil.toGridXML(gridRows, page, totalPages, view); - } - - /** - * Tranlates a list of grid rows into the required jqGrid xml - * - * @param gridRows - * @param page - * @param totalPages - * @param view - * @return - */ - public static String toGridXML(List gridRows, int page, int totalPages, GBGridView view) { - String xml = ""; - try { - Document document = WebUtil.getDocument(); - - // root element - Element rootElement = document.createElement(CommonConstants.ELEMENT_ROWS); - - Element pageElement = document.createElement(CommonConstants.ELEMENT_PAGE); - pageElement.appendChild(document.createTextNode("" + page)); - rootElement.appendChild(pageElement); - - Element totalPageElement = document.createElement(CommonConstants.ELEMENT_TOTAL); - totalPageElement.appendChild(document.createTextNode("" + totalPages)); - rootElement.appendChild(totalPageElement); - - Element recordsElement = document.createElement(CommonConstants.ELEMENT_RECORDS); - recordsElement.appendChild(document.createTextNode("" + gridRows.size())); - rootElement.appendChild(recordsElement); - - Iterator iter = gridRows.iterator(); - while (iter.hasNext()) { - GradebookGridRowDTO gridRow = (GradebookGridRowDTO) iter.next(); - Element rowElement = document.createElement(CommonConstants.ELEMENT_ROW); - rowElement.setAttribute(CommonConstants.ELEMENT_ID, gridRow.getId().toString()); - - // Work out which grid we want to put the data into - ArrayList gridRowStringArray = new ArrayList<>(); - - gridRowStringArray = gridRow.toStringArray(view); - - for (String gradebookItem : gridRowStringArray) { - Element cellElement = document.createElement(CommonConstants.ELEMENT_CELL); - gradebookItem = (gradebookItem != null) ? gradebookItem : ""; - cellElement.appendChild(document.createTextNode(gradebookItem)); - rowElement.appendChild(cellElement); - } - rootElement.appendChild(rowElement); - } - - document.appendChild(rootElement); - xml = WebUtil.getStringFromDocument(document); - - } catch (ParserConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (TransformerException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return xml; - } - - public static String niceFormatting(Double mark) { - String markStr = new DecimalFormat("##0.00").format(mark); - return markStr; - } - - public static String niceFormatting(Double mark, boolean displayAsPercentage) { - String markStr = new DecimalFormat("##0.00").format(mark); - if (displayAsPercentage) { - markStr += "%"; - } - return markStr; - } - - public static ExcelCell createPercentageCell(Double mark, boolean markConversionNeeded) { - return GradebookUtil.createPercentageCell(mark, markConversionNeeded, false, 0); - } - -// public static ExcelCell createPercentageCell(Double mark, boolean markConversionNeeded, Boolean isBold) { -// return createPercentageCell(mark, markConversionNeeded, isBold, 0); -// } - - // if markConversionNeeded is true then mark is divided by 100. Otherwise assumes already a percentage. - public static ExcelCell createPercentageCell(Double mark, boolean markConversionNeeded, Boolean isBold, - int borderStyle) { - Double convertedMark = null; - if (mark != null) { - convertedMark = markConversionNeeded ? mark / 100.0 : mark; - } - - ExcelCell userMarkCell = new ExcelCell(convertedMark, isBold, borderStyle); - userMarkCell.setIsPercentage(true); - return userMarkCell; - } - - /** - * Alters a grid row for sorting and searching - * - * @param gridRows - * @param sortBy - * @param isSearch - * @param searchField - * @param searchOper - * @param searchString - * @param sortOrder - * @param rowLimit - * @param page - * @return - */ - @SuppressWarnings("unchecked") - private static List makeGridRowAlterations(List gridRows, String sortBy, boolean isSearch, String searchField, - String searchOper, String searchString, String sortOrder, int rowLimit, int page) { - - // Sort the list appropriately - if (sortBy != null) { - if (sortBy.equals(GradebookConstants.PARAM_ROW_NAME)) { - Collections.sort(gridRows, new GBRowNameComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_MARK)) { - Collections.sort(gridRows, new GBMarkComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_ID)) { - Collections.sort(gridRows, new GBIDComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_TIME_TAKEN)) { - Collections.sort(gridRows, new GBTimeTakenComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_AVG_TIME_TAKEN)) { - Collections.sort(gridRows, new GBMedianTimeTakenComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_AVG_MARK)) { - Collections.sort(gridRows, new GBAverageMarkComparator()); - } else if (sortBy.equals(GradebookConstants.PARAM_START_DATE)) { - Collections.sort(gridRows, new GBStartDateComparator()); - } else { - Collections.sort(gridRows, new GBRowNameComparator()); - } - } else { - Collections.sort(gridRows, new GBRowNameComparator()); - } - - // if it is a search fix up the set - if (isSearch && searchField != null && searchOper != null && searchString != null) { - gridRows = GradebookUtil.doRowNameSearch(gridRows, searchField, searchOper, searchString.toLowerCase()); - } - - // Reverse the order if requested - if (sortOrder != null && sortOrder.equals(GradebookConstants.SORT_DESC)) { - Collections.reverse(gridRows); - } - - return gridRows; - - } - - /** - * Does the search operation on the set for row names - * - * @param gradebookRows - * @param searchField - * @param searchOper - * @param searchString - * @return - */ - private static List doRowNameSearch(List gradebookRows, String searchField, String searchOper, - String searchString) { - List ret = new ArrayList<>(); - - if (searchField.equals(GradebookConstants.PARAM_ROW_NAME)) { - Iterator it = gradebookRows.iterator(); - - while (it.hasNext()) { - GradebookGridRowDTO userRow = (GradebookGridRowDTO) it.next(); - - String rowName = userRow.getRowName(); - rowName = rowName.toLowerCase(); - - if (searchOper.equals(GradebookConstants.SEARCH_EQUALS)) { - if (rowName.equals(searchString)) { - ret.add(userRow); - } - } else if (searchOper.equals(GradebookConstants.SEARCH_NOT_EQUALS)) { - if (!rowName.equals(searchString)) { - ret.add(userRow); - } - } else if (searchOper.equals(GradebookConstants.SEARCH_BEGINS_WITH)) { - if (rowName.startsWith(searchString)) { - ret.add(userRow); - } - } else if (searchOper.equals(GradebookConstants.SEARCH_ENDS_WITH)) { - if (rowName.endsWith(searchString)) { - ret.add(userRow); - } - } else if (searchOper.equals(GradebookConstants.SEARCH_CONTAINS)) { - if (rowName.contains(searchString)) { - ret.add(userRow); - } - } - } - - } - return ret; - } - - public static GBGridView readGBGridViewParam(HttpServletRequest request, String param_mode, boolean optional) { - String view = WebUtil.readStrParam(request, param_mode, optional); - if (view == null) { - return null; - } else if (view.equals(GradebookConstants.VIEW_MON_USER)) { - return GBGridView.MON_USER; - } else if (view.equals(GradebookConstants.VIEW_MON_ACTIVITY)) { - return GBGridView.MON_ACTIVITY; - } else if (view.equals(GradebookConstants.VIEW_MON_COURSE)) { - return GBGridView.MON_COURSE; - } else if (view.equals(GradebookConstants.VIEW_LRN_COURSE)) { - return GBGridView.LRN_COURSE; - } else if (view.equals(GradebookConstants.VIEW_LRN_ACTIVITY)) { - return GBGridView.LRN_ACTIVITY; - } else if (view.equals(GradebookConstants.VIEW_LIST)) { - return GBGridView.LIST; - } else { - throw new IllegalArgumentException("[" + view + "] is not a legal gradebook view"); - } - } -} +/**************************************************************** + * Copyright (C) 2008 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.gradebook.util; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.lamsfoundation.lams.gradebook.dto.GradebookGridRowDTO; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBAverageMarkComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBIDComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBMarkComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBMedianTimeTakenComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBRowNameComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBStartDateComparator; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBTimeTakenComparator; +import org.lamsfoundation.lams.util.CommonConstants; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class GradebookUtil { + + /** + * Wrapper method for printing the xml for grid rows + * + * It takes the list of rows along with the grid parameter and returns the + * xml for the altered set + * + * + * @param gridRows + * @param view + * @param sortBy + * @param isSearch + * @param searchField + * @param searchOper + * @param searchString + * @param sortOrder + * @param rowLimit + * @param page + * @return + */ + public static String toGridXML(List gridRows, GBGridView view, String sortBy, boolean isSearch, String searchField, + String searchOper, String searchString, String sortOrder, int rowLimit, int page) { + + // Alter the set based on the parameters + gridRows = GradebookUtil.makeGridRowAlterations(gridRows, sortBy, isSearch, searchField, searchOper, + searchString, sortOrder, rowLimit, page); + // Work out the sublist to fetch based on rowlimit and current page. + int totalPages = 1; + if (rowLimit < gridRows.size()) { + + totalPages = new Double( + Math.ceil(new Integer(gridRows.size()).doubleValue() / new Integer(rowLimit).doubleValue())) + .intValue(); + int firstRow = (page - 1) * rowLimit; + int lastRow = firstRow + rowLimit; + + if (lastRow > gridRows.size()) { + gridRows = gridRows.subList(firstRow, gridRows.size()); + } else { + gridRows = gridRows.subList(firstRow, lastRow); + } + + } + + return GradebookUtil.toGridXML(gridRows, page, totalPages, view); + } + + /** + * Tranlates a list of grid rows into the required jqGrid xml + * + * @param gridRows + * @param page + * @param totalPages + * @param view + * @return + */ + public static String toGridXML(List gridRows, int page, int totalPages, GBGridView view) { + String xml = ""; + try { + Document document = WebUtil.getDocument(); + + // root element + Element rootElement = document.createElement(CommonConstants.ELEMENT_ROWS); + + Element pageElement = document.createElement(CommonConstants.ELEMENT_PAGE); + pageElement.appendChild(document.createTextNode("" + page)); + rootElement.appendChild(pageElement); + + Element totalPageElement = document.createElement(CommonConstants.ELEMENT_TOTAL); + totalPageElement.appendChild(document.createTextNode("" + totalPages)); + rootElement.appendChild(totalPageElement); + + Element recordsElement = document.createElement(CommonConstants.ELEMENT_RECORDS); + recordsElement.appendChild(document.createTextNode("" + gridRows.size())); + rootElement.appendChild(recordsElement); + + Iterator iter = gridRows.iterator(); + while (iter.hasNext()) { + GradebookGridRowDTO gridRow = (GradebookGridRowDTO) iter.next(); + Element rowElement = document.createElement(CommonConstants.ELEMENT_ROW); + rowElement.setAttribute(CommonConstants.ELEMENT_ID, gridRow.getId().toString()); + + // Work out which grid we want to put the data into + ArrayList gridRowStringArray = new ArrayList<>(); + + gridRowStringArray = gridRow.toStringArray(view); + + for (String gradebookItem : gridRowStringArray) { + Element cellElement = document.createElement(CommonConstants.ELEMENT_CELL); + gradebookItem = (gradebookItem != null) ? gradebookItem : ""; + cellElement.appendChild(document.createTextNode(gradebookItem)); + rowElement.appendChild(cellElement); + } + rootElement.appendChild(rowElement); + } + + document.appendChild(rootElement); + xml = WebUtil.getStringFromDocument(document); + + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (TransformerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return xml; + } + + public static String niceFormatting(Double mark) { + String markStr = new DecimalFormat("##0.00").format(mark); + return markStr; + } + + public static String niceFormatting(Double mark, boolean displayAsPercentage) { + String markStr = new DecimalFormat("##0.00").format(mark); + if (displayAsPercentage) { + markStr += "%"; + } + return markStr; + } + + /** + * Alters a grid row for sorting and searching + * + * @param gridRows + * @param sortBy + * @param isSearch + * @param searchField + * @param searchOper + * @param searchString + * @param sortOrder + * @param rowLimit + * @param page + * @return + */ + @SuppressWarnings("unchecked") + private static List makeGridRowAlterations(List gridRows, String sortBy, boolean isSearch, String searchField, + String searchOper, String searchString, String sortOrder, int rowLimit, int page) { + + // Sort the list appropriately + if (sortBy != null) { + if (sortBy.equals(GradebookConstants.PARAM_ROW_NAME)) { + Collections.sort(gridRows, new GBRowNameComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_MARK)) { + Collections.sort(gridRows, new GBMarkComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_ID)) { + Collections.sort(gridRows, new GBIDComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_TIME_TAKEN)) { + Collections.sort(gridRows, new GBTimeTakenComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_AVG_TIME_TAKEN)) { + Collections.sort(gridRows, new GBMedianTimeTakenComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_AVG_MARK)) { + Collections.sort(gridRows, new GBAverageMarkComparator()); + } else if (sortBy.equals(GradebookConstants.PARAM_START_DATE)) { + Collections.sort(gridRows, new GBStartDateComparator()); + } else { + Collections.sort(gridRows, new GBRowNameComparator()); + } + } else { + Collections.sort(gridRows, new GBRowNameComparator()); + } + + // if it is a search fix up the set + if (isSearch && searchField != null && searchOper != null && searchString != null) { + gridRows = GradebookUtil.doRowNameSearch(gridRows, searchField, searchOper, searchString.toLowerCase()); + } + + // Reverse the order if requested + if (sortOrder != null && sortOrder.equals(GradebookConstants.SORT_DESC)) { + Collections.reverse(gridRows); + } + + return gridRows; + + } + + /** + * Does the search operation on the set for row names + * + * @param gradebookRows + * @param searchField + * @param searchOper + * @param searchString + * @return + */ + private static List doRowNameSearch(List gradebookRows, String searchField, String searchOper, + String searchString) { + List ret = new ArrayList<>(); + + if (searchField.equals(GradebookConstants.PARAM_ROW_NAME)) { + Iterator it = gradebookRows.iterator(); + + while (it.hasNext()) { + GradebookGridRowDTO userRow = (GradebookGridRowDTO) it.next(); + + String rowName = userRow.getRowName(); + rowName = rowName.toLowerCase(); + + if (searchOper.equals(GradebookConstants.SEARCH_EQUALS)) { + if (rowName.equals(searchString)) { + ret.add(userRow); + } + } else if (searchOper.equals(GradebookConstants.SEARCH_NOT_EQUALS)) { + if (!rowName.equals(searchString)) { + ret.add(userRow); + } + } else if (searchOper.equals(GradebookConstants.SEARCH_BEGINS_WITH)) { + if (rowName.startsWith(searchString)) { + ret.add(userRow); + } + } else if (searchOper.equals(GradebookConstants.SEARCH_ENDS_WITH)) { + if (rowName.endsWith(searchString)) { + ret.add(userRow); + } + } else if (searchOper.equals(GradebookConstants.SEARCH_CONTAINS)) { + if (rowName.contains(searchString)) { + ret.add(userRow); + } + } + } + + } + return ret; + } + + public static GBGridView readGBGridViewParam(HttpServletRequest request, String param_mode, boolean optional) { + String view = WebUtil.readStrParam(request, param_mode, optional); + if (view == null) { + return null; + } else if (view.equals(GradebookConstants.VIEW_MON_USER)) { + return GBGridView.MON_USER; + } else if (view.equals(GradebookConstants.VIEW_MON_ACTIVITY)) { + return GBGridView.MON_ACTIVITY; + } else if (view.equals(GradebookConstants.VIEW_MON_COURSE)) { + return GBGridView.MON_COURSE; + } else if (view.equals(GradebookConstants.VIEW_LRN_COURSE)) { + return GBGridView.LRN_COURSE; + } else if (view.equals(GradebookConstants.VIEW_LRN_ACTIVITY)) { + return GBGridView.LRN_ACTIVITY; + } else if (view.equals(GradebookConstants.VIEW_LIST)) { + return GBGridView.LIST; + } else { + throw new IllegalArgumentException("[" + view + "] is not a legal gradebook view"); + } + } +} Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r67db3e1b2ada0d59ff98c807a54282783797c5e6 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 67db3e1b2ada0d59ff98c807a54282783797c5e6) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -166,15 +166,13 @@ label.monitoring.user.summary.grade =Grade label.monitoring.user.summary.title =Title: label.monitoring.user.summary.question =Question: -label.monitoring.user.summary.ok =Ok label.monitoring.question.summary.history.responses =Responses for the question label.monitoring.question.summary.title =Title label.monitoring.question.summary.question =Question label.monitoring.question.summary.default.mark =Default mark label.monitoring.question.summary.penalty =Penalty label.monitoring.question.summary.average.mark =Average mark label.monitoring.question.summary.group =Group: -label.monitoring.question.summary.ok =Ok output.desc.learner.total.score =Last total score output.desc.learner.time.taken =Time taken output.desc.learner.number.of.attempts =Number of attempts @@ -356,4 +354,7 @@ label.qb.point.biserial =Point biserial outcome.authoring.create.new = [create new] +label.close =Close +label.export.time.attempted =Time attempted + #======= End labels: Exported 337 labels for en AU ===== Index: lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -304,5 +304,7 @@ label.answer.alternatives =Answer alternatives label.close=Close +label.export.time.attempted =Time attempted + #======= End labels: Exported 337 labels for en AU ===== Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r517fff7d1277da3dc87cdb913e8691c8323bb8fd -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 517fff7d1277da3dc87cdb913e8691c8323bb8fd) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -112,10 +112,12 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; -import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.NumberUtil; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelRow; +import org.lamsfoundation.lams.util.excel.ExcelSheet; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -1589,24 +1591,22 @@ } @Override - public LinkedHashMap exportSummary(Assessment assessment, List sessionDtos, - boolean showUserNames) { - LinkedHashMap dataToExport = new LinkedHashMap<>(); - final ExcelCell[] EMPTY_ROW = new ExcelCell[0]; + public List exportSummary(Assessment assessment, List sessionDtos, boolean showUserNames) { + List sheets = new LinkedList<>(); // -------------- First tab: Summary ---------------------------------------------------- if (showUserNames) { - ArrayList summaryTab = new ArrayList<>(); + ExcelSheet summarySheet = new ExcelSheet(getMessage("label.export.summary")); + sheets.add(summarySheet); if (sessionDtos != null) { for (SessionDTO sessionDTO : sessionDtos) { Long sessionId = sessionDTO.getSessionId(); - summaryTab.add(EMPTY_ROW); + summarySheet.addEmptyRow(); - ExcelCell[] sessionTitle = new ExcelCell[1]; - sessionTitle[0] = new ExcelCell(sessionDTO.getSessionName(), true); - summaryTab.add(sessionTitle); + ExcelRow sessionTitleRow = summarySheet.initRow(); + sessionTitleRow.addCell(sessionDTO.getSessionName(), true); List userDtos = new ArrayList<>(); // in case of UseSelectLeaderToolOuput - display only one user @@ -1634,29 +1634,10 @@ userDtos = getPagedUsersBySession(sessionId, 0, countSessionUsers, "userName", "ASC", ""); } - ArrayList summaryTabLearnerList = new ArrayList<>(); - - ExcelCell[] summaryRowTitle = new ExcelCell[3]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.export.user.id"), true, - ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), true, - ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true, - ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryTabLearnerList.add(summaryRowTitle); - float minGrade = -9999999; float maxGrade = 0; - for (AssessmentUserDTO userDto : userDtos) { float grade = userDto.getGrade(); - - ExcelCell[] userResultRow = new ExcelCell[3]; - userResultRow[0] = new ExcelCell(userDto.getLogin(), false); - userResultRow[1] = new ExcelCell(userDto.getFirstName() + " " + userDto.getLastName(), false); - userResultRow[2] = new ExcelCell(grade, false); - summaryTabLearnerList.add(userResultRow); - if (grade < minGrade || minGrade == -9999999) { minGrade = grade; } @@ -1677,101 +1658,101 @@ } // Mark Summary Min, Max + Grouped Percentages - summaryTab.add(EMPTY_ROW); - ExcelCell[] minMaxRow = new ExcelCell[2]; - minMaxRow[0] = new ExcelCell(getMessage("label.number.learners"), true); - minMaxRow[1] = new ExcelCell(totalNumEntries, false); - summaryTab.add(minMaxRow); - minMaxRow = new ExcelCell[2]; - minMaxRow[0] = new ExcelCell(getMessage("label.lowest.mark"), true); - minMaxRow[1] = new ExcelCell((double) minGrade, false); - summaryTab.add(minMaxRow); - minMaxRow = new ExcelCell[2]; - minMaxRow[0] = new ExcelCell(getMessage("label.highest.mark"), true); - minMaxRow[1] = new ExcelCell((double) maxGrade, false); - summaryTab.add(minMaxRow); + summarySheet.addEmptyRow(); + ExcelRow minMaxRow = summarySheet.initRow(); + minMaxRow.addCell(getMessage("label.number.learners"), true); + minMaxRow.addCell(totalNumEntries); - summaryTab.add(EMPTY_ROW); - ExcelCell[] binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(getMessage("label.authoring.basic.list.header.mark"), true, + minMaxRow = summarySheet.initRow(); + minMaxRow.addCell(getMessage("label.lowest.mark"), true); + minMaxRow.addCell((double) minGrade); + + minMaxRow = summarySheet.initRow(); + minMaxRow.addCell(getMessage("label.highest.mark"), true); + minMaxRow.addCell((double) maxGrade); + summarySheet.addEmptyRow(); + + ExcelRow binSummaryRow = summarySheet.initRow(); + binSummaryRow.addCell(getMessage("label.authoring.basic.list.header.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[1] = new ExcelCell(getMessage("label.number.learners"), true, + binSummaryRow.addCell(getMessage("label.number.learners"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[2] = new ExcelCell(getMessage("label.percentage"), true, - ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryTab.add(binSummaryRow); + binSummaryRow.addCell(getMessage("label.percentage"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); float totalNumEntriesAsFloat = totalNumEntries; for (Map.Entry entry : markSummary.entrySet()) { - binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(entry.getKey(), false); - binSummaryRow[1] = new ExcelCell(entry.getValue(), false); - binSummaryRow[2] = new ExcelCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100), - false); - summaryTab.add(binSummaryRow); + binSummaryRow = summarySheet.initRow(); + binSummaryRow.addCell(entry.getKey()); + binSummaryRow.addCell(entry.getValue()); + binSummaryRow.addCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100)); } - summaryTab.add(EMPTY_ROW); + summarySheet.addEmptyRow(); + summarySheet.addEmptyRow(); - summaryTab.add(EMPTY_ROW); - summaryTab.addAll(summaryTabLearnerList); - summaryTab.add(EMPTY_ROW); + ExcelRow summaryTitleRow = summarySheet.initRow(); + summaryTitleRow.addCell(getMessage("label.export.user.id"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryTitleRow.addCell(getMessage("label.monitoring.summary.user.name"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryTitleRow.addCell(getMessage("label.monitoring.summary.total"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + + for (AssessmentUserDTO userDto : userDtos) { + ExcelRow userResultRow = summarySheet.initRow(); + userResultRow.addCell(userDto.getLogin()); + userResultRow.addCell(userDto.getFirstName() + " " + userDto.getLastName()); + userResultRow.addCell(userDto.getGrade()); + } + summarySheet.addEmptyRow(); } } - - dataToExport.put(getMessage("label.export.summary"), summaryTab.toArray(new ExcelCell[][] {})); } // ------------------------------------------------------------------ // -------------- Second tab: Question Summary ---------------------- + ExcelSheet questionSummarySheet = new ExcelSheet(getMessage("lable.export.summary.by.question")); + sheets.add(questionSummarySheet); - ArrayList questionSummaryTab = new ArrayList<>(); - // Create the question summary - ExcelCell[] summaryTitle = new ExcelCell[1]; - summaryTitle[0] = new ExcelCell(getMessage("label.export.question.summary"), true); - questionSummaryTab.add(summaryTitle); - questionSummaryTab.add(EMPTY_ROW); + ExcelRow summaryTitleRow = questionSummarySheet.initRow(); + summaryTitleRow.addCell(getMessage("label.export.question.summary"), true); + questionSummarySheet.addEmptyRow(); Map questionSummaries = getQuestionSummaryForExport(assessment); if (assessment.getQuestions() != null) { Set questions = assessment.getQuestions(); - int count = 0; // question row title - ExcelCell[] questionTitleRow = showUserNames ? new ExcelCell[10] : new ExcelCell[9]; - questionTitleRow[count++] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, + ExcelRow questionTitleRow = new ExcelRow(); + questionTitleRow.addCell(getMessage("label.monitoring.question.summary.question"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, + questionTitleRow.addCell(getMessage("label.authoring.basic.list.header.type"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, + questionTitleRow.addCell(getMessage("label.authoring.basic.penalty.factor"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), - true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.export.user.id"), true, + questionTitleRow.addCell(getMessage("label.monitoring.question.summary.default.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + questionTitleRow.addCell(getMessage("label.export.user.id"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); if (showUserNames) { - questionTitleRow[count++] = new ExcelCell(getMessage("label.monitoring.user.summary.user.name"), true, + questionTitleRow.addCell(getMessage("label.monitoring.user.summary.user.name"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); } - questionTitleRow[count++] = new ExcelCell(getMessage("label.export.date.attempted"), true, + questionTitleRow.addCell(getMessage("label.export.date.attempted"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.authoring.basic.option.answer"), true, + questionTitleRow.addCell(getMessage("label.export.time.attempted"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.export.time.taken"), true, + questionTitleRow.addCell(getMessage("label.authoring.basic.option.answer"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - questionTitleRow[count++] = new ExcelCell(getMessage("label.export.mark"), true, - ExcelCell.BORDER_STYLE_BOTTOM_THIN); + questionTitleRow.addCell(getMessage("label.export.time.taken"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + questionTitleRow.addCell(getMessage("label.export.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); int questionNumber = 1; for (AssessmentQuestion question : questions) { - int colsNum = showUserNames ? 10 : 9; + ExcelRow questionTitle = questionSummarySheet.initRow(); + questionTitle.addCell(getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, + true); - ExcelCell[] questionTitle = new ExcelCell[1]; - questionTitle[0] = new ExcelCell( - getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, true); - questionSummaryTab.add(questionTitle); - // set up the summary table data for the top of the question area. boolean doSummaryTable = question.getType() == QbQuestion.TYPE_MULTIPLE_CHOICE || question.getType() == QbQuestion.TYPE_VERY_SHORT_ANSWERS @@ -1784,48 +1765,42 @@ Long trueKey = 1L; Long falseKey = 0L; if (doSummaryTable) { - questionSummaryTab.add(startSummaryTable(question, summaryOfAnswers, trueKey, falseKey)); + questionSummarySheet.addRow(startSummaryTable(question, summaryOfAnswers, trueKey, falseKey)); } - ArrayList questionSummaryTabTemp = new ArrayList<>(); + //we need to create questionSummaryTabTemp variable prior to writing it to sheet, in order to fill summaryOfAnswers + ArrayList questionSummaryTabTemp = new ArrayList<>(); //add question title row if (question.getType() == QbQuestion.TYPE_MARK_HEDGING) { - count = 0; List options = question.getQbQuestion().getQbOptions(); - colsNum += options.size() - 1; // question row title - ExcelCell[] hedgeQuestionTitleRow = new ExcelCell[colsNum]; - hedgeQuestionTitleRow[count++] = new ExcelCell( - getMessage("label.monitoring.question.summary.question"), true); - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), - true); - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), - true); - hedgeQuestionTitleRow[count++] = new ExcelCell( - getMessage("label.monitoring.question.summary.default.mark"), true); - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.export.user.id"), true); + ExcelRow hedgeQuestionTitleRow = new ExcelRow(); + hedgeQuestionTitleRow.addCell(getMessage("label.monitoring.question.summary.question"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.authoring.basic.list.header.type"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.authoring.basic.penalty.factor"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.monitoring.question.summary.default.mark"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.export.user.id"), true); if (showUserNames) { - hedgeQuestionTitleRow[count++] = new ExcelCell( - getMessage("label.monitoring.user.summary.user.name"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.monitoring.user.summary.user.name"), true); } - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.export.date.attempted"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.export.date.attempted"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.export.time.attempted"), true); for (QbOption option : options) { - hedgeQuestionTitleRow[count++] = new ExcelCell(option.getName().replaceAll("\\<.*?\\>", ""), + ExcelCell cell = hedgeQuestionTitleRow.addCell(option.getName().replaceAll("\\<.*?\\>", ""), true); if (option.isCorrect()) { - hedgeQuestionTitleRow[count - 1].setColor(IndexedColors.GREEN); + cell.setColor(IndexedColors.GREEN); } } - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.export.time.taken"), true); - hedgeQuestionTitleRow[count++] = new ExcelCell(getMessage("label.export.mark"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.export.time.taken"), true); + hedgeQuestionTitleRow.addCell(getMessage("label.export.mark"), true); questionSummaryTabTemp.add(hedgeQuestionTitleRow); } else { questionSummaryTabTemp.add(questionTitleRow); } QuestionSummary questionSummary = questionSummaries.get(question.getUid()); - List> allResultsForQuestion = questionSummary .getQuestionResultsPerSession(); @@ -1835,60 +1810,63 @@ int timeTakenTotal = 0; for (List resultList : allResultsForQuestion) { for (AssessmentQuestionResult questionResult : resultList) { + ExcelRow userResultRow = new ExcelRow(); + userResultRow.addCell(questionResult.getQbQuestion().getName()); + userResultRow.addCell(AssessmentServiceImpl + .getQuestionTypeLanguageLabel(questionResult.getQbQuestion().getType())); + userResultRow.addCell(Float.valueOf(questionResult.getQbQuestion().getPenaltyFactor())); - ExcelCell[] userResultRow = new ExcelCell[colsNum]; - count = 0; - userResultRow[count++] = new ExcelCell(questionResult.getQbQuestion().getName(), false); - userResultRow[count++] = new ExcelCell( - AssessmentServiceImpl.getQuestionTypeLabel(questionResult.getQbQuestion().getType()), - false); - userResultRow[count++] = new ExcelCell( - Float.valueOf(questionResult.getQbQuestion().getPenaltyFactor()), false); Float maxMark = (questionResult.getMaxMark() == null) ? 0 : Float.valueOf(questionResult.getMaxMark()); - userResultRow[count++] = new ExcelCell(maxMark, false); + userResultRow.addCell(maxMark); if (showUserNames) { - userResultRow[count++] = new ExcelCell(questionResult.getUser().getLoginName(), false); - userResultRow[count++] = new ExcelCell(questionResult.getUser().getFullName(), false); + userResultRow.addCell(questionResult.getUser().getLoginName()); + userResultRow.addCell(questionResult.getUser().getFullName()); } else { - userResultRow[count++] = new ExcelCell(questionResult.getUser().getUserId(), false); + userResultRow.addCell(questionResult.getUser().getUserId()); } - userResultRow[count++] = new ExcelCell(questionResult.getFinishDate(), false); + + //date and time + ExcelCell dateCell = userResultRow.addCell(questionResult.getFinishDate()); + dateCell.setDataFormat(ExcelCell.CELL_FORMAT_DATE); + ExcelCell timeCell = userResultRow.addCell(questionResult.getFinishDate()); + timeCell.setDataFormat(ExcelCell.CELL_FORMAT_TIME); + //answer if (question.getType() == QbQuestion.TYPE_MARK_HEDGING) { - Set optionAnswers = questionResult.getOptionAnswers(); for (QbOption option : question.getQbQuestion().getQbOptions()) { for (AssessmentOptionAnswer optionAnswer : optionAnswers) { if (option.getUid().equals(optionAnswer.getOptionUid())) { - userResultRow[count++] = new ExcelCell(optionAnswer.getAnswerInt(), false); + userResultRow.addCell(optionAnswer.getAnswerInt()); break; } } } + } else { - userResultRow[count++] = new ExcelCell( - AssessmentEscapeUtils.printResponsesForExcelExport(questionResult), false); + userResultRow.addCell(AssessmentEscapeUtils.printResponsesForExcelExport(questionResult)); if (doSummaryTable) { summaryNACount = updateSummaryCounts(question, questionResult, summaryOfAnswers, summaryNACount); } - } + //time taken if (questionResult.getAssessmentResult() != null) { Date startDate = questionResult.getAssessmentResult().getStartDate(); Date finishDate = questionResult.getFinishDate(); if ((startDate != null) && (finishDate != null)) { Long seconds = (finishDate.getTime() - startDate.getTime()) / 1000; - userResultRow[count++] = new ExcelCell(seconds, false); + userResultRow.addCell(seconds); timeTakenCount++; timeTakenTotal += seconds; } } + //mark - userResultRow[count++] = new ExcelCell(questionResult.getMark(), false); + userResultRow.addCell(questionResult.getMark()); questionSummaryTabTemp.add(userResultRow); //calculating markCount & markTotal @@ -1900,75 +1878,48 @@ } if (doSummaryTable) { - questionSummaryTab - .add(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); - questionSummaryTab.add(EMPTY_ROW); + questionSummarySheet + .addRow(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); + questionSummarySheet.addEmptyRow(); } + questionSummarySheet.getRows().addAll(questionSummaryTabTemp); // Calculating the averages - ExcelCell[] averageRow; - - if (showUserNames) { - averageRow = new ExcelCell[10]; - - averageRow[7] = new ExcelCell(getMessage("label.export.average"), true); - - if (timeTakenTotal > 0) { - averageRow[8] = new ExcelCell(Long.valueOf(timeTakenTotal / timeTakenCount), false); - } - if (markTotal > 0) { - Float averageMark = Float.valueOf(markTotal / markCount); - averageRow[9] = new ExcelCell(averageMark, false); - } else { - averageRow[9] = new ExcelCell(0.0F, false); - } - } else { - averageRow = new ExcelCell[9]; - averageRow[6] = new ExcelCell(getMessage("label.export.average"), true); - - if (timeTakenTotal > 0) { - averageRow[7] = new ExcelCell(Long.valueOf(timeTakenTotal / timeTakenCount), false); - } - if (markTotal > 0) { - Float averageMark = Float.valueOf(markTotal / markCount); - averageRow[8] = new ExcelCell(averageMark, false); - } else { - averageRow[8] = new ExcelCell(0.0F, false); - } + ExcelRow averageRow = questionSummarySheet.initRow(); + averageRow.addEmptyCells(showUserNames ? 8 : 7); + averageRow.addCell(getMessage("label.export.average"), true); + if (timeTakenTotal > 0) { + averageRow.addCell(Long.valueOf(timeTakenTotal / timeTakenCount)); } + Float averageMark = markTotal > 0 ? Float.valueOf(markTotal / markCount) : 0.0F; + averageRow.addCell(averageMark); - questionSummaryTab.addAll(questionSummaryTabTemp); - questionSummaryTab.add(averageRow); - questionSummaryTab.add(EMPTY_ROW); - + questionSummarySheet.addEmptyRow(); } - } - dataToExport.put(getMessage("lable.export.summary.by.question"), - questionSummaryTab.toArray(new ExcelCell[][] {})); // ------------------------------------------------------------------ // -------------- Third tab: User Summary --------------------------- - ArrayList userSummaryTab = new ArrayList<>(); + ExcelSheet userSummarySheet = new ExcelSheet(getMessage("label.export.summary.by.user")); + sheets.add(userSummarySheet); // Create the question summary - ExcelCell[] userSummaryTitle = new ExcelCell[1]; - userSummaryTitle[0] = new ExcelCell(getMessage("label.export.user.summary"), true); - userSummaryTab.add(userSummaryTitle); + ExcelRow userSummaryTitle = userSummarySheet.initRow(); + userSummaryTitle.addCell(getMessage("label.export.user.summary"), true); - ExcelCell[] summaryRowTitle = new ExcelCell[5]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, + ExcelRow summaryRowTitle = userSummarySheet.initRow(); + summaryRowTitle.addCell(getMessage("label.monitoring.question.summary.question"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, + summaryRowTitle.addCell(getMessage("label.authoring.basic.list.header.type"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, + summaryRowTitle.addCell(getMessage("label.authoring.basic.penalty.factor"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[3] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), true, + summaryRowTitle.addCell(getMessage("label.monitoring.question.summary.default.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[4] = new ExcelCell(getMessage("label.monitoring.question.summary.average.mark"), true, + summaryRowTitle.addCell(getMessage("label.monitoring.question.summary.average.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - userSummaryTab.add(summaryRowTitle); + Float totalGradesPossible = 0F; Float totalAverage = 0F; if (assessment.getQuestionReferences() != null) { @@ -1992,7 +1943,7 @@ AssessmentQuestion question = questionReference.getQuestion(); title = question.getQbQuestion().getName(); - questionType = AssessmentServiceImpl.getQuestionTypeLabel(question.getType()); + questionType = AssessmentServiceImpl.getQuestionTypeLanguageLabel(question.getType()); penaltyFactor = question.getQbQuestion().getPenaltyFactor(); QuestionSummary questionSummary = questionSummaries.get(question.getUid()); @@ -2005,24 +1956,22 @@ int maxGrade = questionReference.getMaxMark(); totalGradesPossible += maxGrade; - ExcelCell[] questCell = new ExcelCell[5]; - questCell[0] = new ExcelCell(title, false); - questCell[1] = new ExcelCell(questionType, false); - questCell[2] = new ExcelCell(penaltyFactor, false); - questCell[3] = new ExcelCell(maxGrade, false); - questCell[4] = new ExcelCell(averageMark, false); - - userSummaryTab.add(questCell); + ExcelRow questCellRow = userSummarySheet.initRow(); + questCellRow.addCell(title); + questCellRow.addCell(questionType); + questCellRow.addCell(penaltyFactor); + questCellRow.addCell(maxGrade); + questCellRow.addCell(averageMark); } if (totalGradesPossible.floatValue() > 0) { - ExcelCell[] totalCell = new ExcelCell[5]; - totalCell[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true); - totalCell[3] = new ExcelCell(totalGradesPossible, false); - totalCell[4] = new ExcelCell(totalAverage, false); - userSummaryTab.add(totalCell); + ExcelRow totalCellRow = userSummarySheet.initRow(); + totalCellRow.addEmptyCells(2); + totalCellRow.addCell(getMessage("label.monitoring.summary.total"), true); + totalCellRow.addCell(totalGradesPossible); + totalCellRow.addCell(totalAverage); } - userSummaryTab.add(EMPTY_ROW); + userSummarySheet.addEmptyRow(); } if (sessionDtos != null) { @@ -2034,111 +1983,78 @@ } for (SessionDTO sessionDTO : sessionDtos) { + userSummarySheet.addEmptyRow(); - userSummaryTab.add(EMPTY_ROW); + ExcelRow sessionTitle = userSummarySheet.initRow(); + sessionTitle.addCell(sessionDTO.getSessionName(), true); - ExcelCell[] sessionTitle = new ExcelCell[1]; - sessionTitle[0] = new ExcelCell(sessionDTO.getSessionName(), true); - userSummaryTab.add(sessionTitle); - AssessmentSession assessmentSession = getSessionBySessionId(sessionDTO.getSessionId()); - Set assessmentUsers = assessmentSession.getAssessmentUsers(); - if (assessmentUsers != null) { - for (AssessmentUser assessmentUser : assessmentUsers) { - if (showUserNames) { - ExcelCell[] userTitleRow = new ExcelCell[6]; - userTitleRow[0] = new ExcelCell(getMessage("label.export.user.id"), true); - userTitleRow[1] = new ExcelCell(getMessage("label.monitoring.user.summary.user.name"), - true); - userTitleRow[2] = new ExcelCell(getMessage("label.export.date.attempted"), true); - userTitleRow[3] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), - true); - userTitleRow[4] = new ExcelCell(getMessage("label.authoring.basic.option.answer"), true); - userTitleRow[5] = new ExcelCell(getMessage("label.export.mark"), true); - userSummaryTab.add(userTitleRow); + ExcelRow userTitleRow = userSummarySheet.initRow(); + userTitleRow.addCell(getMessage("label.export.user.id"), true); + userTitleRow.addCell(getMessage("label.monitoring.user.summary.user.name"), true); + userTitleRow.addCell(getMessage("label.export.date.attempted"), true); + userTitleRow.addCell(getMessage("label.monitoring.question.summary.question"), true); + userTitleRow.addCell(getMessage("label.authoring.basic.option.answer"), true); + userTitleRow.addCell(getMessage("label.export.mark"), true); + } else { - ExcelCell[] userTitleRow = new ExcelCell[5]; - userTitleRow[0] = new ExcelCell(getMessage("label.export.user.id"), true); - userTitleRow[1] = new ExcelCell(getMessage("label.export.date.attempted"), true); - userTitleRow[2] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), - true); - userTitleRow[3] = new ExcelCell(getMessage("label.authoring.basic.option.answer"), true); - userTitleRow[4] = new ExcelCell(getMessage("label.export.mark"), true); - userSummaryTab.add(userTitleRow); + ExcelRow userTitleRow = userSummarySheet.initRow(); + userTitleRow.addCell(getMessage("label.export.user.id"), true); + userTitleRow.addCell(getMessage("label.export.date.attempted"), true); + userTitleRow.addCell(getMessage("label.monitoring.question.summary.question"), true); + userTitleRow.addCell(getMessage("label.authoring.basic.option.answer"), true); + userTitleRow.addCell(getMessage("label.export.mark"), true); } AssessmentResult assessmentResult = userUidToResultMap.get(assessmentUser.getUid()); - if (assessmentResult != null) { Set questionResults = assessmentResult.getQuestionResults(); - if (questionResults != null) { - for (AssessmentQuestionResult questionResult : questionResults) { - + ExcelRow userResultRow = userSummarySheet.initRow(); if (showUserNames) { - ExcelCell[] userResultRow = new ExcelCell[6]; - userResultRow[0] = new ExcelCell(assessmentUser.getLoginName(), false); - userResultRow[1] = new ExcelCell(assessmentUser.getFullName(), false); - userResultRow[2] = new ExcelCell(assessmentResult.getStartDate(), false); - userResultRow[3] = new ExcelCell(questionResult.getQbQuestion().getName(), - false); - userResultRow[4] = new ExcelCell( - AssessmentEscapeUtils.printResponsesForExcelExport(questionResult), - false); - userResultRow[5] = new ExcelCell(questionResult.getMark(), false); - userSummaryTab.add(userResultRow); + userResultRow.addCell(assessmentUser.getLoginName()); + userResultRow.addCell(assessmentUser.getFullName()); } else { - ExcelCell[] userResultRow = new ExcelCell[5]; - userResultRow[0] = new ExcelCell(assessmentUser.getUserId(), false); - userResultRow[1] = new ExcelCell(assessmentResult.getStartDate(), false); - userResultRow[2] = new ExcelCell(questionResult.getQbQuestion().getName(), - false); - userResultRow[3] = new ExcelCell( - AssessmentEscapeUtils.printResponsesForExcelExport(questionResult), - false); - userResultRow[4] = new ExcelCell(questionResult.getMark(), false); - userSummaryTab.add(userResultRow); + userResultRow.addCell(assessmentUser.getUserId()); } + + userResultRow.addCell(assessmentResult.getStartDate()); + userResultRow.addCell(questionResult.getQbQuestion().getName()); + userResultRow.addCell( + AssessmentEscapeUtils.printResponsesForExcelExport(questionResult)); + userResultRow.addCell(questionResult.getMark()); } } - ExcelCell[] userTotalRow; - if (showUserNames) { - userTotalRow = new ExcelCell[6]; - userTotalRow[4] = new ExcelCell(getMessage("label.monitoring.summary.total"), true); - userTotalRow[5] = new ExcelCell(assessmentResult.getGrade(), false); - } else { - userTotalRow = new ExcelCell[5]; - userTotalRow[3] = new ExcelCell(getMessage("label.monitoring.summary.total"), true); - userTotalRow[4] = new ExcelCell(assessmentResult.getGrade(), false); - } - - userSummaryTab.add(userTotalRow); - userSummaryTab.add(EMPTY_ROW); + ExcelRow userTotalRow = userSummarySheet.initRow(); + userTotalRow.addEmptyCells(showUserNames ? 4 : 3); + userTotalRow.addCell(getMessage("label.monitoring.summary.total"), true); + userTotalRow.addCell(assessmentResult.getGrade()); + userSummarySheet.addEmptyRow(); } } } } } - dataToExport.put(getMessage("label.export.summary.by.user"), userSummaryTab.toArray(new ExcelCell[][] {})); - return dataToExport; + return sheets; } - private ExcelCell[] startSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, - Long trueKey, Long falseKey) { - ExcelCell[] summaryTable; + private ExcelRow startSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, Long trueKey, + Long falseKey) { + ExcelRow summaryTableRow; int i = 0; if (question.getType() == QbQuestion.TYPE_MULTIPLE_CHOICE || question.getType() == QbQuestion.TYPE_VERY_SHORT_ANSWERS || question.getType() == QbQuestion.TYPE_NUMERICAL) { + + summaryTableRow = new ExcelRow(); List options = question.getQbQuestion().getQbOptions(); - summaryTable = new ExcelCell[options.size() + 1]; for (QbOption option : options) { summaryOfAnswers.put(option.getUid(), 0); StringBuilder bldr = new StringBuilder(getMessage("label.authoring.basic.option.answer")).append(" ") @@ -2148,23 +2064,23 @@ } else { bldr.append(option.getName().replaceAll("\\<.*?\\>", "")); } - summaryTable[i] = new ExcelCell(bldr.toString(), false); + summaryTableRow.addCell(bldr.toString()); i++; } if (question.getType() == QbQuestion.TYPE_MULTIPLE_CHOICE) { - summaryTable[i++] = new ExcelCell(getMessage("label.not.answered"), false); + summaryTableRow.addCell(getMessage("label.not.answered")); } else { - summaryTable[i++] = new ExcelCell(getMessage("label.other"), false); + summaryTableRow.addCell(getMessage("label.other")); } } else { - summaryTable = new ExcelCell[3]; - summaryTable[0] = new ExcelCell(getMessage("label.authoring.true.false.true"), false); - summaryTable[1] = new ExcelCell(getMessage("label.authoring.true.false.false"), false); - summaryTable[2] = new ExcelCell(getMessage("label.not.answered"), false); + summaryTableRow = new ExcelRow(); + summaryTableRow.addCell(getMessage("label.authoring.true.false.true")); + summaryTableRow.addCell(getMessage("label.authoring.true.false.false")); + summaryTableRow.addCell(getMessage("label.not.answered")); summaryOfAnswers.put(trueKey, 0); summaryOfAnswers.put(falseKey, 0); } - return summaryTable; + return summaryTableRow; } private Integer updateSummaryCounts(AssessmentQuestion question, AssessmentQuestionResult questionResult, @@ -2220,44 +2136,47 @@ return summaryNACount; } - private String valueAsPercentage(Integer value, int total) { - Double percentage = (double) value / total * 100; - return NumberUtil.formatLocalisedNumber(percentage, (Locale) null, 2) + "%"; - } - - private ExcelCell[] outputSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, + private ExcelRow outputSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, Integer summaryNACount, Long trueKey, Long falseKey) { - ExcelCell[] summaryTable = new ExcelCell[summaryOfAnswers.size() + 1]; + ExcelRow summaryTableRow = new ExcelRow(); int total = summaryNACount; for (int value : summaryOfAnswers.values()) { total += value; } - int i = 0; if (question.getType() == QbQuestion.TYPE_MULTIPLE_CHOICE || question.getType() == QbQuestion.TYPE_VERY_SHORT_ANSWERS || question.getType() == QbQuestion.TYPE_NUMERICAL) { for (QbOption option : question.getQbQuestion().getQbOptions()) { - summaryTable[i] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(option.getUid()), total), false); + Double optionPercentage = (double) summaryOfAnswers.get(option.getUid()) / total; + ExcelCell optionCell = summaryTableRow.addPercentageCell(optionPercentage); if (option.getMaxMark() > 0) { - summaryTable[i].setColor(IndexedColors.GREEN); + optionCell.setColor(IndexedColors.GREEN); } - i++; } - summaryTable[i++] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); + } else { - summaryTable = new ExcelCell[3]; - summaryTable[0] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(trueKey), total), false); - summaryTable[1] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(falseKey), total), false); - summaryTable[2] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); - summaryTable[question.getQbQuestion().getCorrectAnswer() ? 0 : 1].setColor(IndexedColors.GREEN); + Double correctPercentage = (double) summaryOfAnswers.get(trueKey) / total; + ExcelCell correctCell = summaryTableRow.addPercentageCell(correctPercentage); + + Double wrongPercentage = (double) summaryOfAnswers.get(falseKey) / total; + ExcelCell wrongCell = summaryTableRow.addPercentageCell(wrongPercentage); + + if (question.getQbQuestion().getCorrectAnswer()) { + correctCell.setColor(IndexedColors.GREEN); + } else { + wrongCell.setColor(IndexedColors.GREEN); + } } - return summaryTable; + Double summaryNAPercentage = (double) summaryNACount / total; + summaryTableRow.addPercentageCell(summaryNAPercentage); + + return summaryTableRow; } /** * Used only for excell export (for getUserSummaryData() method). */ - public static String getQuestionTypeLabel(Integer type) { + public static String getQuestionTypeLanguageLabel(int type) { switch (type) { case QbQuestion.TYPE_ESSAY: return "Essay"; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r419201d3ad6fa99804284edd03c21d0065217c6c -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 419201d3ad6fa99804284edd03c21d0065217c6c) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -46,7 +46,8 @@ import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; import org.lamsfoundation.lams.tool.service.ICommonToolService; -import org.lamsfoundation.lams.util.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelSheet; /** * Interface that defines the contract that all ShareAssessment service provider must follow. @@ -445,7 +446,7 @@ * @param showUserNames * @return */ - LinkedHashMap exportSummary(Assessment assessment, List sessionDtos, + List exportSummary(Assessment assessment, List sessionDtos, boolean showUserNames); /** Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -1,644 +1,642 @@ -/**************************************************************** - * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) - * ============================================================= - * License Information: http://lamsfoundation.org/licensing/lams/2.0/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2.0 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * http://www.gnu.org/licenses/gpl.txt - * **************************************************************** - */ - -package org.lamsfoundation.lams.tool.assessment.web.controller; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeSet; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; -import org.lamsfoundation.lams.qb.dto.QbStatsActivityDTO; -import org.lamsfoundation.lams.qb.service.IQbService; -import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; -import org.lamsfoundation.lams.tool.assessment.dto.AssessmentResultDTO; -import org.lamsfoundation.lams.tool.assessment.dto.AssessmentUserDTO; -import org.lamsfoundation.lams.tool.assessment.dto.LeaderResultsDTO; -import org.lamsfoundation.lams.tool.assessment.dto.QuestionSummary; -import org.lamsfoundation.lams.tool.assessment.dto.ReflectDTO; -import org.lamsfoundation.lams.tool.assessment.dto.SessionDTO; -import org.lamsfoundation.lams.tool.assessment.dto.UserSummary; -import org.lamsfoundation.lams.tool.assessment.model.Assessment; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestion; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionResult; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentResult; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentSession; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; -import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; -import org.lamsfoundation.lams.tool.assessment.service.IAssessmentService; -import org.lamsfoundation.lams.tool.assessment.util.AssessmentEscapeUtils; -import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.CommonConstants; -import org.lamsfoundation.lams.util.DateUtil; -import org.lamsfoundation.lams.util.ExcelCell; -import org.lamsfoundation.lams.util.ExcelUtil; -import org.lamsfoundation.lams.util.JsonUtil; -import org.lamsfoundation.lams.util.WebUtil; -import org.lamsfoundation.lams.web.session.SessionManager; -import org.lamsfoundation.lams.web.util.AttributeNames; -import org.lamsfoundation.lams.web.util.SessionMap; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.util.HtmlUtils; - -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - -@Controller -@RequestMapping("/monitoring") -public class MonitoringController { - public static Logger log = Logger.getLogger(MonitoringController.class); - - @Autowired - @Qualifier("laasseAssessmentService") - private IAssessmentService service; - - @Autowired - private IQbService qbService; - - @RequestMapping("/summary") - public String summary(HttpServletRequest request, HttpServletResponse response) { - - // initialize Session Map - SessionMap sessionMap = new SessionMap<>(); - request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); - request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); - - Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); - List sessionDtos = service.getSessionDtos(contentId, false); - - Assessment assessment = service.getAssessmentByContentId(contentId); - - //set SubmissionDeadline, if any - if (assessment.getSubmissionDeadline() != null) { - Date submissionDeadline = assessment.getSubmissionDeadline(); - HttpSession ss = SessionManager.getSession(); - UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); - TimeZone teacherTimeZone = teacher.getTimeZone(); - Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(teacherTimeZone, submissionDeadline); - request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); - // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed - request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, - DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); - } - - // Create reflectList if reflection is enabled. - if (assessment.isReflectOnActivity()) { - List reflectList = service.getReflectList(assessment.getContentId()); - // Add reflectList to sessionMap - sessionMap.put(AssessmentConstants.ATTR_REFLECT_LIST, reflectList); - } - - //prepare list of the questions to display in question drop down menu, filtering out questions that aren't supposed to be answered - Set questionList = new TreeSet<>(); - //in case there is at least one random question - we need to show all questions in a drop down select - if (assessment.hasRandomQuestion()) { - questionList.addAll(assessment.getQuestions()); - - //show only questions from question list otherwise - } else { - for (QuestionReference reference : assessment.getQuestionReferences()) { - questionList.add(reference.getQuestion()); - } - } - - //prepare toolOutputDefinitions and activityEvaluation - List toolOutputDefinitions = new ArrayList<>(); - toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_LEARNER_TOTAL_SCORE); - toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_BEST_SCORE); - toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_FIRST_SCORE); - toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_AVERAGE_SCORE); - String activityEvaluation = service.getActivityEvaluation(contentId); - sessionMap.put(AssessmentConstants.ATTR_TOOL_OUTPUT_DEFINITIONS, toolOutputDefinitions); - sessionMap.put(AssessmentConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); - - // cache into sessionMap - boolean isGroupedActivity = service.isGroupedActivity(contentId); - sessionMap.put(AssessmentConstants.ATTR_IS_GROUPED_ACTIVITY, isGroupedActivity); - sessionMap.put("sessionDtos", sessionDtos); - sessionMap.put(AssessmentConstants.ATTR_ASSESSMENT, assessment); - sessionMap.put(AssessmentConstants.ATTR_QUESTION_LIST, questionList); - sessionMap.put(AssessmentConstants.ATTR_TOOL_CONTENT_ID, contentId); - sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, - WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID)); - return "pages/monitoring/monitoring"; - } - - @RequestMapping("/userMasterDetail") - public String userMasterDetail(HttpServletRequest request, HttpServletResponse response) { - Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); - Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_SESSION_ID); - String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); - AssessmentResultDTO result = service.getUserMasterDetail(sessionId, userId); - - request.setAttribute(AssessmentConstants.ATTR_ASSESSMENT_RESULT, result); - request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); - return (result == null) ? null : "pages/monitoring/parts/masterDetailLoadUp"; - } - - @RequestMapping("/questionSummary") - public String questionSummary(HttpServletRequest request, HttpServletResponse response) { - SessionMap sessionMap = getSessionMap(request); - - Long questionUid = WebUtil.readLongParam(request, AssessmentConstants.PARAM_QUESTION_UID); - if (questionUid.equals(-1l)) { - return null; - } - Long contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); - QuestionSummary questionSummary = service.getQuestionSummary(contentId, questionUid); - - request.setAttribute(AssessmentConstants.ATTR_QUESTION_SUMMARY, questionSummary); - return "pages/monitoring/parts/questionsummary"; - } - - @RequestMapping("/allocateUserAnswer") - @ResponseStatus(HttpStatus.OK) - public void allocateUserAnswer(HttpServletRequest request, HttpServletResponse response, - @RequestParam Long questionUid, @RequestParam Long targetOptionUid, @RequestParam Long previousOptionUid, - @RequestParam Long questionResultUid) { - service.allocateAnswerToOption(questionUid, targetOptionUid, previousOptionUid, questionResultUid); - } - - @RequestMapping("/userSummary") - public String userSummary(HttpServletRequest request, HttpServletResponse response) { - SessionMap sessionMap = getSessionMap(request); - - Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); - Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_SESSION_ID); - Long contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); - UserSummary userSummary = service.getUserSummary(contentId, userId, sessionId); - - request.setAttribute(AssessmentConstants.ATTR_USER_SUMMARY, userSummary); - return "pages/monitoring/parts/usersummary"; - } - - @RequestMapping("/saveUserGrade") - public void saveUserGrade(HttpServletRequest request, HttpServletResponse response) { - - if ((request.getParameter(AssessmentConstants.PARAM_NOT_A_NUMBER) == null) - && !StringUtils.isEmpty(request.getParameter(AssessmentConstants.PARAM_QUESTION_RESULT_UID))) { - Long questionResultUid = WebUtil.readLongParam(request, AssessmentConstants.PARAM_QUESTION_RESULT_UID); - float newGrade = Float.valueOf(request.getParameter(AssessmentConstants.PARAM_GRADE)); - service.changeQuestionResultMark(questionResultUid, newGrade); - } - } - - /** - * Set Submission Deadline - */ - @RequestMapping("/setSubmissionDeadline") - @ResponseBody - public String setSubmissionDeadline(HttpServletRequest request, HttpServletResponse response) throws IOException { - - Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); - Assessment assessment = service.getAssessmentByContentId(contentID); - - Long dateParameter = WebUtil.readLongParam(request, AssessmentConstants.ATTR_SUBMISSION_DEADLINE, true); - Date tzSubmissionDeadline = null; - String formattedDate = ""; - if (dateParameter != null) { - Date submissionDeadline = new Date(dateParameter); - HttpSession ss = SessionManager.getSession(); - UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); - TimeZone teacherTimeZone = teacher.getTimeZone(); - tzSubmissionDeadline = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, submissionDeadline); - formattedDate = DateUtil.convertToStringForJSON(tzSubmissionDeadline, request.getLocale()); - - } - assessment.setSubmissionDeadline(tzSubmissionDeadline); - service.saveOrUpdateAssessment(assessment); - - response.setContentType("text/plain;charset=utf-8"); - response.getWriter().print(formattedDate); - return null; - } - - /** - * Set tool's activityEvaluation - */ - @RequestMapping("/setActivityEvaluation") - @ResponseBody - public String setActivityEvaluation(HttpServletRequest request, HttpServletResponse response) throws IOException { - SessionMap sessionMap = getSessionMap(request); - - Long contentID = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); - String activityEvaluation = WebUtil.readStrParam(request, AssessmentConstants.ATTR_ACTIVITY_EVALUATION, true); - service.setActivityEvaluation(contentID, activityEvaluation); - - // update the session ready for stats tab to be reloaded otherwise flicking between tabs - // causes the old value to be redisplayed - sessionMap.put(AssessmentConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); - - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - responseJSON.put("success", "true"); - response.setContentType("application/json;charset=utf-8"); - return responseJSON.toString(); - } - - /** - * Refreshes user list. - */ - @RequestMapping("/getUsers") - public String getUsers(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException { - SessionMap sessionMap = getSessionMap(request); - Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); - - Long sessionId = WebUtil.readLongParam(request, "sessionId"); - - // Getting the params passed in from the jqGrid - int page = WebUtil.readIntParam(request, CommonConstants.PARAM_PAGE); - int rowLimit = WebUtil.readIntParam(request, CommonConstants.PARAM_ROWS); - String sortOrder = WebUtil.readStrParam(request, CommonConstants.PARAM_SORD); - String sortBy = WebUtil.readStrParam(request, CommonConstants.PARAM_SIDX, true); - if (StringUtils.isEmpty(sortBy)) { - sortBy = "userName"; - } - String searchString = WebUtil.readStrParam(request, "userName", true); - - List userDtos = new ArrayList<>(); - int countSessionUsers = 0; - //in case of UseSelectLeaderToolOuput - display only one user - if (assessment.isUseSelectLeaderToolOuput()) { - - AssessmentSession session = service.getSessionBySessionId(sessionId); - AssessmentUser groupLeader = session.getGroupLeader(); - - if (groupLeader != null) { - - float assessmentResult = service.getLastTotalScoreByUser(assessment.getUid(), groupLeader.getUserId()); - Long portraitId = service.getPortraitId(groupLeader.getUserId()); - - AssessmentUserDTO userDto = new AssessmentUserDTO(); - userDto.setUserId(groupLeader.getUserId()); - userDto.setFirstName(groupLeader.getFirstName()); - userDto.setLastName(groupLeader.getLastName()); - userDto.setGrade(assessmentResult); - userDto.setPortraitId(portraitId); - userDtos.add(userDto); - countSessionUsers = 1; - } - - } else { - // Get the user list from the db - userDtos = service.getPagedUsersBySession(sessionId, page - 1, rowLimit, sortBy, sortOrder, searchString); - countSessionUsers = service.getCountUsersBySession(sessionId, searchString); - } - - int totalPages = Double.valueOf(Math.ceil(Double.valueOf(countSessionUsers) / Double.valueOf(rowLimit))) - .intValue(); - - ArrayNode rows = JsonNodeFactory.instance.arrayNode(); - int i = 1; - for (AssessmentUserDTO userDto : userDtos) { - - ArrayNode userData = JsonNodeFactory.instance.arrayNode(); - userData.add(userDto.getUserId()); - userData.add(sessionId); - String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); - userData.add(fullName); - userData.add(userDto.getGrade()); - if (userDto.getPortraitId() != null) { - userData.add(userDto.getPortraitId()); - } - - ObjectNode userRow = JsonNodeFactory.instance.objectNode(); - userRow.put("id", i++); - userRow.set("cell", userData); - - rows.add(userRow); - } - - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - responseJSON.put("total", totalPages); - responseJSON.put("page", page); - responseJSON.put("records", countSessionUsers); - responseJSON.set("rows", rows); - - res.setContentType("application/json;charset=utf-8"); - res.getWriter().print(new String(responseJSON.toString())); - return null; - } - - /** - * Refreshes user list. - */ - @RequestMapping("/getUsersByQuestion") - public String getUsersByQuestion(HttpServletRequest request, HttpServletResponse res) - throws IOException, ServletException { - SessionMap sessionMap = getSessionMap(request); - Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); - - Long sessionId = WebUtil.readLongParam(request, "sessionId"); - Long questionUid = WebUtil.readLongParam(request, "questionUid"); - - // Getting the params passed in from the jqGrid - int page = WebUtil.readIntParam(request, CommonConstants.PARAM_PAGE); - int rowLimit = WebUtil.readIntParam(request, CommonConstants.PARAM_ROWS); - String sortOrder = WebUtil.readStrParam(request, CommonConstants.PARAM_SORD); - String sortBy = WebUtil.readStrParam(request, CommonConstants.PARAM_SIDX, true); - if (StringUtils.isEmpty(sortBy)) { - sortBy = "userName"; - } - String searchString = WebUtil.readStrParam(request, "userName", true); - - List userDtos = new ArrayList<>(); - int countSessionUsers = 0; - //in case of UseSelectLeaderToolOuput - display only one user - if (assessment.isUseSelectLeaderToolOuput()) { - - AssessmentSession session = service.getSessionBySessionId(sessionId); - AssessmentUser groupLeader = session.getGroupLeader(); - - if (groupLeader != null) { - - AssessmentResult assessmentResult = service.getLastFinishedAssessmentResult(assessment.getUid(), - groupLeader.getUserId()); - Long questionResultUid = null; - if (assessmentResult != null) { - for (AssessmentQuestionResult dbQuestionResult : assessmentResult.getQuestionResults()) { - if (dbQuestionResult.getQbToolQuestion().getUid().equals(questionUid)) { - questionResultUid = dbQuestionResult.getUid(); - break; - } - } - } - - AssessmentUserDTO userDto = new AssessmentUserDTO(); - userDto.setQuestionResultUid(questionResultUid); - userDto.setFirstName(groupLeader.getFirstName()); - userDto.setLastName(groupLeader.getLastName()); - userDtos.add(userDto); - countSessionUsers = 1; - } - - } else { - // Get the user list from the db - userDtos = service.getPagedUsersBySessionAndQuestion(sessionId, questionUid, page - 1, rowLimit, sortBy, - sortOrder, searchString); - countSessionUsers = service.getCountUsersBySession(sessionId, searchString); - } - - int totalPages = Double.valueOf(Math.ceil(Double.valueOf(countSessionUsers) / Double.valueOf(rowLimit))) - .intValue(); - - ArrayNode rows = JsonNodeFactory.instance.arrayNode(); - int i = 1; - for (AssessmentUserDTO userDto : userDtos) { - - Long questionResultUid = userDto.getQuestionResultUid(); - String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); - - ArrayNode userData = JsonNodeFactory.instance.arrayNode(); - if (questionResultUid != null) { - AssessmentQuestionResult questionResult = service.getAssessmentQuestionResultByUid(questionResultUid); - - userData.add(questionResultUid); - userData.add(questionResult.getMaxMark()); - userData.add(fullName); - //LDEV_NTU-11 Swapping Mark and Response columns in Assessment Monitor - userData.add(questionResult.getMark()); - // show confidence levels if this feature is turned ON - if (assessment.isEnableConfidenceLevels()) { - userData.add(questionResult.getConfidenceLevel()); - } - - userData.add(AssessmentEscapeUtils.printResponsesForJqgrid(questionResult)); - if (userDto.getPortraitId() != null) { - userData.add(userDto.getPortraitId()); - } - - } else { - userData.add(""); - userData.add(""); - userData.add(fullName); - userData.add("-"); - if (assessment.isEnableConfidenceLevels()) { - userData.add(-1); - } - userData.add("-"); - } - - ObjectNode userRow = JsonNodeFactory.instance.objectNode(); - userRow.put("id", i++); - userRow.set("cell", userData); - - rows.add(userRow); - } - - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - responseJSON.put("total", totalPages); - responseJSON.put("page", page); - responseJSON.put("records", countSessionUsers); - responseJSON.set("rows", rows); - - res.setContentType("application/json;charset=utf-8"); - res.getWriter().print(new String(responseJSON.toString())); - return null; - } - - /** - * Get the mark summary with data arranged in bands. Can be displayed graphically or in a table. - */ - @RequestMapping("/getMarkChartData") - public String getMarkChartData(HttpServletRequest request, HttpServletResponse res) - throws IOException, ServletException { - SessionMap sessionMap = getSessionMap(request); - - Long contentId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); - Assessment assessment = service.getAssessmentByContentId(contentId); - List results = null; - - if (assessment != null) { - if (assessment.isUseSelectLeaderToolOuput()) { - results = service.getMarksArrayForLeaders(contentId); - } else { - Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.ATTR_TOOL_SESSION_ID); - results = service.getMarksArray(sessionId); - } - } - - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - if (results != null) { - responseJSON.set("data", JsonUtil.readArray(results)); - } else { - responseJSON.set("data", JsonUtil.readArray(new Float[0])); - } - - res.setContentType("application/json;charset=utf-8"); - res.getWriter().write(responseJSON.toString()); - return null; - - } - - /** - * Excel Summary Export. - */ - @SuppressWarnings("unchecked") - @RequestMapping("/exportSummary") - public String exportSummary(HttpServletRequest request, HttpServletResponse response) throws IOException { - String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); - String fileName = null; - boolean showUserNames = true; - - Long contentId = null; - List sessionDtos; - if (sessionMapID != null) { - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(sessionMapID); - request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); - contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); - showUserNames = true; - sessionDtos = (List) sessionMap.get("sessionDtos"); - - } else { - contentId = WebUtil.readLongParam(request, "toolContentID"); - fileName = WebUtil.readStrParam(request, "fileName"); - showUserNames = false; - sessionDtos = service.getSessionDtos(contentId, true); - } - - Assessment assessment = service.getAssessmentByContentId(contentId); - if (assessment == null) { - return null; - } - - LinkedHashMap dataToExport = service.exportSummary(assessment, sessionDtos, - showUserNames); - - // Setting the filename if it wasn't passed in the request - if (fileName == null) { - fileName = "assessment_" + assessment.getUid() + "_export.xlsx"; - } - - response.setContentType("application/x-download"); - response.setHeader("Content-Disposition", "attachment;filename=" + fileName); - log.debug("Exporting assessment to a spreadsheet: " + assessment.getContentId()); - - // set cookie that will tell JS script that export has been finished - String downloadTokenValue = WebUtil.readStrParam(request, "downloadTokenValue"); - Cookie fileDownloadTokenCookie = new Cookie("fileDownloadToken", downloadTokenValue); - fileDownloadTokenCookie.setPath("/"); - response.addCookie(fileDownloadTokenCookie); - - ServletOutputStream out = response.getOutputStream(); - ExcelUtil.createExcel(out, dataToExport, service.getMessage("label.export.exported.on"), true); - - return null; - } - - @RequestMapping("/statistic") - public String statistic(HttpServletRequest request, HttpServletResponse response) { - SessionMap sessionMap = getSessionMap(request); - - Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); - Assessment assessment = service.getAssessmentByContentId(contentId); - if (assessment != null) { - if (assessment.isUseSelectLeaderToolOuput()) { - LeaderResultsDTO leaderDto = service.getLeaderResultsDTOForLeaders(contentId); - sessionMap.put("leaderDto", leaderDto); - } else { - List sessionDtos = service.getSessionDtos(contentId, true); - sessionMap.put("sessionDtos", sessionDtos); - } - - List qbStats = new LinkedList<>(); - for (AssessmentQuestion question : assessment.getQuestions()) { - QbStatsActivityDTO questionStats = qbService.getActivityStatsByContentId(assessment.getContentId(), - question.getQbQuestion().getUid()); - questionStats.setQbQuestion(question.getQbQuestion()); - qbStats.add(questionStats); - } - request.setAttribute("qbStats", qbStats); - } - return "pages/monitoring/statisticpart"; - } - - /** - * Allows displaying correct answers to learners - */ - @RequestMapping("/discloseCorrectAnswers") - public void discloseCorrectAnswers(HttpServletRequest request, HttpServletResponse response) { - Long questionUid = WebUtil.readLongParam(request, "questionUid"); - Long toolContentId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_TOOL_CONTENT_ID); - - AssessmentQuestion question = service.getAssessmentQuestionByUid(questionUid); - question.setCorrectAnswersDisclosed(true); - service.updateAssessmentQuestion(question); - - service.notifyLearnersOnAnswerDisclose(toolContentId); - - if (log.isDebugEnabled()) { - log.debug("Disclosed correct answers for Assessment tool content ID " + toolContentId + " and question ID " - + questionUid); - } - } - - /** - * Allows displaying other groups' answers to learners - */ - @RequestMapping("/discloseGroupsAnswers") - public void discloseGroupsAnswers(HttpServletRequest request, HttpServletResponse response) { - Long questionUid = WebUtil.readLongParam(request, "questionUid"); - Long toolContentId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_TOOL_CONTENT_ID); - - AssessmentQuestion question = service.getAssessmentQuestionByUid(questionUid); - question.setGroupsAnswersDisclosed(true); - service.updateAssessmentQuestion(question); - - service.notifyLearnersOnAnswerDisclose(toolContentId); - - if (log.isDebugEnabled()) { - log.debug("Disclosed other groups' answers for Assessment tool content ID " + toolContentId - + " and question ID " + questionUid); - } - } - - @SuppressWarnings("unchecked") - private SessionMap getSessionMap(HttpServletRequest request) { - String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); - request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); - return (SessionMap) request.getSession().getAttribute(sessionMapID); - } - -} +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.assessment.web.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.qb.dto.QbStatsActivityDTO; +import org.lamsfoundation.lams.qb.service.IQbService; +import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; +import org.lamsfoundation.lams.tool.assessment.dto.AssessmentResultDTO; +import org.lamsfoundation.lams.tool.assessment.dto.AssessmentUserDTO; +import org.lamsfoundation.lams.tool.assessment.dto.LeaderResultsDTO; +import org.lamsfoundation.lams.tool.assessment.dto.QuestionSummary; +import org.lamsfoundation.lams.tool.assessment.dto.ReflectDTO; +import org.lamsfoundation.lams.tool.assessment.dto.SessionDTO; +import org.lamsfoundation.lams.tool.assessment.dto.UserSummary; +import org.lamsfoundation.lams.tool.assessment.model.Assessment; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestion; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionResult; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentResult; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentSession; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; +import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; +import org.lamsfoundation.lams.tool.assessment.service.IAssessmentService; +import org.lamsfoundation.lams.tool.assessment.util.AssessmentEscapeUtils; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.CommonConstants; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.JsonUtil; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelSheet; +import org.lamsfoundation.lams.util.excel.ExcelUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.util.HtmlUtils; + +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +@Controller +@RequestMapping("/monitoring") +public class MonitoringController { + public static Logger log = Logger.getLogger(MonitoringController.class); + + @Autowired + @Qualifier("laasseAssessmentService") + private IAssessmentService service; + + @Autowired + private IQbService qbService; + + @RequestMapping("/summary") + public String summary(HttpServletRequest request, HttpServletResponse response) { + + // initialize Session Map + SessionMap sessionMap = new SessionMap<>(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + + Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + List sessionDtos = service.getSessionDtos(contentId, false); + + Assessment assessment = service.getAssessmentByContentId(contentId); + + //set SubmissionDeadline, if any + if (assessment.getSubmissionDeadline() != null) { + Date submissionDeadline = assessment.getSubmissionDeadline(); + HttpSession ss = SessionManager.getSession(); + UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone teacherTimeZone = teacher.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(teacherTimeZone, submissionDeadline); + request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); + // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed + request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + } + + // Create reflectList if reflection is enabled. + if (assessment.isReflectOnActivity()) { + List reflectList = service.getReflectList(assessment.getContentId()); + // Add reflectList to sessionMap + sessionMap.put(AssessmentConstants.ATTR_REFLECT_LIST, reflectList); + } + + //prepare list of the questions to display in question drop down menu, filtering out questions that aren't supposed to be answered + Set questionList = new TreeSet<>(); + //in case there is at least one random question - we need to show all questions in a drop down select + if (assessment.hasRandomQuestion()) { + questionList.addAll(assessment.getQuestions()); + + //show only questions from question list otherwise + } else { + for (QuestionReference reference : assessment.getQuestionReferences()) { + questionList.add(reference.getQuestion()); + } + } + + //prepare toolOutputDefinitions and activityEvaluation + List toolOutputDefinitions = new ArrayList<>(); + toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_LEARNER_TOTAL_SCORE); + toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_BEST_SCORE); + toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_FIRST_SCORE); + toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_AVERAGE_SCORE); + String activityEvaluation = service.getActivityEvaluation(contentId); + sessionMap.put(AssessmentConstants.ATTR_TOOL_OUTPUT_DEFINITIONS, toolOutputDefinitions); + sessionMap.put(AssessmentConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); + + // cache into sessionMap + boolean isGroupedActivity = service.isGroupedActivity(contentId); + sessionMap.put(AssessmentConstants.ATTR_IS_GROUPED_ACTIVITY, isGroupedActivity); + sessionMap.put("sessionDtos", sessionDtos); + sessionMap.put(AssessmentConstants.ATTR_ASSESSMENT, assessment); + sessionMap.put(AssessmentConstants.ATTR_QUESTION_LIST, questionList); + sessionMap.put(AssessmentConstants.ATTR_TOOL_CONTENT_ID, contentId); + sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, + WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID)); + return "pages/monitoring/monitoring"; + } + + @RequestMapping("/userMasterDetail") + public String userMasterDetail(HttpServletRequest request, HttpServletResponse response) { + Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); + Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_SESSION_ID); + String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); + AssessmentResultDTO result = service.getUserMasterDetail(sessionId, userId); + + request.setAttribute(AssessmentConstants.ATTR_ASSESSMENT_RESULT, result); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return (result == null) ? null : "pages/monitoring/parts/masterDetailLoadUp"; + } + + @RequestMapping("/questionSummary") + public String questionSummary(HttpServletRequest request, HttpServletResponse response) { + SessionMap sessionMap = getSessionMap(request); + + Long questionUid = WebUtil.readLongParam(request, AssessmentConstants.PARAM_QUESTION_UID); + if (questionUid.equals(-1l)) { + return null; + } + Long contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); + QuestionSummary questionSummary = service.getQuestionSummary(contentId, questionUid); + + request.setAttribute(AssessmentConstants.ATTR_QUESTION_SUMMARY, questionSummary); + return "pages/monitoring/parts/questionsummary"; + } + + @RequestMapping("/allocateUserAnswer") + @ResponseStatus(HttpStatus.OK) + public void allocateUserAnswer(HttpServletRequest request, HttpServletResponse response, + @RequestParam Long questionUid, @RequestParam Long targetOptionUid, @RequestParam Long previousOptionUid, + @RequestParam Long questionResultUid) { + service.allocateAnswerToOption(questionUid, targetOptionUid, previousOptionUid, questionResultUid); + } + + @RequestMapping("/userSummary") + public String userSummary(HttpServletRequest request, HttpServletResponse response) { + SessionMap sessionMap = getSessionMap(request); + + Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); + Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_SESSION_ID); + Long contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); + UserSummary userSummary = service.getUserSummary(contentId, userId, sessionId); + + request.setAttribute(AssessmentConstants.ATTR_USER_SUMMARY, userSummary); + return "pages/monitoring/parts/usersummary"; + } + + @RequestMapping("/saveUserGrade") + public void saveUserGrade(HttpServletRequest request, HttpServletResponse response) { + + if ((request.getParameter(AssessmentConstants.PARAM_NOT_A_NUMBER) == null) + && !StringUtils.isEmpty(request.getParameter(AssessmentConstants.PARAM_QUESTION_RESULT_UID))) { + Long questionResultUid = WebUtil.readLongParam(request, AssessmentConstants.PARAM_QUESTION_RESULT_UID); + float newGrade = Float.valueOf(request.getParameter(AssessmentConstants.PARAM_GRADE)); + service.changeQuestionResultMark(questionResultUid, newGrade); + } + } + + /** + * Set Submission Deadline + */ + @RequestMapping("/setSubmissionDeadline") + @ResponseBody + public String setSubmissionDeadline(HttpServletRequest request, HttpServletResponse response) throws IOException { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Assessment assessment = service.getAssessmentByContentId(contentID); + + Long dateParameter = WebUtil.readLongParam(request, AssessmentConstants.ATTR_SUBMISSION_DEADLINE, true); + Date tzSubmissionDeadline = null; + String formattedDate = ""; + if (dateParameter != null) { + Date submissionDeadline = new Date(dateParameter); + HttpSession ss = SessionManager.getSession(); + UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone teacherTimeZone = teacher.getTimeZone(); + tzSubmissionDeadline = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, submissionDeadline); + formattedDate = DateUtil.convertToStringForJSON(tzSubmissionDeadline, request.getLocale()); + + } + assessment.setSubmissionDeadline(tzSubmissionDeadline); + service.saveOrUpdateAssessment(assessment); + + response.setContentType("text/plain;charset=utf-8"); + response.getWriter().print(formattedDate); + return null; + } + + /** + * Set tool's activityEvaluation + */ + @RequestMapping("/setActivityEvaluation") + @ResponseBody + public String setActivityEvaluation(HttpServletRequest request, HttpServletResponse response) throws IOException { + SessionMap sessionMap = getSessionMap(request); + + Long contentID = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); + String activityEvaluation = WebUtil.readStrParam(request, AssessmentConstants.ATTR_ACTIVITY_EVALUATION, true); + service.setActivityEvaluation(contentID, activityEvaluation); + + // update the session ready for stats tab to be reloaded otherwise flicking between tabs + // causes the old value to be redisplayed + sessionMap.put(AssessmentConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("success", "true"); + response.setContentType("application/json;charset=utf-8"); + return responseJSON.toString(); + } + + /** + * Refreshes user list. + */ + @RequestMapping("/getUsers") + public String getUsers(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException { + SessionMap sessionMap = getSessionMap(request); + Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); + + Long sessionId = WebUtil.readLongParam(request, "sessionId"); + + // Getting the params passed in from the jqGrid + int page = WebUtil.readIntParam(request, CommonConstants.PARAM_PAGE); + int rowLimit = WebUtil.readIntParam(request, CommonConstants.PARAM_ROWS); + String sortOrder = WebUtil.readStrParam(request, CommonConstants.PARAM_SORD); + String sortBy = WebUtil.readStrParam(request, CommonConstants.PARAM_SIDX, true); + if (StringUtils.isEmpty(sortBy)) { + sortBy = "userName"; + } + String searchString = WebUtil.readStrParam(request, "userName", true); + + List userDtos = new ArrayList<>(); + int countSessionUsers = 0; + //in case of UseSelectLeaderToolOuput - display only one user + if (assessment.isUseSelectLeaderToolOuput()) { + + AssessmentSession session = service.getSessionBySessionId(sessionId); + AssessmentUser groupLeader = session.getGroupLeader(); + + if (groupLeader != null) { + + float assessmentResult = service.getLastTotalScoreByUser(assessment.getUid(), groupLeader.getUserId()); + Long portraitId = service.getPortraitId(groupLeader.getUserId()); + + AssessmentUserDTO userDto = new AssessmentUserDTO(); + userDto.setUserId(groupLeader.getUserId()); + userDto.setFirstName(groupLeader.getFirstName()); + userDto.setLastName(groupLeader.getLastName()); + userDto.setGrade(assessmentResult); + userDto.setPortraitId(portraitId); + userDtos.add(userDto); + countSessionUsers = 1; + } + + } else { + // Get the user list from the db + userDtos = service.getPagedUsersBySession(sessionId, page - 1, rowLimit, sortBy, sortOrder, searchString); + countSessionUsers = service.getCountUsersBySession(sessionId, searchString); + } + + int totalPages = Double.valueOf(Math.ceil(Double.valueOf(countSessionUsers) / Double.valueOf(rowLimit))) + .intValue(); + + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + int i = 1; + for (AssessmentUserDTO userDto : userDtos) { + + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(userDto.getUserId()); + userData.add(sessionId); + String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); + userData.add(fullName); + userData.add(userDto.getGrade()); + if (userDto.getPortraitId() != null) { + userData.add(userDto.getPortraitId()); + } + + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); + userRow.put("id", i++); + userRow.set("cell", userData); + + rows.add(userRow); + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("total", totalPages); + responseJSON.put("page", page); + responseJSON.put("records", countSessionUsers); + responseJSON.set("rows", rows); + + res.setContentType("application/json;charset=utf-8"); + res.getWriter().print(new String(responseJSON.toString())); + return null; + } + + /** + * Refreshes user list. + */ + @RequestMapping("/getUsersByQuestion") + public String getUsersByQuestion(HttpServletRequest request, HttpServletResponse res) + throws IOException, ServletException { + SessionMap sessionMap = getSessionMap(request); + Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); + + Long sessionId = WebUtil.readLongParam(request, "sessionId"); + Long questionUid = WebUtil.readLongParam(request, "questionUid"); + + // Getting the params passed in from the jqGrid + int page = WebUtil.readIntParam(request, CommonConstants.PARAM_PAGE); + int rowLimit = WebUtil.readIntParam(request, CommonConstants.PARAM_ROWS); + String sortOrder = WebUtil.readStrParam(request, CommonConstants.PARAM_SORD); + String sortBy = WebUtil.readStrParam(request, CommonConstants.PARAM_SIDX, true); + if (StringUtils.isEmpty(sortBy)) { + sortBy = "userName"; + } + String searchString = WebUtil.readStrParam(request, "userName", true); + + List userDtos = new ArrayList<>(); + int countSessionUsers = 0; + //in case of UseSelectLeaderToolOuput - display only one user + if (assessment.isUseSelectLeaderToolOuput()) { + + AssessmentSession session = service.getSessionBySessionId(sessionId); + AssessmentUser groupLeader = session.getGroupLeader(); + + if (groupLeader != null) { + + AssessmentResult assessmentResult = service.getLastFinishedAssessmentResult(assessment.getUid(), + groupLeader.getUserId()); + Long questionResultUid = null; + if (assessmentResult != null) { + for (AssessmentQuestionResult dbQuestionResult : assessmentResult.getQuestionResults()) { + if (dbQuestionResult.getQbToolQuestion().getUid().equals(questionUid)) { + questionResultUid = dbQuestionResult.getUid(); + break; + } + } + } + + AssessmentUserDTO userDto = new AssessmentUserDTO(); + userDto.setQuestionResultUid(questionResultUid); + userDto.setFirstName(groupLeader.getFirstName()); + userDto.setLastName(groupLeader.getLastName()); + userDtos.add(userDto); + countSessionUsers = 1; + } + + } else { + // Get the user list from the db + userDtos = service.getPagedUsersBySessionAndQuestion(sessionId, questionUid, page - 1, rowLimit, sortBy, + sortOrder, searchString); + countSessionUsers = service.getCountUsersBySession(sessionId, searchString); + } + + int totalPages = Double.valueOf(Math.ceil(Double.valueOf(countSessionUsers) / Double.valueOf(rowLimit))) + .intValue(); + + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + int i = 1; + for (AssessmentUserDTO userDto : userDtos) { + + Long questionResultUid = userDto.getQuestionResultUid(); + String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); + + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + if (questionResultUid != null) { + AssessmentQuestionResult questionResult = service.getAssessmentQuestionResultByUid(questionResultUid); + + userData.add(questionResultUid); + userData.add(questionResult.getMaxMark()); + userData.add(fullName); + //LDEV_NTU-11 Swapping Mark and Response columns in Assessment Monitor + userData.add(questionResult.getMark()); + // show confidence levels if this feature is turned ON + if (assessment.isEnableConfidenceLevels()) { + userData.add(questionResult.getConfidenceLevel()); + } + + userData.add(AssessmentEscapeUtils.printResponsesForJqgrid(questionResult)); + if (userDto.getPortraitId() != null) { + userData.add(userDto.getPortraitId()); + } + + } else { + userData.add(""); + userData.add(""); + userData.add(fullName); + userData.add("-"); + if (assessment.isEnableConfidenceLevels()) { + userData.add(-1); + } + userData.add("-"); + } + + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); + userRow.put("id", i++); + userRow.set("cell", userData); + + rows.add(userRow); + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("total", totalPages); + responseJSON.put("page", page); + responseJSON.put("records", countSessionUsers); + responseJSON.set("rows", rows); + + res.setContentType("application/json;charset=utf-8"); + res.getWriter().print(new String(responseJSON.toString())); + return null; + } + + /** + * Get the mark summary with data arranged in bands. Can be displayed graphically or in a table. + */ + @RequestMapping("/getMarkChartData") + public String getMarkChartData(HttpServletRequest request, HttpServletResponse res) + throws IOException, ServletException { + SessionMap sessionMap = getSessionMap(request); + + Long contentId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); + Assessment assessment = service.getAssessmentByContentId(contentId); + List results = null; + + if (assessment != null) { + if (assessment.isUseSelectLeaderToolOuput()) { + results = service.getMarksArrayForLeaders(contentId); + } else { + Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.ATTR_TOOL_SESSION_ID); + results = service.getMarksArray(sessionId); + } + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (results != null) { + responseJSON.set("data", JsonUtil.readArray(results)); + } else { + responseJSON.set("data", JsonUtil.readArray(new Float[0])); + } + + res.setContentType("application/json;charset=utf-8"); + res.getWriter().write(responseJSON.toString()); + return null; + + } + + /** + * Excel Summary Export. + */ + @SuppressWarnings("unchecked") + @RequestMapping("/exportSummary") + public String exportSummary(HttpServletRequest request, HttpServletResponse response) throws IOException { + String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); + String fileName = null; + boolean showUserNames = true; + + Long contentId = null; + List sessionDtos; + if (sessionMapID != null) { + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapID); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + contentId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_CONTENT_ID); + showUserNames = true; + sessionDtos = (List) sessionMap.get("sessionDtos"); + + } else { + contentId = WebUtil.readLongParam(request, "toolContentID"); + fileName = WebUtil.readStrParam(request, "fileName"); + showUserNames = false; + sessionDtos = service.getSessionDtos(contentId, true); + } + + Assessment assessment = service.getAssessmentByContentId(contentId); + if (assessment == null) { + return null; + } + + List sheets = service.exportSummary(assessment, sessionDtos, showUserNames); + + // Setting the filename if it wasn't passed in the request + if (fileName == null) { + fileName = "assessment_" + assessment.getUid() + "_export.xlsx"; + } + + response.setContentType("application/x-download"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName); + log.debug("Exporting assessment to a spreadsheet: " + assessment.getContentId()); + + // set cookie that will tell JS script that export has been finished + String downloadTokenValue = WebUtil.readStrParam(request, "downloadTokenValue"); + Cookie fileDownloadTokenCookie = new Cookie("fileDownloadToken", downloadTokenValue); + fileDownloadTokenCookie.setPath("/"); + response.addCookie(fileDownloadTokenCookie); + + ServletOutputStream out = response.getOutputStream(); + ExcelUtil.createExcel(out, sheets, service.getMessage("label.export.exported.on"), true); + + return null; + } + + @RequestMapping("/statistic") + public String statistic(HttpServletRequest request, HttpServletResponse response) { + SessionMap sessionMap = getSessionMap(request); + + Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Assessment assessment = service.getAssessmentByContentId(contentId); + if (assessment != null) { + if (assessment.isUseSelectLeaderToolOuput()) { + LeaderResultsDTO leaderDto = service.getLeaderResultsDTOForLeaders(contentId); + sessionMap.put("leaderDto", leaderDto); + } else { + List sessionDtos = service.getSessionDtos(contentId, true); + sessionMap.put("sessionDtos", sessionDtos); + } + + List qbStats = new LinkedList<>(); + for (AssessmentQuestion question : assessment.getQuestions()) { + QbStatsActivityDTO questionStats = qbService.getActivityStatsByContentId(assessment.getContentId(), + question.getQbQuestion().getUid()); + questionStats.setQbQuestion(question.getQbQuestion()); + qbStats.add(questionStats); + } + request.setAttribute("qbStats", qbStats); + } + return "pages/monitoring/statisticpart"; + } + + /** + * Allows displaying correct answers to learners + */ + @RequestMapping("/discloseCorrectAnswers") + public void discloseCorrectAnswers(HttpServletRequest request, HttpServletResponse response) { + Long questionUid = WebUtil.readLongParam(request, "questionUid"); + Long toolContentId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_TOOL_CONTENT_ID); + + AssessmentQuestion question = service.getAssessmentQuestionByUid(questionUid); + question.setCorrectAnswersDisclosed(true); + service.updateAssessmentQuestion(question); + + service.notifyLearnersOnAnswerDisclose(toolContentId); + + if (log.isDebugEnabled()) { + log.debug("Disclosed correct answers for Assessment tool content ID " + toolContentId + " and question ID " + + questionUid); + } + } + + /** + * Allows displaying other groups' answers to learners + */ + @RequestMapping("/discloseGroupsAnswers") + public void discloseGroupsAnswers(HttpServletRequest request, HttpServletResponse response) { + Long questionUid = WebUtil.readLongParam(request, "questionUid"); + Long toolContentId = WebUtil.readLongParam(request, AssessmentConstants.PARAM_TOOL_CONTENT_ID); + + AssessmentQuestion question = service.getAssessmentQuestionByUid(questionUid); + question.setGroupsAnswersDisclosed(true); + service.updateAssessmentQuestion(question); + + service.notifyLearnersOnAnswerDisclose(toolContentId); + + if (log.isDebugEnabled()) { + log.debug("Disclosed other groups' answers for Assessment tool content ID " + toolContentId + + " and question ID " + questionUid); + } + } + + @SuppressWarnings("unchecked") + private SessionMap getSessionMap(HttpServletRequest request) { + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return (SessionMap) request.getSession().getAttribute(sessionMapID); + } + +} Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java =================================================================== diff -u -rdcdc1487609bd4f00afaa93c09272d84ab0cd325 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision dcdc1487609bd4f00afaa93c09272d84ab0cd325) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -11,23 +11,25 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import org.lamsfoundation.lams.qb.model.QbQuestion; import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentResultDTO; +import org.lamsfoundation.lams.tool.assessment.dto.OptionDTO; +import org.lamsfoundation.lams.tool.assessment.dto.QuestionDTO; import org.lamsfoundation.lams.tool.assessment.dto.QuestionSummary; import org.lamsfoundation.lams.tool.assessment.dto.TblAssessmentDTO; import org.lamsfoundation.lams.tool.assessment.dto.TblAssessmentQuestionDTO; import org.lamsfoundation.lams.tool.assessment.dto.TblAssessmentQuestionResultDTO; import org.lamsfoundation.lams.tool.assessment.model.Assessment; import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestion; -import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionOption; import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionResult; import org.lamsfoundation.lams.tool.assessment.model.AssessmentSession; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; +import org.lamsfoundation.lams.tool.assessment.service.AssessmentServiceImpl; import org.lamsfoundation.lams.tool.assessment.service.IAssessmentService; import org.lamsfoundation.lams.tool.assessment.util.AssessmentEscapeUtils; import org.lamsfoundation.lams.tool.assessment.util.AssessmentSessionComparator; -import org.lamsfoundation.lams.tool.assessment.util.SequencableComparator; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.beans.factory.annotation.Autowired; @@ -69,51 +71,52 @@ Assessment assessment = assessmentService.getAssessmentByContentId(toolContentId); //prepare list of the questions, filtering out questions that aren't supposed to be answered - Set questionList = new TreeSet(); + Set questionList = new TreeSet<>(); //in case there is at least one random question - we need to show all questions in a drop down select if (assessment.hasRandomQuestion()) { questionList.addAll(assessment.getQuestions()); //show only questions from question list otherwise } else { - for (QuestionReference reference : (Set) assessment.getQuestionReferences()) { + for (QuestionReference reference : assessment.getQuestionReferences()) { questionList.add(reference.getQuestion()); } } //keep only MCQ type of questions - Set mcqQuestions = new TreeSet(); + Set questionDtos = new TreeSet<>(); int maxOptionsInQuestion = 0; for (AssessmentQuestion question : questionList) { - if (AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE == question.getType()) { - mcqQuestions.add(question); + if (QbQuestion.TYPE_MULTIPLE_CHOICE == question.getType() + || QbQuestion.TYPE_VERY_SHORT_ANSWERS == question.getType()) { + questionDtos.add(new QuestionDTO(question)); //calculate maxOptionsInQuestion - if (question.getOptions().size() > maxOptionsInQuestion) { - maxOptionsInQuestion = question.getOptions().size(); + if (question.getQbQuestion().getQbOptions().size() > maxOptionsInQuestion) { + maxOptionsInQuestion = question.getQbQuestion().getQbOptions().size(); } } } request.setAttribute("maxOptionsInQuestion", maxOptionsInQuestion); int totalNumberOfUsers = assessmentService.getCountUsersByContentId(toolContentId); - for (AssessmentQuestion question : mcqQuestions) { + for (QuestionDTO questionDto : questionDtos) { // build candidate dtos - for (AssessmentQuestionOption option : question.getOptions()) { - int optionAttemptCount = assessmentService.countAttemptsPerOption(option.getUid()); + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + int optionAttemptCount = assessmentService.countAttemptsPerOption(toolContentId, optionDto.getUid()); float percentage = (float) (optionAttemptCount * 100) / totalNumberOfUsers; - option.setPercentage(percentage); + optionDto.setPercentage(percentage); } } - request.setAttribute("questions", mcqQuestions); + request.setAttribute("questions", questionDtos); request.setAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentId); return "pages/tblmonitoring/iraAssessmentStudentChoices"; } private List getAssessmentDtos(String[] toolContentIds, String[] activityTitles) { - List assessmentDtos = new ArrayList(); + List assessmentDtos = new ArrayList<>(); int i = 0; for (String toolContentIdStr : toolContentIds) { String activityTitle = activityTitles[i++]; @@ -141,9 +144,9 @@ private Set prepareQuestionsList(Assessment assessment) { // question list to display - Set questions = new TreeSet(); + Set questions = new TreeSet<>(); boolean hasRandomQuestion = false; - for (QuestionReference reference : (Set) assessment.getQuestionReferences()) { + for (QuestionReference reference : assessment.getQuestionReferences()) { hasRandomQuestion |= reference.isRandomQuestion(); } // in case there is at least one random question - we need to show all questions @@ -152,10 +155,10 @@ // show only questions from question list otherwise } else { - for (QuestionReference reference : (Set) assessment.getQuestionReferences()) { + for (QuestionReference reference : assessment.getQuestionReferences()) { //sort questions the same way references are sorted (as per LKC request) AssessmentQuestion question = reference.getQuestion(); - question.setSequenceId(reference.getSequenceId()); + question.setDisplayOrder(reference.getSequenceId()); questions.add(question); } } @@ -188,16 +191,17 @@ Long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Assessment assessment = assessmentService.getAssessmentByContentId(toolContentId); Map questionSummaries = assessmentService.getQuestionSummaryForExport(assessment); - List tblQuestionDtos = new ArrayList(); + List tblQuestionDtos = new ArrayList<>(); for (QuestionSummary questionSummary : questionSummaries.values()) { - AssessmentQuestion question = questionSummary.getQuestion(); + QuestionDTO questionDto = questionSummary.getQuestionDto(); TblAssessmentQuestionDTO tblQuestionDto = new TblAssessmentQuestionDTO(); - tblQuestionDto.setQuestion(question); - tblQuestionDto.setQuestionTypeLabel(TblMonitoringController.getAssessmentQuestionTypeLabel(question.getType())); - tblQuestionDto.setCorrectAnswer(getAssessmentCorrectAnswer(question)); + tblQuestionDto.setTitle(questionDto.getTitle()); + tblQuestionDto + .setQuestionTypeLabel(AssessmentServiceImpl.getQuestionTypeLanguageLabel(questionDto.getType())); + tblQuestionDto.setCorrectAnswer(getAssessmentCorrectAnswer(questionDto)); - List sessionQuestionResults = new ArrayList(); + List sessionQuestionResults = new ArrayList<>(); for (List questionResultsPerSession : questionSummary .getQuestionResultsPerSession()) { @@ -221,7 +225,7 @@ tblQuestionDtos.add(tblQuestionDto); } - SortedSet sessions = new TreeSet(new AssessmentSessionComparator()); + SortedSet sessions = new TreeSet<>(new AssessmentSessionComparator()); sessions.addAll(assessmentService.getSessionsByContentId(assessment.getContentId())); request.setAttribute("sessions", sessions); @@ -233,81 +237,52 @@ /** * Used only for excell export (for getUserSummaryData() method). */ - private static String getAssessmentQuestionTypeLabel(short type) { - switch (type) { - case AssessmentConstants.QUESTION_TYPE_ESSAY: - return "Essay"; - case AssessmentConstants.QUESTION_TYPE_MATCHING_PAIRS: - return "Matching Pairs"; - case AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE: - return "Multiple Choice"; - case AssessmentConstants.QUESTION_TYPE_NUMERICAL: - return "Numerical"; - case AssessmentConstants.QUESTION_TYPE_ORDERING: - return "Ordering"; - case AssessmentConstants.QUESTION_TYPE_SHORT_ANSWER: - return "Short Answer"; - case AssessmentConstants.QUESTION_TYPE_TRUE_FALSE: - return "True/False"; - case AssessmentConstants.QUESTION_TYPE_MARK_HEDGING: - return "Mark Hedging"; - default: - return null; - } - } - - /** - * Used only for excell export (for getUserSummaryData() method). - */ - private String getAssessmentCorrectAnswer(AssessmentQuestion question) { + private String getAssessmentCorrectAnswer(QuestionDTO questionDto) { StringBuilder sb = new StringBuilder(); - if (question != null) { - switch (question.getType()) { - case AssessmentConstants.QUESTION_TYPE_ESSAY: + if (questionDto != null) { + switch (questionDto.getType()) { + case QbQuestion.TYPE_ESSAY: return "N.A."; - case AssessmentConstants.QUESTION_TYPE_MATCHING_PAIRS: - for (AssessmentQuestionOption option : question.getOptions()) { - sb.append((option.getQuestion() + " - " + option.getOptionString()).replaceAll("\\<.*?\\>", "") - + "
"); + case QbQuestion.TYPE_MATCHING_PAIRS: + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + sb.append( + (optionDto.getMatchingPair() + " - " + optionDto.getName()).replaceAll("\\<.*?\\>", "") + + "
"); } return sb.toString(); - case AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE: - case AssessmentConstants.QUESTION_TYPE_SHORT_ANSWER: - for (AssessmentQuestionOption option : question.getOptions()) { - if (option.getGrade() == 1f) { - return option.getOptionString(); + case QbQuestion.TYPE_MULTIPLE_CHOICE: + case QbQuestion.TYPE_VERY_SHORT_ANSWERS: + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + if (optionDto.getMaxMark() == 1f) { + return optionDto.getName(); } } break; - case AssessmentConstants.QUESTION_TYPE_NUMERICAL: - for (AssessmentQuestionOption option : question.getOptions()) { - if (option.getGrade() == 1f) { - return "" + option.getOptionFloat(); + case QbQuestion.TYPE_NUMERICAL: + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + if (optionDto.getMaxMark() == 1f) { + return "" + optionDto.getNumericalOption(); } } break; - case AssessmentConstants.QUESTION_TYPE_ORDERING: - TreeSet correctOptionSet = new TreeSet( - new SequencableComparator()); - correctOptionSet.addAll(question.getOptions()); - - for (AssessmentQuestionOption option : question.getOptions()) { - sb.append(option.getOptionString() + "\n"); + case QbQuestion.TYPE_ORDERING: + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + sb.append(optionDto.getName() + "\n"); } return sb.toString(); - case AssessmentConstants.QUESTION_TYPE_TRUE_FALSE: - return String.valueOf(question.getCorrectAnswer()); + case QbQuestion.TYPE_TRUE_FALSE: + return String.valueOf(questionDto.getCorrectAnswer()); - case AssessmentConstants.QUESTION_TYPE_MARK_HEDGING: - for (AssessmentQuestionOption option : question.getOptions()) { - if (option.isCorrect()) { - return option.getOptionString(); + case QbQuestion.TYPE_MARK_HEDGING: + for (OptionDTO optionDto : questionDto.getOptionDtos()) { + if (optionDto.isCorrect()) { + return optionDto.getName(); } } break; Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java =================================================================== diff -u -r517fff7d1277da3dc87cdb913e8691c8323bb8fd -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision 517fff7d1277da3dc87cdb913e8691c8323bb8fd) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -53,6 +53,7 @@ import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.util.CellUtil; import org.lamsfoundation.lams.confidencelevel.ConfidenceLevelDTO; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; @@ -105,10 +106,10 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; -import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.NumberUtil; +import org.lamsfoundation.lams.util.excel.ExcelUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.dao.DataAccessException; @@ -616,7 +617,7 @@ mcSessionMarkDTO.setSessionId(session.getMcSessionId().toString()); mcSessionMarkDTO.setSessionName(session.getSession_name().toString()); - List sessionUsers = session.getMcQueUsers(); + Set sessionUsers = session.getMcQueUsers(); Iterator usersIterator = sessionUsers.iterator(); Map mapSessionUsersData = new TreeMap( @@ -921,7 +922,7 @@ Set sessionList = content.getMcSessions(); for (McSession session : sessionList) { Long toolSessionId = session.getMcSessionId(); - List sessionUsers = session.getMcQueUsers(); + Set sessionUsers = session.getMcQueUsers(); for (McQueUsr user : sessionUsers) { @@ -996,7 +997,6 @@ @Override public byte[] prepareSessionDataSpreadsheet(McContent mcContent) throws IOException { - Set questions = mcContent.getMcQueContents(); int maxOptionsInQuestion = 0; for (McQueContent question : questions) { @@ -1022,6 +1022,8 @@ whiteFont.setFontName(ExcelUtil.DEFAULT_FONT_NAME); greenColor.setFont(whiteFont); + short percentageFormat = wb.createDataFormat().getFormat("0%"); + // ======================================================= Report by questionDescription IRA page // ======================================= @@ -1055,15 +1057,17 @@ for (QbOption option : question.getQbQuestion().getQbOptions()) { int optionAttemptCount = getAttemptsCountPerOption(option.getUid(), question.getUid()); cell = row.createCell(count++); - int percentage = (optionAttemptCount * 100) / totalNumberOfUsers; - cell.setCellValue(percentage + "%"); + int percentage = optionAttemptCount / totalNumberOfUsers; + cell.setCellValue(percentage); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); totalPercentage += percentage; if (option.isCorrect()) { cell.setCellStyle(greenColor); } } cell = row.createCell(maxOptionsInQuestion + 1); - cell.setCellValue((100 - totalPercentage) + "%"); + cell.setCellValue((1 - totalPercentage)); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); } rowCount++; @@ -1155,10 +1159,11 @@ cell = row.createCell(count++); cell.setCellValue(new Long(userMark.getTotalMark())); - int totalPercents = (numberOfCorrectlyAnsweredByUser * 100) / questions.size(); + int totalPercents = numberOfCorrectlyAnsweredByUser / questions.size(); totalPercentList.add(totalPercents); cell = row.createCell(count++); - cell.setCellValue(totalPercents + "%"); + cell.setCellValue(totalPercents); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); } rowCount++; @@ -1171,7 +1176,8 @@ cell.setCellValue(messageService.getMessage("label.ave")); for (int numberOfCorrectAnswers : numberOfCorrectAnswersPerQuestion) { cell = row.createCell(count++); - cell.setCellValue(((numberOfCorrectAnswers * 100) / totalPercentList.size()) + "%"); + cell.setCellValue(numberOfCorrectAnswers / totalPercentList.size()); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); } // class mean @@ -1187,7 +1193,8 @@ if (totalPercents.length != 0) { int classMean = sum / totalPercents.length; cell = row.createCell(questions.size() + 3); - cell.setCellValue(classMean + "%"); + cell.setCellValue(classMean); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); } // median @@ -1203,7 +1210,8 @@ median = (int) ((totalPercents[middle - 1] + totalPercents[middle]) / 2.0); } cell = row.createCell(questions.size() + 3); - cell.setCellValue(median + "%"); + cell.setCellValue(median); + CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, percentageFormat); } row = sheet.createRow(rowCount++); @@ -1297,7 +1305,6 @@ @Override public void copyToolContent(Long fromContentId, Long toContentId) { - if (fromContentId == null) { logger.warn("fromContentId is null."); long defaultContentId = getToolDefaultContentIdBySignature(McAppConstants.TOOL_SIGNATURE); @@ -1515,7 +1522,7 @@ if (!existsSession(toolSessionId)) { try { McSession mcSession = new McSession(toolSessionId, new Date(System.currentTimeMillis()), - McSession.INCOMPLETE, toolSessionName, mcContent, new ArrayList()); + McSession.INCOMPLETE, toolSessionName, mcContent, new HashSet()); mcSessionDAO.saveMcSession(mcSession); Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java =================================================================== diff -u -r6aa0f9c7abedde6c4c3cc7fe2b0b19176df284ed -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java (.../McLearningController.java) (revision 6aa0f9c7abedde6c4c3cc7fe2b0b19176df284ed) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java (.../McLearningController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -29,6 +29,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TimeZone; import java.util.TreeMap; @@ -241,7 +242,7 @@ // forwards to the leaderSelection page if (groupLeader == null && !mode.equals(ToolAccessMode.TEACHER.toString())) { - List groupUsers = mcSession.getMcQueUsers();// mcService.getUsersBySession(new + Set groupUsers = mcSession.getMcQueUsers();// mcService.getUsersBySession(new // Long(toolSessionID).longValue()); request.setAttribute(McAppConstants.ATTR_GROUP_USERS, groupUsers); request.setAttribute(McAppConstants.TOOL_SESSION_ID, toolSessionID); Index: lams_tool_lamc/web/authoring/itemlist.jsp =================================================================== diff -u -r9f01141eacca831242aaf29962f640c5b01b65ea -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_lamc/web/authoring/itemlist.jsp (.../itemlist.jsp) (revision 9f01141eacca831242aaf29962f640c5b01b65ea) +++ lams_tool_lamc/web/authoring/itemlist.jsp (.../itemlist.jsp) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -30,6 +30,16 @@
+
+ + + + + + + + +
Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java =================================================================== diff -u -r8d982bb83bb4040e0eba0076df8ab05ff715f2e9 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision 8d982bb83bb4040e0eba0076df8ab05ff715f2e9) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -45,7 +45,8 @@ import org.lamsfoundation.lams.tool.scratchie.model.ScratchieSession; import org.lamsfoundation.lams.tool.scratchie.model.ScratchieUser; import org.lamsfoundation.lams.tool.service.ICommonToolService; -import org.lamsfoundation.lams.util.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelSheet; import org.quartz.SchedulerException; /** @@ -326,7 +327,7 @@ * @param scratchie * @return */ - LinkedHashMap exportExcel(Long contentId); + List exportExcel(Long contentId); /** * Create refection entry into notebook tool. Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== diff -u -r517fff7d1277da3dc87cdb913e8691c8323bb8fd -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 517fff7d1277da3dc87cdb913e8691c8323bb8fd) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -33,7 +33,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -106,10 +105,11 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; -import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.NumberUtil; +import org.lamsfoundation.lams.util.excel.ExcelRow; +import org.lamsfoundation.lams.util.excel.ExcelSheet; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -121,8 +121,6 @@ implements IScratchieService, ICommonScratchieService, ToolContentManager, ToolSessionManager, ToolRestManager { private static Logger log = Logger.getLogger(ScratchieServiceImpl.class.getName()); - private static final ExcelCell[] EMPTY_ROW = new ExcelCell[4]; - private ScratchieDAO scratchieDao; private ScratchieItemDAO scratchieItemDao; @@ -245,7 +243,8 @@ } } - return presetMarks.split(","); + //remove all white spaces and split the settings around matches of "," + return presetMarks.replaceAll("\\s+", "").split(","); } @Override @@ -1248,47 +1247,46 @@ } @Override - public LinkedHashMap exportExcel(Long contentId) { + public List exportExcel(Long contentId) { Scratchie scratchie = scratchieDao.getByContentId(contentId); Collection items = new TreeSet<>(new ScratchieItemComparator()); items.addAll(scratchie.getScratchieItems()); int numberOfItems = items.size(); - LinkedHashMap dataToExport = new LinkedHashMap<>(); + List sheets = new LinkedList<>(); // ======================================================= For Immediate Analysis page // ======================================= + ExcelSheet immediateAnalysisSheet = new ExcelSheet(getMessage("label.for.immediate.analysis")); + sheets.add(immediateAnalysisSheet); - List rowList = new LinkedList<>(); + ExcelRow row = immediateAnalysisSheet.initRow(); + row.addCell(getMessage("label.quick.analysis"), true); - ExcelCell[] row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.quick.analysis"), true); - rowList.add(row); - row = new ExcelCell[2]; - row[1] = new ExcelCell(getMessage("label.in.table.below.we.show"), false); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = immediateAnalysisSheet.initRow(); + row.addEmptyCell(); + row.addCell(getMessage("label.in.table.below.we.show")); + immediateAnalysisSheet.addEmptyRow(); - row = new ExcelCell[3]; - row[2] = new ExcelCell(getMessage("label.questions"), false); - rowList.add(row); + row = immediateAnalysisSheet.initRow(); + row.addEmptyCells(2); + row.addCell(getMessage("label.questions")); - row = new ExcelCell[numberOfItems + 4]; - int columnCount = 1; - row[columnCount++] = new ExcelCell(getMessage("label.teams"), true); + row = immediateAnalysisSheet.initRow(); + row.addEmptyCell(); + row.addCell(getMessage("label.teams"), true); for (int itemCount = 0; itemCount < numberOfItems; itemCount++) { - row[columnCount++] = new ExcelCell("Q" + (itemCount + 1), true); + row.addCell("Q" + (itemCount + 1), true); } - row[columnCount++] = new ExcelCell(getMessage("label.total"), true); - row[columnCount++] = new ExcelCell(getMessage("label.total") + " %", true); - rowList.add(row); + row.addCell(getMessage("label.total"), true); + row.addCell(getMessage("label.total") + " %", true); List summaryByTeam = getSummaryByTeam(scratchie, items); for (GroupSummary summary : summaryByTeam) { - row = new ExcelCell[numberOfItems + 4]; - columnCount = 1; - row[columnCount++] = new ExcelCell(summary.getSessionName(), true); + row = immediateAnalysisSheet.initRow(); + row.addEmptyCell(); + row.addCell(summary.getSessionName(), true); int numberOfFirstChoiceEvents = 0; for (ScratchieItemDTO itemDto : summary.getItemDtos()) { @@ -1307,70 +1305,60 @@ isFirstChoice = getMessage("label.incorrect"); color = IndexedColors.RED; } - row[columnCount++] = new ExcelCell(isFirstChoice, color); + row.addCell(isFirstChoice, color); } - row[columnCount++] = new ExcelCell(new Integer(numberOfFirstChoiceEvents), false); - int percentage = (numberOfItems == 0) ? 0 : (100 * numberOfFirstChoiceEvents) / numberOfItems; - row[columnCount++] = new ExcelCell(percentage + "%", false); - rowList.add(row); + row.addCell(new Integer(numberOfFirstChoiceEvents)); + double percentage = (numberOfItems == 0) ? 0 : (double) numberOfFirstChoiceEvents / numberOfItems; + row.addPercentageCell(percentage); } - ExcelCell[][] firstPageData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("label.for.immediate.analysis"), firstPageData); - // ======================================================= For Report by Team TRA page // ======================================= + ExcelSheet reportByTeamSheet = new ExcelSheet(getMessage("label.report.by.team.tra")); + sheets.add(reportByTeamSheet); - rowList = new LinkedList<>(); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.quick.analysis"), true); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.quick.analysis"), true); - rowList.add(row); - row = new ExcelCell[2]; - row[1] = new ExcelCell(getMessage("label.table.below.shows.which.answer.teams.selected.first.try"), false); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = reportByTeamSheet.initRow(); + row.addEmptyCell(); + row.addCell(getMessage("label.table.below.shows.which.answer.teams.selected.first.try")); + reportByTeamSheet.addEmptyRow(); - row = new ExcelCell[numberOfItems + 3]; - columnCount = 1; + row = reportByTeamSheet.initRow(); + row.addEmptyCell(); for (int itemCount = 0; itemCount < numberOfItems; itemCount++) { - row[columnCount++] = new ExcelCell(getMessage("label.authoring.basic.instruction") + " " + (itemCount + 1), - false); + row.addCell(getMessage("label.authoring.basic.instruction") + " " + (itemCount + 1)); } - row[columnCount++] = new ExcelCell(getMessage("label.total"), false); - row[columnCount++] = new ExcelCell(getMessage("label.total") + " %", false); - rowList.add(row); + row.addCell(getMessage("label.total")); + row.addCell(getMessage("label.total") + " %"); - row = new ExcelCell[numberOfItems + 1]; - columnCount = 0; - row[columnCount++] = new ExcelCell(getMessage("label.correct.answer"), false); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.correct.answer")); for (ScratchieItem item : items) { // find out the correct answer's sequential letter - A,B,C... - String correctOptionLetter = ""; - int optionCount = 1; - for (OptionDTO optionDto : item.getOptionDtos()) { - if (optionDto.isCorrect()) { - correctOptionLetter = String.valueOf((char) ((optionCount + 'A') - 1)); + String correctAnswerLetter = ""; + int answerCount = 1; + for (OptionDTO answer : item.getOptionDtos()) { + if (answer.isCorrect()) { + correctAnswerLetter = String.valueOf((char) ((answerCount + 'A') - 1)); break; } - optionCount++; + answerCount++; } - row[columnCount++] = new ExcelCell(correctOptionLetter, false); + row.addCell(correctAnswerLetter); } - rowList.add(row); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("monitoring.label.group"), false); - rowList.add(row); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("monitoring.label.group")); int groupCount = 1; - int[] percentages = new int[summaryByTeam.size()]; + double[] percentages = new double[summaryByTeam.size()]; for (GroupSummary summary : summaryByTeam) { - row = new ExcelCell[numberOfItems + 3]; - columnCount = 0; - row[columnCount++] = new ExcelCell(summary.getSessionName(), false); + row = reportByTeamSheet.initRow(); + row.addCell(summary.getSessionName()); int numberOfFirstChoiceEvents = 0; for (ScratchieItemDTO itemDto : summary.getItemDtos()) { @@ -1380,12 +1368,12 @@ color = IndexedColors.GREEN; numberOfFirstChoiceEvents++; } - row[columnCount++] = new ExcelCell(itemDto.getOptionsSequence(), color); + row.addCell(itemDto.getOptionsSequence(), color); } - row[columnCount++] = new ExcelCell(new Integer(numberOfFirstChoiceEvents), false); - int percentage = (numberOfItems == 0) ? 0 : (100 * numberOfFirstChoiceEvents) / numberOfItems; - row[columnCount++] = new ExcelCell(percentage + "%", false); - rowList.add(row); + row.addCell(new Integer(numberOfFirstChoiceEvents)); + double percentage = (numberOfItems == 0) ? 0 : (double) numberOfFirstChoiceEvents / numberOfItems; + row.addPercentageCell(percentage); + percentages[groupCount - 1] = percentage; groupCount++; } @@ -1398,76 +1386,65 @@ sum += percentages[i]; } int percentagesLength = percentages.length == 0 ? 1 : percentages.length; - int avgMean = sum / percentagesLength; - row = new ExcelCell[numberOfItems + 3]; - row[0] = new ExcelCell(getMessage("label.avg.mean"), false); - row[numberOfItems + 2] = new ExcelCell(avgMean + "%", false); - rowList.add(row); + double avgMean = (double) sum / percentagesLength; + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.avg.mean")); + row.addEmptyCells(numberOfItems + 1); + row.addPercentageCell(avgMean); // median - int median; + double median; int middle = percentages.length / 2; if ((percentages.length % 2) == 1) { median = percentages[middle]; } else { - median = (int) ((percentages[middle - 1] + percentages[middle]) / 2.0); + median = (percentages[middle - 1] + percentages[middle]) / 2.0; } - row = new ExcelCell[numberOfItems + 3]; - row[0] = new ExcelCell(getMessage("label.median"), false); - row[numberOfItems + 2] = new ExcelCell(median, false); - rowList.add(row); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.median")); + row.addEmptyCells(numberOfItems + 1); + row.addCell(median); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.legend"), false); - rowList.add(row); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.legend")); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.denotes.correct.answer"), IndexedColors.GREEN); - rowList.add(row); + row = reportByTeamSheet.initRow(); + row.addCell(getMessage("label.denotes.correct.answer"), IndexedColors.GREEN); - ExcelCell[][] secondPageData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("label.report.by.team.tra"), secondPageData); - // ======================================================= Research and Analysis page // ======================================= + ExcelSheet researchAndAnalysisSheet = new ExcelSheet(getMessage("label.research.analysis")); + sheets.add(researchAndAnalysisSheet); - // all rows - rowList = new LinkedList<>(); - // Caption - row = new ExcelCell[2]; - row[0] = new ExcelCell(getMessage("label.scratchie.report"), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.scratchie.report"), true); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); // Overall Summary by Team -------------------------------------------------- - row = new ExcelCell[2]; - row[0] = new ExcelCell(getMessage("label.overall.summary.by.team"), true); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.overall.summary.by.team"), true); - row = new ExcelCell[(numberOfItems * 3) + 1]; - columnCount = 1; + row = researchAndAnalysisSheet.initRow(); + row.addEmptyCell(); for (int itemCount = 0; itemCount < numberOfItems; itemCount++) { - row[columnCount] = new ExcelCell(getMessage("label.for.question", new Object[] { itemCount + 1 }), false); - columnCount += 3; + row.addCell(getMessage("label.for.question", new Object[] { itemCount + 1 })); + row.addEmptyCells(2); } - rowList.add(row); - row = new ExcelCell[(numberOfItems * 3) + 1]; - columnCount = 1; + row = researchAndAnalysisSheet.initRow(); + row.addEmptyCell(); for (int itemCount = 0; itemCount < numberOfItems; itemCount++) { - row[columnCount++] = new ExcelCell(getMessage("label.first.choice"), IndexedColors.BLUE); - row[columnCount++] = new ExcelCell(getMessage("label.attempts"), IndexedColors.BLUE); - row[columnCount++] = new ExcelCell(getMessage("label.mark"), IndexedColors.BLUE); + row.addCell(getMessage("label.first.choice"), IndexedColors.BLUE); + row.addCell(getMessage("label.attempts"), IndexedColors.BLUE); + row.addCell(getMessage("label.mark"), IndexedColors.BLUE); } - rowList.add(row); for (GroupSummary summary : summaryByTeam) { - row = new ExcelCell[(numberOfItems * 3) + 1]; - columnCount = 0; + row = researchAndAnalysisSheet.initRow(); - row[columnCount++] = new ExcelCell(summary.getSessionName(), false); + row.addCell(summary.getSessionName()); for (ScratchieItemDTO itemDto : summary.getItemDtos()) { int attempts = itemDto.getUserAttempts(); @@ -1484,152 +1461,135 @@ isFirstChoice = getMessage("label.incorrect"); color = IndexedColors.RED; } - row[columnCount++] = new ExcelCell(isFirstChoice, color); - row[columnCount++] = new ExcelCell(new Long(attempts), color); + row.addCell(isFirstChoice, color); + row.addCell(new Long(attempts), color); Long mark = (itemDto.getUserMark() == -1) ? null : new Long(itemDto.getUserMark()); - row[columnCount++] = new ExcelCell(mark, false); + row.addCell(mark); } - rowList.add(row); } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); // Overall Summary By Individual Student in each Team---------------------------------------- - row = new ExcelCell[2]; - row[0] = new ExcelCell(getMessage("label.overall.summary.by.individual.student"), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.overall.summary.by.individual.student"), true); + researchAndAnalysisSheet.addEmptyRow(); - row = new ExcelCell[4]; - row[1] = new ExcelCell(getMessage("label.attempts"), false); - row[2] = new ExcelCell(getMessage("label.mark"), false); - row[3] = new ExcelCell(getMessage("label.group"), false); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addEmptyCell(); + row.addCell(getMessage("label.attempts")); + row.addCell(getMessage("label.mark")); + row.addCell(getMessage("label.group")); List summaryList = getMonitoringSummary(contentId, false); for (GroupSummary summary : summaryList) { for (ScratchieUser user : summary.getUsers()) { - row = new ExcelCell[4]; - row[0] = new ExcelCell(user.getFirstName() + " " + user.getLastName(), false); - row[1] = new ExcelCell(new Long(summary.getTotalAttempts()), false); + row = researchAndAnalysisSheet.initRow(); + row.addCell(user.getFirstName() + " " + user.getLastName()); + row.addCell(new Long(summary.getTotalAttempts())); Long mark = (summary.getTotalAttempts() == 0) ? null : new Long(summary.getMark()); - row[2] = new ExcelCell(mark, false); - row[3] = new ExcelCell(summary.getSessionName(), false); - rowList.add(row); + row.addCell(mark); + row.addCell(summary.getSessionName()); } } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); // Question Reports----------------------------------------------------------------- - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.question.reports"), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.question.reports"), true); + researchAndAnalysisSheet.addEmptyRow(); SimpleDateFormat fullDateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); for (ScratchieItem item : items) { List itemSummary = getQuestionSummary(contentId, item.getUid()); boolean isMcqItem = item.getQbQuestion().getType() == QbQuestion.TYPE_MULTIPLE_CHOICE; - row = new ExcelCell[1]; - row[0] = new ExcelCell( - getMessage("label.question.semicolon", new Object[] { item.getQbQuestion().getName() }), true); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.question.semicolon", new Object[] { item.getQbQuestion().getName() }), true); - row = new ExcelCell[1]; - row[0] = new ExcelCell(removeHtmlMarkup(item.getQbQuestion().getDescription()), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - + row = researchAndAnalysisSheet.initRow(); + row.addCell(removeHtmlMarkup(item.getQbQuestion().getDescription()), true); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); // show all team summary in case there is more than 1 group if (summaryList.size() > 1 && isMcqItem) { - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.all.teams.summary"), true); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.all.teams.summary"), true); GroupSummary allTeamSummary = itemSummary.get(0); Collection optionDtos = allTeamSummary.getOptionDtos(); - row = new ExcelCell[1 + optionDtos.size()]; + row = researchAndAnalysisSheet.initRow(); + row.addEmptyCell(); for (int i = 0; i < optionDtos.size(); i++) { - row[i + 1] = new ExcelCell((long) i + 1, IndexedColors.YELLOW); + row.addCell((long) i + 1, IndexedColors.YELLOW); } - rowList.add(row); for (OptionDTO optionDto : optionDtos) { - row = new ExcelCell[1 + optionDtos.size()]; - String answer; + row = researchAndAnalysisSheet.initRow(); + String answerTitle = removeHtmlMarkup(optionDto.getAnswer()); + IndexedColors color = null; - answer = removeHtmlMarkup(optionDto.getAnswer()); if (optionDto.isCorrect()) { - answer += "(" + getMessage("label.monitoring.item.summary.correct") + ")"; + answerTitle += "(" + getMessage("label.monitoring.item.summary.correct") + ")"; color = IndexedColors.GREEN; } + row.addCell(answerTitle, color); - columnCount = 0; - row[columnCount++] = new ExcelCell(answer, color); - for (int numberAttempts : optionDto.getAttempts()) { - row[columnCount++] = new ExcelCell(new Long(numberAttempts), false); + row.addCell(new Long(numberAttempts)); } - rowList.add(row); } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); } - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.breakdown.by.team"), true); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.breakdown.by.team"), true); + for (GroupSummary groupSummary : itemSummary) { if (groupSummary.getSessionId().equals(0L)) { continue; } Collection optionDtos = groupSummary.getOptionDtos(); - row = new ExcelCell[1]; - row[0] = new ExcelCell(groupSummary.getSessionName(), true); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(groupSummary.getSessionName(), true); - row = new ExcelCell[1 + optionDtos.size()]; + row = researchAndAnalysisSheet.initRow(); + row.addEmptyCell(); for (int i = 0; i < optionDtos.size(); i++) { - row[i + 1] = new ExcelCell(new Long(i + 1), false); + row.addCell(new Long(i + 1)); } - rowList.add(row); for (OptionDTO optionDto : optionDtos) { - int rowLength = isMcqItem ? 1 + optionDtos.size() : 1 + optionDto.getAttempts().length; - row = new ExcelCell[rowLength]; + + row = researchAndAnalysisSheet.initRow(); String optionTitle = removeHtmlMarkup(optionDto.getAnswer()); if (optionDto.isCorrect()) { optionTitle += "(" + getMessage("label.monitoring.item.summary.correct") + ")"; } + row.addCell(optionTitle); - columnCount = 0; - row[columnCount++] = new ExcelCell(optionTitle, false); - for (int numberAttempts : optionDto.getAttempts()) { - row[columnCount++] = new ExcelCell(new Long(numberAttempts), false); + row.addCell(new Long(numberAttempts)); } - rowList.add(row); } } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + researchAndAnalysisSheet.addEmptyRow(); + researchAndAnalysisSheet.addEmptyRow(); } // Breakdown By Student with Timing---------------------------------------------------- - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.breakdown.by.student.with.timing"), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.breakdown.by.student.with.timing"), true); + researchAndAnalysisSheet.addEmptyRow(); List sessionList = scratchieSessionDao.getByContentId(scratchie.getContentId()); for (ScratchieSession session : sessionList) { @@ -1639,54 +1599,44 @@ if (groupLeader != null) { - row = new ExcelCell[5]; - row[0] = new ExcelCell(groupLeader.getFirstName() + " " + groupLeader.getLastName(), true); - row[1] = new ExcelCell(getMessage("label.attempts") + ":", false); + row = researchAndAnalysisSheet.initRow(); + row.addCell(groupLeader.getFirstName() + " " + groupLeader.getLastName(), true); + row.addCell(getMessage("label.attempts") + ":"); Long attempts = (long) scratchieAnswerVisitDao.getLogCountTotal(sessionId); - row[2] = new ExcelCell(attempts, false); - row[3] = new ExcelCell(getMessage("label.mark") + ":", false); - row[4] = new ExcelCell(new Long(session.getMark()), false); - rowList.add(row); + row.addCell(attempts); + row.addCell(getMessage("label.mark") + ":"); + row.addCell(new Long(session.getMark())); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.team.leader") + session.getSessionName(), false); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.team.leader") + session.getSessionName()); for (ScratchieItem item : items) { - boolean isMcqItem = item.getQbQuestion().getType() == QbQuestion.TYPE_MULTIPLE_CHOICE; - row = new ExcelCell[1]; - row[0] = new ExcelCell( - getMessage("label.question.semicolon", new Object[] { item.getQbQuestion().getName() }), + row = researchAndAnalysisSheet.initRow(); + row.addCell(getMessage("label.question.semicolon", new Object[] { item.getQbQuestion().getName() }), false); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); int i = 1; List logs = scratchieAnswerVisitDao.getLogsBySessionAndItem(sessionId, item.getUid()); for (ScratchieAnswerVisitLog log : logs) { - row = new ExcelCell[4]; - row[0] = new ExcelCell(new Long(i++), false); - String optionDescr = isMcqItem ? removeHtmlMarkup(log.getQbOption().getName()) - : log.getAnswer(); - row[1] = new ExcelCell(optionDescr, false); - row[3] = new ExcelCell(fullDateFormat.format(log.getAccessDate()), false); - rowList.add(row); + row = researchAndAnalysisSheet.initRow(); + row.addCell(new Long(i++)); + String answerDescr = removeHtmlMarkup(log.getQbOption().getName()); + row.addCell(answerDescr); + row.addCell(fullDateFormat.format(log.getAccessDate())); + } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + researchAndAnalysisSheet.addEmptyRow(); } } } - ExcelCell[][] thirdPageData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("label.research.analysis"), thirdPageData); - // ======================================================= For_XLS_export(SPSS analysis) page // ======================================= + ExcelSheet spssAnalysisSheet = new ExcelSheet(getMessage("label.spss.analysis")); + sheets.add(spssAnalysisSheet); - rowList = new LinkedList<>(); - // Table header------------------------------------ int maxOptions = 0; @@ -1696,25 +1646,24 @@ } } - row = new ExcelCell[10 + (maxOptions * 2)]; - columnCount = 0; - row[columnCount++] = new ExcelCell(getMessage("label.student.name"), true); - row[columnCount++] = new ExcelCell(getMessage("label.student.username"), true); - row[columnCount++] = new ExcelCell(getMessage("label.team"), true); - row[columnCount++] = new ExcelCell(getMessage("label.question.number"), true); - row[columnCount++] = new ExcelCell(getMessage("label.question"), true); - row[columnCount++] = new ExcelCell(getMessage("label.correct.answer"), true); - row[columnCount++] = new ExcelCell(getMessage("label.first.choice.accuracy"), true); - row[columnCount++] = new ExcelCell(getMessage("label.number.of.attempts"), true); - row[columnCount++] = new ExcelCell(getMessage("label.mark.awarded"), true); + row = spssAnalysisSheet.initRow(); + row.addCell(getMessage("label.student.name"), true); + row.addCell(getMessage("label.student.username"), true); + row.addCell(getMessage("label.team"), true); + row.addCell(getMessage("label.question.number"), true); + row.addCell(getMessage("label.question"), true); + row.addCell(getMessage("label.correct.answer"), true); + row.addCell(getMessage("label.first.choice.accuracy"), true); + row.addCell(getMessage("label.number.of.attempts"), true); + row.addCell(getMessage("label.mark.awarded"), true); + for (int i = 0; i < maxOptions; i++) { - row[columnCount++] = new ExcelCell(getMessage("label." + (i + 1) + ".answer.selected"), true); + row.addCell(getMessage("label." + (i + 1) + ".answer.selected"), true); } - row[columnCount++] = new ExcelCell(getMessage("label.date"), true); + row.addCell(getMessage("label.date"), true); for (int i = 0; i < maxOptions; i++) { - row[columnCount++] = new ExcelCell(getMessage("label.time.of.selection." + (i + 1)), true); + row.addCell(getMessage("label.time.of.selection." + (i + 1)), true); } - rowList.add(row); // Table content------------------------------------ @@ -1723,22 +1672,20 @@ List users = scratchieUserDao.getBySessionID(sessionId); for (ScratchieUser user : users) { - int questionCount = 1; for (ScratchieItemDTO itemDto : summary.getItemDtos()) { - row = new ExcelCell[10 + (maxOptions * 2)]; - columnCount = 0; + row = spssAnalysisSheet.initRow(); // learner name - row[columnCount++] = new ExcelCell(user.getFirstName() + " " + user.getLastName(), false); + row.addCell(user.getFirstName() + " " + user.getLastName()); // username - row[columnCount++] = new ExcelCell(user.getLoginName(), false); + row.addCell(user.getLoginName()); // group name - row[columnCount++] = new ExcelCell(summary.getSessionName(), false); + row.addCell(summary.getSessionName()); // question number - row[columnCount++] = new ExcelCell(new Long(questionCount++), false); + row.addCell(new Long(questionCount++)); // question title - row[columnCount++] = new ExcelCell(itemDto.getTitle(), false); + row.addCell(itemDto.getTitle()); // correct option String correctOption = ""; @@ -1749,7 +1696,7 @@ correctOption = removeHtmlMarkup(correctOption); } } - row[columnCount++] = new ExcelCell(correctOption, false); + row.addCell(correctOption); // isFirstChoice int attempts = itemDto.getUserAttempts(); @@ -1761,12 +1708,12 @@ } else { isFirstChoice = getMessage("label.incorrect"); } - row[columnCount++] = new ExcelCell(isFirstChoice, false); + row.addCell(isFirstChoice); // attempts - row[columnCount++] = new ExcelCell(new Long(attempts), false); + row.addCell(new Long(attempts)); // mark Object mark = (itemDto.getUserMark() == -1) ? "" : new Long(itemDto.getUserMark()); - row[columnCount++] = new ExcelCell(mark, false); + row.addCell(mark); // options selected List logs = scratchieAnswerVisitDao.getLogsBySessionAndItem(sessionId, @@ -1776,15 +1723,14 @@ } for (ScratchieAnswerVisitLog log : logs) { - String optionText = removeHtmlMarkup( - log.getQbOption() == null ? log.getAnswer() : log.getQbOption().getName()); - row[columnCount++] = new ExcelCell(optionText, false); + String answer = removeHtmlMarkup(log.getQbOption().getName()); + row.addCell(answer); } for (int i = logs.size(); i < itemDto.getOptionDtos().size(); i++) { - row[columnCount++] = new ExcelCell(getMessage("label.none"), false); + row.addCell(getMessage("label.none")); } for (int i = options.size(); i < maxOptions; i++) { - row[columnCount++] = new ExcelCell("", false); + row.addCell(""); } // Date @@ -1794,70 +1740,57 @@ Date accessDate = logs.iterator().next().getAccessDate(); dateStr = dateFormat.format(accessDate); } - row[columnCount++] = new ExcelCell(dateStr, false); + row.addCell(dateStr); // time of selection SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); for (ScratchieAnswerVisitLog log : logs) { Date accessDate = log.getAccessDate(); String timeStr = timeFormat.format(accessDate); - row[columnCount++] = new ExcelCell(timeStr, false); + row.addCell(timeStr); } for (int i = logs.size(); i < maxOptions; i++) { - row[columnCount++] = new ExcelCell("", false); + row.addCell(""); } - - rowList.add(row); } - } - } - ExcelCell[][] fourthPageData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("label.spss.analysis"), fourthPageData); - // ======================================================= Burning questions page // ======================================= - if (scratchie.isBurningQuestionsEnabled()) { - rowList = new LinkedList<>(); + ExcelSheet burningQuestionsSheet = new ExcelSheet(getMessage("label.burning.questions")); + sheets.add(burningQuestionsSheet); - row = new ExcelCell[1]; - row[0] = new ExcelCell(getMessage("label.burning.questions"), true); - rowList.add(row); - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + row = burningQuestionsSheet.initRow(); + row.addCell(getMessage("label.burning.questions"), true); + burningQuestionsSheet.addEmptyRow(); - row = new ExcelCell[3]; - row[0] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), IndexedColors.BLUE); - row[1] = new ExcelCell(getMessage("label.burning.questions"), IndexedColors.BLUE); - row[2] = new ExcelCell(getMessage("label.count"), IndexedColors.BLUE); - rowList.add(row); + row = burningQuestionsSheet.initRow(); + row.addCell(getMessage("label.monitoring.summary.user.name"), IndexedColors.BLUE); + row.addCell(getMessage("label.burning.questions"), IndexedColors.BLUE); + row.addCell(getMessage("label.count"), IndexedColors.BLUE); List burningQuestionItemDtos = getBurningQuestionDtos(scratchie, null, true); for (BurningQuestionItemDTO burningQuestionItemDto : burningQuestionItemDtos) { ScratchieItem item = burningQuestionItemDto.getScratchieItem(); - row = new ExcelCell[1]; - row[0] = new ExcelCell(item.getQbQuestion().getName(), false); - rowList.add(row); + row = burningQuestionsSheet.initRow(); + row.addCell(item.getQbQuestion().getName()); + List burningQuestionDtos = burningQuestionItemDto.getBurningQuestionDtos(); for (BurningQuestionDTO burningQuestionDto : burningQuestionDtos) { String burningQuestion = burningQuestionDto.getBurningQuestion().getQuestion(); - row = new ExcelCell[3]; - row[0] = new ExcelCell(burningQuestionDto.getSessionName(), false); - row[1] = new ExcelCell(burningQuestion, false); - row[2] = new ExcelCell(burningQuestionDto.getLikeCount(), false); - rowList.add(row); + row = burningQuestionsSheet.initRow(); + row.addCell(burningQuestionDto.getSessionName()); + row.addCell(burningQuestion); + row.addCell(burningQuestionDto.getLikeCount()); } - rowList.add(ScratchieServiceImpl.EMPTY_ROW); + burningQuestionsSheet.addEmptyRow(); } - - ExcelCell[][] fifthPageData = rowList.toArray(new ExcelCell[][] {}); - dataToExport.put(getMessage("label.burning.questions"), fifthPageData); } - return dataToExport; + return sheets; } @Override Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java =================================================================== diff -u -r818e9c1b6da3d19d8f388645146a8090b704a23d -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java (.../AuthoringController.java) (revision 818e9c1b6da3d19d8f388645146a8090b704a23d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java (.../AuthoringController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import java.net.URLEncoder; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; @@ -42,6 +43,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.learningdesign.ToolActivity; @@ -186,6 +188,14 @@ Set activitiesProvidingVsaAnswers = scratchieService.getActivitiesProvidingVsaAnswers(contentId); sessionMap.put(ScratchieConstants.ATTR_ACTIVITIES_PROVIDING_VSA_ANSWERS, activitiesProvidingVsaAnswers); + String notifyCloseURL = request.getParameter("notifyCloseURL"); + if (StringUtils.isNotBlank(notifyCloseURL)) { + try { + request.setAttribute("notifyCloseURL", URLEncoder.encode(notifyCloseURL, "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new ServletException("Exception while encoding notifyCloseURL: " + notifyCloseURL, e); + } + } sessionMap.put(AttributeNames.ATTR_MODE, mode); sessionMap.put(ScratchieConstants.ATTR_RESOURCE_FORM, authoringForm); return "pages/authoring/start"; Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java =================================================================== diff -u -r269c13324c6bb998631af858dc8091ad3102ef78 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 269c13324c6bb998631af858dc8091ad3102ef78) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -57,17 +57,20 @@ import org.lamsfoundation.lams.tool.scratchie.util.ScratchieItemComparator; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.DateUtil; -import org.lamsfoundation.lams.util.ExcelCell; -import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.util.excel.ExcelSheet; +import org.lamsfoundation.lams.util.excel.ExcelUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -220,14 +223,15 @@ * @throws IOException */ @RequestMapping("/exportExcel") - private String exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { + @ResponseStatus(HttpStatus.OK) + private void exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { String sessionMapID = request.getParameter(ScratchieConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); Scratchie scratchie = (Scratchie) sessionMap.get(ScratchieConstants.ATTR_SCRATCHIE); - LinkedHashMap dataToExport = scratchieService.exportExcel(scratchie.getContentId()); + List sheets = scratchieService.exportExcel(scratchie.getContentId()); String fileName = "scratchie_export.xlsx"; fileName = FileUtil.encodeFilenameForDownload(request, fileName); @@ -243,9 +247,7 @@ // Code to generate file and write file contents to response ServletOutputStream out = response.getOutputStream(); - ExcelUtil.createExcel(out, dataToExport, null, false); - - return null; + ExcelUtil.createExcel(out, sheets, null, false); } /** Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java =================================================================== diff -u -r269c13324c6bb998631af858dc8091ad3102ef78 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java (.../TblMonitorController.java) (revision 269c13324c6bb998631af858dc8091ad3102ef78) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java (.../TblMonitorController.java) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -28,7 +28,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -41,7 +40,6 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.log4j.Logger; -import org.lamsfoundation.lams.qb.model.QbOption; import org.lamsfoundation.lams.tool.scratchie.ScratchieConstants; import org.lamsfoundation.lams.tool.scratchie.dto.BurningQuestionDTO; import org.lamsfoundation.lams.tool.scratchie.dto.BurningQuestionItemDTO; @@ -54,15 +52,18 @@ import org.lamsfoundation.lams.tool.scratchie.service.IScratchieService; import org.lamsfoundation.lams.tool.scratchie.util.ScratchieItemComparator; import org.lamsfoundation.lams.util.AlphanumComparator; -import org.lamsfoundation.lams.util.ExcelCell; -import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.excel.ExcelRow; +import org.lamsfoundation.lams.util.excel.ExcelSheet; +import org.lamsfoundation.lams.util.excel.ExcelUtil; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -76,11 +77,10 @@ private IScratchieService scratchieService; /** - * Shows tra page + * Shows TRA page */ @RequestMapping("/tra") public String tra(HttpServletRequest request) throws IOException, ServletException { - long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Scratchie scratchie = scratchieService.getScratchieByContentId(toolContentId); @@ -92,22 +92,18 @@ request.setAttribute("items", items); if (attemptedLearnersNumber != 0) { - // find first page in excel file - LinkedHashMap excelDoc = scratchieService.exportExcel(toolContentId); - ExcelCell[][] firstPageData = null; - for (String key : excelDoc.keySet()) { - firstPageData = excelDoc.get(key); - break; - } + // find the first page in excel file + List sheets = scratchieService.exportExcel(toolContentId); + ExcelSheet firstPageData = sheets.get(0); int groupsSize = scratchieService.countSessionsByContentId(toolContentId); ArrayList groupRows = new ArrayList<>(); for (int groupCount = 0; groupCount < groupsSize; groupCount++) { - ExcelCell[] groupRow = firstPageData[5 + groupCount]; + ExcelRow groupRow = firstPageData.getRow(5 + groupCount); String[] groupRow2 = new String[2]; - groupRow2[0] = (String) groupRow[1].getCellValue(); - groupRow2[1] = ((String) groupRow[groupRow.length - 1].getCellValue()).replaceAll("%", ""); + groupRow2[0] = (String) groupRow.getCell(1); + groupRow2[1] = String.valueOf((Double) groupRow.getCell(groupRow.getCells().size() - 1) * 100); groupRows.add(groupRow2); } request.setAttribute("groupRows", groupRows); @@ -121,7 +117,6 @@ */ @RequestMapping("/traStudentChoices") public String traStudentChoices(HttpServletRequest request) throws IOException, ServletException { - long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Scratchie scratchie = scratchieService.getScratchieByContentId(toolContentId); @@ -130,43 +125,33 @@ request.setAttribute("items", items); //find second page in excel file - LinkedHashMap excelDoc = scratchieService.exportExcel(toolContentId); - ExcelCell[][] secondPageData = null; - for (ExcelCell[][] excelPage : excelDoc.values()) { - //check last row string starts with "*" (i.e. the string "*- Denotes the correct option") - if (excelPage.length > 0) { - ExcelCell lastRow = excelPage[excelPage.length - 1][0]; - if (lastRow != null && ((String) lastRow.getCellValue()).startsWith("*")) { - secondPageData = excelPage; - break; - } - } - } + List sheets = scratchieService.exportExcel(toolContentId); + ExcelSheet secondPageData = sheets.get(1); - //correct options - ExcelCell[] correctOptionsRow = secondPageData[4]; - request.setAttribute("correctOptions", correctOptionsRow); + //correct answers + ExcelRow correctOptionsRow = secondPageData.getRow(4); + request.setAttribute("correctAnswers", correctOptionsRow); - //prepare data for displaying user option table + //prepare data for displaying user answers table int groupsSize = scratchieService.countSessionsByContentId(toolContentId); ArrayList sessionDtos = new ArrayList<>(); for (int groupCount = 0; groupCount < groupsSize; groupCount++) { - ExcelCell[] groupRow = secondPageData[6 + groupCount]; + ExcelRow groupRow = secondPageData.getRows().get(6 + groupCount); GroupSummary groupSummary = new GroupSummary(); - String sessionName = groupRow[0].getCellValue().toString(); + String sessionName = groupRow.getCell(0).toString(); groupSummary.setSessionName(sessionName); Collection itemDtos = new ArrayList<>(); for (int i = 1; i <= items.size(); i++) { ScratchieItemDTO itemDto = new ScratchieItemDTO(); - String optionsSequence = groupRow[i].getCellValue().toString(); - String[] optionLetters = optionsSequence.split(", "); + String optionSequence = groupRow.getCell(i).toString(); + String[] optionLetters = optionSequence.split(", "); List optionDtos = new LinkedList<>(); for (int j = 0; j < optionLetters.length; j++) { String optionLetter = optionLetters[j]; - String correctOptionLetter = correctOptionsRow[i].getCellValue().toString(); + String correctOptionLetter = correctOptionsRow.getCell(i).toString(); OptionDTO optionDto = new OptionDTO(); optionDto.setAnswer(optionLetter); @@ -180,10 +165,10 @@ groupSummary.setItemDtos(itemDtos); if (!itemDtos.isEmpty()) { - int total = (Integer) groupRow[itemDtos.size() + 1].getCellValue(); + int total = (Integer) groupRow.getCell(itemDtos.size() + 1); groupSummary.setMark(total); - String totalPercentage = groupRow[itemDtos.size() + 2].getCellValue().toString(); + String totalPercentage = groupRow.getCell(itemDtos.size() + 2).toString(); groupSummary.setTotalPercentage(totalPercentage); } @@ -203,10 +188,11 @@ * @throws IOException */ @RequestMapping("/exportExcel") - public String exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { + @ResponseStatus(HttpStatus.OK) + public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { Long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); - LinkedHashMap dataToExport = scratchieService.exportExcel(toolContentId); + List sheets = scratchieService.exportExcel(toolContentId); String fileName = "scratchie_export.xlsx"; fileName = FileUtil.encodeFilenameForDownload(request, fileName); @@ -216,9 +202,7 @@ // Code to generate file and write file contents to response ServletOutputStream out = response.getOutputStream(); - ExcelUtil.createExcel(out, dataToExport, null, false); - - return null; + ExcelUtil.createExcel(out, sheets, null, false); } /** Index: lams_tool_scratchie/web/pages/authoring/start.jsp =================================================================== diff -u -r06d090eefddaafa108bcd8614d47d3d92f946210 -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/web/pages/authoring/start.jsp (.../start.jsp) (revision 06d090eefddaafa108bcd8614d47d3d92f946210) +++ lams_tool_scratchie/web/pages/authoring/start.jsp (.../start.jsp) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -4,7 +4,7 @@ - + Index: lams_tool_scratchie/web/pages/tblmonitoring/traStudentChoices.jsp =================================================================== diff -u -r3126fb6636e4164bdc6e539eab16ed2a7618fe7e -ra9f95a26e562a58b55c99f2c18e253c151ef457a --- lams_tool_scratchie/web/pages/tblmonitoring/traStudentChoices.jsp (.../traStudentChoices.jsp) (revision 3126fb6636e4164bdc6e539eab16ed2a7618fe7e) +++ lams_tool_scratchie/web/pages/tblmonitoring/traStudentChoices.jsp (.../traStudentChoices.jsp) (revision a9f95a26e562a58b55c99f2c18e253c151ef457a) @@ -105,11 +105,15 @@ - - + + + + + +
- ${correctOptions[i].cellValue} - + ${correctAnswerCell.cellValue} +