Index: lams_tool_imscc/.classpath =================================================================== diff -u --- lams_tool_imscc/.classpath (revision 0) +++ lams_tool_imscc/.classpath (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/.cvsignore =================================================================== diff -u --- lams_tool_imscc/.cvsignore (revision 0) +++ lams_tool_imscc/.cvsignore (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,3 @@ +.myeclipse +.mymetadata +build Index: lams_tool_imscc/conf/hibernate/mappings/.cvsignore =================================================================== diff -u --- lams_tool_imscc/conf/hibernate/mappings/.cvsignore (revision 0) +++ lams_tool_imscc/conf/hibernate/mappings/.cvsignore (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ +org Index: lams_tool_imscc/conf/hibernate/mappings/hibernate.cfg.xml =================================================================== diff -u --- lams_tool_imscc/conf/hibernate/mappings/hibernate.cfg.xml (revision 0) +++ lams_tool_imscc/conf/hibernate/mappings/hibernate.cfg.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,13 @@ + + + + + lams + lamsdemo + jdbc:mysql://localhost/lams + com.mysql.jdbc.Driver + org.hibernate.dialect.MySQLDialect + + + Index: lams_tool_imscc/conf/jar/META-INF/MANIFEST.MF =================================================================== diff -u --- lams_tool_imscc/conf/jar/META-INF/MANIFEST.MF (revision 0) +++ lams_tool_imscc/conf/jar/META-INF/MANIFEST.MF (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,3 @@ +Implementation-Title: LAMS - CommonCartridge Tool +Implementation-Version: 2.1 +Implementation-Vendor: LAMS Foundation (http://lamsfoundation.org) Index: lams_tool_imscc/conf/language/lams/ApplicationResources.properties =================================================================== diff -u --- lams_tool_imscc/conf/language/lams/ApplicationResources.properties (revision 0) +++ lams_tool_imscc/conf/language/lams/ApplicationResources.properties (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,203 @@ +appName = commoncartridge +#language code: en +#locale code: AU + + # CVS ID: $Id$ Exported from the LAMS Community by Ernie Ghiglione on Wed Mar 03 00:17:40 CST 2010 + +#=================== labels for ShareResources =================# + +label.authoring.basic.resource.common.cartridge =Common Cartridge +label.authoring.basic.add.common.cartridge =Add Common Cartridge +label.authoring.basic.add.basiclti.tool =Add Basic LTI Tool + +admin.button.save =Save +admin.expose.user.name =Expose User Name to Basic LTI Tool +admin.expose.user.email =Expose User Email to Basic LTI Tool +admin.page.title =BasicLTI Settings +admin.return =Return to maintain LAMS +admin.success =Configuration successfully saved. + +label.authoring.basic.bascilti.url =Remote Tool Url +label.authoring.basic.bascilti.key =Remote Tool Key +label.authoring.basic.bascilti.secret =Remote Tool Secret +label.authoring.basic.bascilti.button.text =Button Text +label.authoring.basic.bascilti.iframe.height =Frame Height +label.authoring.basic.bascilti.custom.parameters =Custom Parameters (*each starts new line) + +export.label.no.basic.lti =No offline basic LTI tools available + +activity.description =Sharing resources with others. +activity.helptext =Uploading your resources to share with others. +activity.title =Common Cartridge +appName =Common Cartridge +authoring.exception =There is a problem in shared resources authoring page, the reason is {0} +authoring.msg.cancel.save =Do you want to close this window without saving? +button.add =Add +button.cancel =Cancel +button.close =Close +button.edit =Edit +button.try.again =Try again +button.upload =Upload +define.later.message =Please wait for the teacher to complete the contents of this activity. +error.attachment.executable =The uploaded file is executable, please zip it before uploading. +error.inputFileTooLarge =Input File size is too large! +error.msg.default.content.not.find =Could not retrieve default content record for this tool. +error.msg.file.not.found =File not found exception occurs when uploading file. +error.msg.ims.application =ImscpApplicationException occurs when uploading resource item file. +error.msg.ims.package =Invalid IMS CP format. +error.msg.invaid.param.upload =InvalidParameterException occured while trying to upload File. +error.msg.io.exception =IOException occurs when uploading file. +error.msg.repository =A repository error occurred while trying to upload the file. +error.msg.upload.file.not.found =Could not find upload file {0}. +error.msg.website.no.initial.file =Website zip can not find out initial file (index.htm/html or default.htm/html). +error.msg.zip.file.exception =Could not handle zip file when uploading file. +errorPage.heading =Some error occurs when handling your request +errorPage.title =Error page +error.planner.file.blank =In resource {0} file can not be blank. +error.planner.no.resource.save =There has to be at least one resource to save. +error.planner.url.blank =In resource {0} URL can not be blank. +error.reflection.emtpy =Please input Notebook Entry +error.resource.item.desc.blank =Comment/Instruction can not be blank +error.resource.item.file.blank =File can not be blank. +error.resource.item.invalid.url =Invalid URL format. +error.resource.item.title.blank =Title can not be blank. +error.resource.item.url.blank =URL can not be blank. +errors.footer = +errors.header = +errors.maxfilesize =The uploaded file has exceeded the maximum file size limit of {0} bytes +error.title.empty =Title can not be blank +error.upload.failed =Upload file failed: {0} +error.uploading =error uploading +error.valueReqd =Value Required +event.assigment.submit.body =The learner {0} submitted an assigment in a Common Cartridge tool.\n\nThis message was sent automatically, following the tool''s advanced settings. +event.assigment.submit.subject =LAMS: A learner submitted an assigment in a Common Cartridge tool +export.init.resource =Initial Resources +export.label.no.learning.object =No offline package available +export.label.resource =Resource +export.title =Export portfolio of Common Cartridge +label.authoring.advance.allow.learner.add.files =Allow learners to add Files +label.authoring.advance.allow.learner.add.urls =Allow learners to add URLs +label.authoring.advanced.notify.onassigmentsubmit =Notify monitoring teachers when a learner submits a resource +label.authoring.advanced.reflectOnActivity =Add Notebook at end of Common Cartridge with the following instructions: +label.authoring.advance.lock.on.finished =Lock when finished +label.authoring.advance.mini.number.resources.view =Minimum number of resources to view +label.authoring.advance.run.content.auto =Run content automatically (only available if there is exactly one resource) +label.authoring.basic.add.file =Add Common Cartridge +label.authoring.basic.add.learning.object =Add IMS Content Package +label.authoring.basic.add.url =Add Basic LTI +label.authoring.basic.add.website =Add Zipped Website +label.authoring.basic.instruction =Instruction +label.authoring.basic.resource.add.instruction =Add Instruction +label.authoring.basic.resource.delete =Delete +label.authoring.basic.resource.description.input =Description +label.authoring.basic.resource.edit =Edit +label.authoring.basic.resource.file =File +label.authoring.basic.resource.file.input =File +label.authoring.basic.resource.instructions =Instructions +label.authoring.basic.resource.learning.object =IMS CP +label.authoring.basic.resource.list.title =Resource List +label.authoring.basic.resource.preview =Preview +label.authoring.basic.resource.title.input =Title +label.authoring.basic.resource.url =Basic LTI +label.authoring.basic.resource.url.input =URL +label.authoring.basic.resource.verify.url =View +label.authoring.basic.resource.website =Website +label.authoring.basic.resource.zip.file.input =Zip file: +label.authoring.basic.title =Title +label.authoring.cancel.button =Cancel +label.authoring.choosefile.button =Choose file +label.authoring.heading =Common Cartridge +label.authoring.heading.advance =Advanced +label.authoring.heading.advance.desc =Please input advance options for common cartridge +label.authoring.heading.basic =Basic +label.authoring.heading.basic.desc =Basic input information for common cartridge +label.authoring.heading.instructions =Instructions +label.authoring.heading.instructions.desc =Please input online and offline instructions +label.authoring.offline.delete =Delete +label.authoring.offline.file =Upload offline file +label.authoring.offline.filelist =Offline file list +label.authoring.offline.instruction =Offline Instructions +label.authoring.online.delete =Delete +label.authoring.online.file =Upload online file +label.authoring.online.filelist =Online file list +label.authoring.online.instruction =Online Instructions +label.authoring.save.button =Save +label.authoring.upload.offline.button =Upload Offline +label.authoring.upload.online.button =Upload Online +label.author.title =Common Cartridge Authoring +label.cancel =Cancel +label.check.for.new =Check for new +label.completed =Completed +label.continue =Continue +label.delete =Delete +label.description =Description: +label.down =Move down +label.download =Download +label.edit =Edit +label.export.reflection =Notebook Entries +label.finish =Finished +label.finished =Next Activity +label.hide =Hide +label.learning.comment.or.instruction =Comment/Instruction +label.learning.heading =Common Cartridge +label.learning.minimum.review =You must view at least {0} of the resources. +label.learning.new.file =New file details: +label.learning.new.url =New URL details: +label.learning.title =Common Cartridge Learning +label.monitoring.edit.activity.cancel =Cancel +label.monitoring.edit.activity.edit =Edit +label.monitoring.edit.activity.update =Update +label.monitoring.heading.access =Learners list +label.next.instruction =Next Instruction +label.off =Off +label.on =On +label.open =Open +label.resoruce.to.review =Resources to view +label.save =Save +label.show =Show +label.suggest.new =Suggest a new +label.up =Move Up +label.view =View +lable.learning.minimum.view.number.less =You must view at least another {0} of the resources. +message.activityLocked =The instructor has set this activity not to allow you to view or share any more resources after you have finished it. +message.alertContentEdit =Warning: One of more learners have accessed this activity. Changing this content will result in learners getting different information. +message.monitoring.edit.activity.not.editable =This Activity is no longer editable +message.monitoring.summary.no.resource.for.group =No resource available for this group. +message.monitoring.summary.no.session =No Session Available +message.msg.maxFileSize =Max 250K +message.no.reflection.available =No notebook available +message.step.of =Step {0} of {1} +message.warnLockOnFinish =Note: After you click on "Next Activity\u201d, if you come back to this Common Cartridge, you won\u2019t be able to share new resources. +monitoring.label.access.time =Access time +monitoring.label.attachments =Attachments +monitoring.label.group =Group +monitoring.label.hidden =Hidden +monitoring.label.hide =Hide +monitoring.label.instructions =Instructions +monitoring.label.number.learners =Number of Learners +monitoring.label.show =Show +monitoring.label.suggest =Suggested By +monitoring.label.title =Title +monitoring.label.type =Type +monitoring.label.user.loginname =Login name +monitoring.label.user.name =Name +monitoring.summary.note =Note: number of learners is the number of learners who have viewed the resource. +monitoring.tab.edit.activity =Edit Activity +monitoring.tab.instructions =Instruction +monitoring.tab.statistics =Statistic +monitoring.tab.summary =Summary +monitoring.user.fullname =Name +monitoring.user.reflection =Notebook Entry +monitor.summary.td.addNotebook =Add Notebook at end of Common Cartridge +monitor.summary.td.notebookInstructions =Notebook instructions +monitor.summary.th.advancedSettings =Advanced Settings +msg.no.instruction =No instruction available. +open.in.new.window =Open URL in pop-up +page.title.monitoring.view.reflection =View Notebook Entries +run.offline.message =This activity is not being done on the computer. Please see your instructor for details. +title.reflection =Notebook Entry +tool.description =Tool for sharing resources. +tool.display.name =Common Cartridge Tool + + +#======= End labels: Exported 172 labels for en AU ===== Index: lams_tool_imscc/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u --- lams_tool_imscc/conf/language/lams/ApplicationResources_en_AU.properties (revision 0) +++ lams_tool_imscc/conf/language/lams/ApplicationResources_en_AU.properties (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,11 @@ +appName = shareresources +#language code: en +#locale code: AU + + # CVS ID: $Id$ Exported from the LAMS Community by Ernie Ghiglione on Wed Mar 03 00:17:40 CST 2010 + +#=================== labels for ShareResources =================# + + + +#======= End labels: Exported 172 labels for en AU ===== Index: lams_tool_imscc/conf/language/rams/ApplicationResources.properties =================================================================== diff -u --- lams_tool_imscc/conf/language/rams/ApplicationResources.properties (revision 0) +++ lams_tool_imscc/conf/language/rams/ApplicationResources.properties (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,171 @@ +appName = shareresources +#language code: en +#locale code: AU + + # CVS ID: $Id$ Exported from the RAMS Community by Ernie Ghiglione on Tue Aug 12 12:00:29 EST 2008 + +#=================== labels for ShareResources =================# + +appName =Share Resources +activity.title =Common Cartridge +activity.description =Sharing resource with others. +activity.helptext =Uploading your resources to share with others. +tool.display.name =Share Resources Tool +tool.description =Tool for sharing resources. +errorPage.title =Error page +errorPage.heading =Some error occurs when handling your request +label.authoring.heading =Share Resources +label.author.title =Share Resources Authoring +label.authoring.heading.basic =Basic +label.authoring.heading.advance =Advanced +label.authoring.heading.instructions =Instructions +label.authoring.heading.basic.desc =Basic input information for shared resources +label.authoring.heading.instructions.desc =Please input online and offline instructions +label.authoring.heading.advance.desc =Please input advance options for shared resources +label.authoring.basic.title =Title +label.authoring.basic.instruction =Instruction +label.authoring.basic.add.url =Add URL +label.authoring.basic.add.file =Add Single File +label.authoring.basic.add.website =Add Zipped Website +label.authoring.basic.add.learning.object =Add IMS Content Package +label.authoring.basic.resource.list.title =Resource List +label.authoring.basic.resource.url =URL +label.authoring.basic.resource.file =File +label.authoring.basic.resource.website =Website +label.authoring.basic.resource.learning.object =IMS CP +label.authoring.basic.resource.verify.url =Verify URL +label.authoring.basic.resource.preview =Preview +label.authoring.basic.resource.edit =Edit +label.authoring.basic.resource.delete =Delete +label.authoring.basic.resource.add.instruction =Add Instruction +label.authoring.basic.resource.instructions =Instructions +label.authoring.basic.resource.title.input =Title +label.authoring.basic.resource.url.input =URL +label.authoring.basic.resource.file.input =File +label.authoring.basic.resource.description.input =Description +label.authoring.basic.resource.zip.file.input =Zip file: +label.authoring.online.instruction =Online Instructions +label.authoring.offline.instruction =Offline Instructions +label.authoring.online.file =Upload online file +label.authoring.offline.file =Upload offline file +label.authoring.choosefile.button =Choose file +label.authoring.upload.online.button =Upload Online +label.authoring.upload.offline.button =Upload Offline +label.authoring.online.filelist =Online file list +label.authoring.offline.filelist =Offline file list +label.authoring.online.delete =Delete +label.authoring.offline.delete =Delete +label.authoring.advance.lock.on.finished =Lock when finished +label.authoring.advance.run.content.auto =Run content automatically (only available if there is exactly one resource) +label.authoring.advance.mini.number.resources.view =Minimum number of resources to view +label.authoring.advance.allow.learner.add.urls =Allow participants to add URLs +label.authoring.advance.allow.learner.add.files =Allow participants to add Files +label.next.instruction =Next Instruction +label.authoring.save.button =Save +label.authoring.cancel.button =Cancel +label.description =Description: +authoring.exception =There is a problem in shared resources authoring page, the reason is {0} +error.resource.item.title.blank =Title can not be blank. +error.resource.item.url.blank =URL can not be blank. +error.resource.item.file.blank =File can not be blank. +error.resource.item.desc.blank =Comment/Instruction can not be blank +error.resource.item.invalid.url =Invalid URL format. +error.upload.failed =Upload file failed: {0} +error.msg.upload.file.not.found =Could not find upload file {0}. +error.msg.zip.file.exception =Could not handle zip file when uploading file. +error.msg.file.not.found =File not found exception occurs when uploading file. +error.msg.ims.package =Invalid IMS CP format. +error.msg.ims.application =ImscpApplicationException occurs when uploading resource item file. +error.msg.website.no.initial.file =Website zip can not find out initial file (index.htm/html or default.htm/html). +error.msg.io.exception =IOException occurs when uploading file. +error.msg.invaid.param.upload =InvalidParameterException occured while trying to upload File. +error.msg.repository =Repository occurs exception while trying to upload file. +error.msg.default.content.not.find =Could not retrieve default content record for this tool. +msg.no.instruction =No instruction available. +authoring.msg.cancel.save =Do you want to close this window without saving? +label.learning.title =Share Resource +label.learning.heading =Share Resources +label.resoruce.to.review =Resources to view +label.learning.minimum.review =You must view at least {0} of the resources. +lable.learning.minimum.view.number.less =You at least view another {0} of the resources. +label.check.for.new =Check for new +label.suggest.new =Suggest a new +label.learning.new.file =New file details: +label.learning.new.url =New URL details: +label.learning.comment.or.instruction =Comment/Instruction +monitoring.tab.summary =Summary +monitoring.tab.statistics =Statistic +monitoring.tab.instructions =Instruction +monitoring.tab.edit.activity =Edit Activity +monitoring.label.group =Group +monitoring.summary.note =Note: number of participants is the number of participants who have viewed the resource. +monitoring.label.type =Type +monitoring.label.title =Title +monitoring.label.suggest =Suggested By +monitoring.label.number.learners =Number of Participants +monitoring.label.hide =Hide +monitoring.label.show =Show +monitoring.label.user.loginname =Login name +monitoring.label.user.name =Name +monitoring.label.hidden =Hidden +label.monitoring.edit.activity.cancel =Cancel +label.monitoring.edit.activity.update =Update +label.monitoring.edit.activity.edit =Edit +message.monitoring.edit.activity.not.editable =This Activity is no longer editable +export.label.resource =Resource +export.label.no.learning.object =No offline package available +export.title =Export portfolio of Share Resource +export.init.resource =Initial Resources +errors.header = +errors.footer = +error.valueReqd =Value Required +error.inputFileTooLarge =Input File size is too large! +error.uploading =error uploading +error.title.empty =Title can not be blank +message.msg.maxFileSize =Max 250K +label.open =Open +label.delete =Delete +label.download =Download +label.view =View +label.edit =Edit +label.finished =Finished +label.completed =Completed +label.finish =Finish +button.upload =Upload +button.add =Add +button.cancel =Cancel +message.monitoring.summary.no.session =No Session Available +label.show =Show +label.hide =Hide +label.save =Save +label.cancel =Cancel +monitoring.label.access.time =Access time +define.later.message =Please wait for the researcher to complete the contents of this activity. +run.offline.message =This activity is not being done on the computer. Please see your instructor for details. +message.monitoring.summary.no.resource.for.group =No resource available for this group. +button.try.again =Try again +open.in.new.window =Open URL in pop-up +label.up =Move Up +label.down =Move down +label.authoring.advanced.reflectOnActivity =Add Notebook at end of Shared Resources with the following instructions: +error.reflection.emtpy =Please input reflection +title.reflection =Reflection +label.continue =Continue +monitoring.user.fullname =Name +monitoring.user.reflection =Reflection +page.title.monitoring.view.reflection =View Reflection +button.close =Close +message.step.of =Step {0} of {1} +message.no.reflection.available =No notebook available +button.edit =Edit +errors.maxfilesize =The uploaded file has exceeded the maximum file size limit of {0} bytes +error.attachment.executable =The uploaded file is executable, please zip it before uploading. +label.monitoring.heading.access =Participants list +message.alertContentEdit =Warning: One of more participants have accessed this activity. Changing this content will result in students getting different information. +label.export.reflection =Notebook Entries +monitoring.label.attachments =Attachments +message.activityLocked =Note: After you click on "Next Activity" and you come back to this Share Resources, you won't be able to continue. +message.warnLockOnFinish =This activitiy has been setup not to allow sharing and viewing of resources after it has been finished. + + +#======= End labels: Exported 160 labels for en AU ===== Index: lams_tool_imscc/conf/language/rams/ApplicationResources_en_AU.properties =================================================================== diff -u --- lams_tool_imscc/conf/language/rams/ApplicationResources_en_AU.properties (revision 0) +++ lams_tool_imscc/conf/language/rams/ApplicationResources_en_AU.properties (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,171 @@ +appName = shareresources +#language code: en +#locale code: AU + + # CVS ID: $Id$ Exported from the RAMS Community by Ernie Ghiglione on Tue Aug 12 12:00:29 EST 2008 + +#=================== labels for ShareResources =================# + +appName =Share Resources +activity.title =Common Cartridge +activity.description =Sharing resource with others. +activity.helptext =Uploading your resources to share with others. +tool.display.name =Share Resources Tool +tool.description =Tool for sharing resources. +errorPage.title =Error page +errorPage.heading =Some error occurs when handling your request +label.authoring.heading =Share Resources +label.author.title =Share Resources Authoring +label.authoring.heading.basic =Basic +label.authoring.heading.advance =Advanced +label.authoring.heading.instructions =Instructions +label.authoring.heading.basic.desc =Basic input information for shared resources +label.authoring.heading.instructions.desc =Please input online and offline instructions +label.authoring.heading.advance.desc =Please input advance options for shared resources +label.authoring.basic.title =Title +label.authoring.basic.instruction =Instruction +label.authoring.basic.add.url =Add URL +label.authoring.basic.add.file =Add Single File +label.authoring.basic.add.website =Add Zipped Website +label.authoring.basic.add.learning.object =Add IMS Content Package +label.authoring.basic.resource.list.title =Resource List +label.authoring.basic.resource.url =URL +label.authoring.basic.resource.file =File +label.authoring.basic.resource.website =Website +label.authoring.basic.resource.learning.object =IMS CP +label.authoring.basic.resource.verify.url =Verify URL +label.authoring.basic.resource.preview =Preview +label.authoring.basic.resource.edit =Edit +label.authoring.basic.resource.delete =Delete +label.authoring.basic.resource.add.instruction =Add Instruction +label.authoring.basic.resource.instructions =Instructions +label.authoring.basic.resource.title.input =Title +label.authoring.basic.resource.url.input =URL +label.authoring.basic.resource.file.input =File +label.authoring.basic.resource.description.input =Description +label.authoring.basic.resource.zip.file.input =Zip file: +label.authoring.online.instruction =Online Instructions +label.authoring.offline.instruction =Offline Instructions +label.authoring.online.file =Upload online file +label.authoring.offline.file =Upload offline file +label.authoring.choosefile.button =Choose file +label.authoring.upload.online.button =Upload Online +label.authoring.upload.offline.button =Upload Offline +label.authoring.online.filelist =Online file list +label.authoring.offline.filelist =Offline file list +label.authoring.online.delete =Delete +label.authoring.offline.delete =Delete +label.authoring.advance.lock.on.finished =Lock when finished +label.authoring.advance.run.content.auto =Run content automatically (only available if there is exactly one resource) +label.authoring.advance.mini.number.resources.view =Minimum number of resources to view +label.authoring.advance.allow.learner.add.urls =Allow participants to add URLs +label.authoring.advance.allow.learner.add.files =Allow participants to add Files +label.next.instruction =Next Instruction +label.authoring.save.button =Save +label.authoring.cancel.button =Cancel +label.description =Description: +authoring.exception =There is a problem in shared resources authoring page, the reason is {0} +error.resource.item.title.blank =Title can not be blank. +error.resource.item.url.blank =URL can not be blank. +error.resource.item.file.blank =File can not be blank. +error.resource.item.desc.blank =Comment/Instruction can not be blank +error.resource.item.invalid.url =Invalid URL format. +error.upload.failed =Upload file failed: {0} +error.msg.upload.file.not.found =Could not find upload file {0}. +error.msg.zip.file.exception =Could not handle zip file when uploading file. +error.msg.file.not.found =File not found exception occurs when uploading file. +error.msg.ims.package =Invalid IMS CP format. +error.msg.ims.application =ImscpApplicationException occurs when uploading resource item file. +error.msg.website.no.initial.file =Website zip can not find out initial file (index.htm/html or default.htm/html). +error.msg.io.exception =IOException occurs when uploading file. +error.msg.invaid.param.upload =InvalidParameterException occured while trying to upload File. +error.msg.repository =Repository occurs exception while trying to upload file. +error.msg.default.content.not.find =Could not retrieve default content record for this tool. +msg.no.instruction =No instruction available. +authoring.msg.cancel.save =Do you want to close this window without saving? +label.learning.title =Share Resource +label.learning.heading =Share Resources +label.resoruce.to.review =Resources to view +label.learning.minimum.review =You must view at least {0} of the resources. +lable.learning.minimum.view.number.less =You at least view another {0} of the resources. +label.check.for.new =Check for new +label.suggest.new =Suggest a new +label.learning.new.file =New file details: +label.learning.new.url =New URL details: +label.learning.comment.or.instruction =Comment/Instruction +monitoring.tab.summary =Summary +monitoring.tab.statistics =Statistic +monitoring.tab.instructions =Instruction +monitoring.tab.edit.activity =Edit Activity +monitoring.label.group =Group +monitoring.summary.note =Note: number of participants is the number of participants who have viewed the resource. +monitoring.label.type =Type +monitoring.label.title =Title +monitoring.label.suggest =Suggested By +monitoring.label.number.learners =Number of Participants +monitoring.label.hide =Hide +monitoring.label.show =Show +monitoring.label.user.loginname =Login name +monitoring.label.user.name =Name +monitoring.label.hidden =Hidden +label.monitoring.edit.activity.cancel =Cancel +label.monitoring.edit.activity.update =Update +label.monitoring.edit.activity.edit =Edit +message.monitoring.edit.activity.not.editable =This Activity is no longer editable +export.label.resource =Resource +export.label.no.learning.object =No offline package available +export.title =Export portfolio of Share Resource +export.init.resource =Initial Resources +errors.header = +errors.footer = +error.valueReqd =Value Required +error.inputFileTooLarge =Input File size is too large! +error.uploading =error uploading +error.title.empty =Title can not be blank +message.msg.maxFileSize =Max 250K +label.open =Open +label.delete =Delete +label.download =Download +label.view =View +label.edit =Edit +label.finished =Finished +label.completed =Completed +label.finish =Finish +button.upload =Upload +button.add =Add +button.cancel =Cancel +message.monitoring.summary.no.session =No Session Available +label.show =Show +label.hide =Hide +label.save =Save +label.cancel =Cancel +monitoring.label.access.time =Access time +define.later.message =Please wait for the researcher to complete the contents of this activity. +run.offline.message =This activity is not being done on the computer. Please see your instructor for details. +message.monitoring.summary.no.resource.for.group =No resource available for this group. +button.try.again =Try again +open.in.new.window =Open URL in pop-up +label.up =Move Up +label.down =Move down +label.authoring.advanced.reflectOnActivity =Add Notebook at end of Shared Resources with the following instructions: +error.reflection.emtpy =Please input reflection +title.reflection =Reflection +label.continue =Continue +monitoring.user.fullname =Name +monitoring.user.reflection =Reflection +page.title.monitoring.view.reflection =View Reflection +button.close =Close +message.step.of =Step {0} of {1} +message.no.reflection.available =No notebook available +button.edit =Edit +errors.maxfilesize =The uploaded file has exceeded the maximum file size limit of {0} bytes +error.attachment.executable =The uploaded file is executable, please zip it before uploading. +label.monitoring.heading.access =Participants list +message.alertContentEdit =Warning: One of more participants have accessed this activity. Changing this content will result in students getting different information. +label.export.reflection =Notebook Entries +monitoring.label.attachments =Attachments +message.activityLocked =Note: After you click on "Next Activity" and you come back to this Share Resources, you won't be able to continue. +message.warnLockOnFinish =This activitiy has been setup not to allow sharing and viewing of resources after it has been finished. + + +#======= End labels: Exported 160 labels for en AU ===== Index: lams_tool_imscc/conf/war/META-INF/MANIFEST.MF =================================================================== diff -u --- lams_tool_imscc/conf/war/META-INF/MANIFEST.MF (revision 0) +++ lams_tool_imscc/conf/war/META-INF/MANIFEST.MF (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,4 @@ +Implementation-Title: LAMS - CommonCartridge Tool +Implementation-Version: 2.1 +Implementation-Vendor: LAMS Foundation (http://lamsfoundation.org) +Class-Path: ./lams.jar ./lams-tool-laimsc11.jar ./lams-contentrepository.jar Index: lams_tool_imscc/conf/xdoclet/global-exceptions.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/global-exceptions.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/global-exceptions.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,8 @@ + + + Index: lams_tool_imscc/conf/xdoclet/global-forwards.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/global-forwards.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/global-forwards.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,6 @@ + + + + + + Index: lams_tool_imscc/conf/xdoclet/struts-actions.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/struts-actions.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/struts-actions.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/conf/xdoclet/struts-forms.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/struts-forms.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/struts-forms.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ + Index: lams_tool_imscc/conf/xdoclet/struts-message-resources.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/struts-message-resources.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/struts-message-resources.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ + Index: lams_tool_imscc/conf/xdoclet/struts-plugins.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/struts-plugins.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/struts-plugins.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,15 @@ + + + + + + Index: lams_tool_imscc/conf/xdoclet/validation-forms.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/validation-forms.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/validation-forms.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,29 @@ + Index: lams_tool_imscc/conf/xdoclet/validation-global.xml =================================================================== diff -u --- lams_tool_imscc/conf/xdoclet/validation-global.xml (revision 0) +++ lams_tool_imscc/conf/xdoclet/validation-global.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,6 @@ + + + datePattern + yyyy-MM-dd + + Index: lams_tool_imscc/db/model/commonCartridge.clay =================================================================== diff -u --- lams_tool_imscc/db/model/commonCartridge.clay (revision 0) +++ lams_tool_imscc/db/model/commonCartridge.clay (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
Index: lams_tool_imscc/db/sql/activity_insert.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/activity_insert.sql (revision 0) +++ lams_tool_imscc/db/sql/activity_insert.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,82 @@ +# Connection: ROOT LOCAL +# Host: localhost +# Saved: 2005-04-07 11:08:32 +# +INSERT INTO lams_learning_activity +( +activity_ui_id +, description +, title +, help_text +, xcoord +, ycoord +, parent_activity_id +, parent_ui_id +, learning_activity_type_id +, grouping_support_type_id +, apply_grouping_flag +, grouping_id +, grouping_ui_id +, order_id +, define_later_flag +, learning_design_id +, learning_library_id +, create_date_time +, run_offline_flag +, max_number_of_options +, min_number_of_options +, options_instructions +, tool_id +, tool_content_id +, activity_category_id +, gate_activity_level_id +, gate_open_flag +, gate_start_time_offset +, gate_end_time_offset +, gate_start_date_time +, gate_end_date_time +, library_activity_ui_image +, create_grouping_id +, create_grouping_ui_id +, library_activity_id +, language_file +) +VALUES +( +NULL +, 'CommonCartridge' +, 'CommonCartridge' +, 'Put some help text here.' +, NULL +, NULL +, NULL +, NULL +, 1 +, 2 +, 0 +, NULL +, NULL +, NULL +, 0 +, NULL +, ${learning_library_id} +, NOW() +, 0 +, NULL +, NULL +, NULL +, ${tool_id} +, NULL +, 4 +, NULL +, NULL +, NULL +, NULL +, NULL +, NULL +, 'tool/laimsc11/images/icon_commonCartridge.swf' +, NULL +, NULL +, NULL +, 'org.lamsfoundation.lams.tool.commonCartridge.ApplicationResources' +) Index: lams_tool_imscc/db/sql/create_lams_tool_commonCartridge.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/create_lams_tool_commonCartridge.sql (revision 0) +++ lams_tool_imscc/db/sql/create_lams_tool_commonCartridge.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,141 @@ +SET FOREIGN_KEY_CHECKS=0; +drop table if exists tl_laimsc11_attachment; +drop table if exists tl_laimsc11_item_instruction; +drop table if exists tl_laimsc11_commonCartridge; +drop table if exists tl_laimsc11_commonCartridge_item; +drop table if exists tl_laimsc11_commonCartridge_item_visit_log; +drop table if exists tl_laimsc11_session; +drop table if exists tl_laimsc11_user; +drop table if exists tl_laimsc11_configuration; + +create table tl_laimsc11_attachment ( + uid bigint not null auto_increment, + file_version_id bigint, + file_type varchar(255), + file_name varchar(255), + file_uuid bigint, + create_date datetime, + commonCartridge_uid bigint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_item_instruction ( + uid bigint not null auto_increment, + description varchar(255), + sequence_id integer, + item_uid bigint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_commonCartridge ( + uid bigint not null auto_increment, + create_date datetime, + update_date datetime, + create_by bigint, + title varchar(255), + run_offline tinyint, + lock_on_finished tinyint, + instructions text, + online_instructions text, + offline_instructions text, + content_in_use tinyint, + define_later tinyint, + content_id bigint unique, + mini_view_commonCartridge_number integer, + allow_auto_run tinyint, + reflect_instructions varchar(255), + reflect_on_activity smallint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_commonCartridge_item ( + uid bigint not null auto_increment, + file_uuid bigint, + file_version_id bigint, + description varchar(255), + ims_schema varchar(255), + init_item varchar(255), + organization_xml text, + title varchar(255), + url text, + launch_url varchar(255), + secure_launch_url varchar(255), + tool_key varchar(255), + tool_secret varchar(255), + custom_str text, + button_text varchar(255), + frame_height integer, + create_by bigint, + create_date datetime, + create_by_author tinyint, + is_hide tinyint, + item_type smallint, + file_type varchar(255), + file_name varchar(255), + open_url_new_window tinyint, + commonCartridge_uid bigint, + session_uid bigint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_item_log ( + uid bigint not null auto_increment, + access_date datetime, + commonCartridge_item_uid bigint, + user_uid bigint, + complete tinyint, + session_id bigint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_session ( + uid bigint not null auto_increment, + session_end_date datetime, + session_start_date datetime, + status integer, + commonCartridge_uid bigint, + session_id bigint, + session_name varchar(250), + primary key (uid) +)type=innodb; +create table tl_laimsc11_user ( + uid bigint not null auto_increment, + user_id bigint, + last_name varchar(255), + first_name varchar(255), + login_name varchar(255), + session_finished smallint, + session_uid bigint, + commonCartridge_uid bigint, + primary key (uid) +)type=innodb; +create table tl_laimsc11_configuration ( + uid bigint not null auto_increment, + config_key varchar(30) unique, + config_value varchar(255), + primary key (uid) +)TYPE=InnoDB; + +alter table tl_laimsc11_attachment add index FK_NEW_1279208528_1E7009430E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_1E7009430E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_item_instruction add index FK_NEW_1279208528_A5665013980570ED (item_uid), add constraint FK_NEW_1279208528_A5665013980570ED foreign key (item_uid) references tl_laimsc11_commonCartridge_item (uid); +alter table tl_laimsc11_commonCartridge add index FK_NEW_1279208528_89093BF758092FB (create_by), add constraint FK_NEW_1279208528_89093BF758092FB foreign key (create_by) references tl_laimsc11_user (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F93758092FB (create_by), add constraint FK_NEW_1279208528_F52D1F93758092FB foreign key (create_by) references tl_laimsc11_user (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F9330E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_F52D1F9330E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F93EC0D3147 (session_uid), add constraint FK_NEW_1279208528_F52D1F93EC0D3147 foreign key (session_uid) references tl_laimsc11_session (uid); +alter table tl_laimsc11_item_log add index FK_NEW_1279208528_693580A438BF8DFE (commonCartridge_item_uid), add constraint FK_NEW_1279208528_693580A438BF8DFE foreign key (commonCartridge_item_uid) references tl_laimsc11_commonCartridge_item (uid); +alter table tl_laimsc11_item_log add index FK_NEW_1279208528_693580A441F9365D (user_uid), add constraint FK_NEW_1279208528_693580A441F9365D foreign key (user_uid) references tl_laimsc11_user (uid); +alter table tl_laimsc11_session add index FK_NEW_1279208528_24AA78C530E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_24AA78C530E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_user add index FK_NEW_1279208528_30113BFCEC0D3147 (session_uid), add constraint FK_NEW_1279208528_30113BFCEC0D3147 foreign key (session_uid) references tl_laimsc11_session (uid); +alter table tl_laimsc11_user add index FK_NEW_1279208528_30113BFC309ED320 (commonCartridge_uid), add constraint FK_NEW_1279208528_30113BFC309ED320 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); + + + +INSERT INTO `tl_laimsc11_commonCartridge` (`uid`, `create_date`, `update_date`, `create_by`, `title`, `run_offline`, `lock_on_finished`, + `instructions`, `online_instructions`, `offline_instructions`, `content_in_use`, `define_later`, `content_id`, + `mini_view_commonCartridge_number`, `allow_auto_run`,`reflect_on_activity`) VALUES + (1,NULL,NULL,NULL,'CommonCartridge','0','0','Instructions ',null,null,0,0,${default_content_id},0,0,0); + +INSERT INTO `tl_laimsc11_commonCartridge_item` (`uid`, `file_uuid`, `file_version_id`, `description`, `ims_schema`, `init_item`, `organization_xml`, `title`, `url`, `create_by`, `create_date`, `create_by_author`, `is_hide`, `item_type`, `file_type`, `file_name`, `open_url_new_window`, `commonCartridge_uid`, `session_uid`, `frame_height`) VALUES + (1,NULL,NULL,NULL,NULL,NULL,NULL,'Web Search','http://www.google.com ',null,NOW(),1,0,1,NULL,NULL,0,1,NULL, 100); + +INSERT INTO `tl_laimsc11_configuration` (`config_key`, `config_value`) VALUES + ('allowExposeUserName', 'true'); +INSERT INTO `tl_laimsc11_configuration` (`config_key`, `config_value`) VALUES + ('allowExposeUserEmail', 'true'); + +SET FOREIGN_KEY_CHECKS=1; Index: lams_tool_imscc/db/sql/db_version_insert.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/db_version_insert.sql (revision 0) +++ lams_tool_imscc/db/sql/db_version_insert.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,2 @@ +-- $Id$ +INSERT INTO patches VALUES ('@signature@', '@tool_version@', NOW(), 'F'); Index: lams_tool_imscc/db/sql/drop_lams_tool_commonCartridge.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/drop_lams_tool_commonCartridge.sql (revision 0) +++ lams_tool_imscc/db/sql/drop_lams_tool_commonCartridge.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,14 @@ +SET FOREIGN_KEY_CHECKS=0; +drop table if exists tl_laimsc11_attachment; +drop table if exists tl_laimsc11_item_instruction; +drop table if exists tl_laimsc11_commonCartridge; +drop table if exists tl_laimsc11_commonCartridge_item; +drop table if exists tl_laimsc11_item_log; +drop table if exists tl_laimsc11_session; +drop table if exists tl_laimsc11_user; +SET FOREIGN_KEY_CHECKS=1; + + + + + Index: lams_tool_imscc/db/sql/library_insert.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/library_insert.sql (revision 0) +++ lams_tool_imscc/db/sql/library_insert.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,18 @@ +# Connection: ROOT LOCAL +# Host: localhost +# Saved: 2005-04-07 10:50:55 +# +INSERT INTO lams_learning_library +( +description, +title, +valid_flag, +create_date_time +) +VALUES +( +'Share commonCartridge', +'Share commonCartridge', +0, +NOW() +) Index: lams_tool_imscc/db/sql/table-schema.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/table-schema.sql (revision 0) +++ lams_tool_imscc/db/sql/table-schema.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,36 @@ +alter table tl_laimsc11_attachment drop foreign key FK_NEW_1279208528_1E7009430E79035; +alter table tl_laimsc11_item_instruction drop foreign key FK_NEW_1279208528_A5665013980570ED; +alter table tl_laimsc11_item_log drop foreign key FK_NEW_1279208528_63195BC938BF8DFE; +alter table tl_laimsc11_item_log drop foreign key FK_NEW_1279208528_63195BC941F9365D; +alter table tl_laimsc11_commonCartridge drop foreign key FK_NEW_1279208528_89093BF758092FB; +alter table tl_laimsc11_commonCartridge_item drop foreign key FK_NEW_1279208528_F52D1F9330E79035; +alter table tl_laimsc11_commonCartridge_item drop foreign key FK_NEW_1279208528_F52D1F93EC0D3147; +alter table tl_laimsc11_commonCartridge_item drop foreign key FK_NEW_1279208528_F52D1F93758092FB; +alter table tl_laimsc11_session drop foreign key FK_NEW_1279208528_24AA78C530E79035; +alter table tl_laimsc11_user drop foreign key FK_NEW_1279208528_30113BFC30E79035; +alter table tl_laimsc11_user drop foreign key FK_NEW_1279208528_30113BFCEC0D3147; +drop table if exists tl_laimsc11_attachment; +drop table if exists tl_laimsc11_item_instruction; +drop table if exists tl_laimsc11_item_log; +drop table if exists tl_laimsc11_commonCartridge; +drop table if exists tl_laimsc11_commonCartridge_item; +drop table if exists tl_laimsc11_session; +drop table if exists tl_laimsc11_user; +create table tl_laimsc11_attachment (uid bigint not null auto_increment, file_version_id bigint, file_type varchar(255), file_name varchar(255), file_uuid bigint, create_date datetime, commonCartridge_uid bigint, primary key (uid)); +create table tl_laimsc11_item_instruction (uid bigint not null auto_increment, description varchar(255), sequence_id integer, item_uid bigint, primary key (uid)); +create table tl_laimsc11_item_log (uid bigint not null auto_increment, access_date datetime, commonCartridge_item_uid bigint, user_uid bigint, complete bit, session_id bigint, primary key (uid)); +create table tl_laimsc11_commonCartridge (uid bigint not null auto_increment, create_date datetime, update_date datetime, create_by bigint, title varchar(255), run_offline bit, lock_on_finished bit, instructions text, online_instructions text, offline_instructions text, content_in_use bit, define_later bit, content_id bigint unique, allow_add_files bit, allow_add_urls bit, mini_view_commonCartridge_number integer, allow_auto_run bit, reflect_instructions varchar(255), reflect_on_activity bit,assigment_submit_notify tinyint DEFAULT 0, primary key (uid)); +create table tl_laimsc11_commonCartridge_item (uid bigint not null auto_increment, file_uuid bigint, file_version_id bigint, description varchar(255), ims_schema varchar(255), init_item varchar(255), organization_xml text, title varchar(255), url text, create_by bigint, create_date datetime, create_by_author bit, is_hide bit, item_type smallint, file_type varchar(255), file_name varchar(255), open_url_new_window bit, commonCartridge_uid bigint, session_uid bigint, primary key (uid)); +create table tl_laimsc11_session (uid bigint not null auto_increment, session_end_date datetime, session_start_date datetime, status integer, commonCartridge_uid bigint, session_id bigint, session_name varchar(250), primary key (uid)); +create table tl_laimsc11_user (uid bigint not null auto_increment, user_id bigint, last_name varchar(255), first_name varchar(255), login_name varchar(255), session_uid bigint, commonCartridge_uid bigint, session_finished bit, primary key (uid)); +alter table tl_laimsc11_attachment add index FK_NEW_1279208528_1E7009430E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_1E7009430E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_item_instruction add index FK_NEW_1279208528_A5665013980570ED (item_uid), add constraint FK_NEW_1279208528_A5665013980570ED foreign key (item_uid) references tl_laimsc11_commonCartridge_item (uid); +alter table tl_laimsc11_item_log add index FK_NEW_1279208528_63195BC938BF8DFE (commonCartridge_item_uid), add constraint FK_NEW_1279208528_63195BC938BF8DFE foreign key (commonCartridge_item_uid) references tl_laimsc11_commonCartridge_item (uid); +alter table tl_laimsc11_item_log add index FK_NEW_1279208528_63195BC941F9365D (user_uid), add constraint FK_NEW_1279208528_63195BC941F9365D foreign key (user_uid) references tl_laimsc11_user (uid); +alter table tl_laimsc11_commonCartridge add index FK_NEW_1279208528_89093BF758092FB (create_by), add constraint FK_NEW_1279208528_89093BF758092FB foreign key (create_by) references tl_laimsc11_user (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F9330E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_F52D1F9330E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F93EC0D3147 (session_uid), add constraint FK_NEW_1279208528_F52D1F93EC0D3147 foreign key (session_uid) references tl_laimsc11_session (uid); +alter table tl_laimsc11_commonCartridge_item add index FK_NEW_1279208528_F52D1F93758092FB (create_by), add constraint FK_NEW_1279208528_F52D1F93758092FB foreign key (create_by) references tl_laimsc11_user (uid); +alter table tl_laimsc11_session add index FK_NEW_1279208528_24AA78C530E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_24AA78C530E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_user add index FK_NEW_1279208528_30113BFC30E79035 (commonCartridge_uid), add constraint FK_NEW_1279208528_30113BFC30E79035 foreign key (commonCartridge_uid) references tl_laimsc11_commonCartridge (uid); +alter table tl_laimsc11_user add index FK_NEW_1279208528_30113BFCEC0D3147 (session_uid), add constraint FK_NEW_1279208528_30113BFCEC0D3147 foreign key (session_uid) references tl_laimsc11_session (uid); Index: lams_tool_imscc/db/sql/tool_insert.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/tool_insert.sql (revision 0) +++ lams_tool_imscc/db/sql/tool_insert.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,64 @@ +# Connection: ROOT LOCAL +# Host: localhost +# Saved: 2005-04-07 10:42:43 +# +INSERT INTO lams_tool +( +tool_signature, +service_name, +tool_display_name, +description, +tool_identifier, +tool_version, +learning_library_id, +default_tool_content_id, +valid_flag, +grouping_support_type_id, +supports_run_offline_flag, +learner_url, +learner_preview_url, +learner_progress_url, +author_url, +monitor_url, +define_later_url, +export_pfolio_learner_url, +export_pfolio_class_url, +contribute_url, +moderation_url, +pedagogical_planner_url, +help_url, +language_file, +create_date_time, +modified_date_time, +admin_url +) +VALUES +( +'laimsc11', +'commonCartridgeService', +'Shared CommonCartridge', +'Shared CommonCartridge', +'sharedcommonCartridge', +'@tool_version@', +NULL, +NULL, +0, +2, +1, +'tool/laimsc11/learning/start.do?mode=learner', +'tool/laimsc11/learning/start.do?mode=author', +'tool/laimsc11/learning/start.do?mode=teacher', +'tool/laimsc11/authoring/start.do', +'tool/laimsc11/monitoring/summary.do', +'tool/laimsc11/definelater.do', +'tool/laimsc11/exportPortfolio?mode=learner', +'tool/laimsc11/exportPortfolio?mode=teacher', +'tool/laimsc11/contribute.do', +'tool/laimsc11/moderate.do', +'tool/laimsc11/authoring/initPedagogicalPlannerForm.do', +'http://wiki.lamsfoundation.org/display/lamsdocs/laimsc11', +'org.lamsfoundation.lams.tool.commonCartridge.ApplicationResources', +NOW(), +NOW(), +'tool/laimsc11/laimsc11admin/start.do' +) Index: lams_tool_imscc/db/sql/updatescripts/updateTo20070227.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/updatescripts/updateTo20070227.sql (revision 0) +++ lams_tool_imscc/db/sql/updatescripts/updateTo20070227.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,4 @@ +-- Update the CommonCartridge tables to 20070227 +-- This is for the LAMS 2.0.1 release. + +UPDATE lams_tool set modified_date_time = now(), classpath_addition = 'lams-tool-laimsc11.jar', context_file = '/org/lamsfoundation/lams/tool/commonCartridge/commonCartridgeApplicationContext.xml' where tool_signature = 'laimsc11'; Index: lams_tool_imscc/db/sql/updatescripts/updateTo20080229.sql =================================================================== diff -u --- lams_tool_imscc/db/sql/updatescripts/updateTo20080229.sql (revision 0) +++ lams_tool_imscc/db/sql/updatescripts/updateTo20080229.sql (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,2 @@ +UPDATE lams_tool SET modified_date_time = NOW() WHERE tool_signature = "laimsc11"; +UPDATE lams_tool SET tool_version = "20080229" WHERE tool_signature = "laimsc11"; Index: lams_tool_imscc/lib/jaxen/jaxen-full.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/jaxen/sax.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/jaxen/saxpath.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/castor-0.9.5.3-xml.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/jdom.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/moonunitsrc.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/reload-diva.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/reload-editor.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/reload-jdom.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/reload-moonunit.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/lib/reload_2_0_1/xercesImpl.jar =================================================================== diff -u Binary files differ Index: lams_tool_imscc/licenses/Jaxen LICENSE.txt =================================================================== diff -u --- lams_tool_imscc/licenses/Jaxen LICENSE.txt (revision 0) +++ lams_tool_imscc/licenses/Jaxen LICENSE.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,33 @@ +/* + $Id$ + + Copyright 2003-2006 The Werken Company. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Jaxen Project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ Index: lams_tool_imscc/licenses/castor license.txt =================================================================== diff -u --- lams_tool_imscc/licenses/castor license.txt (revision 0) +++ lams_tool_imscc/licenses/castor license.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,38 @@ +Copyright 2000-2002 (C) Intalio Inc. All Rights Reserved. + +Redistribution and use of this software and associated documentation +("Software"), with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions of source code must retain copyright statements + and notices. Redistributions must also contain a copy of this + document. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name "ExoLab" must not be used to endorse or promote products + derived from this Software without prior written permission of + Intalio Inc. For written permission, please contact info@exolab.org. + +4. Products derived from this Software may not be called "Castor" + nor may "Castor" appear in their names without prior written + permission of Intalio Inc. Exolab, Castor and Intalio are + trademarks of Intalio Inc. + +5. Due credit should be given to the ExoLab Project + (http://www.exolab.org/). + +THIS SOFTWARE IS PROVIDED BY INTALIO AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO OR ITS +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. Index: lams_tool_imscc/licenses/jdom licence.txt =================================================================== diff -u --- lams_tool_imscc/licenses/jdom licence.txt (revision 0) +++ lams_tool_imscc/licenses/jdom licence.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,54 @@ +/*-- + + Copyright (C) 2000-2002 Brett McLaughlin & Jason Hunter. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the disclaimer that follows + these conditions in the documentation and/or other materials + provided with the distribution. + + 3. The name "JDOM" must not be used to endorse or promote products + derived from this software without prior written permission. For + written permission, please contact license@jdom.org. + + 4. Products derived from this software may not be called "JDOM", nor + may "JDOM" appear in their name, without prior written permission + from the JDOM Project Management (pm@jdom.org). + + In addition, we request (but do not require) that you include in the + end-user documentation provided with the redistribution and/or in the + software itself an acknowledgement equivalent to the following: + "This product includes software developed by the + JDOM Project (http://www.jdom.org/)." + Alternatively, the acknowledgment may be graphical using the logos + available at http://www.jdom.org/images/logos. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + This software consists of voluntary contributions made by many + individuals on behalf of the JDOM Project and was originally + created by Brett McLaughlin and + Jason Hunter . For more information on the + JDOM Project, please see . + + */ + Index: lams_tool_imscc/licenses/library_licenses.txt =================================================================== diff -u --- lams_tool_imscc/licenses/library_licenses.txt (revision 0) +++ lams_tool_imscc/licenses/library_licenses.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,28 @@ +Tigra Tree Javascript license description: +There is no license fee or royalty fee to be paid at any time for using the Tigra Tree Menu v1.x +You may include the source code or modified source code within your own projects for either personal or commercial use but excluding the restrictions outlined below. The following restrictions apply to all parts of the component, including all source code, samples and documentation. + + * Header block of script file (tree.js) CAN NOT be modified or removed. + * The above items CAN NOT be sold as are, either individually or together. + * The above items CAN NOT be modified and then sold as a library component, either individually or together. + + +For more detail, http://www.softcomplex.com/products/tigra_tree_menu/docs/ + +Library/Package License + +Used for the IMSCP functionality (Reload Project) +castor-0.9.5.3-xml.jar Castor License +jdom.jar Jdom Jar License +moonunitsrc.jar Reload License +reload-diva.jar Reload License +reload-editor.jar Reload License +reload-jdom.jar Reload License +reload-moonunit.jar Reload License +xercesImpl.jar Apache Software License 1.1 +xml-apis.jar Apache Software License 1.1 + +Other libraries +jaxen-full.jar Jaxen Jar License (The Werken Company) +sax.jar Public Domain +saxpath.jar Jaxen Jar License (The Werken Company) Index: lams_tool_imscc/licenses/reload licence.txt =================================================================== diff -u --- lams_tool_imscc/licenses/reload licence.txt (revision 0) +++ lams_tool_imscc/licenses/reload licence.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,45 @@ +RELOAD Tools and Libraries + +Copyright (c) 2002-2004 Oleg Liber, Bill Olivier, Phillip Beauvoir + +This licence covers: + +The Reload "jdom" library +The Reload "diva" library +The Reload "dweezil" library +The Reload "jdom" library +The Reload "moonunit" library +The Reload "xindice" library +The Reload Editor +The Reload SCORM Player +The Reload Schema Viewer Eclipse Plugin + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Project Management Contact: + +Oleg Liber +Bolton Institute of Higher Education +Deane Road +Bolton BL3 5AB +UK + +e-mail: o.liber@bolton.ac.uk + + +Technical Contact: + +Phillip Beauvoir +Bolton Institute of Higher Education +Deane Road +Bolton BL3 5AB +UK + +e-mail: p.beauvoir@bolton.ac.uk + + +Web: http://www.reload.ac.uk Index: lams_tool_imscc/licenses/xerces licence.txt =================================================================== diff -u --- lams_tool_imscc/licenses/xerces licence.txt (revision 0) +++ lams_tool_imscc/licenses/xerces licence.txt (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,56 @@ +/* + * The Apache Software License, Version 1.1 + * + * + * Copyright (c) 1999-2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com. For more + * information on the Apache Software Foundation, please see + * . + */ Index: lams_tool_imscc/src/java/net/oauth/ConsumerProperties.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/ConsumerProperties.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/ConsumerProperties.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,130 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * A pool of OAuthConsumers that are constructed from Properties. Each consumer + * has a name, which is a property of the OAuthConsumer. Other properties come + * from Properties whose names are prefixed with the consumer's name. For + * example, a consumer's credentials come from properties named + * [name].consumerKey and [name].consumerSecret. + * + * @author John Kristian + */ +public class ConsumerProperties { + + public static URL getResource(String name, ClassLoader loader) + throws IOException { + URL resource = loader.getResource(name); + if (resource == null) { + throw new IOException("resource not found: " + name); + } + return resource; + } + + public static Properties getProperties(URL source) throws IOException { + InputStream input = source.openStream(); + try { + Properties p = new Properties(); + p.load(input); + return p; + } finally { + input.close(); + } + } + + public ConsumerProperties(String resourceName, ClassLoader loader) + throws IOException { + this(getProperties(getResource(resourceName, loader))); + } + + public ConsumerProperties(Properties consumerProperties) { + this.consumerProperties = consumerProperties; + } + + private final Properties consumerProperties; + + private final Map pool = new HashMap(); + + /** Get the consumer with the given name. */ + public OAuthConsumer getConsumer(String name) throws MalformedURLException { + OAuthConsumer consumer; + synchronized (pool) { + consumer = pool.get(name); + } + if (consumer == null) { + consumer = newConsumer(name); + } + synchronized (pool) { + OAuthConsumer first = pool.get(name); + if (first == null) { + pool.put(name, consumer); + } else { + /* + * Another thread just constructed an identical OAuthConsumer. + * Use that one (and discard the one we just constructed). + */ + consumer = first; + } + } + return consumer; + } + + protected OAuthConsumer newConsumer(String name) + throws MalformedURLException { + String base = consumerProperties.getProperty(name + + ".serviceProvider.baseURL"); + URL baseURL = (base == null) ? null : new URL(base); + OAuthServiceProvider serviceProvider = new OAuthServiceProvider(getURL( + baseURL, name + ".serviceProvider.requestTokenURL"), getURL( + baseURL, name + ".serviceProvider.userAuthorizationURL"), + getURL(baseURL, name + ".serviceProvider.accessTokenURL")); + OAuthConsumer consumer = new OAuthConsumer(consumerProperties + .getProperty(name + ".callbackURL"), consumerProperties + .getProperty(name + ".consumerKey"), consumerProperties + .getProperty(name + ".consumerSecret"), serviceProvider); + consumer.setProperty("name", name); + if (baseURL != null) { + consumer.setProperty("serviceProvider.baseURL", baseURL); + } + for (Map.Entry prop : consumerProperties.entrySet()) { + String propName = (String) prop.getKey(); + if (propName.startsWith(name + ".consumer.")) { + String c = propName.substring(name.length() + 10); + consumer.setProperty(c, prop.getValue()); + } + } + return consumer; + } + + private String getURL(URL base, String name) throws MalformedURLException { + String url = consumerProperties.getProperty(name); + if (base != null) { + url = (new URL(base, url)).toExternalForm(); + } + return url; + } + +} Index: lams_tool_imscc/src/java/net/oauth/OAuth.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuth.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuth.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,351 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author John Kristian + */ +public class OAuth { + + public static final String VERSION_1_0 = "1.0"; + + /** The encoding used to represent characters as bytes. */ + public static final String ENCODING = "UTF-8"; + + /** The MIME type for a sequence of OAuth parameters. */ + public static final String FORM_ENCODED = "application/x-www-form-urlencoded"; + + public static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key"; + public static final String OAUTH_TOKEN = "oauth_token"; + public static final String OAUTH_TOKEN_SECRET = "oauth_token_secret"; + public static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method"; + public static final String OAUTH_SIGNATURE = "oauth_signature"; + public static final String OAUTH_TIMESTAMP = "oauth_timestamp"; + public static final String OAUTH_NONCE = "oauth_nonce"; + public static final String OAUTH_VERSION = "oauth_version"; + public static final String OAUTH_CALLBACK = "oauth_callback"; + + public static final String HMAC_SHA1 = "HMAC-SHA1"; + public static final String RSA_SHA1 = "RSA-SHA1"; + + /** + * Strings used for problem + * reporting. + */ + public static class Problems { + public static final String VERSION_REJECTED = "version_rejected"; + public static final String PARAMETER_ABSENT = "parameter_absent"; + public static final String PARAMETER_REJECTED = "parameter_rejected"; + public static final String TIMESTAMP_REFUSED = "timestamp_refused"; + public static final String NONCE_USED = "nonce_used"; + public static final String SIGNATURE_METHOD_REJECTED = "signature_method_rejected"; + public static final String SIGNATURE_INVALID = "signature_invalid"; + public static final String CONSUMER_KEY_UNKNOWN = "consumer_key_unknown"; + public static final String CONSUMER_KEY_REJECTED = "consumer_key_rejected"; + public static final String CONSUMER_KEY_REFUSED = "consumer_key_refused"; + public static final String TOKEN_USED = "token_used"; + public static final String TOKEN_EXPIRED = "token_expired"; + public static final String TOKEN_REVOKED = "token_revoked"; + public static final String TOKEN_REJECTED = "token_rejected"; + public static final String ADDITIONAL_AUTHORIZATION_REQUIRED = "additional_authorization_required"; + public static final String PERMISSION_UNKNOWN = "permission_unknown"; + public static final String PERMISSION_DENIED = "permission_denied"; + public static final String USER_REFUSED = "user_refused"; + + public static final String OAUTH_ACCEPTABLE_VERSIONS = "oauth_acceptable_versions"; + public static final String OAUTH_ACCEPTABLE_TIMESTAMPS = "oauth_acceptable_timestamps"; + public static final String OAUTH_PARAMETERS_ABSENT = "oauth_parameters_absent"; + public static final String OAUTH_PARAMETERS_REJECTED = "oauth_parameters_rejected"; + public static final String OAUTH_PROBLEM_ADVICE = "oauth_problem_advice"; + + /** + * A map from an oauth_problem value to + * the appropriate HTTP response code. + */ + public static final Map TO_HTTP_CODE = mapToHttpCode(); + + private static Map mapToHttpCode() { + Integer badRequest = new Integer(400); + Integer unauthorized = new Integer(401); + Integer serviceUnavailable = new Integer(503); + Map map = new HashMap(); + + map.put(Problems.VERSION_REJECTED, badRequest); + map.put(Problems.PARAMETER_ABSENT, badRequest); + map.put(Problems.PARAMETER_REJECTED, badRequest); + map.put(Problems.TIMESTAMP_REFUSED, badRequest); + map.put(Problems.SIGNATURE_METHOD_REJECTED, badRequest); + + map.put(Problems.NONCE_USED, unauthorized); + map.put(Problems.TOKEN_USED, unauthorized); + map.put(Problems.TOKEN_EXPIRED, unauthorized); + map.put(Problems.TOKEN_REVOKED, unauthorized); + map.put(Problems.TOKEN_REJECTED, unauthorized); + map.put("token_not_authorized", unauthorized); + map.put(Problems.SIGNATURE_INVALID, unauthorized); + map.put(Problems.CONSUMER_KEY_UNKNOWN, unauthorized); + map.put(Problems.CONSUMER_KEY_REJECTED, unauthorized); + map.put(Problems.ADDITIONAL_AUTHORIZATION_REQUIRED, unauthorized); + map.put(Problems.PERMISSION_UNKNOWN, unauthorized); + map.put(Problems.PERMISSION_DENIED, unauthorized); + + map.put(Problems.USER_REFUSED, serviceUnavailable); + map.put(Problems.CONSUMER_KEY_REFUSED, serviceUnavailable); + return Collections.unmodifiableMap(map); + } + + } + + /** Return true if the given Content-Type header means FORM_ENCODED. */ + public static boolean isFormEncoded(String contentType) { + if (contentType == null) { + return false; + } + int semi = contentType.indexOf(";"); + if (semi >= 0) { + contentType = contentType.substring(0, semi); + } + return FORM_ENCODED.equalsIgnoreCase(contentType.trim()); + } + + /** + * Construct a form-urlencoded document containing the given sequence of + * name/value pairs. Use OAuth percent encoding (not exactly the encoding + * mandated by HTTP). + */ + public static String formEncode(Iterable parameters) + throws IOException { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + formEncode(parameters, b); + return new String(b.toByteArray()); + } + + /** + * Write a form-urlencoded document into the given stream, containing the + * given sequence of name/value pairs. + */ + public static void formEncode(Iterable parameters, + OutputStream into) throws IOException { + if (parameters != null) { + boolean first = true; + for (Map.Entry parameter : parameters) { + if (first) { + first = false; + } else { + into.write('&'); + } + into.write(percentEncode(toString(parameter.getKey())) + .getBytes()); + into.write('='); + into.write(percentEncode(toString(parameter.getValue())) + .getBytes()); + } + } + } + + /** Parse a form-urlencoded document. */ + public static List decodeForm(String form) { + List list = new ArrayList(); + if (!isEmpty(form)) { + for (String nvp : form.split("\\&")) { + int equals = nvp.indexOf('='); + String name; + String value; + if (equals < 0) { + name = decodePercent(nvp); + value = null; + } else { + name = decodePercent(nvp.substring(0, equals)); + value = decodePercent(nvp.substring(equals + 1)); + } + list.add(new Parameter(name, value)); + } + } + return list; + } + + /** Construct a &-separated list of the given values, percentEncoded. */ + public static String percentEncode(Iterable values) { + StringBuilder p = new StringBuilder(); + for (Object v : values) { + if (p.length() > 0) { + p.append("&"); + } + p.append(OAuth.percentEncode(toString(v))); + } + return p.toString(); + } + + public static String percentEncode(String s) { + if (s == null) { + return ""; + } + try { + return URLEncoder.encode(s, ENCODING) + // OAuth encodes some characters differently: + .replace("+", "%20").replace("*", "%2A") + .replace("%7E", "~"); + // This could be done faster with more hand-crafted code. + } catch (UnsupportedEncodingException wow) { + throw new RuntimeException(wow.getMessage(), wow); + } + } + + public static String decodePercent(String s) { + try { + return URLDecoder.decode(s, ENCODING); + // This implements http://oauth.pbwiki.com/FlexibleDecoding + } catch (java.io.UnsupportedEncodingException wow) { + throw new RuntimeException(wow.getMessage(), wow); + } + } + + /** + * Construct a Map containing a copy of the given parameters. If several + * parameters have the same name, the Map will contain the first value, + * only. + */ + public static Map newMap(Iterable from) { + Map map = new HashMap(); + if (from != null) { + for (Map.Entry f : from) { + String key = toString(f.getKey()); + if (!map.containsKey(key)) { + map.put(key, toString(f.getValue())); + } + } + } + return map; + } + + /** Construct a list of Parameters from name, value, name, value... */ + public static List newList(String... parameters) { + List list = new ArrayList(parameters.length / 2); + for (int p = 0; p + 1 < parameters.length; p += 2) { + list.add(new Parameter(parameters[p], parameters[p + 1])); + } + return list; + } + + /** A name/value pair. */ + public static class Parameter implements Map.Entry { + + public Parameter(String key, String value) { + this.key = key; + this.value = value; + } + + private final String key; + + private String value; + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + public String setValue(String value) { + try { + return this.value; + } finally { + this.value = value; + } + } + + @Override + public String toString() { + return percentEncode(getKey()) + '=' + percentEncode(getValue()); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Parameter that = (Parameter) obj; + if (key == null) { + if (that.key != null) + return false; + } else if (!key.equals(that.key)) + return false; + if (value == null) { + if (that.value != null) + return false; + } else if (!value.equals(that.value)) + return false; + return true; + } + } + + private static final String toString(Object from) { + return (from == null) ? null : from.toString(); + } + + /** + * Construct a URL like the given one, but with the given parameters added + * to its query string. + */ + public static String addParameters(String url, String... parameters) + throws IOException { + return addParameters(url, newList(parameters)); + } + + public static String addParameters(String url, + Iterable> parameters) + throws IOException { + String form = formEncode(parameters); + if (form == null || form.length() <= 0) { + return url; + } else { + return url + ((url.indexOf("?") < 0) ? '?' : '&') + form; + } + } + + public static boolean isEmpty(String str) { + return (str == null) || (str.length() == 0); + } +} Index: lams_tool_imscc/src/java/net/oauth/OAuthAccessor.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthAccessor.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthAccessor.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,100 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URISyntaxException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Properties of one User of an OAuthConsumer. Properties may be added freely, + * e.g. to support extensions. + * + * @author John Kristian + */ +public class OAuthAccessor implements Cloneable, Serializable { + + private static final long serialVersionUID = 5590788443138352999L; + + public final OAuthConsumer consumer; + public String requestToken; + public String accessToken; + public String tokenSecret; + + public OAuthAccessor(OAuthConsumer consumer) { + this.consumer = consumer; + this.requestToken = null; + this.accessToken = null; + this.tokenSecret = null; + } + + private final Map properties = new HashMap(); + + @Override + public OAuthAccessor clone() { + try { + return (OAuthAccessor) super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + public Object getProperty(String name) { + return properties.get(name); + } + + public void setProperty(String name, Object value) { + properties.put(name, value); + } + + /** + * Construct a request message containing the given parameters but no body. + * Don't send the message, merely construct it. The caller will ordinarily + * send it, for example by calling OAuthClient.invoke or access. + * + * @param method + * the HTTP request method. If this is null, use the default + * method; that is getProperty("httpMethod") or (if that's null) + * consumer.getProperty("httpMethod") or (if that's null) + * OAuthMessage.GET. + */ + public OAuthMessage newRequestMessage(String method, String url, Collection parameters, + InputStream body) throws OAuthException, IOException, URISyntaxException { + if (method == null) { + method = (String) this.getProperty("httpMethod"); + if (method == null) { + method = (String) this.consumer.getProperty("httpMethod"); + if (method == null) { + method = OAuthMessage.GET; + } + } + } + OAuthMessage message = new OAuthMessage(method, url, parameters, body); + message.addRequiredParameters(this); + return message; + } + + public OAuthMessage newRequestMessage(String method, String url, Collection parameters) + throws OAuthException, IOException, URISyntaxException { + return newRequestMessage(method, url, parameters, null); + } + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthConsumer.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthConsumer.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthConsumer.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,70 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import net.oauth.http.HttpMessage; + +/** + * Properties of an OAuth Consumer. Properties may be added freely, e.g. to + * support extensions. + * + * @author John Kristian + */ +public class OAuthConsumer implements Serializable { + + private static final long serialVersionUID = -2258581186977818580L; + + public final String callbackURL; + public final String consumerKey; + public final String consumerSecret; + public final OAuthServiceProvider serviceProvider; + + public OAuthConsumer(String callbackURL, String consumerKey, + String consumerSecret, OAuthServiceProvider serviceProvider) { + this.callbackURL = callbackURL; + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + this.serviceProvider = serviceProvider; + } + + private final Map properties = new HashMap(); + + public Object getProperty(String name) { + return properties.get(name); + } + + public void setProperty(String name, Object value) { + properties.put(name, value); + } + + /** + * The name of the property whose value is the Accept-Encoding header in + * HTTP requests. + */ + public static final String ACCEPT_ENCODING = "HTTP.header." + HttpMessage.ACCEPT_ENCODING; + + /** + * The name of the property whose value is the Accessor Secret. + */ + public static final String ACCESSOR_SECRET = "oauth_accessor_secret"; + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthException.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthException.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,53 @@ +/* + * Copyright 2008 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.oauth; + +/** + * Superclass for extensions thrown by the OAuth library. + */ +public class OAuthException extends Exception { + + /** + * For subclasses only. + */ + protected OAuthException() { + } + + /** + * @param message + */ + public OAuthException(String message) { + super(message); + } + + /** + * @param cause + */ + public OAuthException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public OAuthException(String message, Throwable cause) { + super(message, cause); + } + + private static final long serialVersionUID = 1L; + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthMessage.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthMessage.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthMessage.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,412 @@ +/* + * Copyright 2007, 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.oauth.client.OAuthClient; +import net.oauth.http.HttpMessage; +import net.oauth.signature.OAuthSignatureMethod; + +/** + * A request or response message used in the OAuth protocol. + *

+ * The parameters in this class are not percent-encoded. Methods like + * OAuthClient.invoke and OAuthResponseMessage.completeParameters are + * responsible for percent-encoding parameters before transmission and decoding + * them after reception. + * + * @author John Kristian + */ +public class OAuthMessage { + + public OAuthMessage(String method, String URL, Collection parameters) { + this(method, URL, parameters, null); + } + + public OAuthMessage(String method, String URL, Collection parameters, + InputStream bodyAsStream) { + this.method = method; + this.URL = URL; + this.bodyAsStream = bodyAsStream; + if (parameters == null) { + this.parameters = new ArrayList>(); + } else { + this.parameters = new ArrayList>(parameters.size()); + for (Map.Entry p : parameters) { + this.parameters.add(new OAuth.Parameter( + toString(p.getKey()), toString(p.getValue()))); + } + } + } + + public String method; + public String URL; + + private final List> parameters; + private Map parameterMap; + private boolean parametersAreComplete = false; + private final List> headers = new ArrayList>(); + private final InputStream bodyAsStream; + + public String toString() { + return "OAuthMessage(" + method + ", " + URL + ", " + parameters + ")"; + } + + /** A caller is about to get a parameter. */ + private void beforeGetParameter() throws IOException { + if (!parametersAreComplete) { + completeParameters(); + parametersAreComplete = true; + } + } + + /** + * Finish adding parameters; for example read an HTTP response body and + * parse parameters from it. + */ + protected void completeParameters() throws IOException { + } + + public List> getParameters() throws IOException { + beforeGetParameter(); + return Collections.unmodifiableList(parameters); + } + + public void addParameter(String key, String value) { + addParameter(new OAuth.Parameter(key, value)); + } + + public void addParameter(Map.Entry parameter) { + parameters.add(parameter); + parameterMap = null; + } + + public void addParameters( + Collection> parameters) { + this.parameters.addAll(parameters); + parameterMap = null; + } + + public String getParameter(String name) throws IOException { + return getParameterMap().get(name); + } + + public String getConsumerKey() throws IOException { + return getParameter(OAuth.OAUTH_CONSUMER_KEY); + } + + public String getToken() throws IOException { + return getParameter(OAuth.OAUTH_TOKEN); + } + + public String getSignatureMethod() throws IOException { + return getParameter(OAuth.OAUTH_SIGNATURE_METHOD); + } + + public String getSignature() throws IOException { + return getParameter(OAuth.OAUTH_SIGNATURE); + } + + protected Map getParameterMap() throws IOException { + beforeGetParameter(); + if (parameterMap == null) { + parameterMap = OAuth.newMap(parameters); + } + return parameterMap; + } + + /** + * The MIME type of the body of this message. + * + * @return the MIME type, or null to indicate the type is unknown. + */ + public String getBodyType() { + return getHeader(HttpMessage.CONTENT_TYPE); + } + + /** + * The character encoding of the body of this message. + * + * @return the name of an encoding, or "ISO-8859-1" if no charset has been + * specified. + */ + public String getBodyEncoding() { + return HttpMessage.DEFAULT_CHARSET; + } + + /** + * The value of the last HTTP header with the given name. The name is case + * insensitive. + * + * @return the value of the last header, or null to indicate that there is + * no such header in this message. + */ + public final String getHeader(String name) { + String value = null; // no such header + for (Map.Entry header : getHeaders()) { + if (name.equalsIgnoreCase(header.getKey())) { + value = header.getValue(); + } + } + return value; + } + + /** All HTTP headers. You can add headers to this list. */ + public final List> getHeaders() { + return headers; + } + + /** + * Read the body of the HTTP request or response and convert it to a String. + * This method isn't repeatable, since it consumes and closes getBodyAsStream. + * + * @return the body, or null to indicate there is no body. + */ + public final String readBodyAsString() throws IOException + { + InputStream body = getBodyAsStream(); + return readAll(body, getBodyEncoding()); + } + + /** + * Get a stream from which to read the body of the HTTP request or response. + * This is designed to support efficient streaming of a large message. + * The caller must close the returned stream, to release the underlying + * resources such as the TCP connection for an HTTP response. + * + * @return a stream from which to read the body, or null to indicate there + * is no body. + */ + public InputStream getBodyAsStream() throws IOException { + return bodyAsStream; + } + + /** Construct a verbose description of this message and its origins. */ + public Map getDump() throws IOException { + Map into = new HashMap(); + dump(into); + return into; + } + + protected void dump(Map into) throws IOException { + into.put("URL", URL); + if (parametersAreComplete) { + try { + into.putAll(getParameterMap()); + } catch (Exception ignored) { + } + } + } + + /** + * Verify that the required parameter names are contained in the actual + * collection. + * + * @throws OAuthProblemException + * one or more parameters are absent. + * @throws IOException + */ + public void requireParameters(String... names) + throws OAuthProblemException, IOException { + Set present = getParameterMap().keySet(); + List absent = new ArrayList(); + for (String required : names) { + if (!present.contains(required)) { + absent.add(required); + } + } + if (!absent.isEmpty()) { + OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT); + problem.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.percentEncode(absent)); + throw problem; + } + } + + /** + * Add some of the parameters needed to request access to a protected + * resource, if they aren't already in the message. + * + * @throws IOException + * @throws URISyntaxException + */ + public void addRequiredParameters(OAuthAccessor accessor) + throws OAuthException, IOException, URISyntaxException { + final Map pMap = OAuth.newMap(parameters); + if (pMap.get(OAuth.OAUTH_TOKEN) == null && accessor.accessToken != null) { + addParameter(OAuth.OAUTH_TOKEN, accessor.accessToken); + } + final OAuthConsumer consumer = accessor.consumer; + if (pMap.get(OAuth.OAUTH_CONSUMER_KEY) == null) { + addParameter(OAuth.OAUTH_CONSUMER_KEY, consumer.consumerKey); + } + String signatureMethod = pMap.get(OAuth.OAUTH_SIGNATURE_METHOD); + if (signatureMethod == null) { + signatureMethod = (String) consumer.getProperty(OAuth.OAUTH_SIGNATURE_METHOD); + if (signatureMethod == null) { + signatureMethod = OAuth.HMAC_SHA1; + } + addParameter(OAuth.OAUTH_SIGNATURE_METHOD, signatureMethod); + } + if (pMap.get(OAuth.OAUTH_TIMESTAMP) == null) { + addParameter(OAuth.OAUTH_TIMESTAMP, (System.currentTimeMillis() / 1000) + ""); + } + if (pMap.get(OAuth.OAUTH_NONCE) == null) { + addParameter(OAuth.OAUTH_NONCE, System.nanoTime() + ""); + } + if (pMap.get(OAuth.OAUTH_VERSION) == null) { + addParameter(OAuth.OAUTH_VERSION, OAuth.VERSION_1_0); + } + this.sign(accessor); + } + + /** + * Add a signature to the message. + * + * @throws URISyntaxException + */ + public void sign(OAuthAccessor accessor) throws IOException, + OAuthException, URISyntaxException { + OAuthSignatureMethod.newSigner(this, accessor).sign(this); + } + + /** + * Construct an HTTP request from this OAuth message. + * + * @param style + * where to put the OAuth parameters, within the HTTP request + * @deprecated use HttpMessage.newRequest + */ + public HttpMessage toHttpRequest(OAuthClient.ParameterStyle style) throws IOException { + return HttpMessage.newRequest(this, style.getReplacement()); + } + + /** + * Check that the message is valid. + * + * @throws IOException + * @throws URISyntaxException + * + * @throws OAuthProblemException + * the message is invalid + */ + public void validateMessage(OAuthAccessor accessor, OAuthValidator validator) + throws OAuthException, IOException, URISyntaxException { + validator.validateMessage(this, accessor); + } + + /** + * Construct a WWW-Authenticate or Authentication header value, containing + * the given realm plus all the parameters whose names begin with "oauth_". + */ + public String getAuthorizationHeader(String realm) throws IOException { + StringBuilder into = new StringBuilder(); + if (realm != null) { + into.append(" realm=\"").append(OAuth.percentEncode(realm)).append('"'); + } + beforeGetParameter(); + if (parameters != null) { + for (Map.Entry parameter : parameters) { + String name = toString(parameter.getKey()); + if (name.startsWith("oauth_")) { + if (into.length() > 0) into.append(","); + into.append(" "); + into.append(OAuth.percentEncode(name)).append("=\""); + into.append(OAuth.percentEncode(toString(parameter.getValue()))).append('"'); + } + } + } + return AUTH_SCHEME + into.toString(); + } + + /** + * Read all the data from the given stream, and close it. + * + * @return null if from is null, or the data from the stream converted to a + * String + */ + public static String readAll(InputStream from, String encoding) throws IOException + { + if (from == null) { + return null; + } + try { + StringBuilder into = new StringBuilder(); + Reader r = new InputStreamReader(from, encoding); + char[] s = new char[512]; + for (int n; 0 < (n = r.read(s));) { + into.append(s, 0, n); + } + return into.toString(); + } finally { + from.close(); + } + } + + /** + * Parse the parameters from an OAuth Authorization or WWW-Authenticate + * header. The realm is included as a parameter. If the given header doesn't + * start with "OAuth ", return an empty list. + */ + public static List decodeAuthorization(String authorization) { + List into = new ArrayList(); + if (authorization != null) { + Matcher m = AUTHORIZATION.matcher(authorization); + if (m.matches()) { + if (AUTH_SCHEME.equalsIgnoreCase(m.group(1))) { + for (String nvp : m.group(2).split("\\s*,\\s*")) { + m = NVP.matcher(nvp); + if (m.matches()) { + String name = OAuth.decodePercent(m.group(1)); + String value = OAuth.decodePercent(m.group(2)); + into.add(new OAuth.Parameter(name, value)); + } + } + } + } + } + return into; + } + + public static final String AUTH_SCHEME = "OAuth"; + + public static final String GET = "GET"; + public static final String POST = "POST"; + public static final String PUT = "PUT"; + public static final String DELETE = "DELETE"; + + private static final Pattern AUTHORIZATION = Pattern.compile("\\s*(\\w*)\\s+(.*)"); + private static final Pattern NVP = Pattern.compile("(\\S*)\\s*\\=\\s*\"([^\"]*)\""); + + private static final String toString(Object from) { + return (from == null) ? null : from.toString(); + } + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthProblemException.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthProblemException.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthProblemException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,105 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.util.HashMap; +import java.util.Map; + +import net.oauth.http.HttpMessage; + +/** + * Describes an OAuth-related problem, using a set of named parameters. One + * parameter identifies the basic problem, and the others provide supplementary + * diagnostic information. This can be used to capture information from a + * response that conforms to the OAuth Problem Reporting + * extension. + * + * @author John Kristian + */ +public class OAuthProblemException extends OAuthException { + + public static final String OAUTH_PROBLEM = "oauth_problem"; + + public OAuthProblemException() { + } + + public OAuthProblemException(String problem) { + super(problem); + if (problem != null) { + parameters.put(OAUTH_PROBLEM, problem); + } + } + + private final Map parameters = new HashMap(); + + @Override + public String getMessage() { + String msg = super.getMessage(); + if (msg != null) + return msg; + msg = getProblem(); + if (msg != null) + return msg; + Object response = getParameters().get(HttpMessage.RESPONSE); + if (response != null) { + msg = response.toString(); + int eol = msg.indexOf("\n"); + if (eol < 0) { + eol = msg.indexOf("\r"); + } + if (eol >= 0) { + msg = msg.substring(0, eol); + } + msg = msg.trim(); + if (msg.length() > 0) { + return msg; + } + } + response = getHttpStatusCode(); + if (response != null) { + return HttpMessage.STATUS_CODE + " " + response; + } + return null; + } + + public void setParameter(String name, Object value) { + getParameters().put(name, value); + } + + public Map getParameters() { + return parameters; + } + + public String getProblem() { + return (String) getParameters().get(OAUTH_PROBLEM); + } + + public int getHttpStatusCode() { + Object code = getParameters().get(HttpMessage.STATUS_CODE); + if (code == null) { + return 200; + } else if (code instanceof Number) { // the usual case + return ((Number) code).intValue(); + } else { + return Integer.parseInt(code.toString()); + } + } + + private static final long serialVersionUID = 1L; + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthServiceProvider.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthServiceProvider.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthServiceProvider.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,41 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth; + +import java.io.Serializable; + +/** + * Properties of an OAuth Service Provider. + * + * @author John Kristian + */ +public class OAuthServiceProvider implements Serializable { + + private static final long serialVersionUID = 3306534392621038574L; + + public final String requestTokenURL; + public final String userAuthorizationURL; + public final String accessTokenURL; + + public OAuthServiceProvider(String requestTokenURL, + String userAuthorizationURL, String accessTokenURL) { + this.requestTokenURL = requestTokenURL; + this.userAuthorizationURL = userAuthorizationURL; + this.accessTokenURL = accessTokenURL; + } + +} Index: lams_tool_imscc/src/java/net/oauth/OAuthValidator.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/OAuthValidator.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/OAuthValidator.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,42 @@ +/* + * Copyright 2008 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.oauth; + +import java.io.IOException; +import java.net.URISyntaxException; + +/** + * An algorithm to determine whether a message has a valid signature, a correct + * version number, a fresh timestamp, etc. + * + * @author Dirk Balfanz + * @author John Kristian + */ +public interface OAuthValidator { + + /** + * Check that the given message from the given accessor is valid. + * @throws OAuthException TODO + * @throws IOException TODO + * @throws URISyntaxException + * @throws OAuthProblemException the message is invalid. + * The implementation should throw exceptions that conform to the OAuth + * Problem Reporting extension. + */ + public void validateMessage(OAuthMessage message, OAuthAccessor accessor) + throws OAuthException, IOException, URISyntaxException; + +} Index: lams_tool_imscc/src/java/net/oauth/ParameterStyle.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/ParameterStyle.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/ParameterStyle.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,24 @@ +package net.oauth; + +/** + * Where to place OAuth parameters in an HTTP message. The alternatives are + * summarized in OAuth Core section 5.2. + */ +public enum ParameterStyle { + /** + * Send parameters whose names begin with "oauth_" in an HTTP header, and + * other parameters (whose names don't begin with "oauth_") in either the + * message body or URL query string. The header formats are specified by + * OAuth Core section 5.4. + */ + AUTHORIZATION_HEADER, + + /** + * Send all parameters in the message body, with a Content-Type of + * application/x-www-form-urlencoded. + */ + BODY, + + /** Send all parameters in the query string part of the URL. */ + QUERY_STRING; +} Index: lams_tool_imscc/src/java/net/oauth/SimpleOAuthValidator.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/SimpleOAuthValidator.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/SimpleOAuthValidator.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,170 @@ +/* + * Copyright 2008 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.oauth; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import net.oauth.signature.OAuthSignatureMethod; + +/** + * A simple OAuthValidator, which checks the version, whether the timestamp + * is close to now and the signature is valid. Each check may be overridden. + * + * @author Dirk Balfanz + * @author John Kristian + */ +public class SimpleOAuthValidator implements OAuthValidator { + + /** The default window for timestamps is 5 minutes. */ + public static final long DEFAULT_TIMESTAMP_WINDOW = 5 * 60 * 1000L; + + /** + * Names of parameters that may not appear twice in a valid message. + * This limitation is specified by OAuth Core section 5. + */ + public static final Set SINGLE_PARAMETERS = constructSingleParameters(); + + private static Set constructSingleParameters() { + Set s = new HashSet(); + for (String p : new String[] { OAuth.OAUTH_CONSUMER_KEY, OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET, + OAuth.OAUTH_CALLBACK, OAuth.OAUTH_SIGNATURE_METHOD, OAuth.OAUTH_SIGNATURE, OAuth.OAUTH_TIMESTAMP, + OAuth.OAUTH_NONCE, OAuth.OAUTH_VERSION }) { + s.add(p); + } + return Collections.unmodifiableSet(s); + } + + /** + * Construct a validator that rejects messages more than five minutes out + * of date, or with a OAuth version other than 1.0, or with an invalid + * signature. + */ + public SimpleOAuthValidator() { + this(DEFAULT_TIMESTAMP_WINDOW, Double.parseDouble(OAuth.VERSION_1_0)); + } + + /** + * Public constructor. + * + * @param timestampWindowSec + * specifies, in seconds, the windows (into the past and + * into the future) in which we'll accept timestamps. + * @param maxVersion + * the maximum acceptable oauth_version + */ + public SimpleOAuthValidator(long timestampWindowMsec, double maxVersion) { + this.timestampWindow = timestampWindowMsec; + this.maxVersion = maxVersion; + } + + protected final double minVersion = 1.0; + protected final double maxVersion; + protected final long timestampWindow; + + /** {@inherit} + * @throws URISyntaxException */ + public void validateMessage(OAuthMessage message, OAuthAccessor accessor) + throws OAuthException, IOException, URISyntaxException { + checkSingleParameters(message); + validateVersion(message); + validateTimestampAndNonce(message); + validateSignature(message, accessor); + } + + /** Throw an exception if any SINGLE_PARAMETERS occur repeatedly. */ + protected void checkSingleParameters(OAuthMessage message) throws IOException, OAuthException { + // Check for repeated oauth_ parameters: + boolean repeated = false; + Map> nameToValues = new HashMap>(); + for (Map.Entry parameter : message.getParameters()) { + String name = parameter.getKey(); + if (SINGLE_PARAMETERS.contains(name)) { + Collection values = nameToValues.get(name); + if (values == null) { + values = new ArrayList(); + nameToValues.put(name, values); + } else { + repeated = true; + } + values.add(parameter.getValue()); + } + } + if (repeated) { + Collection rejected = new ArrayList(); + for (Map.Entry> p : nameToValues.entrySet()) { + String name = p.getKey(); + Collection values = p.getValue(); + if (values.size() > 1) { + for (String value : values) { + rejected.add(new OAuth.Parameter(name, value)); + } + } + } + OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.PARAMETER_REJECTED); + problem.setParameter(OAuth.Problems.OAUTH_PARAMETERS_REJECTED, OAuth.formEncode(rejected)); + throw problem; + } + } + + protected void validateVersion(OAuthMessage message) + throws OAuthException, IOException { + String versionString = message.getParameter(OAuth.OAUTH_VERSION); + if (versionString != null) { + double version = Double.parseDouble(versionString); + if (version < minVersion || maxVersion < version) { + OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.VERSION_REJECTED); + problem.setParameter(OAuth.Problems.OAUTH_ACCEPTABLE_VERSIONS, minVersion + "-" + maxVersion); + throw problem; + } + } + } + + /** This implementation doesn't check the nonce value. */ + protected void validateTimestampAndNonce(OAuthMessage message) + throws IOException, OAuthProblemException { + message.requireParameters(OAuth.OAUTH_TIMESTAMP, OAuth.OAUTH_NONCE); + long timestamp = Long.parseLong(message.getParameter(OAuth.OAUTH_TIMESTAMP)) * 1000L; + long now = currentTimeMsec(); + long min = now - timestampWindow; + long max = now + timestampWindow; + if (timestamp < min || max < timestamp) { + OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.TIMESTAMP_REFUSED); + problem.setParameter(OAuth.Problems.OAUTH_ACCEPTABLE_TIMESTAMPS, min + "-" + max); + throw problem; + } + } + + protected void validateSignature(OAuthMessage message, OAuthAccessor accessor) + throws OAuthException, IOException, URISyntaxException { + message.requireParameters(OAuth.OAUTH_CONSUMER_KEY, + OAuth.OAUTH_SIGNATURE_METHOD, OAuth.OAUTH_SIGNATURE); + OAuthSignatureMethod.newSigner(message, accessor).validate(message); + } + + protected long currentTimeMsec() { + return System.currentTimeMillis(); + } + +} Index: lams_tool_imscc/src/java/net/oauth/client/ExcerptInputStream.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/client/ExcerptInputStream.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/client/ExcerptInputStream.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,42 @@ +package net.oauth.client; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** A decorator that retains a copy of the first few bytes of data. */ +public class ExcerptInputStream extends BufferedInputStream +{ + /** + * A marker that's appended to the excerpt if it's less than the complete + * stream. + */ + public static final byte[] ELLIPSIS = " ...".getBytes(); + + public ExcerptInputStream(InputStream in) throws IOException { + super(in); + mark(LIMIT); + int total = 0; + int read; + while ((read = read(excerpt, total, LIMIT - total)) != -1 && ((total += read) < LIMIT)); + if (total == LIMIT) { + // Only add the ellipsis if there are at least LIMIT bytes + System.arraycopy(ELLIPSIS, 0, excerpt, total, ELLIPSIS.length); + } else { + byte[] tmp = new byte[total]; + System.arraycopy(excerpt, 0, tmp, 0, total); + excerpt = tmp; + } + reset(); + } + + private static final int LIMIT = 1024; + private byte[] excerpt = new byte[LIMIT + ELLIPSIS.length]; + + /** The first few bytes of data, plus ELLIPSIS if there are more bytes. */ + public byte[] getExcerpt() + { + return excerpt; + } + +} Index: lams_tool_imscc/src/java/net/oauth/client/OAuthClient.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/client/OAuthClient.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/client/OAuthClient.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,333 @@ +/* + * Copyright 2007, 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.client; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.http.HttpClient; +import net.oauth.http.HttpMessage; +import net.oauth.http.HttpMessageDecoder; +import net.oauth.http.HttpResponseMessage; + +/** + * Methods for an OAuth consumer to request tokens from a service provider. + *

+ * This class can also be used to request access to protected resources, in some + * cases. But not in all cases. For example, this class can't handle arbitrary + * HTTP headers. + *

+ * Methods of this class return a response as an OAuthMessage, from which you + * can get a body or parameters but not both. Calling a getParameter method will + * read and close the body (like readBodyAsString), so you can't read it later. + * If you read or close the body first, then getParameter can't read it. The + * response headers should tell you whether the response contains encoded + * parameters, that is whether you should call getParameter or not. + *

+ * Methods of this class don't follow redirects. When they receive a redirect + * response, they throw an OAuthProblemException, with properties + * HttpResponseMessage.STATUS_CODE = the redirect code + * HttpResponseMessage.LOCATION = the redirect URL. Such a redirect can't be + * handled at the HTTP level, if the second request must carry another OAuth + * signature (with different parameters). For example, Google's Service Provider + * routinely redirects requests for access to protected resources, and requires + * the redirected request to be signed. + * + * @author John Kristian + */ +public class OAuthClient { + + public OAuthClient(HttpClient http) + { + this.http = http; + httpParameters.put(HttpClient.FOLLOW_REDIRECTS, Boolean.FALSE); + } + + private HttpClient http; + protected final Map httpParameters = new HashMap(); + + public void setHttpClient(HttpClient http) { + this.http = http; + } + + public HttpClient getHttpClient() { + return http; + } + + /** + * HTTP client parameters, as a map from parameter name to value. + * + * @see HttpClient for parameter names. + */ + public Map getHttpParameters() { + return httpParameters; + } + + /** + * Get a fresh request token from the service provider. + * + * @param accessor + * should contain a consumer that contains a non-null consumerKey + * and consumerSecret. Also, + * accessor.consumer.serviceProvider.requestTokenURL should be + * the URL (determined by the service provider) for getting a + * request token. + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public void getRequestToken(OAuthAccessor accessor) throws IOException, + OAuthException, URISyntaxException { + getRequestToken(accessor, null); + } + + /** + * Get a fresh request token from the service provider. + * + * @param accessor + * should contain a consumer that contains a non-null consumerKey + * and consumerSecret. Also, + * accessor.consumer.serviceProvider.requestTokenURL should be + * the URL (determined by the service provider) for getting a + * request token. + * @param httpMethod + * typically OAuthMessage.POST or OAuthMessage.GET, or null to + * use the default method. + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public void getRequestToken(OAuthAccessor accessor, String httpMethod) + throws IOException, OAuthException, URISyntaxException { + getRequestToken(accessor, httpMethod, null); + } + + /** Get a fresh request token from the service provider. + * + * @param accessor + * should contain a consumer that contains a non-null consumerKey + * and consumerSecret. Also, + * accessor.consumer.serviceProvider.requestTokenURL should be + * the URL (determined by the service provider) for getting a + * request token. + * @param httpMethod + * typically OAuthMessage.POST or OAuthMessage.GET, or null to + * use the default method. + * @param parameters + * additional parameters for this request, or null to indicate + * that there are no additional parameters. + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public void getRequestToken(OAuthAccessor accessor, String httpMethod, + Collection parameters) throws IOException, + OAuthException, URISyntaxException { + accessor.accessToken = null; + accessor.tokenSecret = null; + { + // This code supports the 'Variable Accessor Secret' extension + // described in http://oauth.pbwiki.com/AccessorSecret + Object accessorSecret = accessor + .getProperty(OAuthConsumer.ACCESSOR_SECRET); + if (accessorSecret != null) { + List p = (parameters == null) ? new ArrayList( + 1) + : new ArrayList(parameters); + p.add(new OAuth.Parameter("oauth_accessor_secret", + accessorSecret.toString())); + parameters = p; + // But don't modify the caller's parameters. + } + } + OAuthMessage response = invoke(accessor, httpMethod, + accessor.consumer.serviceProvider.requestTokenURL, parameters); + accessor.requestToken = response.getParameter(OAuth.OAUTH_TOKEN); + accessor.tokenSecret = response.getParameter(OAuth.OAUTH_TOKEN_SECRET); + response.requireParameters(OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET); + } + + /** + * Get an access token from the service provider, in exchange for an + * authorized request token. + * + * @param accessor + * should contain a non-null requestToken and tokenSecret, and a + * consumer that contains a consumerKey and consumerSecret. Also, + * accessor.consumer.serviceProvider.accessTokenURL should be the + * URL (determined by the service provider) for getting an access + * token. + * @param httpMethod + * typically OAuthMessage.POST or OAuthMessage.GET, or null to + * use the default method. + * @param parameters + * additional parameters for this request, or null to indicate + * that there are no additional parameters. + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public OAuthMessage getAccessToken(OAuthAccessor accessor, String httpMethod, + Collection parameters) throws IOException, OAuthException, URISyntaxException { + if (accessor.requestToken != null) { + if (parameters == null) { + parameters = OAuth.newList(OAuth.OAUTH_TOKEN, accessor.requestToken); + } else if (!OAuth.newMap(parameters).containsKey(OAuth.OAUTH_TOKEN)) { + List p = new ArrayList(parameters); + p.add(new OAuth.Parameter(OAuth.OAUTH_TOKEN, accessor.requestToken)); + parameters = p; + } + } + OAuthMessage response = invoke(accessor, httpMethod, + accessor.consumer.serviceProvider.accessTokenURL, parameters); + response.requireParameters(OAuth.OAUTH_TOKEN, OAuth.OAUTH_TOKEN_SECRET); + accessor.accessToken = response.getParameter(OAuth.OAUTH_TOKEN); + accessor.tokenSecret = response.getParameter(OAuth.OAUTH_TOKEN_SECRET); + return response; + } + + /** + * Construct a request message, send it to the service provider and get the + * response. + * + * @param httpMethod + * the HTTP request method, or null to use the default method + * @return the response + * @throws URISyntaxException + * the given url isn't valid syntactically + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public OAuthMessage invoke(OAuthAccessor accessor, String httpMethod, + String url, Collection parameters) + throws IOException, OAuthException, URISyntaxException { + OAuthMessage request = accessor.newRequestMessage(httpMethod, url, parameters); + Object accepted = accessor.consumer.getProperty(OAuthConsumer.ACCEPT_ENCODING); + if (accepted != null) { + request.getHeaders().add(new OAuth.Parameter(HttpMessage.ACCEPT_ENCODING, accepted.toString())); + } + Object ps = accessor.consumer.getProperty(PARAMETER_STYLE); + net.oauth.ParameterStyle style = (ps == null) ? net.oauth.ParameterStyle.BODY + : Enum.valueOf(net.oauth.ParameterStyle.class, ps.toString()); + return invoke(request, style); + } + + /** + * The name of the OAuthConsumer property whose value is the ParameterStyle + * to be used by invoke. + */ + public static final String PARAMETER_STYLE = "parameterStyle"; + + /** + * The name of the OAuthConsumer property whose value is the Accept-Encoding + * header in HTTP requests. + * @deprecated use {@link OAuthConsumer#ACCEPT_ENCODING} instead + */ + @Deprecated + public static final String ACCEPT_ENCODING = OAuthConsumer.ACCEPT_ENCODING; + + /** + * Construct a request message, send it to the service provider and get the + * response. + * + * @return the response + * @throws URISyntaxException + * the given url isn't valid syntactically + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public OAuthMessage invoke(OAuthAccessor accessor, String url, + Collection parameters) throws IOException, + OAuthException, URISyntaxException { + return invoke(accessor, null, url, parameters); + } + + /** + * Send a request message to the service provider and get the response. + * + * @return the response + * @throws IOException + * failed to communicate with the service provider + * @throws OAuthProblemException + * the HTTP response status code was not 200 (OK) + */ + public OAuthMessage invoke(OAuthMessage request, net.oauth.ParameterStyle style) + throws IOException, OAuthException { + OAuthResponseMessage response = access(request, style); + if ((response.getHttpResponse().getStatusCode() / 100) != 2) { + throw response.toOAuthProblemException(); + } + return response; + } + + /** + * Send a request and return the response. Don't try to decide whether the + * response indicates success; merely return it. + */ + public OAuthResponseMessage access(OAuthMessage request, net.oauth.ParameterStyle style) throws IOException { + HttpMessage httpRequest = HttpMessage.newRequest(request, style); + HttpResponseMessage httpResponse = http.execute(httpRequest, httpParameters); + httpResponse = HttpMessageDecoder.decode(httpResponse); + return new OAuthResponseMessage(httpResponse); + } + + /** + * Where to place parameters in an HTTP message. + * + * @deprecated use net.oauth.ParameterStyle. + */ + public static enum ParameterStyle { + AUTHORIZATION_HEADER(net.oauth.ParameterStyle.AUTHORIZATION_HEADER), + BODY (net.oauth.ParameterStyle.BODY), + QUERY_STRING (net.oauth.ParameterStyle.QUERY_STRING); + + public net.oauth.ParameterStyle getReplacement() { + return replacement; + } + + private ParameterStyle(net.oauth.ParameterStyle replacement) { + this.replacement = replacement; + } + + private final net.oauth.ParameterStyle replacement; + } + + /** @deprecated */ + public OAuthMessage invoke(OAuthMessage request, ParameterStyle style) + throws IOException, OAuthException { + return invoke(request, style.getReplacement()); + } + + /** @deprecated */ + public OAuthResponseMessage access(OAuthMessage request, ParameterStyle style) + throws IOException { + return access(request, style.getReplacement()); + } + + protected static final String PUT = OAuthMessage.PUT; + protected static final String POST = OAuthMessage.POST; + protected static final String DELETE = OAuthMessage.DELETE; + protected static final String CONTENT_LENGTH = HttpMessage.CONTENT_LENGTH; + +} Index: lams_tool_imscc/src/java/net/oauth/client/OAuthResponseMessage.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/client/OAuthResponseMessage.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/client/OAuthResponseMessage.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,117 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.client; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import net.oauth.OAuth; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.http.HttpResponseMessage; + +/** + * An HTTP response, encapsulated as an OAuthMessage. + * + * @author John Kristian + */ +public class OAuthResponseMessage extends OAuthMessage +{ + OAuthResponseMessage(HttpResponseMessage http) throws IOException + { + super(http.method, http.url.toExternalForm(), null); + this.http = http; + getHeaders().addAll(http.headers); + for (Map.Entry header : http.headers) { + if ("WWW-Authenticate".equalsIgnoreCase(header.getKey())) { + for (OAuth.Parameter parameter : decodeAuthorization(header.getValue())) { + if (!"realm".equalsIgnoreCase(parameter.getKey())) { + addParameter(parameter); + } + } + } + } + } + + private final HttpResponseMessage http; + + public HttpResponseMessage getHttpResponse() { + return http; + } + + @Override + public InputStream getBodyAsStream() throws IOException + { + return http.getBody(); + } + + @Override + public String getBodyEncoding() + { + return http.getContentCharset(); + } + + @Override + public void requireParameters(String... names) throws OAuthProblemException, IOException { + try { + super.requireParameters(names); + } catch (OAuthProblemException problem) { + problem.getParameters().putAll(getDump()); + throw problem; + } + } + + /** + * Encapsulate this message as an exception. Read and close the body of this + * message. + */ + public OAuthProblemException toOAuthProblemException() throws IOException { + OAuthProblemException problem = new OAuthProblemException(); + try { + getParameters(); // decode the response body + } catch (IOException ignored) { + } + problem.getParameters().putAll(getDump()); + try { + InputStream b = getBodyAsStream(); + if (b != null) { + b.close(); // release resources + } + } catch (IOException ignored) { + } + return problem; + } + + @Override + protected void completeParameters() throws IOException + { + super.completeParameters(); + String body = readBodyAsString(); + if (body != null) { + addParameters(OAuth.decodeForm(body.trim())); + } + } + + @Override + protected void dump(Map into) throws IOException + { + super.dump(into); + http.dump(into); + } + +} Index: lams_tool_imscc/src/java/net/oauth/consumer.properties.sample =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/consumer.properties.sample (revision 0) +++ lams_tool_imscc/src/java/net/oauth/consumer.properties.sample (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,16 @@ +# NamedConsumerPool can gets consumer configuration parameters from a file like this. + +ma.gnolia.consumerKey: - Your key here - +ma.gnolia.consumerSecret: - Your secret here - +ma.gnolia.serviceProvider.requestTokenURL: http://ma.gnolia.com/oauth/get_request_token +ma.gnolia.serviceProvider.userAuthorizationURL: http://ma.gnolia.com/oauth/authorize +ma.gnolia.serviceProvider.accessTokenURL: http://ma.gnolia.com/oauth/get_access_token + +twitter.consumerKey: - Your key here - +twitter.consumerSecret: - Your secret here - +twitter.callbackURL: - Your URL here - +twitter.consumer.oauth_signature_method: PLAINTEXT +# There can be more consumer properties. +twitter.serviceProvider.requestTokenURL: http://twitter.com/oauth/request_token +twitter.serviceProvider.userAuthorizationURL: http://twitter.com/oauth/authorize +twitter.serviceProvider.accessTokenURL: http://twitter.com/oauth/access_token Index: lams_tool_imscc/src/java/net/oauth/http/HttpClient.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/http/HttpClient.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/http/HttpClient.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.http; + +import java.io.IOException; +import java.util.Map; + +import net.oauth.OAuthMessage; + +// TODO: move this class into oauth-core-consumer, together with HttpMessage. +// The sticky part is deleting the method OAuthMessage.toHttpRequest. +public interface HttpClient { + + /** + * Send an HTTP request and return the response. + * + * @param httpParameters + * HTTP client parameters, as a map from parameter name to value. + * Parameter names are defined as constants below. + */ + HttpResponseMessage execute(HttpMessage request, Map httpParameters) throws IOException; + + /** + * The name of the parameter that is the maximum time to wait to connect to + * the server. (Integer msec) + */ + static final String CONNECT_TIMEOUT = "connectTimeout"; + + /** + * The name of the parameter that is the maximum time to wait for response + * data. (Integer msec) + */ + static final String READ_TIMEOUT = "readTimeout"; + + /** The name of the parameter to automatically follow redirects. (Boolean) */ + static final String FOLLOW_REDIRECTS = "followRedirects"; + + static final String GET = OAuthMessage.GET; + static final String POST = OAuthMessage.POST; + static final String PUT = OAuthMessage.PUT; + static final String DELETE = OAuthMessage.DELETE; + +} Index: lams_tool_imscc/src/java/net/oauth/http/HttpMessage.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/http/HttpMessage.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/http/HttpMessage.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,223 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.http; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.oauth.OAuth; +import net.oauth.OAuthMessage; +import net.oauth.ParameterStyle; +import net.oauth.client.ExcerptInputStream; + +// TODO: move this class into oauth-core-consumer, together with ExcerptInputStream. +// The sticky part is deleting the method OAuthMessage.toHttpRequest. +/** + * An HTTP request or response. + * + * @author John Kristian + */ +public class HttpMessage +{ + + public HttpMessage() + { + this(null, null); + } + + public HttpMessage(String method, URL url) + { + this(method, url, null); + } + + public HttpMessage(String method, URL url, InputStream body) + { + this.method = method; + this.url = url; + this.body = body; + } + + public String method; + public URL url; + public final List> headers = new ArrayList>(); + protected InputStream body = null; + + /** + * Get the value of the last header of the given name. The name is + * case-insensitive. + */ + public final String getHeader(String name) + { + String value = null; + for (Map.Entry header : headers) { + if (equalsIgnoreCase(name, header.getKey())) { + value = header.getValue(); + } + } + return value; + } + + /** + * Remove all headers of the given name. The name is case insensitive. + * + * @return the value of the last header with that name, or null to indicate + * there was no such header + */ + public String removeHeaders(String name) + { + String value = null; + for (Iterator> i = headers.iterator(); i.hasNext();) { + Map.Entry header = i.next(); + if (equalsIgnoreCase(name, header.getKey())) { + value = header.getValue(); + i.remove(); + } + } + return value; + } + + public final String getContentCharset() + { + return getCharset(getHeader(CONTENT_TYPE)); + } + + public final InputStream getBody() throws IOException + { + if (body == null) { + InputStream raw = openBody(); + if (raw != null) { + body = new ExcerptInputStream(raw); + } + } + return body; + } + + protected InputStream openBody() throws IOException + { + return null; + } + + /** Put a description of this message and its origins into the given Map. */ + public void dump(Map into) throws IOException + { + } + + /** + * Construct an HTTP request from this OAuth message. + * + * @param style + * where to put the OAuth parameters, within the HTTP request + */ + public static HttpMessage newRequest(OAuthMessage from, ParameterStyle style) throws IOException { + final boolean isPost = OAuthMessage.POST.equalsIgnoreCase(from.method); + InputStream body = from.getBodyAsStream(); + if (style == ParameterStyle.BODY && !(isPost && body == null)) { + style = ParameterStyle.QUERY_STRING; + } + String url = from.URL; + final List> headers = new ArrayList>(from.getHeaders()); + switch (style) { + case QUERY_STRING: + url = OAuth.addParameters(url, from.getParameters()); + break; + case BODY: { + byte[] form = OAuth.formEncode(from.getParameters()).getBytes(from.getBodyEncoding()); + headers.add(new OAuth.Parameter(CONTENT_TYPE, OAuth.FORM_ENCODED)); + headers.add(new OAuth.Parameter(CONTENT_LENGTH, form.length + "")); + body = new ByteArrayInputStream(form); + break; + } + case AUTHORIZATION_HEADER: + headers.add(new OAuth.Parameter("Authorization", from.getAuthorizationHeader(null))); + // Find the non-OAuth parameters: + List> others = from.getParameters(); + if (others != null && !others.isEmpty()) { + others = new ArrayList>(others); + for (Iterator> p = others.iterator(); p.hasNext();) { + if (p.next().getKey().startsWith("oauth_")) { + p.remove(); + } + } + // Place the non-OAuth parameters elsewhere in the request: + if (isPost && body == null) { + byte[] form = OAuth.formEncode(others).getBytes(from.getBodyEncoding()); + headers.add(new OAuth.Parameter(CONTENT_TYPE, OAuth.FORM_ENCODED)); + headers.add(new OAuth.Parameter(CONTENT_LENGTH, form.length + "")); + body = new ByteArrayInputStream(form); + } else { + url = OAuth.addParameters(url, others); + } + } + break; + } + HttpMessage httpRequest = new HttpMessage(from.method, new URL(url), body); + httpRequest.headers.addAll(headers); + return httpRequest; + } + + private static boolean equalsIgnoreCase(String x, String y) + { + if (x == null) + return y == null; + else + return x.equalsIgnoreCase(y); + } + + private static final String getCharset(String mimeType) + { + if (mimeType != null) { + Matcher m = CHARSET.matcher(mimeType); + if (m.find()) { + String charset = m.group(1); + if (charset.length() >= 2 && charset.charAt(0) == '"' + && charset.charAt(charset.length() - 1) == '"') { + charset = charset.substring(1, charset.length() - 1); + charset = charset.replace("\\\"", "\""); + } + return charset; + } + } + return DEFAULT_CHARSET; + } + + /** The name of a dump entry whose value is the HTTP request. */ + public static final String REQUEST = "HTTP request"; + + /** The name of a dump entry whose value is the HTTP response. */ + public static final String RESPONSE = "HTTP response"; + + /** The name of a dump entry whose value is the HTTP status code. */ + public static final String STATUS_CODE = "HTTP status"; + + public static final String ACCEPT_ENCODING = "Accept-Encoding"; + public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final String CONTENT_LENGTH = "Content-Length"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + + private static final Pattern CHARSET = Pattern + .compile("; *charset *= *([^;\"]*|\"([^\"]|\\\\\")*\")(;|$)"); + +} Index: lams_tool_imscc/src/java/net/oauth/http/HttpMessageDecoder.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/http/HttpMessageDecoder.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/http/HttpMessageDecoder.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.http; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +// TODO: move this class into oauth-core-consumer, together with HttpMessage. +// The sticky part is deleting the method OAuthMessage.toHttpRequest. +/** A decorator that handles Content-Encoding. */ +public class HttpMessageDecoder extends HttpResponseMessage { + + /** + * Decode the given message if necessary and possible. + * + * @return a decorator that decodes the body of the given message; or the + * given message if this class can't decode it. + */ + public static HttpResponseMessage decode(HttpResponseMessage message) + throws IOException { + if (message != null) { + String encoding = getEncoding(message); + if (encoding != null) { + return new HttpMessageDecoder(message, encoding); + } + } + return message; + } + + public static final String GZIP = "gzip"; + public static final String DEFLATE = "deflate"; + public static final String ACCEPTED = GZIP + "," + DEFLATE; + + private static String getEncoding(HttpMessage message) { + String encoding = message.getHeader(CONTENT_ENCODING); + if (encoding == null) { + // That's easy. + } else if (GZIP.equalsIgnoreCase(encoding) + || ("x-" + GZIP).equalsIgnoreCase(encoding)) { + return GZIP; + } else if (DEFLATE.equalsIgnoreCase(encoding)) { + return DEFLATE; + } + return null; + } + + private HttpMessageDecoder(HttpResponseMessage in, String encoding) + throws IOException { + super(in.method, in.url); + this.headers.addAll(in.headers); + removeHeaders(CONTENT_ENCODING); // handled here + removeHeaders(CONTENT_LENGTH); // unpredictable + InputStream body = in.getBody(); + if (body != null) { + if (encoding == GZIP) { + body = new GZIPInputStream(body); + } else if (encoding == DEFLATE) { + body = new InflaterInputStream(body); + } else { + assert false; + } + } + this.body = body; + this.in = in; + } + + private final HttpResponseMessage in; + + @Override + public void dump(Map into) throws IOException { + in.dump(into); + } + + @Override + public int getStatusCode() throws IOException { + return in.getStatusCode(); + } + +} Index: lams_tool_imscc/src/java/net/oauth/http/HttpResponseMessage.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/http/HttpResponseMessage.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/http/HttpResponseMessage.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,60 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.http; + +import java.io.IOException; +import java.net.URL; +import java.util.Map; + +// TODO: move this class into oauth-core-consumer, together with HttpMessage. +// The sticky part is deleting the method OAuthMessage.toHttpRequest. +/** + * An HTTP response. + * + * @author John Kristian + */ +public abstract class HttpResponseMessage extends HttpMessage { + + protected HttpResponseMessage(String method, URL url) { + super(method, url); + } + + @Override + public void dump(Map into) throws IOException { + super.dump(into); + into.put(STATUS_CODE, Integer.valueOf(getStatusCode())); + String location = getHeader(LOCATION); + if (location != null) { + into.put(LOCATION, location); + } + } + + public abstract int getStatusCode() throws IOException; + + /** The name of a dump entry whose value is the response Location header. */ + public static final String LOCATION = "Location"; + + /** The name of a dump entry whose value is the HTTP status code. */ + public static final String STATUS_CODE = "HTTP status"; + + /** The statusCode that indicates a normal outcome. */ + public static final int STATUS_OK = 200; + + /** The standard end-of-line marker in an HTTP message. */ + public static final String EOL = "\r\n"; + +} Index: lams_tool_imscc/src/java/net/oauth/server/HttpRequestMessage.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/server/HttpRequestMessage.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/server/HttpRequestMessage.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.server; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import net.oauth.OAuth; +import net.oauth.OAuthMessage; + +/** + * An HttpServletRequest, encapsulated as an OAuthMessage. + * + * @author John Kristian + */ +public class HttpRequestMessage extends OAuthMessage { + + public HttpRequestMessage(HttpServletRequest request, String URL) { + super(request.getMethod(), URL, getParameters(request)); + this.request = request; + copyHeaders(request, getHeaders()); + } + + private final HttpServletRequest request; + + @Override + public InputStream getBodyAsStream() throws IOException { + return request.getInputStream(); + } + + @Override + public String getBodyEncoding() { + return request.getCharacterEncoding(); + } + + private static void copyHeaders(HttpServletRequest request, Collection> into) { + Enumeration names = request.getHeaderNames(); + if (names != null) { + while (names.hasMoreElements()) { + String name = names.nextElement(); + Enumeration values = request.getHeaders(name); + if (values != null) { + while (values.hasMoreElements()) { + into.add(new OAuth.Parameter(name, values.nextElement())); + } + } + } + } + } + + public static List getParameters(HttpServletRequest request) { + List list = new ArrayList(); + for (Enumeration headers = request.getHeaders("Authorization"); headers != null + && headers.hasMoreElements();) { + String header = headers.nextElement(); + for (OAuth.Parameter parameter : OAuthMessage + .decodeAuthorization(header)) { + if (!"realm".equalsIgnoreCase(parameter.getKey())) { + list.add(parameter); + } + } + } + for (Object e : request.getParameterMap().entrySet()) { + Map.Entry entry = (Map.Entry) e; + String name = entry.getKey(); + for (String value : entry.getValue()) { + list.add(new OAuth.Parameter(name, value)); + } + } + return list; + } + +} Index: lams_tool_imscc/src/java/net/oauth/server/OAuthServlet.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/server/OAuthServlet.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/server/OAuthServlet.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,160 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.server; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.oauth.OAuth; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; +import net.oauth.http.HttpMessage; + +/** + * Utility methods for servlets that implement OAuth. + * + * @author John Kristian + */ +public class OAuthServlet { + + /** + * Extract the parts of the given request that are relevant to OAuth. + * Parameters include OAuth Authorization headers and the usual request + * parameters in the query string and/or form encoded body. The header + * parameters come first, followed by the rest in the order they came from + * request.getParameterMap(). + * + * @param URL + * the official URL of this service; that is the URL a legitimate + * client would use to compute the digital signature. If this + * parameter is null, this method will try to reconstruct the URL + * from the HTTP request; which may be wrong in some cases. + */ + public static OAuthMessage getMessage(HttpServletRequest request, String URL) { + if (URL == null) { + URL = request.getRequestURL().toString(); + } + int q = URL.indexOf('?'); + if (q >= 0) { + URL = URL.substring(0, q); + // The query string parameters will be included in + // the result from getParameters(request). + } + return new HttpRequestMessage(request, URL); + } + + /** Reconstruct the requested URL, complete with query string (if any). */ + public static String getRequestURL(HttpServletRequest request) { + StringBuffer url = request.getRequestURL(); + String queryString = request.getQueryString(); + if (queryString != null) { + url.append("?").append(queryString); + } + return url.toString(); + } + + public static void handleException(HttpServletResponse response, + Exception e, String realm) throws IOException, ServletException { + handleException(response, e, realm, true); + } + + public static void handleException(HttpServletResponse response, + Exception e, String realm, boolean sendBody) throws IOException, + ServletException { + if (e instanceof OAuthProblemException) { + OAuthProblemException problem = (OAuthProblemException) e; + Object httpCode = problem.getParameters().get(HttpMessage.STATUS_CODE); + if (httpCode == null) { + httpCode = PROBLEM_TO_HTTP_CODE.get(problem.getProblem()); + } + if (httpCode == null) { + httpCode = SC_FORBIDDEN; + } + response.reset(); + response.setStatus(Integer.parseInt(httpCode.toString())); + OAuthMessage message = new OAuthMessage(null, null, problem + .getParameters().entrySet()); + response.addHeader("WWW-Authenticate", message + .getAuthorizationHeader(realm)); + if (sendBody) { + sendForm(response, message.getParameters()); + } + } else if (e instanceof IOException) { + throw (IOException) e; + } else if (e instanceof ServletException) { + throw (ServletException) e; + } else if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new ServletException(e); + } + } + + private static final Integer SC_FORBIDDEN = new Integer( + HttpServletResponse.SC_FORBIDDEN); + + private static final Map PROBLEM_TO_HTTP_CODE = OAuth.Problems.TO_HTTP_CODE; + + /** Send the given parameters as a form-encoded response body. */ + public static void sendForm(HttpServletResponse response, + Iterable parameters) throws IOException { + response.resetBuffer(); + response.setContentType(OAuth.FORM_ENCODED + ";charset=" + + OAuth.ENCODING); + OAuth.formEncode(parameters, response.getOutputStream()); + } + + /** + * Return the HTML representation of the given plain text. Characters that + * would have special significance in HTML are replaced by character entity + * references. Whitespace is not converted. + */ + public static String htmlEncode(String s) { + if (s == null) { + return null; + } + StringBuilder html = new StringBuilder(s.length()); + for (char c : s.toCharArray()) { + switch (c) { + case '<': + html.append("<"); + break; + case '>': + html.append(">"); + break; + case '&': + html.append("&"); + // This also takes care of numeric character references; + // for example © becomes &#169. + break; + case '"': + html.append("""); + break; + default: + html.append(c); + break; + } + } + return html.toString(); + } + +} Index: lams_tool_imscc/src/java/net/oauth/signature/Base64.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/Base64.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/Base64.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,714 @@ +/* + * Copyright 2001-2008 The Apache Software Foundation. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.signature; + +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; + +/** + * Provides Base64 encoding and decoding as defined by RFC 2045. + * + *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ * + * @see RFC 2045 + * @author Apache Software Foundation + * @author John Kristian + */ +class Base64 { + /** + * Chunk size per RFC 2045 section 6.8. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 2045 section 6.8 + */ + static final int CHUNK_SIZE = 76; + + /** + * Chunk separator per RFC 2045 section 2.1. + * + * @see RFC 2045 section 2.1 + */ + static final byte[] CHUNK_SEPARATOR = {'\r','\n'}; + + /** + * This array is a lookup table that translates 6-bit positive integer + * index values into their "Base64 Alphabet" equivalents as specified + * in Table 1 of RFC 2045. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] intToBase64 = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * Byte used to pad output. + */ + private static final byte PAD = '='; + + /** + * This array is a lookup table that translates unicode characters + * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) + * into their 6-bit positive integer equivalents. Characters that + * are not in the Base64 alphabet but fall within the bounds of the + * array are translated to -1. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] base64ToInt = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + /** Mask used to extract 6 bits, used when encoding */ + private static final int MASK_6BITS = 0x3f; + + /** Mask used to extract 8 bits, used in decoding base64 bytes */ + private static final int MASK_8BITS = 0xff; + + // The static final fields above are used for the original static byte[] methods on Base64. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + + /** + * Line length for encoding. Not used when decoding. A value of zero or less implies + * no chunking of the base64 encoded data. + */ + private final int lineLength; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Convenience variable to help us determine when our buffer is going to run out of + * room and needs resizing. decodeSize = 3 + lineSeparator.length; + */ + private final int decodeSize; + + /** + * Convenience variable to help us determine when our buffer is going to run out of + * room and needs resizing. encodeSize = 4 + lineSeparator.length; + */ + private final int encodeSize; + + /** + * Buffer for streaming. + */ + private byte[] buf; + + /** + * Position where next character should be written in the buffer. + */ + private int pos; + + /** + * Position where next character should be read from the buffer. + */ + private int readPos; + + /** + * Variable tracks how many characters have been written to the current line. + * Only used when encoding. We use it to make sure each encoded line never + * goes beyond lineLength (if lineLength > 0). + */ + private int currentLinePos; + + /** + * Writes to the buffer only occur after every 3 reads when encoding, an + * every 4 reads when decoding. This variable helps track that. + */ + private int modulus; + + /** + * Boolean flag to indicate the EOF has been reached. Once EOF has been + * reached, this Base64 object becomes useless, and must be thrown away. + */ + private boolean eof; + + /** + * Place holder for the 3 bytes we're dealing with for our base64 logic. + * Bitwise operations store and extract the base64 encoding or decoding from + * this variable. + */ + private int x; + + /** + * Default constructor: lineLength is 76, and the lineSeparator is CRLF + * when encoding, and all forms can be decoded. + */ + public Base64() { + this(CHUNK_SIZE, CHUNK_SEPARATOR); + } + + /** + *

+ * Consumer can use this constructor to choose a different lineLength + * when encoding (lineSeparator is still CRLF). All forms of data can + * be decoded. + *

+ * Note: lineLengths that aren't multiples of 4 will still essentially + * end up being multiples of 4 in the encoded data. + *

+ * + * @param lineLength each line of encoded data will be at most this long + * (rounded up to nearest multiple of 4). + * If lineLength <= 0, then the output will not be divided into lines (chunks). + * Ignored when decoding. + */ + public Base64(int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + *

+ * Consumer can use this constructor to choose a different lineLength + * and lineSeparator when encoding. All forms of data can + * be decoded. + *

+ * Note: lineLengths that aren't multiples of 4 will still essentially + * end up being multiples of 4 in the encoded data. + *

+ * @param lineLength Each line of encoded data will be at most this long + * (rounded up to nearest multiple of 4). Ignored when decoding. + * If <= 0, then output will not be divided into lines (chunks). + * @param lineSeparator Each line of encoded data will end with this + * sequence of bytes. + * If lineLength <= 0, then the lineSeparator is not used. + * @throws IllegalArgumentException The provided lineSeparator included + * some base64 characters. That's not going to work! + */ + public Base64(int lineLength, byte[] lineSeparator) { + this.lineLength = lineLength; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + if (lineLength > 0) { + this.encodeSize = 4 + lineSeparator.length; + } else { + this.encodeSize = 4; + } + this.decodeSize = encodeSize - 1; + if (containsBase64Byte(lineSeparator)) { + String sep; + try { + sep = new String(lineSeparator, "UTF-8"); + } catch (UnsupportedEncodingException uee) { + sep = new String(lineSeparator); + } + throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]"); + } + } + + /** + * Returns true if this Base64 object has buffered data for reading. + * + * @return true if there is Base64 object still available for reading. + */ + boolean hasData() { return buf != null; } + + /** + * Returns the amount of buffered data available for reading. + * + * @return The amount of buffered data available for reading. + */ + int avail() { return buf != null ? pos - readPos : 0; } + + /** Doubles our buffer. */ + private void resizeBuf() { + if (buf == null) { + buf = new byte[8192]; + pos = 0; + readPos = 0; + } else { + byte[] b = new byte[buf.length * 2]; + System.arraycopy(buf, 0, b, 0, buf.length); + buf = b; + } + } + + /** + * Extracts buffered data into the provided byte[] array, starting + * at position bPos, up to a maximum of bAvail bytes. Returns how + * many bytes were actually extracted. + * + * @param b byte[] array to extract the buffered data into. + * @param bPos position in byte[] array to start extraction at. + * @param bAvail amount of bytes we're allowed to extract. We may extract + * fewer (if fewer are available). + * @return The number of bytes successfully extracted into the provided + * byte[] array. + */ + int readResults(byte[] b, int bPos, int bAvail) { + if (buf != null) { + int len = Math.min(avail(), bAvail); + if (buf != b) { + System.arraycopy(buf, readPos, b, bPos, len); + readPos += len; + if (readPos >= pos) { + buf = null; + } + } else { + // Re-using the original consumer's output array is only + // allowed for one round. + buf = null; + } + return len; + } else { + return eof ? -1 : 0; + } + } + + /** + * Small optimization where we try to buffer directly to the consumer's + * output array for one round (if consumer calls this method first!) instead + * of starting our own buffer. + * + * @param out byte[] array to buffer directly to. + * @param outPos Position to start buffering into. + * @param outAvail Amount of bytes available for direct buffering. + */ + void setInitialBuffer(byte[] out, int outPos, int outAvail) { + // We can re-use consumer's original output array under + // special circumstances, saving on some System.arraycopy(). + if (out != null && out.length == outAvail) { + buf = out; + pos = outPos; + readPos = outPos; + } + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. + * Must be called at least twice: once with the data to encode, and once + * with inAvail set to "-1" to alert encoder that EOF has been reached, + * so flush last remaining bytes (if not multiple of 3). + *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, + * and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in byte[] array of binary data to base64 encode. + * @param inPos Position to start reading data from. + * @param inAvail Amount of bytes available from input for encoding. + */ + void encode(byte[] in, int inPos, int inAvail) { + if (eof) { + return; + } + + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + eof = true; + if (buf == null || buf.length - pos < encodeSize) { + resizeBuf(); + } + switch (modulus) { + case 1: + buf[pos++] = intToBase64[(x >> 2) & MASK_6BITS]; + buf[pos++] = intToBase64[(x << 4) & MASK_6BITS]; + buf[pos++] = PAD; + buf[pos++] = PAD; + break; + + case 2: + buf[pos++] = intToBase64[(x >> 10) & MASK_6BITS]; + buf[pos++] = intToBase64[(x >> 4) & MASK_6BITS]; + buf[pos++] = intToBase64[(x << 2) & MASK_6BITS]; + buf[pos++] = PAD; + break; + } + if (lineLength > 0) { + System.arraycopy(lineSeparator, 0, buf, pos, lineSeparator.length); + pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + if (buf == null || buf.length - pos < encodeSize) { + resizeBuf(); + } + modulus = (++modulus) % 3; + int b = in[inPos++]; + if (b < 0) { b += 256; } + x = (x << 8) + b; + if (0 == modulus) { + buf[pos++] = intToBase64[(x >> 18) & MASK_6BITS]; + buf[pos++] = intToBase64[(x >> 12) & MASK_6BITS]; + buf[pos++] = intToBase64[(x >> 6) & MASK_6BITS]; + buf[pos++] = intToBase64[x & MASK_6BITS]; + currentLinePos += 4; + if (lineLength > 0 && lineLength <= currentLinePos) { + System.arraycopy(lineSeparator, 0, buf, pos, lineSeparator.length); + pos += lineSeparator.length; + currentLinePos = 0; + } + } + } + } + } + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. + * Should be called at least twice: once with the data to decode, and once + * with inAvail set to "-1" to alert decoder that EOF has been reached. + * The "-1" call is not necessary when decoding, but it doesn't hurt, either. + *

+ * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) + * data is handled, since CR and LF are silently ignored, but has implications + * for other bytes, too. This method subscribes to the garbage-in, garbage-out + * philosophy: it will not check the provided data for validity. + *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, + * and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ + * @param in byte[] array of ascii data to base64 decode. + * @param inPos Position to start reading data from. + * @param inAvail Amount of bytes available from input for encoding. + */ + void decode(byte[] in, int inPos, int inAvail) { + if (eof) { + return; + } + if (inAvail < 0) { + eof = true; + } + for (int i = 0; i < inAvail; i++) { + if (buf == null || buf.length - pos < decodeSize) { + resizeBuf(); + } + byte b = in[inPos++]; + if (b == PAD) { + x = x << 6; + switch (modulus) { + case 2: + x = x << 6; + buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); + break; + case 3: + buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); + buf[pos++] = (byte) ((x >> 8) & MASK_8BITS); + break; + } + // WE'RE DONE!!!! + eof = true; + return; + } else { + if (b >= 0 && b < base64ToInt.length) { + int result = base64ToInt[b]; + if (result >= 0) { + modulus = (++modulus) % 4; + x = (x << 6) + result; + if (modulus == 0) { + buf[pos++] = (byte) ((x >> 16) & MASK_8BITS); + buf[pos++] = (byte) ((x >> 8) & MASK_8BITS); + buf[pos++] = (byte) (x & MASK_8BITS); + } + } + } + } + } + } + + /** + * Returns whether or not the octet is in the base 64 alphabet. + * + * @param octet + * The value to test + * @return true if the value is defined in the the base 64 alphabet, false otherwise. + */ + public static boolean isBase64(byte octet) { + return octet == PAD || (octet >= 0 && octet < base64ToInt.length && base64ToInt[octet] != -1); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. + * Currently the method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is + * empty; false, otherwise + */ + public static boolean isArrayByteBase64(byte[] arrayOctet) { + for (int i = 0; i < arrayOctet.length; i++) { + if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { + return false; + } + } + return true; + } + + /* + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. + * + * @param arrayOctet + * byte array to test + * @return true if any byte is a valid character in the Base64 alphabet; false herwise + */ + private static boolean containsBase64Byte(byte[] arrayOctet) { + for (int i = 0; i < arrayOctet.length; i++) { + if (isBase64(arrayOctet[i])) { + return true; + } + } + return false; + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * @param binaryData + * binary data to encode + * @return Base64 characters + */ + public static byte[] encodeBase64(byte[] binaryData) { + return encodeBase64(binaryData, false); + } + + /** + * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks + * + * @param binaryData + * binary data to encode + * @return Base64 characters chunked in 76 character blocks + */ + public static byte[] encodeBase64Chunked(byte[] binaryData) { + return encodeBase64(binaryData, true); + } + + /** + * Decodes a byte[] containing containing characters in the Base64 alphabet. + * + * @param pArray + * A byte array containing Base64 character data + * @return a byte array containing binary data + */ + public byte[] decode(byte[] pArray) { + return decodeBase64(pArray); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + */ + public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) { + if (binaryData == null || binaryData.length == 0) { + return binaryData; + } + Base64 b64 = isChunked ? new Base64() : new Base64(0); + + long len = (binaryData.length * 4) / 3; + long mod = len % 4; + if (mod != 0) { + len += 4 - mod; + } + if (isChunked) { + len += (1 + (len / CHUNK_SIZE)) * CHUNK_SEPARATOR.length; + } + + if (len > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "Input array too big, output array would be bigger than Integer.MAX_VALUE=" + Integer.MAX_VALUE); + } + byte[] buf = new byte[(int) len]; + b64.setInitialBuffer(buf, 0, buf.length); + b64.encode(binaryData, 0, binaryData.length); + b64.encode(binaryData, 0, -1); // Notify encoder of EOF. + + // Encoder might have resized, even though it was unnecessary. + if (b64.buf != buf) { + b64.readResults(buf, 0, buf.length); + } + return buf; + } + + /** + * Decodes Base64 data into octets + * + * @param base64Data Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decodeBase64(byte[] base64Data) { + if (base64Data == null || base64Data.length == 0) { + return base64Data; + } + Base64 b64 = new Base64(); + + long len = (base64Data.length * 3) / 4; + byte[] buf = new byte[(int) len]; + b64.setInitialBuffer(buf, 0, buf.length); + b64.decode(base64Data, 0, base64Data.length); + b64.decode(base64Data, 0, -1); // Notify decoder of EOF. + + // We have no idea what the line-length was, so we + // cannot know how much of our array wasn't used. + byte[] result = new byte[b64.pos]; + b64.readResults(result, 0, result.length); + return result; + } + + /** + * Check if a byte value is whitespace or not. + * + * @param byteToCheck the byte to check + * @return true if byte is whitespace, false otherwise + */ + private static boolean isWhiteSpace(byte byteToCheck){ + switch (byteToCheck) { + case ' ' : + case '\n' : + case '\r' : + case '\t' : + return true; + default : + return false; + } + } + + /** + * Discards any characters outside of the base64 alphabet, per the requirements on page 25 of RFC 2045 - "Any + * characters outside of the base64 alphabet are to be ignored in base64 encoded data." + * + * @param data + * The base-64 encoded data to groom + * @return The data, less non-base64 characters (see RFC 2045). + */ + static byte[] discardNonBase64(byte[] data) { + byte groomedData[] = new byte[data.length]; + int bytesCopied = 0; + + for (int i = 0; i < data.length; i++) { + if (isBase64(data[i])) { + groomedData[bytesCopied++] = data[i]; + } + } + + byte packedData[] = new byte[bytesCopied]; + + System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); + + return packedData; + } + + // Implementation of the Encoder Interface + + /** + * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A byte array containing only Base64 character data + */ + public byte[] encode(byte[] pArray) { + return encodeBase64(pArray, false); + } + + // Implementation of integer encoding used for crypto + /** + * Decode a byte64-encoded integer according to crypto + * standards such as W3C's XML-Signature + * + * @param pArray a byte array containing base64 character data + * @return A BigInteger + */ + public static BigInteger decodeInteger(byte[] pArray) { + return new BigInteger(1, decodeBase64(pArray)); + } + + /** + * Encode to a byte64-encoded integer according to crypto + * standards such as W3C's XML-Signature + * + * @param bigInt a BigInteger + * @return A byte array containing base64 character data + * @throws NullPointerException if null is passed in + */ + public static byte[] encodeInteger(BigInteger bigInt) { + if(bigInt == null) { + throw new NullPointerException("encodeInteger called with null parameter"); + } + + return encodeBase64(toIntegerBytes(bigInt), false); + } + + /** + * Returns a byte-array representation of a BigInteger + * without sign bit. + * + * @param bigInt BigInteger to be converted + * @return a byte array representation of the BigInteger parameter + */ + static byte[] toIntegerBytes(BigInteger bigInt) { + int bitlen = bigInt.bitLength(); + // round bitlen + bitlen = ((bitlen + 7) >> 3) << 3; + byte[] bigBytes = bigInt.toByteArray(); + + if(((bigInt.bitLength() % 8) != 0) && + (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { + return bigBytes; + } + + // set up params for copying everything but sign bit + int startSrc = 0; + int len = bigBytes.length; + + // if bigInt is exactly byte-aligned, just skip signbit in copy + if((bigInt.bitLength() % 8) == 0) { + startSrc = 1; + len--; + } + + int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec + byte[] resizedBytes = new byte[bitlen / 8]; + + System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); + + return resizedBytes; + } +} Index: lams_tool_imscc/src/java/net/oauth/signature/HMAC_SHA1.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/HMAC_SHA1.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/HMAC_SHA1.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,102 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.signature; + +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.util.Arrays; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import net.oauth.OAuth; +import net.oauth.OAuthException; + +/** + * @author John Kristian + */ +class HMAC_SHA1 extends OAuthSignatureMethod { + + @Override + protected String getSignature(String baseString) throws OAuthException { + try { + String signature = base64Encode(computeSignature(baseString)); + return signature; + } catch (GeneralSecurityException e) { + throw new OAuthException(e); + } catch (UnsupportedEncodingException e) { + throw new OAuthException(e); + } + } + + @Override + protected boolean isValid(String signature, String baseString) + throws OAuthException { + try { + byte[] expected = computeSignature(baseString); + byte[] actual = decodeBase64(signature); + return Arrays.equals(expected, actual); + } catch (GeneralSecurityException e) { + throw new OAuthException(e); + } catch (UnsupportedEncodingException e) { + throw new OAuthException(e); + } + } + + private byte[] computeSignature(String baseString) + throws GeneralSecurityException, UnsupportedEncodingException { + SecretKey key = null; + synchronized (this) { + if (this.key == null) { + String keyString = OAuth.percentEncode(getConsumerSecret()) + + '&' + OAuth.percentEncode(getTokenSecret()); + byte[] keyBytes = keyString.getBytes(ENCODING); + this.key = new SecretKeySpec(keyBytes, MAC_NAME); + } + key = this.key; + } + Mac mac = Mac.getInstance(MAC_NAME); + mac.init(key); + byte[] text = baseString.getBytes(ENCODING); + return mac.doFinal(text); + } + + /** ISO-8859-1 or US-ASCII would work, too. */ + private static final String ENCODING = OAuth.ENCODING; + + private static final String MAC_NAME = "HmacSHA1"; + + private SecretKey key = null; + + @Override + public void setConsumerSecret(String consumerSecret) { + synchronized (this) { + key = null; + } + super.setConsumerSecret(consumerSecret); + } + + @Override + public void setTokenSecret(String tokenSecret) { + synchronized (this) { + key = null; + } + super.setTokenSecret(tokenSecret); + } + +} Index: lams_tool_imscc/src/java/net/oauth/signature/OAuthSignatureMethod.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/OAuthSignatureMethod.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/OAuthSignatureMethod.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,298 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.signature; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthException; +import net.oauth.OAuthMessage; +import net.oauth.OAuthProblemException; + +/** + * A pair of algorithms for computing and verifying an OAuth digital signature. + * + * @author John Kristian + */ +public abstract class OAuthSignatureMethod { + + /** Add a signature to the message. + * @throws URISyntaxException + * @throws IOException */ + public void sign(OAuthMessage message) + throws OAuthException, IOException, URISyntaxException { + message.addParameter(new OAuth.Parameter("oauth_signature", + getSignature(message))); + } + + /** + * Check whether the message has a valid signature. + * @throws URISyntaxException + * + * @throws OAuthProblemException + * the signature is invalid + */ + public void validate(OAuthMessage message) + throws IOException, OAuthException, URISyntaxException { + message.requireParameters("oauth_signature"); + String signature = message.getSignature(); + String baseString = getBaseString(message); + if (!isValid(signature, baseString)) { + OAuthProblemException problem = new OAuthProblemException( + "signature_invalid"); + problem.setParameter("oauth_signature", signature); + problem.setParameter("oauth_signature_base_string", baseString); + problem.setParameter("oauth_signature_method", message + .getSignatureMethod()); + throw problem; + } + } + + protected String getSignature(OAuthMessage message) + throws OAuthException, IOException, URISyntaxException { + String baseString = getBaseString(message); + String signature = getSignature(baseString); + // Logger log = Logger.getLogger(getClass().getName()); + // if (log.isLoggable(Level.FINE)) { + // log.fine(signature + "=getSignature(" + baseString + ")"); + // } + return signature; + } + + protected void initialize(String name, OAuthAccessor accessor) + throws OAuthException { + String secret = accessor.consumer.consumerSecret; + if (name.endsWith(_ACCESSOR)) { + // This code supports the 'Accessor Secret' extensions + // described in http://oauth.pbwiki.com/AccessorSecret + final String key = OAuthConsumer.ACCESSOR_SECRET; + Object accessorSecret = accessor.getProperty(key); + if (accessorSecret == null) { + accessorSecret = accessor.consumer.getProperty(key); + } + if (accessorSecret != null) { + secret = accessorSecret.toString(); + } + } + if (secret == null) { + secret = ""; + } + setConsumerSecret(secret); + } + + public static final String _ACCESSOR = "-Accessor"; + + /** Compute the signature for the given base string. */ + protected abstract String getSignature(String baseString) throws OAuthException; + + /** Decide whether the signature is valid. */ + protected abstract boolean isValid(String signature, String baseString) + throws OAuthException; + + private String consumerSecret; + + private String tokenSecret; + + protected String getConsumerSecret() { + return consumerSecret; + } + + protected void setConsumerSecret(String consumerSecret) { + this.consumerSecret = consumerSecret; + } + + public String getTokenSecret() { + return tokenSecret; + } + + public void setTokenSecret(String tokenSecret) { + this.tokenSecret = tokenSecret; + } + + public static String getBaseString(OAuthMessage message) + throws IOException, URISyntaxException { + List> parameters; + String url = message.URL; + int q = url.indexOf('?'); + if (q < 0) { + parameters = message.getParameters(); + } else { + // Combine the URL query string with the other parameters: + parameters = new ArrayList>(); + parameters.addAll(OAuth.decodeForm(message.URL.substring(q + 1))); + parameters.addAll(message.getParameters()); + url = url.substring(0, q); + } + return OAuth.percentEncode(message.method.toUpperCase()) + '&' + + OAuth.percentEncode(normalizeUrl(url)) + '&' + + OAuth.percentEncode(normalizeParameters(parameters)); + } + + protected static String normalizeUrl(String url) throws URISyntaxException { + URI uri = new URI(url); + String scheme = uri.getScheme().toLowerCase(); + String authority = uri.getAuthority().toLowerCase(); + boolean dropPort = (scheme.equals("http") && uri.getPort() == 80) + || (scheme.equals("https") && uri.getPort() == 443); + if (dropPort) { + // find the last : in the authority + int index = authority.lastIndexOf(":"); + if (index >= 0) { + authority = authority.substring(0, index); + } + } + String path = uri.getRawPath(); + if (path == null || path.length() <= 0) { + path = "/"; // conforms to RFC 2616 section 3.2.2 + } + // we know that there is no query and no fragment here. + return scheme + "://" + authority + path; + } + + protected static String normalizeParameters( + Collection parameters) throws IOException { + if (parameters == null) { + return ""; + } + List p = new ArrayList( + parameters.size()); + for (Map.Entry parameter : parameters) { + if (!"oauth_signature".equals(parameter.getKey())) { + p.add(new ComparableParameter(parameter)); + } + } + Collections.sort(p); + return OAuth.formEncode(getParameters(p)); + } + + public static byte[] decodeBase64(String s) { + return BASE64.decode(s.getBytes()); + } + + public static String base64Encode(byte[] b) { + return new String(BASE64.encode(b)); + } + + private static final Base64 BASE64 = new Base64(); + + public static OAuthSignatureMethod newSigner(OAuthMessage message, + OAuthAccessor accessor) throws IOException, OAuthException { + message.requireParameters(OAuth.OAUTH_SIGNATURE_METHOD); + OAuthSignatureMethod signer = newMethod(message.getSignatureMethod(), + accessor); + signer.setTokenSecret(accessor.tokenSecret); + return signer; + } + + /** The factory for signature methods. */ + public static OAuthSignatureMethod newMethod(String name, + OAuthAccessor accessor) throws OAuthException { + try { + Class methodClass = NAME_TO_CLASS.get(name); + if (methodClass != null) { + OAuthSignatureMethod method = (OAuthSignatureMethod) methodClass + .newInstance(); + method.initialize(name, accessor); + return method; + } + OAuthProblemException problem = new OAuthProblemException(OAuth.Problems.SIGNATURE_METHOD_REJECTED); + String acceptable = OAuth.percentEncode(NAME_TO_CLASS.keySet()); + if (acceptable.length() > 0) { + problem.setParameter("oauth_acceptable_signature_methods", + acceptable.toString()); + } + throw problem; + } catch (InstantiationException e) { + throw new OAuthException(e); + } catch (IllegalAccessException e) { + throw new OAuthException(e); + } + } + + /** + * Subsequently, newMethod(name) will attempt to instantiate the given + * class, with no constructor parameters. + */ + public static void registerMethodClass(String name, Class clazz) { + NAME_TO_CLASS.put(name, clazz); + } + + private static final Map NAME_TO_CLASS = new ConcurrentHashMap(); + static { + registerMethodClass("HMAC-SHA1", HMAC_SHA1.class); + registerMethodClass("PLAINTEXT", PLAINTEXT.class); + registerMethodClass("RSA-SHA1", RSA_SHA1.class); + registerMethodClass("HMAC-SHA1" + _ACCESSOR, HMAC_SHA1.class); + registerMethodClass("PLAINTEXT" + _ACCESSOR, PLAINTEXT.class); + } + + /** An efficiently sortable wrapper around a parameter. */ + private static class ComparableParameter implements + Comparable { + + ComparableParameter(Map.Entry value) { + this.value = value; + String n = toString(value.getKey()); + String v = toString(value.getValue()); + this.key = OAuth.percentEncode(n) + ' ' + OAuth.percentEncode(v); + // ' ' is used because it comes before any character + // that can appear in a percentEncoded string. + } + + final Map.Entry value; + + private final String key; + + private static String toString(Object from) { + return (from == null) ? null : from.toString(); + } + + public int compareTo(ComparableParameter that) { + return this.key.compareTo(that.key); + } + + @Override + public String toString() { + return key; + } + + } + + /** Retrieve the original parameters from a sorted collection. */ + private static List getParameters( + Collection parameters) { + if (parameters == null) { + return null; + } + List list = new ArrayList(parameters.size()); + for (ComparableParameter parameter : parameters) { + list.add(parameter.value); + } + return list; + } + +} Index: lams_tool_imscc/src/java/net/oauth/signature/PLAINTEXT.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/PLAINTEXT.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/PLAINTEXT.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,64 @@ +/* + * Copyright 2007 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.signature; + +import net.oauth.OAuth; +import net.oauth.OAuthException; + +/** + * @author John Kristian + */ +class PLAINTEXT extends OAuthSignatureMethod { + + @Override + public String getSignature(String baseString) { + return getSignature(); + } + + @Override + protected boolean isValid(String signature, String baseString) + throws OAuthException { + return signature.equals(getSignature()); + } + + private synchronized String getSignature() { + if (signature == null) { + signature = OAuth.percentEncode(getConsumerSecret()) + '&' + + OAuth.percentEncode(getTokenSecret()); + } + return signature; + } + + private String signature = null; + + @Override + public void setConsumerSecret(String consumerSecret) { + synchronized (this) { + signature = null; + } + super.setConsumerSecret(consumerSecret); + } + + @Override + public void setTokenSecret(String tokenSecret) { + synchronized (this) { + signature = null; + } + super.setTokenSecret(tokenSecret); + } + +} Index: lams_tool_imscc/src/java/net/oauth/signature/RSA_SHA1.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/RSA_SHA1.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/RSA_SHA1.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,337 @@ +/* + * Copyright 2007 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.oauth.signature; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.EncodedKeySpec; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import net.oauth.OAuth; +import net.oauth.OAuthAccessor; +import net.oauth.OAuthException; +import net.oauth.signature.pem.PEMReader; +import net.oauth.signature.pem.PKCS1EncodedKeySpec; + +/** + * Class to handle RSA-SHA1 signatures on OAuth requests. A consumer + * that wishes to use public-key signatures on messages does not need + * a shared secret with the service provider, but it needs a private + * RSA signing key. You create it like this: + * + * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, + * null, provider); + * c.setProperty(RSA_SHA1.PRIVATE_KEY, consumer_privateRSAKey); + * + * consumer_privateRSAKey must be an RSA signing key and + * of type java.security.PrivateKey, String, byte[] or InputStream. + * The key must either PKCS#1 or PKCS#8 encoded. + * + * A service provider that wishes to verify signatures made by such a + * consumer does not need a shared secret with the consumer, but it needs + * to know the consumer's public key. You create the necessary + * OAuthConsumer object (on the service provider's side) like this: + * + * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, + * null, provider); + * c.setProperty(RSA_SHA1.PUBLIC_KEY, consumer_publicRSAKey); + * + * consumer_publicRSAKey must be the consumer's public RSAkey and + * of type java.security.PublicKey, String, or byte[]. In the latter two + * cases, the key must be X509-encoded (byte[]) or X509-encoded and + * then Base64-encoded (String). + * + * Alternatively, a service provider that wishes to verify signatures made + * by such a consumer can use a X509 certificate containing the consumer's + * public key. You create the necessary OAuthConsumer object (on the service + * provider's side) like this: + * + * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key, + * null, provider); + * c.setProperty(RSA_SHA1.X509_CERTIFICATE, consumer_cert); + * + * consumer_cert must be a X509 Certificate containing the consumer's public + * key and be of type java.security.cert.X509Certificate, String, + * or byte[]. In the latter two cases, the certificate must be DER-encoded + * (byte[]) or PEM-encoded (String). + * + * @author Dirk Balfanz + * + */ +public class RSA_SHA1 extends OAuthSignatureMethod { + + final static public String PRIVATE_KEY = "RSA-SHA1.PrivateKey"; + final static public String PUBLIC_KEY = "RSA-SHA1.PublicKey"; + final static public String X509_CERTIFICATE = "RSA-SHA1.X509Certificate"; + + private PrivateKey privateKey = null; + private PublicKey publicKey = null; + + @Override + protected void initialize(String name, OAuthAccessor accessor) + throws OAuthException { + super.initialize(name, accessor); + + // Due to the support of PEM input stream, the keys must be cached. + // The stream may not be markable so it can't be read again. + try { + Object privateKeyObject = accessor.consumer.getProperty(PRIVATE_KEY); + if (privateKeyObject != null) { + privateKey = loadPrivateKey(privateKeyObject); + } + + Object publicKeyObject = accessor.consumer.getProperty(PUBLIC_KEY); + if (publicKeyObject != null) { + publicKey = loadPublicKey(publicKeyObject, false); + } else { // public key was null. perhaps they gave us a X509 cert. + Object certObject = accessor.consumer.getProperty(X509_CERTIFICATE); + if (certObject != null) { + publicKey = loadPublicKey(certObject, true); + } + } + } catch (GeneralSecurityException e) { + throw new OAuthException(e); + } catch (IOException e) { + throw new OAuthException(e); + } + } + + private PublicKey getPublicKeyFromDerCert(byte[] certObject) + throws GeneralSecurityException { + CertificateFactory fac = CertificateFactory.getInstance("X509"); + ByteArrayInputStream in = new ByteArrayInputStream(certObject); + X509Certificate cert = (X509Certificate)fac.generateCertificate(in); + return cert.getPublicKey(); + } + + private PublicKey getPublicKeyFromDer(byte[] publicKeyObject) + throws GeneralSecurityException { + KeyFactory fac = KeyFactory.getInstance("RSA"); + EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyObject); + return fac.generatePublic(pubKeySpec); + } + + private PublicKey getPublicKeyFromPem(String pem) + throws GeneralSecurityException, IOException { + + InputStream stream = new ByteArrayInputStream( + pem.getBytes("UTF-8")); + + PEMReader reader = new PEMReader(stream); + byte[] bytes = reader.getDerBytes(); + PublicKey pubKey; + + if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) { + KeySpec keySpec = new X509EncodedKeySpec(bytes); + KeyFactory fac = KeyFactory.getInstance("RSA"); + pubKey = fac.generatePublic(keySpec); + } else if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) { + pubKey = getPublicKeyFromDerCert(bytes); + } else { + throw new IOException("Invalid PEM fileL: Unknown marker for " + + " public key or cert " + reader.getBeginMarker()); + } + + return pubKey; + } + + private PrivateKey getPrivateKeyFromDer(byte[] privateKeyObject) + throws GeneralSecurityException { + KeyFactory fac = KeyFactory.getInstance("RSA"); + EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privateKeyObject); + return fac.generatePrivate(privKeySpec); + } + + private PrivateKey getPrivateKeyFromPem(String pem) + throws GeneralSecurityException, IOException { + + InputStream stream = new ByteArrayInputStream( + pem.getBytes("UTF-8")); + + PEMReader reader = new PEMReader(stream); + byte[] bytes = reader.getDerBytes(); + KeySpec keySpec; + + if (PEMReader.PRIVATE_PKCS1_MARKER.equals(reader.getBeginMarker())) { + keySpec = (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); + } else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) { + keySpec = new PKCS8EncodedKeySpec(bytes); + } else { + throw new IOException("Invalid PEM file: Unknown marker " + + "for private key " + reader.getBeginMarker()); + } + + KeyFactory fac = KeyFactory.getInstance("RSA"); + return fac.generatePrivate(keySpec); + } + + @Override + protected String getSignature(String baseString) throws OAuthException { + try { + byte[] signature = sign(baseString.getBytes(OAuth.ENCODING)); + return base64Encode(signature); + } catch (UnsupportedEncodingException e) { + throw new OAuthException(e); + } catch (GeneralSecurityException e) { + throw new OAuthException(e); + } + } + + @Override + protected boolean isValid(String signature, String baseString) + throws OAuthException { + try { + return verify(decodeBase64(signature), + baseString.getBytes(OAuth.ENCODING)); + } catch (UnsupportedEncodingException e) { + throw new OAuthException(e); + } catch (GeneralSecurityException e) { + throw new OAuthException(e); + } + } + + private byte[] sign(byte[] message) throws GeneralSecurityException { + if (privateKey == null) { + throw new IllegalStateException("need to set private key with " + + "OAuthConsumer.setProperty when " + + "generating RSA-SHA1 signatures."); + } + Signature signer = Signature.getInstance("SHA1withRSA"); + signer.initSign(privateKey); + signer.update(message); + return signer.sign(); + } + + private boolean verify(byte[] signature, byte[] message) + throws GeneralSecurityException { + if (publicKey == null) { + throw new IllegalStateException("need to set public key with " + + " OAuthConsumer.setProperty when " + + "verifying RSA-SHA1 signatures."); + } + Signature verifier = Signature.getInstance("SHA1withRSA"); + verifier.initVerify(publicKey); + verifier.update(message); + return verifier.verify(signature); + } + + /** + * Load private key from various sources, including + *
    + *
  • A PrivateKey object + *
  • A string buffer for PEM + *
  • A byte array with PKCS#8 encoded key + *
+ * @param privateKeyObject + * @return The private key + * @throws IOException + * @throws GeneralSecurityException + */ + private PrivateKey loadPrivateKey(Object privateKeyObject) + throws IOException, GeneralSecurityException { + + PrivateKey privateKey; + + if (privateKeyObject instanceof PrivateKey) { + privateKey = (PrivateKey)privateKeyObject; + } else if (privateKeyObject instanceof String) { + try { + // PEM Reader's native string constructor is for filename. + privateKey = getPrivateKeyFromPem((String)privateKeyObject); + } catch (IOException e) { + // Check if it's PEM with markers stripped + privateKey = getPrivateKeyFromDer( + decodeBase64((String)privateKeyObject)); + } + } else if (privateKeyObject instanceof byte[]) { + privateKey = getPrivateKeyFromDer((byte[])privateKeyObject); + } else { + throw new IllegalArgumentException( + "Private key set through RSA_SHA1.PRIVATE_KEY must be of " + + "type PrivateKey, String or byte[] and not " + + privateKeyObject.getClass().getName()); + } + + return privateKey; + } + + /** + * Load a public key from key file or certificate. It can load from + * different sources depending on the type of the input, + *
    + *
  • A PublicKey object + *
  • A X509Certificate object + *
  • A string buffer for PEM + *
  • A byte array with X509 encoded key or certificate + *
+ * + * @param publicKeyObject The object for public key or certificate + * @param isCert True if this object is provided as Certificate + * @return The public key + * @throws IOException + * @throws GeneralSecurityException + */ + private PublicKey loadPublicKey(Object publicKeyObject, boolean isCert) + throws IOException, GeneralSecurityException { + + PublicKey publicKey; + + if (publicKeyObject instanceof PublicKey) { + publicKey = (PublicKey)publicKeyObject; + } else if (publicKeyObject instanceof X509Certificate) { + publicKey = ((X509Certificate) publicKeyObject).getPublicKey(); + } else if (publicKeyObject instanceof String) { + try { + publicKey = getPublicKeyFromPem((String)publicKeyObject); + } catch (IOException e) { + // Check if it's marker-stripped PEM for public key + if (isCert) + throw e; + publicKey = getPublicKeyFromDer( + decodeBase64((String)publicKeyObject)); + } + } else if (publicKeyObject instanceof byte[]) { + if (isCert) + publicKey = getPublicKeyFromDerCert((byte[])publicKeyObject); + else + publicKey = getPublicKeyFromDer((byte[])publicKeyObject); + } else { + String source; + if (isCert) + source = "RSA_SHA1.X509_CERTIFICATE"; + else + source = "RSA_SHA1.PUBLIC_KEY"; + throw new IllegalArgumentException( + "Public key or certificate set through " + source + " must be of " + + "type PublicKey, String or byte[], and not " + + publicKeyObject.getClass().getName()); + } + + return publicKey; + } +} Index: lams_tool_imscc/src/java/net/oauth/signature/pem/Asn1Object.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/pem/Asn1Object.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/pem/Asn1Object.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,150 @@ +/**************************************************************************** + * Copyright (c) 1998-2009 AOL LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +package net.oauth.signature.pem; + +import java.io.IOException; +import java.math.BigInteger; + +/** + * An ASN.1 TLV. The object is not parsed. It can + * only handle integers and strings. + * + * @author zhang + * + */ +class Asn1Object { + + protected final int type; + protected final int length; + protected final byte[] value; + protected final int tag; + + /** + * Construct a ASN.1 TLV. The TLV could be either a + * constructed or primitive entity. + * + *

The first byte in DER encoding is made of following fields, + *

+     *-------------------------------------------------
+     *|Bit 8|Bit 7|Bit 6|Bit 5|Bit 4|Bit 3|Bit 2|Bit 1|
+     *-------------------------------------------------
+     *|  Class    | CF  |     +      Type             |
+     *-------------------------------------------------
+     * 
+ *
    + *
  • Class: Universal, Application, Context or Private + *
  • CF: Constructed flag. If 1, the field is constructed. + *
  • Type: This is actually called tag in ASN.1. It + * indicates data type (Integer, String) or a construct + * (sequence, choice, set). + *
+ * + * @param tag Tag or Identifier + * @param length Length of the field + * @param value Encoded octet string for the field. + */ + public Asn1Object(int tag, int length, byte[] value) { + this.tag = tag; + this.type = tag & 0x1F; + this.length = length; + this.value = value; + } + + public int getType() { + return type; + } + + public int getLength() { + return length; + } + + public byte[] getValue() { + return value; + } + + public boolean isConstructed() { + return (tag & DerParser.CONSTRUCTED) == DerParser.CONSTRUCTED; + } + + /** + * For constructed field, return a parser for its content. + * + * @return A parser for the construct. + * @throws IOException + */ + public DerParser getParser() throws IOException { + if (!isConstructed()) + throw new IOException("Invalid DER: can't parse primitive entity"); //$NON-NLS-1$ + + return new DerParser(value); + } + + /** + * Get the value as integer + * + * @return BigInteger + * @throws IOException + */ + public BigInteger getInteger() throws IOException { + if (type != DerParser.INTEGER) + throw new IOException("Invalid DER: object is not integer"); //$NON-NLS-1$ + + return new BigInteger(value); + } + + /** + * Get value as string. Most strings are treated + * as Latin-1. + * + * @return Java string + * @throws IOException + */ + public String getString() throws IOException { + + String encoding; + + switch (type) { + + // Not all are Latin-1 but it's the closest thing + case DerParser.NUMERIC_STRING: + case DerParser.PRINTABLE_STRING: + case DerParser.VIDEOTEX_STRING: + case DerParser.IA5_STRING: + case DerParser.GRAPHIC_STRING: + case DerParser.ISO646_STRING: + case DerParser.GENERAL_STRING: + encoding = "ISO-8859-1"; //$NON-NLS-1$ + break; + + case DerParser.BMP_STRING: + encoding = "UTF-16BE"; //$NON-NLS-1$ + break; + + case DerParser.UTF8_STRING: + encoding = "UTF-8"; //$NON-NLS-1$ + break; + + case DerParser.UNIVERSAL_STRING: + throw new IOException("Invalid DER: can't handle UCS-4 string"); //$NON-NLS-1$ + + default: + throw new IOException("Invalid DER: object is not a string"); //$NON-NLS-1$ + } + + return new String(value, encoding); + } +} Index: lams_tool_imscc/src/java/net/oauth/signature/pem/DerParser.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/pem/DerParser.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/pem/DerParser.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,170 @@ +/**************************************************************************** + * Copyright (c) 1998-2009 AOL LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +package net.oauth.signature.pem; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; + +/** + * A bare-minimum ASN.1 DER decoder, just having enough functions to + * decode PKCS#1 private keys. Especially, it doesn't handle explicitly + * tagged types with an outer tag. + * + *

This parser can only handle one layer. To parse nested constructs, + * get a new parser for each layer using Asn1Object.getParser(). + * + *

There are many DER decoders in JRE but using them will tie this + * program to a specific JCE/JVM. + * + * @author zhang + * + */ +class DerParser { + + // Classes + public final static int UNIVERSAL = 0x00; + public final static int APPLICATION = 0x40; + public final static int CONTEXT = 0x80; + public final static int PRIVATE = 0xC0; + + // Constructed Flag + public final static int CONSTRUCTED = 0x20; + + // Tag and data types + public final static int ANY = 0x00; + public final static int BOOLEAN = 0x01; + public final static int INTEGER = 0x02; + public final static int BIT_STRING = 0x03; + public final static int OCTET_STRING = 0x04; + public final static int NULL = 0x05; + public final static int OBJECT_IDENTIFIER = 0x06; + public final static int REAL = 0x09; + public final static int ENUMERATED = 0x0a; + public final static int RELATIVE_OID = 0x0d; + + public final static int SEQUENCE = 0x10; + public final static int SET = 0x11; + + public final static int NUMERIC_STRING = 0x12; + public final static int PRINTABLE_STRING = 0x13; + public final static int T61_STRING = 0x14; + public final static int VIDEOTEX_STRING = 0x15; + public final static int IA5_STRING = 0x16; + public final static int GRAPHIC_STRING = 0x19; + public final static int ISO646_STRING = 0x1A; + public final static int GENERAL_STRING = 0x1B; + + public final static int UTF8_STRING = 0x0C; + public final static int UNIVERSAL_STRING = 0x1C; + public final static int BMP_STRING = 0x1E; + + public final static int UTC_TIME = 0x17; + public final static int GENERALIZED_TIME = 0x18; + + protected InputStream in; + + /** + * Create a new DER decoder from an input stream. + * + * @param in + * The DER encoded stream + */ + public DerParser(InputStream in) throws IOException { + this.in = in; + } + + /** + * Create a new DER decoder from a byte array. + * + * @param The + * encoded bytes + * @throws IOException + */ + public DerParser(byte[] bytes) throws IOException { + this(new ByteArrayInputStream(bytes)); + } + + /** + * Read next object. If it's constructed, the value holds + * encoded content and it should be parsed by a new + * parser from Asn1Object.getParser. + * + * @return A object + * @throws IOException + */ + public Asn1Object read() throws IOException { + int tag = in.read(); + + if (tag == -1) + throw new IOException("Invalid DER: stream too short, missing tag"); //$NON-NLS-1$ + + int length = getLength(); + + byte[] value = new byte[length]; + int n = in.read(value); + if (n < length) + throw new IOException("Invalid DER: stream too short, missing value"); //$NON-NLS-1$ + + Asn1Object o = new Asn1Object(tag, length, value); + + return o; + } + + /** + * Decode the length of the field. Can only support length + * encoding up to 4 octets. + * + *

In BER/DER encoding, length can be encoded in 2 forms, + *

    + *
  • Short form. One octet. Bit 8 has value "0" and bits 7-1 + * give the length. + *
  • Long form. Two to 127 octets (only 4 is supported here). + * Bit 8 of first octet has value "1" and bits 7-1 give the + * number of additional length octets. Second and following + * octets give the length, base 256, most significant digit first. + *
+ * @return The length as integer + * @throws IOException + */ + private int getLength() throws IOException { + + int i = in.read(); + if (i == -1) + throw new IOException("Invalid DER: length missing"); //$NON-NLS-1$ + + // A single byte short length + if ((i & ~0x7F) == 0) + return i; + + int num = i & 0x7F; + + // We can't handle length longer than 4 bytes + if ( i >= 0xFF || num > 4) + throw new IOException("Invalid DER: length field too big (" //$NON-NLS-1$ + + i + ")"); //$NON-NLS-1$ + + byte[] bytes = new byte[num]; + int n = in.read(bytes); + if (n < num) + throw new IOException("Invalid DER: length too short"); //$NON-NLS-1$ + + return new BigInteger(1, bytes).intValue(); + } + +} Index: lams_tool_imscc/src/java/net/oauth/signature/pem/PEMReader.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/pem/PEMReader.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/pem/PEMReader.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,135 @@ +/**************************************************************************** + * Copyright (c) 1998-2009 AOL LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **************************************************************************** + * + * @author: zhang + * @version: $Revision$ + * @created: Apr 24, 2009 + * + * Description: A class to decode PEM files + * + ****************************************************************************/ +package net.oauth.signature.pem; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import net.oauth.signature.OAuthSignatureMethod; + +/** + * This class convert PEM into byte array. The begin marker + * is saved and it can be used to determine the type of the + * PEM file. + * + * @author zhang + */ +public class PEMReader { + + // Begin markers for all supported PEM files + public static final String PRIVATE_PKCS1_MARKER = + "-----BEGIN RSA PRIVATE KEY-----"; + public static final String PRIVATE_PKCS8_MARKER = + "-----BEGIN PRIVATE KEY-----"; + public static final String CERTIFICATE_X509_MARKER = + "-----BEGIN CERTIFICATE-----"; + public static final String PUBLIC_X509_MARKER = + "-----BEGIN PUBLIC KEY-----"; + + private static final String BEGIN_MARKER = "-----BEGIN "; + + private InputStream stream; + private byte[] derBytes; + private String beginMarker; + + public PEMReader(InputStream inStream) throws IOException { + stream = inStream; + readFile(); + } + + public PEMReader(byte[] buffer) throws IOException { + this(new ByteArrayInputStream(buffer)); + } + + public PEMReader(String fileName) throws IOException { + this(new FileInputStream(fileName)); + } + + public byte[] getDerBytes() { + return derBytes; + } + + public String getBeginMarker() { + return beginMarker; + } + + /** + * Read the PEM file and save the DER encoded octet + * stream and begin marker. + * + * @throws IOException + */ + protected void readFile() throws IOException { + + String line; + BufferedReader reader = new BufferedReader( + new InputStreamReader(stream)); + try { + while ((line = reader.readLine()) != null) + { + if (line.indexOf(BEGIN_MARKER) != -1) + { + beginMarker = line.trim(); + String endMarker = beginMarker.replace("BEGIN", "END"); + derBytes = readBytes(reader, endMarker); + return; + } + } + throw new IOException("Invalid PEM file: no begin marker"); + } finally { + reader.close(); + } + } + + + /** + * Read the lines between BEGIN and END marker and convert + * the Base64 encoded content into binary byte array. + * + * @return DER encoded octet stream + * @throws IOException + */ + private byte[] readBytes(BufferedReader reader, String endMarker) throws IOException + { + String line = null; + StringBuffer buf = new StringBuffer(); + + while ((line = reader.readLine()) != null) + { + if (line.indexOf(endMarker) != -1) { + + return OAuthSignatureMethod.decodeBase64(buf.toString()); + } + + buf.append(line.trim()); + } + + throw new IOException("Invalid PEM file: No end marker"); + } +} Index: lams_tool_imscc/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java =================================================================== diff -u --- lams_tool_imscc/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java (revision 0) +++ lams_tool_imscc/src/java/net/oauth/signature/pem/PKCS1EncodedKeySpec.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,116 @@ +/**************************************************************************** + * Copyright (c) 1998-2009 AOL LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **************************************************************************** + * + * @author: zhang + * @version: $Revision$ + * @created: Apr 24, 2009 + * + * Description: A KeySpec for PKCS#1 encoded RSA private key + * + ****************************************************************************/ +package net.oauth.signature.pem; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.spec.RSAPrivateCrtKeySpec; + +/** + * PKCS#1 encoded private key is commonly used with OpenSSL. It provides CRT parameters + * so the private key operation can be much faster than using exponent/modulus alone, + * which is the case for PKCS#8 encoded key. + * + *

Unfortunately, JCE doesn't have an API to decode the DER. This class takes DER + * buffer and decoded into CRT key. + * + * @author zhang + */ +public class PKCS1EncodedKeySpec { + + private RSAPrivateCrtKeySpec keySpec; + + /** + * Create a PKCS#1 keyspec from DER encoded buffer + * + * @param keyBytes DER encoded octet stream + * @throws IOException + */ + public PKCS1EncodedKeySpec(byte[] keyBytes) throws IOException { + decode(keyBytes); + } + + /** + * Get the key spec that JCE understands. + * + * @return CRT keyspec defined by JCE + */ + public RSAPrivateCrtKeySpec getKeySpec() { + return keySpec; + } + + /** + * Decode PKCS#1 encoded private key into RSAPrivateCrtKeySpec. + * + *

The ASN.1 syntax for the private key with CRT is + * + *

+     * -- 
+     * -- Representation of RSA private key with information for the CRT algorithm.
+     * --
+     * RSAPrivateKey ::= SEQUENCE {
+     *   version           Version, 
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER,  -- e
+     *   privateExponent   INTEGER,  -- d
+     *   prime1            INTEGER,  -- p
+     *   prime2            INTEGER,  -- q
+     *   exponent1         INTEGER,  -- d mod (p-1)
+     *   exponent2         INTEGER,  -- d mod (q-1) 
+     *   coefficient       INTEGER,  -- (inverse of q) mod p
+     *   otherPrimeInfos   OtherPrimeInfos OPTIONAL 
+     * }
+     * 
+ * + * @param keyBytes PKCS#1 encoded key + * @throws IOException + */ + + private void decode(byte[] keyBytes) throws IOException { + + DerParser parser = new DerParser(keyBytes); + + Asn1Object sequence = parser.read(); + if (sequence.getType() != DerParser.SEQUENCE) + throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$ + + // Parse inside the sequence + parser = sequence.getParser(); + + parser.read(); // Skip version + BigInteger modulus = parser.read().getInteger(); + BigInteger publicExp = parser.read().getInteger(); + BigInteger privateExp = parser.read().getInteger(); + BigInteger prime1 = parser.read().getInteger(); + BigInteger prime2 = parser.read().getInteger(); + BigInteger exp1 = parser.read().getInteger(); + BigInteger exp2 = parser.read().getInteger(); + BigInteger crtCoef = parser.read().getInteger(); + + keySpec = new RSAPrivateCrtKeySpec( + modulus, publicExp, privateExp, prime1, prime2, + exp1, exp2, crtCoef); + } +} Index: lams_tool_imscc/src/java/org/imsglobal/basiclti/Base64.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/imsglobal/basiclti/Base64.java (revision 0) +++ lams_tool_imscc/src/java/org/imsglobal/basiclti/Base64.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,267 @@ +/* + * $Header$ + * $Revision$ + * $Date$ + * + * Copyright 1999-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.imsglobal.basiclti; +// package org.apache.commons.httpclient.util; + +// import org.apache.commons.httpclient.HttpConstants; + +/** + * Base64 encoder and decoder. + * + + * This class provides encoding/decoding methods for the Base64 encoding as + * defined by RFC 2045, N. Freed and N. Borenstein. RFC 2045: Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. + * Reference 1996. Available at: + * http://www.ietf.org/rfc/rfc2045.txt + * + + + * + * @author Jeffrey Rodriguez + * @author Mike Bowler + * @version $Revision$ $Date$ + * + */ +public final class Base64 { + + /** */ + private static final int BASELENGTH = 255; + + /** */ + private static final int LOOKUPLENGTH = 64; + + /** */ + private static final int TWENTYFOURBITGROUP = 24; + + /** */ + private static final int EIGHTBIT = 8; + + /** */ + private static final int SIXTEENBIT = 16; + + /** */ + private static final int SIXBIT = 6; + + /** */ + private static final int FOURBYTE = 4; + + /** The sign bit as an int */ + private static final int SIGN = -128; + + /** The padding character */ + private static final byte PAD = (byte) '='; + + /** The alphabet */ + private static final byte [] BASE64_ALPHABET = new byte[BASELENGTH]; + + /** The lookup alphabet */ + private static final byte [] LOOKUP_BASE64_ALPHABET = new byte[LOOKUPLENGTH]; + + static { + + for (int i = 0; i < BASELENGTH; i++) { + BASE64_ALPHABET[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) { + BASE64_ALPHABET[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) { + BASE64_ALPHABET[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) { + BASE64_ALPHABET[i] = (byte) (i - '0' + 52); + } + + BASE64_ALPHABET['+'] = 62; + BASE64_ALPHABET['/'] = 63; + + for (int i = 0; i <= 25; i++) { + LOOKUP_BASE64_ALPHABET[i] = (byte) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) { + LOOKUP_BASE64_ALPHABET[i] = (byte) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) { + LOOKUP_BASE64_ALPHABET[i] = (byte) ('0' + j); + } + LOOKUP_BASE64_ALPHABET[62] = (byte) '+'; + LOOKUP_BASE64_ALPHABET[63] = (byte) '/'; + + } + + /** + * Create an instance. + */ + private Base64() { + // the constructor is intentionally private + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Base64-encoded array + */ + public static byte[] encode(byte[] binaryData) { + + int lengthDataBits = binaryData.length * EIGHTBIT; + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + byte encodedData[] = null; + + + if (fewerThan24bits != 0) { //data not divisible by 24 bit + encodedData = new byte[(numberTriplets + 1) * 4]; + } else { // 16 or 8 bit + encodedData = new byte[numberTriplets * 4]; + } + + byte k = 0; + byte l = 0; + byte b1 = 0; + byte b2 = 0; + byte b3 = 0; + int encodedIndex = 0; + int dataIndex = 0; + int i = 0; + for (i = 0; i < numberTriplets; i++) { + + dataIndex = i * 3; + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + b3 = binaryData[dataIndex + 2]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + encodedIndex = i * 4; + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) + : (byte) ((b1) >> 2 ^ 0xc0); + + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) + : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) + : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; + encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 + | (k << 4)]; + encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[(l << 2) + | val3]; + encodedData[encodedIndex + 3] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + dataIndex = i * 3; + encodedIndex = i * 4; + if (fewerThan24bits == EIGHTBIT) { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) + : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; + encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[k << 4]; + encodedData[encodedIndex + 2] = PAD; + encodedData[encodedIndex + 3] = PAD; + } else if (fewerThan24bits == SIXTEENBIT) { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) + : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) + : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; + encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 + | (k << 4)]; + encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[l << 2]; + encodedData[encodedIndex + 3] = PAD; + } + return encodedData; + } + + + /** + * Decodes Base64 data into octects + * + * @param base64Data byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decode(byte[] base64Data) { + // Should we throw away anything not in base64Data ? + + // handle the edge case, so we don't have to worry about it later + if (base64Data.length == 0) { + return new byte[0]; + } + + int numberQuadruple = base64Data.length / FOURBYTE; + byte decodedData[] = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + { + // this block sizes the output array properly - rlw + int lastData = base64Data.length; + // ignore the '=' padding + while (base64Data[lastData - 1] == PAD) { + if (--lastData == 0) { return new byte[0]; } + } + decodedData = new byte[lastData - numberQuadruple]; + } + + for (int i = 0; i < numberQuadruple; i++) { + dataIndex = i * 4; + marker0 = base64Data[dataIndex + 2]; + marker1 = base64Data[dataIndex + 3]; + + b1 = BASE64_ALPHABET[base64Data[dataIndex]]; + b2 = BASE64_ALPHABET[base64Data[dataIndex + 1]]; + + if (marker0 != PAD && marker1 != PAD) { //No PAD e.g 3cQl + b3 = BASE64_ALPHABET[marker0]; + b4 = BASE64_ALPHABET[marker1]; + + decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) + | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); + } else if (marker0 == PAD) { //Two PAD e.g. 3c[Pad][Pad] + decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4) ; + } else if (marker1 == PAD) { //One PAD e.g. 3cQ[Pad] + b3 = BASE64_ALPHABET[marker0]; + decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) + | ((b3 >> 2) & 0xf)); + } + encodedIndex += 3; + } + return decodedData; + } +} \ No newline at end of file Index: lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIConstants.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIConstants.java (revision 0) +++ lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIConstants.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2008 IMS GLobal Learning Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package org.imsglobal.basiclti; + +public class BasicLTIConstants { + /** + * context_id=8213060-006f-27b2066ac545 + *

+ * This is an opaque identifier that uniquely identifies the context that + * contains the link being launched. + */ + public static final String CONTEXT_ID = "context_id"; + /** + * context_label=SI182 + *

+ * A label for the context - intended to fit in a column. + */ + public static final String CONTEXT_LABEL = "context_label"; + /** + * context_title=Design of Personal Environments + *

+ * A title of the context - it should be about the length of a line. + */ + public static final String CONTEXT_TITLE = "context_title"; + + /** + * context_type=CourseSection + *

+ * This string is a comma-separated list of URN values that identify the type + * of context. At a minimum, the list MUST include a URN value drawn from the + * LIS vocabulary (see Appendix A). The assumed namespace of these URNs is the + * LIS vocabulary so TCs can use the handles when the intent is to refer to an + * LIS context type. If the TC wants to include a context type from another + * namespace, a fully-qualified URN should be used. + */ + public static final String CONTEXT_TYPE = "context_type"; + public static final String CONTEXT_TYPE_COURSE_OFFERING = "CourseOffering"; + public static final String CONTEXT_TYPE_COURSE_SECTION = "CourseSection"; + public static final String CONTEXT_TYPE_COURSE_TEMPLATE = "CourseTemplate"; + public static final String CONTEXT_TYPE_GROUP = "GROUP"; + + /** + * ext_param=value + *

+ * Systems can add their own values to the launch but should prefix + * any extensions with "ext_". + */ + public static final String EXTENSION_PREFIX = "ext_"; + /** + * custom_keyname=value + *

+ * The creator of a Basic LTI link can add custom key/value parameters to a + * launch which are to be included with the launch of the Basic LTI link. The + * Common Cartridge section below describes how these parameters are + * represented when storing custom parameters in a Common Cartridge. + *

+ * When there are custom name / value parameters in the launch, a POST + * parameter is included for each custom parameter. The parameter names are + * mapped to lower case and any character that is neither a number nor letter + * in a parameter name is replaced with an "underscore". So if a custom entry + * was as follows: + *

+ * Review:Chapter=1.2.56 + *

+ * Would map to: custom_review_chapter=1.2.56 + *

+ * Creators of Basic LTI links would be well served to limit their parameter + * names to lower case and to use no punctuation other than underscores. If + * these custom parameters are included in the Basic LTI link, the TC must + * include them in the launch data or the TP may fail to function. + */ + public static final String CUSTOM_PREFIX = "custom_"; + /** + * Parameters with the OAuth prefix are also acceptible. + */ + public static final String OAUTH_PREFIX = "oauth_"; + /** + * launch_presentation_document_target=iframe + *

+ * The value should be either 'frame', 'iframe' or 'window'. This field + * communicates the kind of browser window/frame where the TC has launched the + * tool. + */ + public static final String LAUNCH_PRESENTATION_DOCUMENT_TARGET = "launch_presentation_document_target"; + /** + * launch_presentation_height=240 + *

+ * The height of the window or frame where the content from the tool will be + * displayed. + */ + public static final String LAUNCH_PRESENTATION_HEIGHT = "launch_presentation_height"; + /** + * launch_presentation_locale=en_US_variant + *

+ * Language, country and variant separated by underscores. Language is the + * lower-case, two-letter code as defined by ISO-639 (list of codes available + * at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt). Country is the + * upper-case, two-letter code as defined by ISO-3166 (list of codes available + * at http://www.chemie.fu- berlin.de/diverse/doc/ISO_3166.html). Country and + * variant codes are optional. + */ + public static final String LAUNCH_PRESENTATION_LOCALE = "launch_presentation_locale"; + /** + * launch_presentation_return_url=http://lmsng.school.edu/portal/123/page/988/ + *

+ * Fully qualified URL where the TP can redirect the user back to the TC interface. This + * URL can be used once the TP is finished or if the TP cannot start or has some + * technical difficulty. In the case of an error, the TP may add a parameter called + * lti_errormsg that includes some detail as to the nature of the error. The + * lti_errormsg value should make sense if displayed to the user. If the tool has + * displayed a message to the end user and only wants to give the TC a message to log, + * use the parameter lti_errorlog instead of lti_errormsg. If the tool is terminating + * normally, and wants a message displayed to the user it can include a text message as + * the lti_msg parameter to the return URL. If the tool is terminating normally and + * wants to give the TC a message to log, use the parameter lti_log. This data should be + * sent on the URL as a GET - so the TP should take care to keep the overall length of + * the parameters small enough to fit within the limitations of a GET request. + */ + public static final String LAUNCH_PRESENTATION_RETURN_URL = "launch_presentation_return_url"; + /** + * launch_presentation_width=320 + *

+ * The width of the window or frame where the content from the tool will be + * displayed. + */ + public static final String LAUNCH_PRESENTATION_WIDTH = "launch_presentation_width"; + /** + * launch_presentation_css_url=http://www.toolconsumer.url/path/to/lti.css + *

+ * This points to a fully qualified URL for a CSS which can be used to style the tool. + * There are no officially defined CSS classes for this file, but the Consumer can + * apply styles to paragraphs, body, and the various HTML elements. It is up to the + * tool as to whether this CSS is used or not, and in what order this is included relative + * to the tool-specific CSS. + */ + public static final String LAUNCH_PRESENTATION_CSS_URL = "launch_presentation_css_url"; + /** + * lis_person_contact_email_primary=user@school.edu + *

+ * These fields contain information about the user account that is performing + * this launch. The names of these data items are taken from LIS. The precise + * meaning of the content in these fields is defined by LIS. + */ + public static final String LIS_PERSON_CONTACT_EMAIL_PRIMARY = "lis_person_contact_email_primary"; + /** + * lis_person_name_family=Public + *

+ * These fields contain information about the user account that is performing + * this launch. The names of these data items are taken from LIS. The precise + * meaning of the content in these fields is defined by LIS. + */ + public static final String LIS_PERSON_NAME_FAMILY = "lis_person_name_family"; + /** + * lis_person_name_full=Jane Q. Public + *

+ * These fields contain information about the user account that is performing + * this launch. The names of these data items are taken from LIS. The precise + * meaning of the content in these fields is defined by LIS. + */ + public static final String LIS_PERSON_NAME_FULL = "lis_person_name_full"; + /** + * lis_person_name_given=Jane + *

+ * These fields contain information about the user account that is performing + * this launch. The names of these data items are taken from LIS. The precise + * meaning of the content in these fields is defined by LIS. + */ + public static final String LIS_PERSON_NAME_GIVEN = "lis_person_name_given"; + + /** + * lis_person_sourcedid=school.edu:user + *

+ * This field contains the LIS identifier for the user account that is + * performing this launch. The example syntax of "school:user" + * is not the required format � lis_person_sourcedid is simply a + * globally unique identifier (i.e., a normalized string). This field + * is optional and its content and meaning are defined by LIS. + */ + public static final String LIS_PERSON_SOURCEDID = "lis_person_sourcedid"; + + /** + * lis_course_offering_sourcedid=school.edu:SI182-F08
+ * lis_course_section_sourcedid=school.edu:SI182-001-F08 + *

+ * These fields contain LIS course identifiers associated with the + * context of this launch. These fields are optional and their + * content and meaning are defined by LIS. + */ + public static final String LIS_COURSE_OFFERING_SOURCEDID = "lis_course_offering_sourcedid"; + public static final String LIS_COURSE_SECTION_SOURCEDID = "lis_course_section_sourcedid"; + + /** + * lis_result_sourcedid=83873872987329873264783687634 + *

+ * This field contains an identifier that indicates the LIS Result + * Identifier (if any) associated with this launch. This field is + * optional and its content and meaning is defined by LIS. + */ + public static final String LIS_RESULT_SOURCEDID = "lis_result_sourcedid"; + + /** + * lti_message_type=basic-lti-launch-request + *

+ * This indicates that this is a Basic LTI Launch Message. This allows a TP to + * accept a number of different LTI message types at the same launch URL. This + * parameter is required. + */ + public static final String LTI_MESSAGE_TYPE = "lti_message_type"; + /** + * lti_version=LTI-1p0 + *

+ * This indicates which version of the specification is being used for this + * particular message. This parameter is required. + */ + public static final String LTI_VERSION = "lti_version"; + // launch settings per spec - computed not stored + /** + * resource_link_id=88391-e1919-bb3456 + *

+ * This is an opaque unique identifier that the TC guarantees will be unique + * within the TC for every placement of the link. If the tool / activity is + * placed multiple times in the same context, each of those placements will be + * distinct. This value will also change if the item is exported from one + * system or context and imported into another system or context. This + * parameter is required. + */ + public static final String RESOURCE_LINK_ID = "resource_link_id"; + + /** + * resource_link_title=My Weekly Wiki + *

+ * A title for the resource. This is the clickable text that appears + * in the link. This parameter is recommended. + */ + public static final String RESOURCE_LINK_TITLE = "resource_link_title"; + + /** + * resource_link_description=� + *

+ * A plain text description of the link�s destination, suitable for + * display alongside the link. Typically no more than several lines + * long. This parameter is optional. + */ + public static final String RESOURCE_LINK_DESCRIPTION = "resource_link_description"; + + /** + * roles=Instructor,Student + *

+ * A comma-separated list of URN values for roles. If this list is non-empty, + * it should contain at least one role from the LIS System Role, LIS + * Institution Role, or LIS Context Role vocabularies (See Appendix A). The + * assumed namespace of these URNs is the LIS vocabulary of LIS Context Roles + * so TCs can use the handles when the intent is to refer to an LIS context + * role. If the TC wants to include a role from another namespace, a + * fully-qualified URN should be used. Usage of roles from non-LIS + * vocabularies is discouraged as it may limit interoperability. This + * parameter is recommended. + */ + public static final String ROLES = "roles"; + /** + * tool_consumer_instance_contact_email=System.Admin@school.edu + *

+ * An email contact for the TC instance. + */ + public static final String TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL = "tool_consumer_instance_contact_email"; + /** + * tool_consumer_instance_description=University of School (LMSng) + *

+ * This is a user visible field - it should be about the length of a line. + */ + public static final String TOOL_CONSUMER_INSTANCE_DESCRIPTION = "tool_consumer_instance_description"; + // global settings + /** + * tool_consumer_instance_guid=lmsng.school.edu + *

+ * This is a key to be used when setting a TC-wide password. The TP uses this + * as a key to look up the TC-wide secret when validating a message. A common + * practice is to use the DNS of the organization or the DNS of the TC + * instance. If the organization has multiple TC instances, then the best + * practice is to prefix the domain name with a locally unique identifier for + * the TC instance. This parameter is recommended. + */ + public static final String TOOL_CONSUMER_INSTANCE_GUID = "tool_consumer_instance_guid"; + /** + * tool_consumer_instance_name=SchoolU + *

+ * This is a user visible field - it should be about the length of a column. + */ + public static final String TOOL_CONSUMER_INSTANCE_NAME = "tool_consumer_instance_name"; + /** + * Missing from implementation guide. Needs documentation. Not required, but + * "tasty". + */ + public static final String TOOL_CONSUMER_INSTANCE_URL = "tool_consumer_instance_url"; + /** + * user_id=0ae836b9-7fc9-4060-006f-27b2066ac545 + *

+ * Uniquely identifies the user. This should not contain any identifying + * information for the user. Best practice is that this field should be a + * TC-generated long-term "primary key" to the user record - not the logical + * key. This parameter is recommended. + */ + public static final String USER_ID = "user_id"; + + /** + * ext_sakai_provider_eid=jsmith26 + *

+ * If set, this will signal that the external application has provided an eid which + * should be used preferentially. Many external applications will not have access to a user's uuid + * in Sakai, so this allows integrations with those systems. + * This parameter is optional and is unique to the Sakai Basic LTI provider. + */ + public static final String EXT_SAKAI_PROVIDER_EID = "ext_sakai_provider_eid"; + + /** + * Utility array useful for validating property names when building launch + * data. + */ + public static final String[] validPropertyNames = { CONTEXT_ID, + CONTEXT_LABEL, CONTEXT_TITLE, CONTEXT_TYPE, + LAUNCH_PRESENTATION_DOCUMENT_TARGET, LAUNCH_PRESENTATION_HEIGHT, + LAUNCH_PRESENTATION_LOCALE, LAUNCH_PRESENTATION_RETURN_URL, + LAUNCH_PRESENTATION_WIDTH, LIS_PERSON_CONTACT_EMAIL_PRIMARY, + LAUNCH_PRESENTATION_CSS_URL, + LIS_PERSON_NAME_FAMILY, LIS_PERSON_NAME_FULL, LIS_PERSON_NAME_GIVEN, + LIS_PERSON_SOURCEDID, LIS_COURSE_OFFERING_SOURCEDID, + LIS_COURSE_SECTION_SOURCEDID, LIS_RESULT_SOURCEDID, + LTI_MESSAGE_TYPE, LTI_VERSION, RESOURCE_LINK_ID, + RESOURCE_LINK_TITLE, RESOURCE_LINK_DESCRIPTION, ROLES, + TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL, TOOL_CONSUMER_INSTANCE_DESCRIPTION, + TOOL_CONSUMER_INSTANCE_GUID, TOOL_CONSUMER_INSTANCE_NAME, + TOOL_CONSUMER_INSTANCE_URL, USER_ID }; +} \ No newline at end of file Index: lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIUtil.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIUtil.java (revision 0) +++ lams_tool_imscc/src/java/org/imsglobal/basiclti/BasicLTIUtil.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,849 @@ +/* + * $URL$ + * $Id$ + * + * Copyright (c) 2008 IMS GLobal Learning Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.imsglobal.basiclti; + +import static org.imsglobal.basiclti.BasicLTIConstants.CUSTOM_PREFIX; +import static org.imsglobal.basiclti.BasicLTIConstants.LTI_MESSAGE_TYPE; +import static org.imsglobal.basiclti.BasicLTIConstants.LTI_VERSION; +import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL; +import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_DESCRIPTION; +import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_GUID; +import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_NAME; +import static org.imsglobal.basiclti.BasicLTIConstants.TOOL_CONSUMER_INSTANCE_URL; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.TreeMap; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import net.oauth.OAuthAccessor; +import net.oauth.OAuthConsumer; +import net.oauth.OAuthMessage; + +/* Leave out until we have JTidy 0.8 in the repository + import org.w3c.tidy.Tidy; + import java.io.ByteArrayOutputStream; + */ + +/** + * Some Utility code for IMS Basic LTI + * http://www.anyexample.com/programming/java + * /java_simple_class_to_compute_sha_1_hash.xml + *

+ * Sample Descriptor + * + *

+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <basic_lti_link xmlns="http://www.imsglobal.org/xsd/imsbasiclti_v1p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ *   <title>generated by tp+user</title>
+ *   <description>generated by tp+user</description>
+ *   <custom>
+ *     <parameter key="keyname">value</parameter>
+ *   </custom>
+ *   <extensions platform="www.lms.com">
+ *     <parameter key="keyname">value</parameter>
+ *   </extensions>
+ *   <launch_url>url to the basiclti launch URL</launch_url>
+ *   <secure_launch_url>url to the basiclti launch URL</secure_launch_url>
+ *   <icon>url to an icon for this tool (optional)</icon>
+ *   <secure_icon>url to an icon for this tool (optional)</secure_icon>
+ *   <cartridge_icon identifierref="BLTI001_Icon"/>
+ *   <vendor>
+ *     <code>vendor.com</code>
+ *     <name>Vendor Name</name>
+ *     <description>
+ *            This is a Grade Book that supports many column types.
+ *          </description>
+ *     <contact>
+ *       <email>support@vendor.com</email>
+ *     </contact>
+ *     <url>http://www.vendor.com/product</url>
+ *   </vendor>
+ * </basic_lti_link>
+ * 
+ */ +public class BasicLTIUtil { + + // We use the built-in Java logger because this code needs to be very generic + private static Logger M_log = Logger.getLogger(BasicLTIUtil.class.toString()); + + /** To turn on really verbose debugging */ + private static boolean verbosePrint = false; + + public static final String BASICLTI_SUBMIT = "ext_basiclti_submit"; + + private static final Pattern CUSTOM_REGEX = Pattern.compile("[^A-Za-z0-9]"); + private static final String UNDERSCORE = "_"; + + // Simple Debug Print Mechanism + public static void dPrint(String str) { + if (verbosePrint) + System.out.println(str); + M_log.fine(str); + } + + public static String validateDescriptor(String descriptor) { + if (descriptor == null) + return null; + if (descriptor.indexOf(" tm = XMLMap.getFullMap(descriptor.trim()); + if (tm == null) + return null; + + // We demand at least an endpoint + String ltiSecureLaunch = XMLMap.getString(tm, + "/basic_lti_link/secure_launch_url"); + // We demand at least an endpoint + if (ltiSecureLaunch != null && ltiSecureLaunch.trim().length() > 0) + return ltiSecureLaunch; + String ltiLaunch = XMLMap.getString(tm, "/basic_lti_link/launch_url"); + if (ltiLaunch != null && ltiLaunch.trim().length() > 0) + return ltiLaunch; + return null; + } + + /** + * Any properties which are not well known (i.e. in + * {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom + * properties per the specified semantics. NOTE: no blacklisting of keys is + * performed. + * + * @param rawProperties + * A set of properties that will be cleaned. + * @return A cleansed version of rawProperties. + */ + public static Map cleanupProperties( + final Map rawProperties) { + return cleanupProperties(rawProperties, null); + } + + /** + * Any properties which are not well known (i.e. in + * {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom + * properties per the specified semantics. + * + * @param rawProperties + * A set of properties that will be cleaned. + * @param blackList + * An array of {@link String}s which are considered unsafe to be + * included in launch data. Any matches will be removed from the + * return. + * @return A cleansed version of rawProperties. + */ + public static Map cleanupProperties( + final Map rawProperties, final String[] blackList) { + final Map newProp = new HashMap( + rawProperties.size()); // roughly the same size + for (String okey : rawProperties.keySet()) { + final String key = okey.trim(); + if (blackList != null) { + boolean blackListed = false; + for (String blackKey : blackList) { + if (blackKey.equals(key)) { + blackListed = true; + break; + } + } + if (blackListed) { + continue; + } + } + final String value = rawProperties.get(key); + if (value == null || "".equals(value)) { + // remove null or empty values + continue; + } + if (isSpecifiedPropertyName(key)) { + // a well known property name + newProp.put(key, value); + } else { + // convert to a custom property name + newProp.put(adaptToCustomPropertyName(key), value); + } + } + return newProp; + } + + /** + * Any properties which are not well known (i.e. in + * {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom + * properties per the specified semantics. + * + * @deprecated See {@link #cleanupProperties(Map)} + * @param rawProperties + * A set of {@link Properties} that will be cleaned. Keys must be of + * type {@link String}. + * @return A cleansed version of {@link Properties}. + */ + public static Properties cleanupProperties(final Properties rawProperties) { + final Map map = cleanupProperties( + convertToMap(rawProperties), null); + return convertToProperties(map); + } + + /** + * Checks to see if the passed propertyName is equal to one of the Strings + * contained in {@link BasicLTIConstants#validPropertyNames}. String matching + * is case sensitive. + * + * @param propertyName + * @return true if propertyName is equal to one of the Strings contained in + * {@link BasicLTIConstants#validPropertyNames} + * or is a custom parameter oe extension parameter ; + * else return false. + */ + public static boolean isSpecifiedPropertyName(final String propertyName) { + boolean found = false; + if ( propertyName.startsWith(BasicLTIConstants.CUSTOM_PREFIX) ) return true; + if ( propertyName.startsWith(BasicLTIConstants.EXTENSION_PREFIX) ) return true; + if ( propertyName.startsWith(BasicLTIConstants.OAUTH_PREFIX) ) return true; + for (String key : BasicLTIConstants.validPropertyNames) { + if (key.equals(propertyName)) { + found = true; + break; + } + } + return found; + } + + /** + * A simple utility method which implements the specified semantics of custom + * properties. + *

+ * i.e. The parameter names are mapped to lower case and any character that is + * neither a number nor letter in a parameter name is replaced with an + * "underscore". + *

+ * e.g. Review:Chapter=1.2.56 would map to custom_review_chapter=1.2.56. + * + * @param propertyName + * @return + */ + public static String adaptToCustomPropertyName(final String propertyName) { + if (propertyName == null || "".equals(propertyName)) { + throw new IllegalArgumentException("propertyName cannot be null"); + } + String customName = propertyName.toLowerCase(); + customName = CUSTOM_REGEX.matcher(customName).replaceAll(UNDERSCORE); + if (!customName.startsWith(CUSTOM_PREFIX)) { + customName = CUSTOM_PREFIX + customName; + } + return customName; + } + + /** + * Add the necessary fields and sign. + * + * @deprecated See: + * {@link BasicLTIUtil#signProperties(Map, String, String, String, String, String, String, String, String, String)} + * + * @param postProp + * @param url + * @param method + * @param oauth_consumer_key + * @param oauth_consumer_secret + * @param org_id + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_GUID} + * @param org_desc + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_DESCRIPTION} + * @param org_url + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_URL} + * @return + */ + public static Properties signProperties(Properties postProp, String url, + String method, String oauth_consumer_key, String oauth_consumer_secret, + String org_id, String org_desc, String org_url) { + final Map signedMap = signProperties( + convertToMap(postProp), url, method, oauth_consumer_key, + oauth_consumer_secret, org_id, org_desc, org_url, null, null); + return convertToProperties(signedMap); + } + + /** + * Add the necessary fields and sign. + * + * @param postProp + * @param url + * @param method + * @param oauth_consumer_key + * @param oauth_consumer_secret + * @param tool_consumer_instance_guid + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_GUID} + * @param tool_consumer_instance_description + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_DESCRIPTION} + * @param tool_consumer_instance_url + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_URL} + * @param tool_consumer_instance_name + * See: {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_NAME} + * @param tool_consumer_instance_contact_email + * See: + * {@link BasicLTIConstants#TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL} + * @return + */ + public static Map signProperties( + Map postProp, String url, String method, + String oauth_consumer_key, String oauth_consumer_secret, + String tool_consumer_instance_guid, + String tool_consumer_instance_description, + String tool_consumer_instance_url, String tool_consumer_instance_name, + String tool_consumer_instance_contact_email) { + postProp = BasicLTIUtil.cleanupProperties(postProp); + postProp.put(LTI_VERSION, "LTI-1p0"); + postProp.put(LTI_MESSAGE_TYPE, "basic-lti-launch-request"); + // Allow caller to internationalize this for us... + if (postProp.get(BASICLTI_SUBMIT) == null) { + postProp.put(BASICLTI_SUBMIT, "Launch Endpoint with BasicLTI Data"); + } + if (tool_consumer_instance_guid != null) + postProp.put(TOOL_CONSUMER_INSTANCE_GUID, tool_consumer_instance_guid); + if (tool_consumer_instance_description != null) + postProp.put(TOOL_CONSUMER_INSTANCE_DESCRIPTION, + tool_consumer_instance_description); + if (tool_consumer_instance_url != null) + postProp.put(TOOL_CONSUMER_INSTANCE_URL, tool_consumer_instance_url); + if (tool_consumer_instance_name != null) + postProp.put(TOOL_CONSUMER_INSTANCE_NAME, tool_consumer_instance_name); + if (tool_consumer_instance_contact_email != null) + postProp.put(TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL, + tool_consumer_instance_contact_email); + + if (postProp.get("oauth_callback") == null) + postProp.put("oauth_callback", "about:blank"); + + if (oauth_consumer_key == null || oauth_consumer_secret == null) { + dPrint("No signature generated in signProperties"); + return postProp; + } + + OAuthMessage oam = new OAuthMessage(method, url, postProp.entrySet()); + OAuthConsumer cons = new OAuthConsumer("about:blank", oauth_consumer_key, + oauth_consumer_secret, null); + OAuthAccessor acc = new OAuthAccessor(cons); + try { + oam.addRequiredParameters(acc); + // System.out.println("Base Message String\n"+OAuthSignatureMethod.getBaseString(oam)+"\n"); + + List> params = oam.getParameters(); + + Map nextProp = new HashMap(); + // Convert to Map + for (final Map.Entry entry : params) { + nextProp.put(entry.getKey(), entry.getValue()); + } + return nextProp; + } catch (net.oauth.OAuthException e) { + M_log.warning("BasicLTIUtil.signProperties OAuth Exception " + + e.getMessage()); + throw new Error(e); + } catch (java.io.IOException e) { + M_log.warning("BasicLTIUtil.signProperties IO Exception " + + e.getMessage()); + throw new Error(e); + } catch (java.net.URISyntaxException e) { + M_log.warning("BasicLTIUtil.signProperties URI Syntax Exception " + + e.getMessage()); + throw new Error(e); + } + + } + + /** + * Create the HTML to render a POST form and then automatically submit it. + * Make sure to call {@link #cleanupProperties(Properties)} before signing. + * + * @deprecated Moved to {@link #postLaunchHTML(Map, String, boolean)} + * @param cleanProperties + * Assumes you have called {@link #cleanupProperties(Properties)} + * beforehand. + * @param endpoint + * The LTI launch url. + * @param debug + * Useful for viewing the HTML before posting to end point. + * @return the HTML ready for IFRAME src = inclusion. + */ + public static String postLaunchHTML(final Properties cleanProperties, + String endpoint, boolean debug) { + Map map = convertToMap(cleanProperties); + return postLaunchHTML(map, endpoint, debug); + } + + /** + * Create the HTML to render a POST form and then automatically submit it. + * Make sure to call {@link #cleanupProperties(Properties)} before signing. + * + * @param cleanProperties + * Assumes you have called {@link #cleanupProperties(Properties)} + * beforehand. + * @param endpoint + * The LTI launch url. + * @param debug + * Useful for viewing the HTML before posting to end point. + * @return the HTML ready for IFRAME src = inclusion. + */ + public static String postLaunchHTML( + final Map cleanProperties, String endpoint, boolean debug) { + if (cleanProperties == null || cleanProperties.isEmpty()) { + throw new IllegalArgumentException( + "cleanProperties == null || cleanProperties.isEmpty()"); + } + if (endpoint == null) { + throw new IllegalArgumentException("endpoint == null"); + } + Map newMap = null; + if (debug) { + // sort the properties for readability + newMap = new TreeMap(cleanProperties); + } else { + newMap = cleanProperties; + } + StringBuilder text = new StringBuilder(); + // paint form + text.append("

\n"); + text.append("
\n"); + for (Entry entry : newMap.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + if (value == null) + continue; + // This will escape the contents pretty much - at least + // we will be safe and not generate dangerous HTML + key = htmlspecialchars(key); + value = htmlspecialchars(value); + if (key.equals(BASICLTI_SUBMIT)) { + text.append("\n"); + } + text.append("\n"); + text.append("
\n"); + // paint debug output + if (debug) { + text.append("
\n");
+      text.append("BasicLTI Endpoint\n");
+      text.append(endpoint);
+      text.append("\n\n");
+      text.append("BasicLTI Parameters:\n");
+      for (Entry entry : newMap.entrySet()) {
+        String key = entry.getKey();
+        String value = entry.getValue();
+        if (value == null)
+          continue;
+        text.append(key);
+        text.append("=");
+        text.append(value);
+        text.append("\n");
+      }
+      text.append("
\n"); + } else { + // paint auto submit script + text + .append(" \n"); + } + + String htmltext = text.toString(); + return htmltext; + } + + /** + * @deprecated See: {@link #parseDescriptor(Map, Map, String)} + * @param launch_info + * Variable is mutated by this method. + * @param postProp + * Variable is mutated by this method. + * @param descriptor + * @return + */ + public static boolean parseDescriptor(Properties launch_info, + Properties postProp, String descriptor) { + // this is an ugly copy/paste of the non-@deprecated method + // could not convert data types as they variables get mutated (ugh) + Map tm = null; + try { + tm = XMLMap.getFullMap(descriptor.trim()); + } catch (Exception e) { + M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor: " + + e.getMessage()); + return false; + } + if (tm == null) { + M_log.warning("Unable to parse XML in parseDescriptor"); + return false; + } + + String launch_url = toNull(XMLMap.getString(tm, + "/basic_lti_link/launch_url")); + String secure_launch_url = toNull(XMLMap.getString(tm, + "/basic_lti_link/secure_launch_url")); + if (launch_url == null && secure_launch_url == null) + return false; + + setProperty(launch_info, "launch_url", launch_url); + setProperty(launch_info, "secure_launch_url", secure_launch_url); + + // Extensions for hand-authored placements - The export process should scrub + // these + setProperty(launch_info, "key", toNull(XMLMap.getString(tm, + "/basic_lti_link/x-secure/launch_key"))); + setProperty(launch_info, "secret", toNull(XMLMap.getString(tm, + "/basic_lti_link/x-secure/launch_secret"))); + + List> theList = XMLMap.getList(tm, + "/basic_lti_link/custom/parameter"); + for (Map setting : theList) { + dPrint("Setting=" + setting); + String key = XMLMap.getString(setting, "/!key"); // Get the key attribute + String value = XMLMap.getString(setting, "/"); // Get the value + if (key == null || value == null) + continue; + key = "custom_" + mapKeyName(key); + dPrint("key=" + key + " val=" + value); + postProp.setProperty(key, value); + } + return true; + } + + /** + * + * @param launch_info + * Variable is mutated by this method. + * @param postProp + * Variable is mutated by this method. + * @param descriptor + * @return + */ + public static boolean parseDescriptor(Map launch_info, + Map postProp, String descriptor) { + Map tm = null; + try { + tm = XMLMap.getFullMap(descriptor.trim()); + } catch (Exception e) { + M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor: " + + e.getMessage()); + return false; + } + if (tm == null) { + M_log.warning("Unable to parse XML in parseDescriptor"); + return false; + } + + String launch_url = toNull(XMLMap.getString(tm, + "/basic_lti_link/launch_url")); + String secure_launch_url = toNull(XMLMap.getString(tm, + "/basic_lti_link/secure_launch_url")); + if (launch_url == null && secure_launch_url == null) + return false; + + setProperty(launch_info, "launch_url", launch_url); + setProperty(launch_info, "secure_launch_url", secure_launch_url); + + // Extensions for hand-authored placements - The export process should scrub + // these + setProperty(launch_info, "key", toNull(XMLMap.getString(tm, + "/basic_lti_link/x-secure/launch_key"))); + setProperty(launch_info, "secret", toNull(XMLMap.getString(tm, + "/basic_lti_link/x-secure/launch_secret"))); + + List> theList = XMLMap.getList(tm, + "/basic_lti_link/custom/parameter"); + for (Map setting : theList) { + dPrint("Setting=" + setting); + String key = XMLMap.getString(setting, "/!key"); // Get the key attribute + String value = XMLMap.getString(setting, "/"); // Get the value + if (key == null || value == null) + continue; + key = "custom_" + mapKeyName(key); + dPrint("key=" + key + " val=" + value); + postProp.put(key, value); + } + return true; + } + + // Remove fields that should not be exported + public static String prepareForExport(String descriptor) { + Map tm = null; + try { + tm = XMLMap.getFullMap(descriptor.trim()); + } catch (Exception e) { + M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor" + + e.getMessage()); + return null; + } + if (tm == null) { + M_log.warning("Unable to parse XML in prepareForExport"); + return null; + } + XMLMap.removeSubMap(tm, "/basic_lti_link/x-secure"); + String retval = XMLMap.getXML(tm, true); + return retval; + } + + /** + * The parameter name is mapped to lower case and any character that is + * neither a number or letter is replaced with an "underscore". So if a custom + * entry was as follows: + * + * 1.2.56 + * + * Would map to: custom_vendor_chapter=1.2.56 + */ + public static String mapKeyName(String keyname) { + StringBuffer sb = new StringBuffer(); + if (keyname == null) + return null; + keyname = keyname.trim(); + if (keyname.length() < 1) + return null; + for (int i = 0; i < keyname.length(); i++) { + Character ch = Character.toLowerCase(keyname.charAt(i)); + if (Character.isLetter(ch) || Character.isDigit(ch)) { + sb.append(ch); + } else { + sb.append('_'); + } + } + return sb.toString(); + } + + public static String toNull(String str) { + if (str == null) + return null; + if (str.trim().length() < 1) + return null; + return str; + } + + /** + * Mutates the passed Map map variable. Puts the key,value + * into the Map if the value is not null and is not empty. + * + * @param map + * Variable is mutated by this method. + * @param key + * @param value + */ + public static void setProperty(final Map map, + final String key, final String value) { + if (value != null && !"".equals(value)) { + map.put(key, value); + } + } + + /** + * Mutates the passed Properties props variable. Puts the key,value into the + * Map if the value is not null and is not empty. + * + * @deprecated See: {@link #setProperty(Map, String, String)} + * @param props + * Variable is mutated by this method. + * @param key + * @param value + */ + public static void setProperty(Properties props, String key, String value) { + if (value == null) + return; + if (value.trim().length() < 1) + return; + props.setProperty(key, value); + } + + // Basic utility to encode form text - handle the "safe cases" + public static String htmlspecialchars(String input) { + if (input == null) + return null; + String retval = input.replace("&", "&"); + retval = retval.replace("\"", """); + retval = retval.replace("<", "<"); + retval = retval.replace(">", ">"); + retval = retval.replace(">", ">"); + retval = retval.replace("=", "="); + return retval; + } + + /** + * Simple utility method to help with the migration from Properties to + * Map. + * + * @param properties + * @return + */ + @SuppressWarnings("unchecked") + public static Map convertToMap(final Properties properties) { + final Map map = new HashMap(properties); + return map; + } + + /** + * Simple utility method to help with the migration from Map + * to Properties. + * + * @deprecated Should migrate to Map signatures. + * @param map + * @return + */ + public static Properties convertToProperties(final Map map) { + final Properties properties = new Properties(); + if (map != null) { + for (Entry entry : map.entrySet()) { + properties.setProperty(entry.getKey(), entry.getValue()); + } + } + return properties; + } + + /** + *

+ * Checks if a String is whitespace, empty ("") or null. + *

+ * + *
+   * StringUtils.isBlank(null)      = true
+   * StringUtils.isBlank("")        = true
+   * StringUtils.isBlank(" ")       = true
+   * StringUtils.isBlank("bob")     = false
+   * StringUtils.isBlank("  bob  ") = false
+   * 
+ * + * @param str + * the String to check, may be null + * @return true if the String is null, empty or whitespace + * @since 2.0 + */ + public static boolean isBlank(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false)) { + return false; + } + } + return true; + } + + /** + *

+ * Checks if a String is not empty (""), not null and not whitespace only. + *

+ * + *
+   * StringUtils.isNotBlank(null)      = false
+   * StringUtils.isNotBlank("")        = false
+   * StringUtils.isNotBlank(" ")       = false
+   * StringUtils.isNotBlank("bob")     = true
+   * StringUtils.isNotBlank("  bob  ") = true
+   * 
+ * + * @param str + * the String to check, may be null + * @return true if the String is not empty and not null and not + * whitespace + * @since 2.0 + */ + public static boolean isNotBlank(String str) { + return !isBlank(str); + } + + /** + *

+ * Compares two Strings, returning true if they are equal. + *

+ * + *

+ * nulls are handled without exceptions. Two null + * references are considered to be equal. The comparison is case sensitive. + *

+ * + *
+   * StringUtils.equals(null, null)   = true
+   * StringUtils.equals(null, "abc")  = false
+   * StringUtils.equals("abc", null)  = false
+   * StringUtils.equals("abc", "abc") = true
+   * StringUtils.equals("abc", "ABC") = false
+   * 
+ * + * @see java.lang.String#equals(Object) + * @param str1 + * the first String, may be null + * @param str2 + * the second String, may be null + * @return true if the Strings are equal, case sensitive, or both + * null + */ + public static boolean equals(String str1, String str2) { + return str1 == null ? str2 == null : str1.equals(str2); + } + + /** + *

+ * Compares two Strings, returning true if they are equal + * ignoring the case. + *

+ * + *

+ * nulls are handled without exceptions. Two null + * references are considered equal. Comparison is case insensitive. + *

+ * + *
+   * StringUtils.equalsIgnoreCase(null, null)   = true
+   * StringUtils.equalsIgnoreCase(null, "abc")  = false
+   * StringUtils.equalsIgnoreCase("abc", null)  = false
+   * StringUtils.equalsIgnoreCase("abc", "abc") = true
+   * StringUtils.equalsIgnoreCase("abc", "ABC") = true
+   * 
+ * + * @see java.lang.String#equalsIgnoreCase(String) + * @param str1 + * the first String, may be null + * @param str2 + * the second String, may be null + * @return true if the Strings are equal, case insensitive, or + * both null + */ + public static boolean equalsIgnoreCase(String str1, String str2) { + return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); + } +} \ No newline at end of file Index: lams_tool_imscc/src/java/org/imsglobal/basiclti/XMLMap.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/imsglobal/basiclti/XMLMap.java (revision 0) +++ lams_tool_imscc/src/java/org/imsglobal/basiclti/XMLMap.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,1310 @@ +/* + * $URL$ + * $Id$ + * + * Copyright (c) 2009 IMS GLobal Learning Consortium, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + * + **********************************************************************************/ + +package org.imsglobal.basiclti; + +/* + * This is a little project I call mdom.org which stands for "Map-Dom" or "XML Doms in Maps" + * or "XML Documents meet Java Maps" - clearly there is homage to XPath style parsing in the + * formation of the keys in the Maps - but XPath is not used. + * + * It is my attempt to build a simple, self-contained, static class to make XML parsing + * REALLY simple in Java - the idea is to approximate the ease of taking apart and + * putting together chunks of XML in languages like Perl, Python, PHP, and Ruby. + * While the typed nature of Java makes it so there is a little extra syntax, it has + * been reduced to some pretty simple stuff with really forgiving calls. + * + * This has had several names - initially it is called XMLMap - these are pre-release + * versions ad I leave copies of this around as I move through projects and use + * the software. When I get serious, I will distribute this as org.mdom.MDom and + * distribute it as a jar with versions and all that. + * + * It is really easy to take apart XML as long as there are no repeated elements. + * The function getMap returns a map of keys and values - the keys are the path + * starting at the root node of the XML and the value is the element stored inside. + * You can get attributes as well. This example: + * + * + * B + * + * D + * + * + * + * Map xmlMap = XMLMap.getMap("BD"); + * + * Ends up with the following in the map: + * + * /a/b!x = X + * /a/b = B + * /a/c/d = D + * + * You simply use the hash get method to pull out the information. + * + * System.out.println(xmlMap.get("/a/b")) + * + * Once it is parsed into the Map - everything is quick and simple. + * + * Things are similar in creating XML - You make a TreeMap and put entries in using put() + * + * Map newMap = new TreeMap; + * newMap.put("/a/b!x","X"); + * newMap.put("/a/b", "B"); + * newMap.put("/a/b/c", "C"); + * String newXml = XMLMap.getXML(simpleMap, true); + * + * Another technique is the concept of submaps - you can extract a submap from a Map and then + * graft it directly onto some other bit of XML. + * + * Map subMap = XMLMap.selectSubMap(tm, "/a/c"); + * Map joinedMap = new TreeMap(); + * System.out.println("subMap="+subMap); + * joinedMap.put("/top/id", "1234"); + * joinedMap.put("/top/fun", subMap); // Graft the map onto this node + * String joinedXml = XMLMap.getXML(joinedMap, true); + * System.out.println("joinedXML\n"+joinedXml); + * + * Produces this XML: + * + * + * + * D + * + * 1234 + * + * + * The portion "below" /a/c was extracted and grafted onto the new XML at /top/fun. + * You can mix strings and Maps in the same map and you can have maps within maps. + * Once you switch to the Map you can even add an array of strings to an entry. + * + * Map arrayMap = new TreeMap(); + * String [] strar = { "first", "second", "third" }; + * arrayMap.put("/root/stuff", strar); + * String arrayXml = XMLMap.getXML(arrayMap, true); + * + * Produces: + * + * + * first + * second + * third + * + * + * The other major concept is how we parse XML and handle multiple items - such as in an RSS feed. + * When faced with a string of XML where you expect to get sets of items you need to parse the XML + * and get a "full" map - in this case, when the XMLMap parser sees multiple peer child nodes it + * returns a List> in the entry. This makes getting lists of Maps realy easy + * but can make the basic looking things up in the map a little harder. There are two approaches to + * this - you can either flatten the map or use the getString method to pull out all of the strings. + * The getString method does not "go into" any lists of maps - flattening does flatten through + * lists of maps, picking the first element of each list. + * + * Here is a way to look up single elements in a Full Map : + * + * Map rssFullMap = XMLMap.getFullMap(rssText); + * System.out.println("Rss Version="+XMLMap.getString(rssFullMap,"/rss!version")); + * System.out.println("Chan-title="+XMLMap.getString(rssFullMap,"/rss/channel/title")); + * + * Here is how you flatten the Map int a Map and use get to lookup + * + * Map rssStringMap = XMLMap.flattenMap(rssFullMap); + * System.out.println("Rss Version="+rssStringMap.get("/rss!version")); + * System.out.println("Chan-title="+rssStringMap.get("/rss/channel/title")); + * + * Iterating through a Full Map is pretty easy: + + * for ( Map rssItem : XMLMap.getList(rssFullMap,"/rss/channel/item")) { + * System.out.println("=== Item ==="); + * System.out.println(" Item-title="+XMLMap.getString(rssItem, "/title")); + * } + * + * If you have nested sets of elements - you will get back a List> that can + * also be iterated. In this example, we get a list of sites, then each site has a list of tools + * and each tool has a list of properties. The getList() method returns empty lists so + * that this code works even if the elements are not present or empty - the loops simply + * iterate zero times: + * + * Map theMap = XMLMap.getFullMap(bob); + * List> theList = XMLMap.getList(theMap, "/sites/site"); + * for ( Map siteMap : theList) { + * System.out.println("Id="+XMLMap.getString(siteMap,"/id")); + * for ( Map toolMap : XMLMap.getList(siteMap,"/tools/tool")) { + * System.out.println("ToolId="+XMLMap.getString(toolMap,"/toolid")); + * for ( Map property : XMLMap.getList(toolMap, "/properties/property")) { + * System.out.println("key="+XMLMap.getString(property, "/key")); + * System.out.println("val="+XMLMap.getString(property, "/val")); + * } + * } + * } + * + * You can retrieve an element within a site using getString() and then iterate through the + * sub-elements using getList(). + * + * There is a convenient variation of the getList() method which takes a String which combines + * the making of the map and retrieving of the list is you have no other use for the map: + * + * for ( Map siteMap : XMLMap.getList(bob,"/sites/site")) { + * System.out.println("Id="+XMLMap.getString(siteMap,"/id")); + * ... + * } + * + * This class has static unit tests built in and a static main that can run the sample code and produce + * output. This is to insure that the jar file is 100% Self-contained. + * + * TO DO: + * + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +/** + * a simple utility class for REST style XML + * kind of lets us act like we are in PHP. + */ +public class XMLMap { + + private static boolean debugFlag = false; + + public static Map getMap(String str) + { + if ( str == null ) return null; + Document doc = documentFromString(str); + if ( doc == null ) return null; + return getMap(doc); + } + + public static Map getMap(Document doc) + { + Map tm = getObjectMap(doc, false); + if ( tm == null ) return null; + return flattenMap(tm); + } + + public static Map flattenMap(Map theMap) { + if (theMap == null) + return null; + // Reduce to the first column of elements for the simple return value + TreeMap retval = new TreeMap(); + for (final Entry entry : theMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + // No need to handle String[] - because they will not + // be stored when doFull == false + if (value instanceof String) { + String svalue = (String) value; + // doDebug(d,key+" = " + value); + retval.put(key, svalue); + } + } + return retval; + } + + public static Map getFullMap(Document doc) + { + return getObjectMap(doc, true); + } + + public static Map getFullMap(String str) + { + if ( str == null ) return null; + Document doc = documentFromString(str); + if ( doc == null ) return null; + return getObjectMap(doc, true); + } + + private static Map getObjectMap(Document doc, boolean doFull) + { + if ( doc == null ) return null; + Map tm = new TreeMap(); + recurse(tm, "", doc, doFull,0); + return tm; + } + + // A Utility Method we expose so folks can reuse if they like + public static Document documentFromString(String input) + { + try{ + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document document = parser.parse(new ByteArrayInputStream(input.getBytes())); + return document; + } catch (Exception e) { + return null; + } + } + + private static String addSlash(String path) + { + if ( path == null ) return "/"; + if ( path.trim().equals("/") ) return "/"; + return path + "/"; + } + + private static void recurse(Map tm, String path, Node parentNode, boolean doFull, int d) + { + doDebug(d,"> recurse path="+path+" parentNode="+ nodeToString(parentNode)); + d++; + + NodeList nl = parentNode.getChildNodes(); + NamedNodeMap nm = parentNode.getAttributes(); + + // Count the TextNodes + String value = null; + + // Insert the text node if we find one + if ( nl != null ) for (int i = 0; i< nl.getLength(); i++ ) { + Node node = nl.item(i); + if (node.getNodeType() == Node.TEXT_NODE) { + value = node.getNodeValue(); + if ( value == null ) break; + if ( value.trim().length() < 1 ) break; + // doDebug(d,"Adding path="+path+" value="+node.getNodeValue()); + tm.put(path,node.getNodeValue()); + break; // Only the first one + } + } + + // Now loop through and add the attribute values + if ( nm != null ) for (int i = 0; i< nm.getLength(); i++ ) { + Node node = nm.item(i); + if (node.getNodeType() == Node.ATTRIBUTE_NODE) { + String name = node.getNodeName(); + value = node.getNodeValue(); + // doDebug(d,"ATTR "+path+"("+name+") = "+node.getNodeValue()); + if ( name == null || name.trim().length() < 1 || + value == null || value.trim().length() < 1 ) continue; + + String newPath = path+"!"+name; + tm.put(newPath,value); + } + } + + // If we are not doing the full DOM - we only traverse the first child + // with the same name - so we use a set to record which nodes + // we have gone down. + if ( ! doFull ) { + // Now descend the tree to the next level deeper !! + Set done = new HashSet(); + if ( nl != null ) for (int i = 0; i< nl.getLength(); i++ ) { + Node node = nl.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE && ( ! done.contains(node.getNodeName())) ) { + doDebug(d,"Going down the rabbit hole path="+path+" node="+node.getNodeName()); + recurse(tm, addSlash(path)+node.getNodeName(),node,doFull,d); + doDebug(d,"Back from the rabbit hole path="+path+" node="+node.getNodeName()); + done.add(node.getNodeName()); + } + } + d--; + doDebug(d,"< recurse path="+path+" parentNode="+ nodeToString(parentNode)); + return; + } + + // If we are going to do the full expansion - we need to know when + // There are more than one child with the same name. If there are more + // One child, we make list of Maps. + + Map childMap = new TreeMap(); + if ( nl != null ) for (int i = 0; i< nl.getLength(); i++ ) { + Node node = nl.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE ) { + Integer count = childMap.get(node.getNodeName()); + if ( count == null ) count = Integer.valueOf(0); + count = count + 1; + // Insert or Replace + childMap.put(node.getNodeName(), count); + } + } + + if ( childMap.size() < 1 ) return; + + // Now go through the children nodes and make a List of Maps + Iterator iter = childMap.keySet().iterator(); + Map>> nodeMap = new TreeMap>>(); + while ( iter.hasNext() ) { + String nextChild = iter.next(); + if ( nextChild == null ) continue; + Integer count = childMap.get(nextChild); + if ( count == null ) continue; + if ( count < 2 ) continue; + doDebug(d,"Making a List for "+nextChild); + List> newList = new ArrayList>(); + nodeMap.put(nextChild,newList); + } + + // Now descend the tree to the next level deeper !! + if ( nl != null ) for (int i = 0; i< nl.getLength(); i++ ) { + Node node = nl.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE ) { + String childName = node.getNodeName(); + if ( childName == null ) continue; + List> mapList = nodeMap.get(childName); + if ( mapList == null ) { + doDebug(d,"Going down the single rabbit hole path="+path+" node="+node.getNodeName()); + recurse(tm, addSlash(path)+node.getNodeName(),node,doFull,d); + doDebug(d,"Back from the single rabbit hole path="+path+" node="+node.getNodeName()); + } else { + doDebug(d,"Going down the multi rabbit hole path="+path+" node="+node.getNodeName()); + Map newMap = new TreeMap(); + recurse(newMap,"/",node,doFull,d); + doDebug(d,"Back from the multi rabbit hole path="+path+" node="+node.getNodeName()+" map="+newMap); + if ( newMap.size() > 0 ) mapList.add(newMap); + } + } + } + + // Now append the multi-node maps to our current map + Iterator iter2 = nodeMap.keySet().iterator(); + while ( iter2.hasNext() ) { + String nextChild = iter2.next(); + if ( nextChild == null ) continue; + List> newList = nodeMap.get(nextChild); + if ( newList == null ) continue; + if ( newList.size() < 1 ) continue; + doDebug(d,"Adding sub-map name="+nextChild+" list="+newList); + tm.put(path+"/"+nextChild, newList); + } + d--; + doDebug(d,"< recurse path="+path+" parentNode="+ nodeToString(parentNode)); + } + + @SuppressWarnings("unchecked") + public static String getXML(Map tm) + { + Document document = getXMLDom(tm); + if ( document == null ) return null; + return documentToString(document, false); + } + + @SuppressWarnings("unchecked") + public static String getXML(Map tm, boolean pretty) + { + Document document = getXMLDom(tm); + if ( document == null ) return null; + String retval = documentToString(document, pretty); + // Since the built in transform seems unable to indent + // We patch it ourselves to keep from being ugly + if ( pretty ) { + retval = prettyPostProcess(retval); + } + return retval; + } + + // This process a pretty print from an input string - + // It does it the hard way - using the methods in this class. + // It may not be the ideal way to pretty print a XML String + // but it is our way and we want to be D.R.Y. here... + // As such you may see some error messages from + // the XMLMap class in the pretty printing. + public static String prettyPrint(String input) + { + Map theMap = XMLMap.getFullMap(input); + return XMLMap.getXML(theMap, true); + } + + private static String prettyPostProcess(String inString) + { + StringBuffer sb = new StringBuffer(); + int depth = 0; + boolean newLine = false; + for (int i=0; i tm) + { + if ( tm == null ) return null; + Document document = null; + + try{ + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + document = parser.newDocument(); + } catch (Exception e) { + return null; + } + + iterateMap(document, document.getDocumentElement(), tm, 0); + return document; + } + + /* Remember that the map is a linear list of entries + /a/b B1 + /a/c Map + /x X1 + /y Y1 + /y!r R1 + /a/c!q Q1 + /a/d D1 + + + B1 + + X1 + Y1 + + D1 + + */ + @SuppressWarnings("unchecked") + private static void iterateMap(Document document, Node parentNode, Map tm, int d) + { + doDebug(d,"> IterateMap parentNode= "+ nodeToString(parentNode)); + d++; + Iterator iter = tm.keySet().iterator(); + while( iter.hasNext() ) { + String key = iter.next(); + if ( key == null ) continue; + if ( ! key.startsWith("/") ) continue; // Skip + Object obj = tm.get(key); + if ( obj == null ) { + continue; + } if ( obj instanceof String ) { + storeInDom(document, parentNode, key, (String) obj, 0, d); + } else if ( obj instanceof String [] ) { + String [] strArray = (String []) obj; + doDebug(d,"Looping through an array of length "+strArray.length); + for(int i=0; i < strArray.length; i++ ) { + storeInDom(document, parentNode, key, strArray[i], i, d); + } + } else if ( obj instanceof Map ) { + Map subMap = (Map) obj; + Node startNode = getNodeAtPath(document, parentNode, key, 0, d); + doDebug(d,"descending into Map path="+key+" startNode="+ nodeToString(startNode)); + iterateMap(document, startNode, subMap, d); + doDebug(d,"back from descent Map path="+key+" startNode="+ nodeToString(startNode)); + } else if ( obj instanceof List ) { + List lst = (List) obj; + doDebug(d,"Have a list that is this long "+lst.size()); + Iterator listIter = lst.iterator(); + int newPos = 0; + while ( listIter.hasNext() ) { + Object listObj = listIter.next(); + doDebug(d,"Processing List element@"+newPos+" "+listObj.getClass().getName()); + if ( listObj instanceof String ) { + storeInDom(document, parentNode, key, (String) listObj, newPos, d); + newPos++; + } if ( listObj instanceof Map ) { + Map subMap = (Map) listObj; + doDebug(d,"Retrieving key from List-Map path="+key+"@"+newPos); + Node startNode = getNodeAtPath(document, parentNode, key, newPos, d); + doDebug(d,"descending into List-Map path="+key+"@"+newPos+" startNode="+ nodeToString(startNode)); + iterateMap(document, startNode, subMap, d); + doDebug(d,"back from descent List-Map path="+key+"@"+newPos+" startNode="+ nodeToString(startNode)); + newPos++; + } else { + System.out.println("XMLMap Encountered an object of type "+obj.getClass().getName()+" in a List which should contain only Map objects"); + } + } + } else { + doDebug(d,"Found a "+obj.getClass().getName()+" do not know how to iterate."); + } + } + d--; + doDebug(d,"< IterateMap parentNode = "+ nodeToString(parentNode)); + } + + private static void storeInDom(Document document, Node parentNode, String key, String value, int nodePos, int d) + { + doDebug(d,"> storeInDom"+key+"@"+ nodePos + " = " + value + " parent="+ nodeToString(parentNode)); + d++; + if ( document == null || key == null || value == null ) return; + if ( parentNode == null ) parentNode = document; + doDebug(d,"parentNode I="+ nodeToString(parentNode)); + + String [] newPath = key.split("/"); + doDebug(d,"newPath = "+outStringArray(newPath)); + String nodeAttr = null; + for ( int i=1; i< newPath.length; i++ ) + { + String nodeName = newPath[i]; + if ( i == newPath.length-1 ) { + // doDebug(d,"Splitting !="+nodeName); + // check to see if we have a nodename=attributename + String [] nodeSplit = nodeName.split("!"); + if ( nodeSplit.length > 1 ) { + nodeName = nodeSplit[0]; + nodeAttr = nodeSplit[1]; + // doDebug(d,"new nodeName="+nodeName+" nodeAttr="+nodeAttr); + } + parentNode = getOrAddChildNode(document, parentNode, nodeName, nodePos, d); + } else { + parentNode = getOrAddChildNode(document, parentNode, nodeName, 0, d); + } + } + // doDebug(d,"parentNode after="+ nodeToString(parentNode)); + + if ( nodeAttr != null ) + { + if ( value!= null && parentNode instanceof Element ) + { + Element element = (Element) parentNode; + // doDebug(d,"Adding an attribute "+nodeAttr); + element.setAttribute(nodeAttr,value); + } + } + else if ( value != null ) + { + Text newNode = document.createTextNode(value); + parentNode.appendChild(newNode); + } + // d--; + // doDebug(d,"xml="+documentToString(document,false)); + // doDebug(d,"< storeInDom"+key+" = " + value); + } + + // Note - sadly this does not "return" the attr name - hence we need + // to replicate this code in storeInDom :( + private static Node getNodeAtPath(Document document, Node parentNode, String path, int nodePos, int d) + { + if ( parentNode == null ) parentNode = document; + doDebug(d,"> getNodeAtPath path@" + nodePos + "="+path+" parentNode="+ nodeToString(parentNode)); + d++; + + String [] newPath = path.split("/"); + // doDebug(d,"newPath = "+outStringArray(newPath)); + for ( int i=1; i< newPath.length; i++ ) + { + String nodeName = newPath[i]; + if ( i == newPath.length-1 ) { + // doDebug(d,"Splitting !="+nodeName); + // check to see if we have a nodename=attributename + String [] nodeSplit = nodeName.split("!"); + if ( nodeSplit.length > 1 ) { + nodeName = nodeSplit[0]; + // doDebug(d,"new nodeName="+nodeName); + } + parentNode = getOrAddChildNode(document, parentNode, nodeName, nodePos, d); + } else { + parentNode = getOrAddChildNode(document, parentNode, nodeName, 0, d); + } + } + d--; + doDebug(d,"< getNodeAtPath returning="+ nodeToString(parentNode)); + return parentNode; + } + + private static Node getOrAddChildNode(Document doc, Node parentNode, String nodeName,int whichNode, int d) + { + doDebug(d,"> getOrAddChildNode name="+nodeName+"@"+whichNode+" parentNode="+ nodeToString(parentNode)); + d++; + if ( nodeName == null || parentNode == null) return null; + + // Check to see if we are somewhere in an index + int begpos = nodeName.indexOf('['); + int endpos = nodeName.indexOf(']'); + // doDebug(d,"Looking for bracket ipos="+begpos+" endpos="+endpos); + if ( begpos > 0 && endpos > begpos && endpos < nodeName.length() ) { + String indStr = nodeName.substring(begpos+1,endpos); + doDebug(d,"Index String = "+ indStr); + nodeName = nodeName.substring(0,begpos); + doDebug(d,"New Nodename="+nodeName); + Integer iVal = new Integer(indStr); + doDebug(d,"Integer = "+iVal); + whichNode = iVal; + } + + NodeList nl = parentNode.getChildNodes(); + int foundNodes = -1; + if ( nl != null ) for (int i = 0; i< nl.getLength(); i++ ) { + Node node = nl.item(i); + // doDebug(d,"length= " +nl.getLength()+ " i="+i+" NT="+node.getNodeType()); + // doDebug(d,"searching nn="+nodeName+" nc="+node.getNodeName()); + if (node.getNodeType() == Node.ELEMENT_NODE) { + if ( nodeName.equals(node.getNodeName()) ) { + foundNodes++; + d--; + doDebug(d,"< getOrAddChildNode found name="+ nodeToString(node)); + doDebug(d,"foundNodes = "+foundNodes+" looking for node="+whichNode); + if ( foundNodes >= whichNode ) return node; + } + } + } + + Element newNode = null; + while ( foundNodes < whichNode ) { + foundNodes++; + doDebug(d,"Adding node at position " + foundNodes + " moving toward " + whichNode); + if ( nodeName == null ) continue; + newNode = doc.createElement(nodeName); + doDebug(d,"Adding "+nodeName+" at "+ nodeToString(parentNode)+" in "+doc); + parentNode.appendChild(newNode); + doDebug(d,"xml="+documentToString(doc,false)); + doDebug(d,"getOrAddChildNode added newnode="+ nodeToString(newNode)); + } + d--; + doDebug(d,"< getOrAddChildNode added newnode="+ nodeToString(newNode)); + return newNode; + } + + public static String outStringArray(String [] arr) + { + if ( arr == null ) return null; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < arr.length; i++ ) { + if ( i > 0 ) sb.append(" "); + sb.append("["+i+"]="); + sb.append(arr[i]); + } + return sb.toString(); + } + + public static String nodeToString(Node node) + { + if ( node == null ) return null; + String retval = node.getNodeName(); + while ( (node = node.getParentNode()) != null ) { + retval = node.getNodeName() + "/" + retval; + } + return "/" + retval; + } + + // Optionally setup indenting to "pretty print" + // Note - this is not very pretty at least in my testing - but it is better + // than all string together + public static String documentToString(Document document, boolean pretty) + { + try { + javax.xml.transform.Transformer tf = + javax.xml.transform.TransformerFactory.newInstance().newTransformer(); + if ( pretty ) { + tf.setOutputProperty(OutputKeys.INDENT, "yes"); + tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + } + ByteArrayOutputStream baStream = new ByteArrayOutputStream(); + tf.transform (new javax.xml.transform.dom.DOMSource (document), + new javax.xml.transform.stream.StreamResult (baStream)); + return baStream.toString(); + } catch (Exception e) { + return null; + } + } + + // Someone better at Generics can yell at me as to how this should have been + // done to use the same code for either objects or strings. Sorry. + public static Map selectSubMap(Map sm, String selection) + { + if ( sm == null ) return null; + selection = selection.trim(); + if ( badSelection(selection) ) return null; + Map retval = new TreeMap(); + selectSubMap(sm, retval, null, null, selection); + return retval; + } + + public static Map selectFullSubMap(Map om, String selection) + { + if ( om == null ) return null; + selection = selection.trim(); + if ( badSelection(selection) ) return null; + Map retval = new TreeMap(); + selectSubMap(null, null, om, retval, selection); + return retval; + } + + private static boolean badSelection(String selection) + { + if ( selection == null ) return true; + if ( selection.equals("/") ) return true; + if ( selection.length() < 2 ) return true; + if ( ! selection.startsWith("/") ) return true; + return false; + } + + private static void selectSubMap(Map sm, Map sret, + Map om, Map oret, String selection) + { + Iterator iter = null; + if ( sm != null ) { + iter = sm.keySet().iterator(); + } else { + iter = om.keySet().iterator(); + } + + while( iter.hasNext() ) { + String key = iter.next(); + boolean match = false; + String newKey = null; + if ( key.equals(selection) ) { + match = true; + newKey = "/"; + } else if ( selection.endsWith("/") && key.startsWith(selection)) { + match = true; + newKey = key.substring(selection.length()-1); + } else if ( key.startsWith(selection+"/") ) { + match = true; + newKey = key.substring(selection.length()); + } else if ( key.startsWith(selection+"!") ) { + match = true; + newKey = "/" + key.substring(selection.length()); + } + if ( ! match ) continue; + // doDebug(d,"newKey = "+newKey); + if ( sm != null ) { + String value = sm.get(key); + if ( value == null ) continue; + sret.put(newKey,value); + // doDebug(d,newKey+" = " + value); + } else { + Object value = om.get(key); + if ( value == null ) continue; + oret.put(newKey,value); + // doDebug(d,newKey+" = " + value); + } + } + } + + /* + * Remove a submap. Depending if the string ends ina slash - there are + * two behaviors. + * /x/y/ All of the children are removed but the node is left intact + * /x/y All of the children are removed and the node itself and + * any attributes are removed as well (typical case) + */ + @SuppressWarnings("unchecked") + public static void removeSubMap(Map tm, String selection) + { + if ( tm == null ) return; + selection = selection.trim(); + if ( badSelection(selection) ) return; + + // If the selection does not end with /, generate the + // Attribute and children selections + selection = selection.trim(); + String childSel = selection; + String attrSel = selection; + if ( ! selection.endsWith("/") ) { + childSel = selection + "/"; + attrSel = selection + "!"; + } + + // Track what we will delete until loop is done + Set delSet = new HashSet(); + + Iterator iter = tm.keySet().iterator(); + while( iter.hasNext() ) { + Object key = iter.next(); + if ( ! (key instanceof String) ) continue; + String strKey = (String) key; + if ( strKey.equals(selection) || strKey.startsWith(childSel) || strKey.startsWith(attrSel)) { + delSet.add(strKey); + // System.out.println("Deleting key="+key); + } + } + + // Actually remove... + Iterator setIter = delSet.iterator(); + while( setIter.hasNext() ) { + String key = setIter.next(); + tm.remove(key); + } + } + + private static void doDebug(int d, String str) { + if ( ! debugFlag ) return; + for(int i=0; i theMap, String key) + { + if ( theMap == null ) return null; + Object obj = theMap.get(key); + if ( obj == null ) return null; + if ( obj instanceof String ) return (String) obj; + return null; + } + + /* This goes to a set of nodes that are intended to be multiple nodes and returns a list whether there + * are one or many nodes. + * + * + * + * p1keyp1val + * + * + * p2akeyp2aval + * p2bkeyp2bval + * + * + * + * List> p1s = XMLMap.getList(mnop,"/abc/p1s/p1"); + * List> p2s = XMLMap.getList(mnop,"/abc/p2s/p2"); + * + * Always return a list even if it is just an empty list so this code works: + * + * for ( Map siteMap : XMLMap.getList(mnop,"/sites/site")) { + * System.out.println("Site="+siteMap); + * } + */ + @SuppressWarnings("unchecked") + public static List> getList(Map theMap,String key) + { + ArrayList> al = new ArrayList>(); + if ( theMap == null || key == null ) return al; + + // If this is a nice little list of maps - we are golden - send the list back + Object obj = theMap.get(key); + if ( obj instanceof List ) return (List>) obj; + + // We may have a single String value - we may have a single terminal value + // perhaps with some attributes + // + // + // 1300 + // + // + + // See if there is one sub map there... + Map oneMap = selectFullSubMap(theMap, key); + // System.out.println("One submap = "+oneMap); + if ( oneMap == null ) return al; + + // If the map is not empty - return am empty list + // rather than a one element list with an empty map + if ( oneMap.isEmpty() ) return al; + + // Make a list of one submap... + al.add(oneMap); + return al; + } + + // Note that getList with the first parameter to getList is a String, it does a + // getMap and then a getList with that Map - this allows the following + // rather dense code: + + // for ( Map siteMap : XMLMap.getList(xmlString,"/sites/site")) { + + // The long form of this looks as follows: + + // Map theMap = XMLMap.getFullMap(xmlString); + // List> theList = XMLMap.getList(theMap, "/sites/site"); + // for ( Map siteMap : theList) { + + // The short form should only be used if this is the only time you will parse + // to get a FullMap - otherwise - get the FullMap once and pull out the different bits + // from the map without reparsing the xmlString. + + public static List> getList(String xmlInput,String key) + { + Map tmpMap = XMLMap.getFullMap(xmlInput); + return XMLMap.getList(tmpMap,key); + } + + /* + * Unit Tests - Keep these public in case folks want to call them when they are + * only in possession of a jar file - makes the jar file a bearer instrument at + * the cost of some extra space. + */ + + public static boolean unitTest(String xmlString, boolean doDebug) + { + + if ( xmlString == null ) return false; + debugFlag = doDebug; + + // If Debug is turned on - let the chips fly, exceptions and + // All... + if ( doDebug ) { + debugFlag = true; + String pretty1 = XMLMap.prettyPrint(xmlString); + String pretty2 = XMLMap.prettyPrint(pretty1); + if ( pretty1.equals(pretty2) ) return true; + System.out.println("XMLMap - unit test failed"); + return false; + } + + // For Debug off - we first try it silently and in a try/catch block + debugFlag = false; + try { + String pretty1 = XMLMap.prettyPrint(xmlString); + String pretty2 = XMLMap.prettyPrint(pretty1); + if ( pretty1.equals(pretty2) ) return true; + } + catch (Throwable t) { + // We will re-do below so folks see the trace back - + // in the context of debug + } + + // If we failed - re-do it with verbose mode on + System.out.println("XMLMap - unit test failed"); + System.out.println(xmlString); + debugFlag = true; + String pretty1 = XMLMap.prettyPrint(xmlString); + System.out.println("Pretty Print Version pass 1\n"+pretty1); + String pretty2 = XMLMap.prettyPrint(pretty1); + System.out.println("Pretty Print Version pass 2\n"+pretty2); + debugFlag = false; // Always reset class-wide variable + return false; + } + + // Some Unit Test and sample Strings + private static final String simpleText = "BD"; + private static final String sitesText = " sue fred Title sakai.web.content p1key p1val p2key p2val sakai-wiki wikikey sakai-blog "; + private static final String rssText = "Dr-Chuck's MediaTelevision Shows and other mediahttp://www.dr-chuck.com/media.phpTrack Days with John Merlin WilliamsThis film is about racing street Motorcyles.http://www.dr-chuck.comMotocross RacingDr. Chuck comes in second to last and is covered with mud.http://www.dr-chuck.com/"; + + public static boolean allUnitTests() { + if ( !unitTest(simpleText, false) ) return false; + if ( !unitTest(sitesText, false) ) return false; + if ( !unitTest(rssText, false) ) return false; + return true; + } + + public static void main(String[] args) { + System.out.println("Running XMLMap (www.mdom.org) unit tests.."); + if (allUnitTests()) { + System.out.println("Unit tests passed..."); + } else { + throw new Error("Unit tests failed!"); + } + runSamples(); + } + + public static void runSamples() { + System.out.println("Running XMLMap (www.mdom.org) Samples..."); + debugFlag = false; + + // Test the parsing of a Basic string Map + Map tm = XMLMap.getMap(simpleText); + // System.out.println("tm="+tm); + + // Test the production of a basic map + Map simpleMap = new TreeMap(); + simpleMap.put("/a/b!x", "X"); + simpleMap.put("/a/b", "B"); + simpleMap.put("/a/c/d", "D"); + System.out.println("simpleMap\n"+simpleMap); + String simpleXml = XMLMap.getXML(simpleMap, true); + System.out.println("simpleXml\n"+simpleXml); + unitTest(simpleXml,false); + + // Do a select of a subMap + Map subMap = XMLMap.selectSubMap(tm, "/a/c"); + Map joinedMap = new TreeMap(); + System.out.println("subMap="+subMap); + joinedMap.put("/top/id", "1234"); + joinedMap.put("/top/fun", subMap); // Graft the map onto this node + System.out.println("joinedMap\n"+joinedMap); + String joinedXml = XMLMap.getXML(joinedMap, true); + System.out.println("joinedXML\n"+joinedXml); + unitTest(joinedXml,false); + + // Do an Array + Map arrayMap = new TreeMap(); + String [] arrayStr = { "first", "second", "third" }; + arrayMap.put("/root/stuff", arrayStr); + System.out.println("arrayMap\n"+arrayMap); + String arrayXml = XMLMap.getXML(arrayMap, true); + System.out.println("arrayXml\n"+arrayXml); + unitTest(arrayXml,false); + + // Make a Map that is a combination of Maps, String, and Arrays + Map newMap = new TreeMap(); + + newMap.put("/Root/milton","Root-milton"); + newMap.put("/Root/joe","Root-joe"); + + Map m2 = new TreeMap(); + m2.put("/fred/a","fred-a"); + m2.put("/fred/b","fred-b"); + newMap.put("/Root/freds", m2); + + // Add a list of maps + // + // + // + // key-0 + // val-0 + // + // + // key-1 + // val-1 + // + // + // + + List> lm = new ArrayList>(); + Map m3 = null; + m3 = new TreeMap(); + m3.put("/key","key-0"); + m3.put("/val","val-0"); + lm.add(m3); + + m3 = new TreeMap(); + m3.put("/key","key-1"); + m3.put("/val","val-1"); + lm.add(m3); + + newMap.put("/Root/maps/map", lm); + + // Add an array of Strings + // + // first + // second + // third + // + + String [] strar = { "first", "second", "third" }; + newMap.put("/Root/array", strar); + + // Add a list of Maps - this is a bit of a weird application - mostly as a + // completeness test to insure lists of maps and arrays are equivalent. Also + // since the getFullMap returns maps, not Arrays of strings, this is necessary + // to insure symmetry - i.e. we can take a map structure we produce and + // regenerate the XML. Most users will not use this form in construction. + // + // + // item-1 + // item-2 + // + + List> l1 = new ArrayList>(); + Map m4 = new TreeMap(); + m4.put("/", "item-1"); + l1.add(m4); + Map m5 = new TreeMap(); + m5.put("/", "item-2"); + l1.add(m5); + newMap.put("/Root/item", l1); + + // Put in using the XMLMap bracket Syntax - not a particularly good + // Way to represent multiple items - it is just here for completeness. + newMap.put("/Root/anns/ann[0]","Root-ann[0]"); + newMap.put("/Root/anns/ann[1]","Root-ann[1]"); + newMap.put("/Root/bobs/bob[0]/key","Root-bobs-bob[0]-key"); + newMap.put("/Root/bobs/bob[0]/val","Root-bobs-bob[0]-val"); + newMap.put("/Root/bobs/bob[1]/key","Root-bobs-bob[1]-key"); + newMap.put("/Root/bobs/bob[1]/val","Root-bobs-bob[1]-val"); + + // This is not allowed because maps cannot have duplicates + /* + Map m6 = new TreeMap(); + m5.put("/two", "two-1"); + m5.put("/two", "two-2"); + newMap.put("/Root", m6); + */ + + // Take the Map - turn it into XML and then parse the returned + // XML into a second map - take the second map and produce more XML + // If all goes well, the two generated blobs of XML should be the + // same. If anything goes wrong - we re-do it with lots of debug + String complexXml = null; + boolean success = false; + debugFlag = false; + try { + complexXml = XMLMap.getXML(newMap, true); + success = true; + } catch(Exception e) { + success = false; + } + + // If we fail - do it again with deep levels of verbosity + if ( success ) { + unitTest(complexXml,false); + } else { + debugFlag = true; + System.out.println("\n MISMATCH AND/OR SOME ERROR HAS OCCURED - REDO in VERBODE MODE"); + System.out.println("Starting out newMap="+newMap); + complexXml = XMLMap.getXML(newMap, true); + unitTest(complexXml,false); + debugFlag = false; + } + + // A different example - iterating through nested sets - demonstrating the short form + // of getSites() with the first parameter a string -the commented code below is the long form. + + // Map theMap = XMLMap.getFullMap(sitesText); + // List> theList = XMLMap.getList(theMap, "/sites/site"); + // for ( Map siteMap : theList) { + + // The short form using convenience method if you don't need the map for anything else + System.out.println("\nParsing Sites Structure"); + for ( Map siteMap : XMLMap.getList(sitesText,"/sites/site")) { + System.out.println("Site="+siteMap); + System.out.println("Id="+XMLMap.getString(siteMap,"/id")); + for ( Map toolMap : XMLMap.getList(siteMap,"/tools/tool")) { + System.out.println("Tool="+toolMap); + System.out.println("ToolId="+XMLMap.getString(toolMap,"/toolid")); + for ( Map property : XMLMap.getList(toolMap, "/properties/property")) { + System.out.println("key="+XMLMap.getString(property, "/key")); + System.out.println("val="+XMLMap.getString(property, "/val")); + } + } + } + + // Lets parse some RSS as a final kind of easy but quite practical test + debugFlag = false; + System.out.println("\nParsing RSS Feed"); + // System.out.println(XMLMap.prettyPrint(rssText)); + Map rssFullMap = XMLMap.getFullMap(rssText); + System.out.println("RSS Full Map\n"+rssFullMap); + System.out.println("Rss Version="+XMLMap.getString(rssFullMap,"/rss!version")); + System.out.println("Chan-desc="+XMLMap.getString(rssFullMap,"/rss/channel/description")); + System.out.println("Chan-title="+XMLMap.getString(rssFullMap,"/rss/channel/title")); + + Map rssStringMap = XMLMap.flattenMap(rssFullMap); + System.out.println("RSS Flat String Only Map\n"+rssStringMap); + System.out.println("Rss Version="+rssStringMap.get("/rss!version")); + System.out.println("Chan-desc="+rssStringMap.get("/rss/channel/description")); + System.out.println("Chan-title="+rssStringMap.get("/rss/channel/title")); + + for ( Map rssItem : XMLMap.getList(rssFullMap,"/rss/channel/item")) { + System.out.println("=== Item ==="); + System.out.println(" Item-title="+XMLMap.getString(rssItem, "/title")); + System.out.println(" Item-description="+XMLMap.getString(rssItem, "/description")); + System.out.println(" Item-link="+XMLMap.getString(rssItem, "/link")); + } + } +} + +/* Sample output from test run with lines wrapped a bit: + +Running XMLMap (www.mdom.org) unit tests.. +Unit tests passed... +Running XMLMap (www.mdom.org) Samples... +tm={/a/b=B, /a/b!x=X, /a/c/d=D} +simpleMap +{/a/b=B, /a/b!x=X, /a/c/d=D} +simpleXml + + + B + + D + + + +subMap={/d=D} +joinedMap +{/top/fun={/d=D}, /top/id=1234} +joinedXML + + + + D + + 1234 + + +arrayMap +{/root/stuff=[Ljava.lang.String;@6f50a8} +arrayXml + + + first + second + third + + + +Parsing Sites Structure +Site={/id=sue} +Id=sue +Site={/id=fred, /title=Title, /tools/tool=[{/properties/property=[{/key=p1key, /val=p1val}, + {/key=p2key, /val=p2val}], /toolid=sakai.web.content}, {/properties/property/key=wikikey, + /toolid=sakai-wiki}, {/toolid=sakai-blog}]} + +Id=fred +Tool={/properties/property=[{/key=p1key, /val=p1val}, {/key=p2key, /val=p2val}], /toolid=sakai.web.content} +ToolId=sakai.web.content +key=p1key +val=p1val +key=p2key +val=p2val +Tool={/properties/property/key=wikikey, /toolid=sakai-wiki} +ToolId=sakai-wiki +key=wikikey +val=null +Tool={/toolid=sakai-blog} +ToolId=sakai-blog + +Parsing RSS Feed +RSS Full Map +{/rss!version=2.0, /rss/channel/description=Television Shows and other media, + /rss/channel/item=[{/description=This film is about racing street Motorcyles., + /link=http://www.dr-chuck.com, /title=Track Days with John Merlin Williams}, + {/description=Dr. Chuck comes in second to last and is covered with mud., + /link=http://www.dr-chuck.com/, /title=Motocross Racing}], + /rss/channel/link=http://www.dr-chuck.com/media.php, /rss/channel/title=Dr-Chuck's Media} + +Rss Version=2.0 +Chan-desc=Television Shows and other media +Chan-title=Dr-Chuck's Media +RSS Flat String Only Map +{/rss!version=2.0, /rss/channel/description=Television Shows and other media, + /rss/channel/link=http://www.dr-chuck.com/media.php, /rss/channel/title=Dr-Chuck's Media} + +Rss Version=2.0 +Chan-desc=Television Shows and other media +Chan-title=Dr-Chuck's Media +=== Item === + Item-title=Track Days with John Merlin Williams + Item-description=This film is about racing street Motorcyles. + Item-link=http://www.dr-chuck.com +=== Item === + Item-title=Motocross Racing + Item-description=Dr. Chuck comes in second to last and is covered with mud. + Item-link=http://www.dr-chuck.com/ + + */ Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/CommonCartridgeConstants.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/CommonCartridgeConstants.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/CommonCartridgeConstants.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,147 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge; + +public class CommonCartridgeConstants { + public static final String TOOL_SIGNATURE = "laimsc11"; + + public static final String RESOURCE_SERVICE = "commonCartridgeService"; + + public static final String TOOL_CONTENT_HANDLER_NAME = "commonCartridgeToolContentHandler"; + + public static final int COMPLETED = 1; + + // commonCartridge type; + public static final short RESOURCE_TYPE_BASIC_LTI = 1; + + public static final short RESOURCE_TYPE_COMMON_CARTRIDGE = 2; + + // for action forward name + public static final String SUCCESS = "success"; + + public static final String ERROR = "error"; + + public static final String DEFINE_LATER = "definelater"; + + // for parameters' name + public static final String PARAM_TOOL_CONTENT_ID = "toolContentID"; + + public static final String PARAM_TOOL_SESSION_ID = "toolSessionID"; + + public static final String PARAM_FILE_VERSION_ID = "fileVersionId"; + + public static final String PARAM_FILE_UUID = "fileUuid"; + + public static final String PARAM_ITEM_INDEX = "itemIndex"; + + public static final String PARAM_RESOURCE_ITEM_UID = "itemUid"; + + public static final String PARAM_CURRENT_INSTRUCTION_INDEX = "insIdx"; + + public static final String PARAM_RUN_OFFLINE = "runOffline"; + + public static final String PARAM_OPEN_URL_POPUP = "popupUrl"; + + public static final String PARAM_TITLE = "title"; + + // for request attribute name + public static final String ATTR_TOOL_CONTENT_ID = "toolContentID"; + + public static final String ATTR_TOOL_SESSION_ID = "toolSessionID"; + + public static final String ATTR_RESOURCE_ITEM_LIST = "commonCartridgeList"; + + public static final String ATT_ATTACHMENT_LIST = "instructionAttachmentList"; + + public static final String ATTR_DELETED_RESOURCE_ITEM_LIST = "deleteCommonCartridgeList"; + + public static final String ATTR_DELETED_ATTACHMENT_LIST = "deletedAttachmmentList"; + + public static final String ATTR_DELETED_RESOURCE_ITEM_ATTACHMENT_LIST = "deletedItemAttachmmentList";; + + public static final String ATTR_RESOURCE_REVIEW_URL = "commonCartridgeItemReviewUrl"; + + public static final String ATTR_RESOURCE = "commonCartridge"; + + public static final String ATTR_RUN_AUTO = "runAuto"; + + public static final String ATTR_RESOURCE_ITEM_UID = "itemUid"; + + public static final String ATTR_NEXT_ACTIVITY_URL = "nextActivityUrl"; + + public static final String ATTR_SUMMARY_LIST = "summaryList"; + + public static final String ATTR_USER_LIST = "userList"; + + public static final String ATTR_RESOURCE_INSTRUCTION = "instructions"; + + public static final String ATTR_FINISH_LOCK = "finishedLock"; + + public static final String ATTR_LOCK_ON_FINISH = "lockOnFinish"; + + public static final String ATTR_SESSION_MAP_ID = "sessionMapID"; + + public static final String ATTR_RESOURCE_FORM = "commonCartridgeForm"; + + public static final String ATTR_ADD_RESOURCE_TYPE = "addType"; + + public static final String ATTR_FILE_TYPE_FLAG = "fileTypeFlag"; + + public static final String ATTR_TITLE = "title"; + + public static final String ATTR_INSTRUCTIONS = "instructions"; + + public static final String ATTR_USER_FINISHED = "userFinished"; + + // error message keys + public static final String ERROR_MSG_TITLE_BLANK = "error.resource.item.title.blank"; + + public static final String ERROR_MSG_URL_BLANK = "error.resource.item.url.blank"; + + public static final String ERROR_MSG_DESC_BLANK = "error.resource.item.desc.blank"; + + public static final String ERROR_MSG_FILE_BLANK = "error.resource.item.file.blank"; + + public static final String ERROR_MSG_INVALID_URL = "error.resource.item.invalid.url"; + + public static final String ERROR_MSG_UPLOAD_FAILED = "error.upload.failed"; + + public static final String PAGE_EDITABLE = "isPageEditable"; + + public static final String MODE_AUTHOR_SESSION = "author_session"; + + public static final String ATTR_REFLECTION_ON = "reflectOn"; + + public static final String ATTR_REFLECTION_INSTRUCTION = "reflectInstructions"; + + public static final String ATTR_REFLECTION_ENTRY = "reflectEntry"; + + public static final String ATTR_REFLECT_LIST = "reflectList"; + + public static final String ATTR_USER_UID = "userUid"; + + public static final String DEFUALT_PROTOCOL_REFIX = "http://"; + + public static final String ALLOW_PROTOCOL_REFIX = new String("[http://|https://|ftp://|nntp://]"); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/commonCartridgeApplicationContext.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/commonCartridgeApplicationContext.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/commonCartridgeApplicationContext.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,144 @@ + + + + + + + + + org.lamsfoundation.lams.tool.commonCartridge.ApplicationResources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,+java.lang.Exception + PROPAGATION_REQUIRED,+java.lang.Exception + PROPAGATION_REQUIRED,+java.lang.Exception + PROPAGATION_REQUIRED,+java.lang.Exception + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeAttachmentDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeAttachmentDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeAttachmentDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,28 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +public interface CommonCartridgeAttachmentDAO extends DAO { + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeConfigItemDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeConfigItemDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeConfigItemDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,33 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import org.lamsfoundation.lams.dao.IBaseDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; + +public interface CommonCartridgeConfigItemDAO extends IBaseDAO { + void saveOrUpdate(CommonCartridgeConfigItem toConfig); + + public CommonCartridgeConfigItem getConfigItemByKey(final String configKey); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,36 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; + +public interface CommonCartridgeDAO extends DAO { + + CommonCartridge getByContentId(Long contentId); + + CommonCartridge getByUid(Long commonCartridgeUid); + + void delete(CommonCartridge commonCartridge); + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,42 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; + +public interface CommonCartridgeItemDAO extends DAO { + + /** + * Return all commonCartridge items which is uploaded by author in given commonCartridgeUid. + * + * @param commonCartridgeUid + * @return + */ + List getAuthoringItems(Long commonCartridgeUid); + + CommonCartridgeItem getByUid(Long commonCartridgeItemUid); + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemVisitDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemVisitDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeItemVisitDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,47 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import java.util.List; +import java.util.Map; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemVisitLog; + +public interface CommonCartridgeItemVisitDAO extends DAO { + + public CommonCartridgeItemVisitLog getCommonCartridgeItemLog(Long itemUid, Long userId); + + public int getUserViewLogCount(Long sessionId, Long userUid); + + /** + * Return list which contains key pair which key is commonCartridge item uid, value is number view. + * + * @param contentId + * @return + */ + public Map getSummary(Long contentId); + + public List getCommonCartridgeItemLogBySession(Long sessionId, Long itemUid); + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeSessionDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeSessionDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeSessionDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,40 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; + +public interface CommonCartridgeSessionDAO extends DAO { + + CommonCartridgeSession getSessionBySessionId(Long sessionId); + + List getByContentId(Long toolContentId); + + void delete(CommonCartridgeSession session); + + void deleteBySessionId(Long toolSessionId); + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeUserDAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeUserDAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/CommonCartridgeUserDAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,37 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; + +public interface CommonCartridgeUserDAO extends DAO { + + CommonCartridgeUser getUserByUserIDAndSessionID(Long userID, Long sessionId); + + CommonCartridgeUser getUserByUserIDAndContentID(Long userId, Long contentId); + + List getBySessionID(Long sessionId); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/DAO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/DAO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/DAO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,76 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao; + +import java.io.Serializable; +import java.util.List; + +/** + * Data Access Object (DAO) interface. This is an interface used to tag our DAO classes and to provide common methods to + * all DAOs. + * + * @author Andrey Balan + */ +public interface DAO { + + /** + * Generic method used to get all objects of a particular type. This is the same as lookup up all rows in a table. + * + * @param clazz + * the type of objects (a.k.a. while table) to get data from + * @return List of populated objects + */ + public List getObjects(Class clazz); + + /** + * Generic method to get an object based on class and identifier. An ObjectRetrievalFailureException Runtime + * Exception is thrown if nothing is found. + * + * @param clazz + * model class to lookup + * @param id + * the identifier (primary key) of the class + * @return a populated object + * @see org.springframework.orm.ObjectRetrievalFailureException + */ + public Object getObject(Class clazz, Serializable id); + + /** + * Generic method to save an object - handles both update and insert. + * + * @param o + * the object to save + */ + public void saveObject(Object o); + + /** + * Generic method to delete an object based on class and id + * + * @param clazz + * model class to lookup + * @param id + * the identifier (primary key) of the class + */ + public void removeObject(Class clazz, Serializable id); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/BaseDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/BaseDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/BaseDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,72 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.lamsfoundation.lams.tool.commonCartridge.dao.DAO; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * This class serves as the Base class for all other DAOs - namely to hold + * common methods that they might all use. Can be used for standard CRUD + * operations.

+ * + * @author Andrey Balan + */ +public class BaseDAOHibernate extends HibernateDaoSupport implements DAO { + protected final Log log = LogFactory.getLog(getClass()); + + /** + * @see com.edgenius.paradise.dao.DAO#saveObject(java.lang.Object) + */ + public void saveObject(Object o) { + getHibernateTemplate().saveOrUpdate(o); + } + + /** + * @see com.edgenius.paradise.dao.DAO#getObject(java.lang.Class, java.io.Serializable) + */ + public Object getObject(Class clazz, Serializable id) { + Object o = getHibernateTemplate().get(clazz, id); + return o; + } + + /** + * @see com.edgenius.paradise.dao.DAO#getObjects(java.lang.Class) + */ + public List getObjects(Class clazz) { + return getHibernateTemplate().loadAll(clazz); + } + + /** + * @see com.edgenius.paradise.dao.DAO#removeObject(java.lang.Class, java.io.Serializable) + */ + public void removeObject(Class clazz, Serializable id) { + getHibernateTemplate().delete(getObject(clazz, id)); + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeAttachmentDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeAttachmentDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeAttachmentDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,30 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeAttachmentDAO; + +public class CommonCartridgeAttachmentDAOHibernate extends BaseDAOHibernate implements CommonCartridgeAttachmentDAO{ + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeConfigItemDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeConfigItemDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeConfigItemDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,50 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.lamsfoundation.lams.dao.hibernate.BaseDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeConfigItemDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; +import org.springframework.orm.hibernate3.HibernateCallback; + +public class CommonCartridgeConfigItemDAOHibernate extends BaseDAO implements CommonCartridgeConfigItemDAO { + private static final String LOAD_CONFIG_ITEM_BY_KEY = "from CommonCartridgeConfigItem configuration" + + " where configuration.configKey=:key"; + + public CommonCartridgeConfigItem getConfigItemByKey(final String configKey) { + return (CommonCartridgeConfigItem) getHibernateTemplate().execute(new HibernateCallback() { + public Object doInHibernate(Session session) throws HibernateException { + return session.createQuery(LOAD_CONFIG_ITEM_BY_KEY).setString("key", configKey).uniqueResult(); + } + }); + + } + + public void saveOrUpdate(CommonCartridgeConfigItem configItem) { + this.getHibernateTemplate().saveOrUpdate(configItem); + this.getHibernateTemplate().flush(); + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,55 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; + +/** + * + * @author Andrey Balan + */ +public class CommonCartridgeDAOHibernate extends BaseDAOHibernate implements CommonCartridgeDAO { + private static final String GET_RESOURCE_BY_CONTENTID = "from " + CommonCartridge.class.getName() + + " as r where r.contentId=?"; + + public CommonCartridge getByContentId(Long contentId) { + List list = getHibernateTemplate().find(GET_RESOURCE_BY_CONTENTID, contentId); + if (list.size() > 0) + return (CommonCartridge) list.get(0); + else + return null; + } + + public CommonCartridge getByUid(Long commonCartridgeUid) { + return (CommonCartridge) getObject(CommonCartridge.class, commonCartridgeUid); + } + + public void delete(CommonCartridge commonCartridge) { + this.getHibernateTemplate().delete(commonCartridge); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,45 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeItemDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; + +public class CommonCartridgeItemDAOHibernate extends BaseDAOHibernate implements CommonCartridgeItemDAO { + + private static final String FIND_AUTHORING_ITEMS = "from " + CommonCartridgeItem.class.getName() + + " where commonCartridge_uid = ? order by create_date asc"; + + public List getAuthoringItems(Long commonCartridgeUid) { + + return this.getHibernateTemplate().find(FIND_AUTHORING_ITEMS, commonCartridgeUid); + } + + public CommonCartridgeItem getByUid(Long commonCartridgeItemUid) { + return (CommonCartridgeItem) this.getObject(CommonCartridgeItem.class, commonCartridgeItemUid); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemVisitDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemVisitDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeItemVisitDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,85 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeItemVisitDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemVisitLog; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; + +public class CommonCartridgeItemVisitDAOHibernate extends BaseDAOHibernate implements CommonCartridgeItemVisitDAO { + + private static final String FIND_BY_ITEM_AND_USER = "from " + CommonCartridgeItemVisitLog.class.getName() + + " as r where r.user.userId = ? and r.commonCartridgeItem.uid=?"; + + private static final String FIND_BY_ITEM_BYSESSION = "from " + CommonCartridgeItemVisitLog.class.getName() + + " as r where r.sessionId = ? and r.commonCartridgeItem.uid=?"; + + private static final String FIND_VIEW_COUNT_BY_USER = "select count(*) from " + + CommonCartridgeItemVisitLog.class.getName() + " as r where r.sessionId=? and r.user.userId =?"; + + private static final String FIND_SUMMARY = "select v.commonCartridgeItem.uid, count(v.commonCartridgeItem) from " + + CommonCartridgeItemVisitLog.class.getName() + " as v , " + CommonCartridgeSession.class.getName() + + " as s, " + CommonCartridge.class.getName() + " as r " + " where v.sessionId = s.sessionId " + + " and s.commonCartridge.uid = r.uid " + " and r.contentId =? " + + " group by v.sessionId, v.commonCartridgeItem.uid "; + + public CommonCartridgeItemVisitLog getCommonCartridgeItemLog(Long itemUid, Long userId) { + List list = getHibernateTemplate().find(FIND_BY_ITEM_AND_USER, new Object[] { userId, itemUid }); + if (list == null || list.size() == 0) + return null; + return (CommonCartridgeItemVisitLog) list.get(0); + } + + public int getUserViewLogCount(Long toolSessionId, Long userUid) { + List list = getHibernateTemplate().find(FIND_VIEW_COUNT_BY_USER, new Object[] { toolSessionId, userUid }); + if (list == null || list.size() == 0) + return 0; + return ((Number) list.get(0)).intValue(); + } + + public Map getSummary(Long contentId) { + + // Note: Hibernate 3.1 query.uniqueResult() returns Integer, Hibernate 3.2 query.uniqueResult() returns Long + List result = getHibernateTemplate().find(FIND_SUMMARY, contentId); + Map summaryList = new HashMap(result.size()); + for (Object[] list : result) { + if (list[1] != null) { + summaryList.put((Long) list[0], new Integer(((Number) list[1]).intValue())); + } + } + return summaryList; + + } + + public List getCommonCartridgeItemLogBySession(Long sessionId, Long itemUid) { + + return getHibernateTemplate().find(FIND_BY_ITEM_BYSESSION, new Object[] { sessionId, itemUid }); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeSessionDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeSessionDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeSessionDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,57 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeSessionDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; + +public class CommonCartridgeSessionDAOHibernate extends BaseDAOHibernate implements CommonCartridgeSessionDAO { + + private static final String FIND_BY_SESSION_ID = "from " + CommonCartridgeSession.class.getName() + + " as p where p.sessionId=?"; + private static final String FIND_BY_CONTENT_ID = "from " + CommonCartridgeSession.class.getName() + + " as p where p.commonCartridge.contentId=?"; + + public CommonCartridgeSession getSessionBySessionId(Long sessionId) { + List list = getHibernateTemplate().find(FIND_BY_SESSION_ID, sessionId); + if (list == null || list.size() == 0) + return null; + return (CommonCartridgeSession) list.get(0); + } + + public List getByContentId(Long toolContentId) { + return getHibernateTemplate().find(FIND_BY_CONTENT_ID, toolContentId); + } + + public void delete(CommonCartridgeSession session) { + this.getHibernateTemplate().delete(session); + } + + public void deleteBySessionId(Long toolSessionId) { + this.removeObject(CommonCartridgeSession.class, toolSessionId); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeUserDAOHibernate.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeUserDAOHibernate.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dao/hibernate/CommonCartridgeUserDAOHibernate.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,58 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dao.hibernate; + +import java.util.List; + +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeUserDAO; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; + +public class CommonCartridgeUserDAOHibernate extends BaseDAOHibernate implements CommonCartridgeUserDAO { + + private static final String FIND_BY_USER_ID_CONTENT_ID = "from " + CommonCartridgeUser.class.getName() + + " as u where u.userId =? and u.commonCartridge.contentId=?"; + private static final String FIND_BY_USER_ID_SESSION_ID = "from " + CommonCartridgeUser.class.getName() + + " as u where u.userId =? and u.session.sessionId=?"; + private static final String FIND_BY_SESSION_ID = "from " + CommonCartridgeUser.class.getName() + + " as u where u.session.sessionId=?"; + + public CommonCartridgeUser getUserByUserIDAndSessionID(Long userID, Long sessionId) { + List list = this.getHibernateTemplate().find(FIND_BY_USER_ID_SESSION_ID, new Object[] { userID, sessionId }); + if (list == null || list.size() == 0) + return null; + return (CommonCartridgeUser) list.get(0); + } + + public CommonCartridgeUser getUserByUserIDAndContentID(Long userId, Long contentId) { + List list = this.getHibernateTemplate().find(FIND_BY_USER_ID_CONTENT_ID, new Object[] { userId, contentId }); + if (list == null || list.size() == 0) + return null; + return (CommonCartridgeUser) list.get(0); + } + + public List getBySessionID(Long sessionId) { + return this.getHibernateTemplate().find(FIND_BY_SESSION_ID, sessionId); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dbupdates/autopatchContext.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dbupdates/autopatchContext.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dbupdates/autopatchContext.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,11 @@ + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/ReflectDTO.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/ReflectDTO.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/ReflectDTO.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,80 @@ +package org.lamsfoundation.lams.tool.commonCartridge.dto; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; + +/** + * + * @author Andrey Balan + * + */ +public class ReflectDTO { + private Long userUid; + private String fullName; + private String loginName; + private boolean hasRefection; + private String reflectInstrctions; + private boolean finishReflection; + private String reflect; + + public ReflectDTO(CommonCartridgeUser user) { + this.setLoginName(user.getLoginName()); + this.setFullName(user.getFirstName() + " " + user.getLastName()); + this.setUserUid(user.getUid()); + } + + public boolean isFinishReflection() { + return finishReflection; + } + + public void setFinishReflection(boolean finishReflection) { + this.finishReflection = finishReflection; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public boolean isHasRefection() { + return hasRefection; + } + + public void setHasRefection(boolean hasRefection) { + this.hasRefection = hasRefection; + } + + public String getLoginName() { + return loginName; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + + public String getReflect() { + return reflect; + } + + public void setReflect(String reflect) { + this.reflect = reflect; + } + + public String getReflectInstrctions() { + return reflectInstrctions; + } + + public void setReflectInstrctions(String reflectInstrctions) { + this.reflectInstrctions = reflectInstrctions; + } + + public Long getUserUid() { + return userUid; + } + + public void setUserUid(Long userUid) { + this.userUid = userUid; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/Summary.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/Summary.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/dto/Summary.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,258 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.dto; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemInstruction; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeWebUtils; + +/** + * List contains following element:
+ * + *
  • session_id
  • session_name
  • CommonCartridgeItem.uid
  • CommonCartridgeItem.item_type
  • + * CommonCartridgeItem.create_by_author
  • CommonCartridgeItem.is_hide
  • CommonCartridgeItem.title
  • + * User.login_name
  • count(commonCartridge_item_uid)
  • + * + * @author Andrey Balan + */ +public class Summary { + + private Long sessionId; + private String sessionName; + private Long itemUid; + private short itemType; + private boolean itemCreateByAuthor; + private boolean itemHide; + private String itemTitle; + private List itemInstructions = new ArrayList(); + private String username; + private int viewNumber; + + // following is used for export portfolio programs: + private String url; + private Long fileUuid; + private Long fileVersionId; + private String fileName; + private String attachmentLocalUrl; + + // true: initial group item, false, belong to some group. + private boolean isInitGroup; + + public Summary() { + } + + /** + * Contruction method for monitoring summary function. + * + * Don't not set isInitGroup and viewNumber fields + * + * @param sessionName + * @param item + * @param isInitGroup + */ + public Summary(Long sessionId, String sessionName, CommonCartridgeItem item) { + this.sessionId = sessionId; + this.sessionName = sessionName; + if (item != null) { + this.itemUid = item.getUid(); + this.itemType = item.getType(); + this.itemCreateByAuthor = item.isCreateByAuthor(); + this.itemHide = item.isHide(); + this.itemTitle = item.getTitle(); + this.username = item.getCreateBy() == null ? "" : item.getCreateBy().getLoginName(); + this.url = CommonCartridgeWebUtils.protocol(item.getUrl()); + this.fileName = item.getFileName(); + this.fileUuid = item.getFileUuid(); + this.fileVersionId = item.getFileVersionId(); + } else + this.itemUid = new Long(-1); + } + + /** + * Contruction method for export profolio function. + * + * Don't not set sessionId and viewNumber fields + * + * @param sessionName + * @param item + * @param isInitGroup + */ + public Summary(Long sessionId, String sessionName, CommonCartridgeItem item, boolean isInitGroup) { + this.sessionId = sessionId; + this.sessionName = sessionName; + if (item != null) { + this.itemUid = item.getUid(); + this.itemType = item.getType(); + this.itemCreateByAuthor = item.isCreateByAuthor(); + this.itemHide = item.isHide(); + this.itemTitle = item.getTitle(); + this.username = item.getCreateBy() == null ? "" : item.getCreateBy().getLoginName(); + this.url = CommonCartridgeWebUtils.protocol(item.getUrl()); + this.fileName = item.getFileName(); + this.fileUuid = item.getFileUuid(); + this.fileVersionId = item.getFileVersionId(); + + for (CommonCartridgeItemInstruction instruction : (Set) item + .getItemInstructions()) { + itemInstructions.add(instruction.getDescription()); + } + } else + this.itemUid = new Long(-1); + this.isInitGroup = isInitGroup; + } + + public boolean isItemCreateByAuthor() { + return itemCreateByAuthor; + } + + public void setItemCreateByAuthor(boolean itemCreateByAuthor) { + this.itemCreateByAuthor = itemCreateByAuthor; + } + + public boolean isItemHide() { + return itemHide; + } + + public void setItemHide(boolean itemHide) { + this.itemHide = itemHide; + } + + public String getItemTitle() { + return itemTitle; + } + + public void setItemTitle(String itemTitle) { + this.itemTitle = itemTitle; + } + + public short getItemType() { + return itemType; + } + + public void setItemType(short itemType) { + this.itemType = itemType; + } + + public Long getItemUid() { + return itemUid; + } + + public void setItemUid(Long itemUid) { + this.itemUid = itemUid; + } + + public Long getSessionId() { + return sessionId; + } + + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + public String getSessionName() { + return sessionName; + } + + public void setSessionName(String sessionName) { + this.sessionName = sessionName; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public int getViewNumber() { + return viewNumber; + } + + public void setViewNumber(int viewNumber) { + this.viewNumber = viewNumber; + } + + public Long getFileUuid() { + return fileUuid; + } + + public void setFileUuid(Long fileUuid) { + this.fileUuid = fileUuid; + } + + public Long getFileVersionId() { + return fileVersionId; + } + + public void setFileVersionId(Long fileVersionId) { + this.fileVersionId = fileVersionId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public boolean isInitGroup() { + return isInitGroup; + } + + public void setInitGroup(boolean isInitGroup) { + this.isInitGroup = isInitGroup; + } + + public String getAttachmentLocalUrl() { + return attachmentLocalUrl; + } + + public void setAttachmentLocalUrl(String attachmentLocalUrl) { + this.attachmentLocalUrl = attachmentLocalUrl; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public List getItemInstructions() { + return itemInstructions; + } + + public void setItemInstructions(List itemInstructions) { + this.itemInstructions = itemInstructions; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IContentPackageConverter.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IContentPackageConverter.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IContentPackageConverter.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,64 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +/** + * A ContentPackageConverter converts an IMS Content Package into the + * data needed for our tool. The only implementation initially done was + * SimpleContentPackageCoverter. + * + * The creation method of the converter (which is unique to each converter) + * will need to parse the package and have the data ready for the "get" + * calls. + * + * Note: Classes that implement this interface should be normal POJOS, + * not singletons. This allows them to have instance data. + */ +public interface IContentPackageConverter { + + /** + * @return Returns the defaultItem. + */ + public abstract String getDefaultItem(); + + /** + * @return Returns the description. + */ + public abstract String getDescription(); + + /** + * @return Returns the organzationXML. + */ + public abstract String getOrganzationXML(); + + /** + * @return Returns the schema. + */ + public abstract String getSchema(); + + /** + * @return Returns the title. + */ + public abstract String getTitle(); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IMSManifestException.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IMSManifestException.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/IMSManifestException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,63 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +/** + * This exception is thrown when an error occurs that may be related to the formatting of the IMS content package. e.g. + * the manifest file is missing. + * + * @author Fiona Malikoff + */ +public class IMSManifestException extends ImscpApplicationException { + + /** + * + */ + public IMSManifestException() { + super(); + } + + /** + * @param arg0 + */ + public IMSManifestException(String arg0) { + super(arg0); + } + + /** + * @param arg0 + */ + public IMSManifestException(Throwable arg0) { + super(arg0); + } + + /** + * @param arg0 + * @param arg1 + */ + public IMSManifestException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/ImscpApplicationException.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/ImscpApplicationException.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/ImscpApplicationException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,62 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +/** + * Generic exception for the imscr tool. + * + * @author Fiona Malikoff + */ +public class ImscpApplicationException extends Exception { + + /** + * + */ + public ImscpApplicationException() { + super(); + } + + /** + * @param arg0 + */ + public ImscpApplicationException(String arg0) { + super(arg0); + } + + /** + * @param arg0 + */ + public ImscpApplicationException(Throwable arg0) { + super(arg0); + } + + /** + * @param arg0 + * @param arg1 + */ + public ImscpApplicationException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/OrganizationXMLDef.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/OrganizationXMLDef.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/OrganizationXMLDef.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,42 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +/** + * This contains the "tag" of items in the organization xml. May be used + * by JSP pages to get the tag names right! + * + * @author Fiona Malikoff + */ +public final class OrganizationXMLDef { + + public static final String DEFAULT = "default"; + public static final String ITEM = "item"; + public static final String PARAMETERS = "parameters"; + public static final String HREF = "href"; + public static final String IDENTIFIER = "identifier"; + public static final String RESOURCE = "commonCartridge"; + public static final String TITLE = "title"; + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleCommonCartridgeConverter.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleCommonCartridgeConverter.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleCommonCartridgeConverter.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,658 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.imsglobal.basiclti.BasicLTIUtil; +import org.imsglobal.basiclti.XMLMap; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jdom.Namespace; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; + +import uk.ac.reload.jdom.XMLDocument; +import uk.ac.reload.jdom.XMLPath; +import uk.ac.reload.jdom.XMLUtils; +import uk.ac.reload.moonunit.contentpackaging.CP_Core; + +/** + * SimpleContentPackageConverter contains the code required for parsing the IMS Content Package and converting the info + * into our own structures. + * + * Note: this class has instance data, so do not use it as a singleton. + * + * @author Fiona Malikoff + */ +public class SimpleCommonCartridgeConverter implements IContentPackageConverter { + + private Logger log = Logger.getLogger(SimpleCommonCartridgeConverter.class); + + // manifestDoc and cpCore are set up in the constructor. They are then used + // to generate the rest of the values + private XMLDocument manifestDoc = null; + private CP_Core cpCore = null; + + private String schema = null; + private String title = null; + private String description = null; + private String defaultItem = null; + private String organzationXML = null; + + // cachedCommonCartridgeList is used to avoid building up the list + // every time an item is parsed - otherwise there is a lot + // of processing done by the reload code time and time again. + private Element[] cachedCommonCartridgeList = null; + + // --- + + private Properties types = new Properties(); + private Properties hrefs = new Properties(); + private Map manifestFullMap = null; + private String directoryName = null; + private List basicLTIItems = null; + + /** + * Set up a package converter, using the supplied directory as the package. The package should be parsed + * automatically and the values readied for calls to getSchema(), getTitle(), etc. + * + * @param directoryName + * : directory containing an expanded IMS content package. + * @throws IMSManifestException + * if there is an error in parsing the manifest file due to an error in the file or an unexpected value. + * @throws ImscpApplicationException + * if there is any other error + */ + public SimpleCommonCartridgeConverter(String directoryName) throws IMSManifestException, ImscpApplicationException { + this.directoryName = directoryName; + this.manifestFullMap = getManifestFullMap(); + + // this.manifestDoc = getDocument(directoryName); + // this.cpCore = new CP_Core(manifestDoc); + // + // // initialise the property file required for the reload code. Needed to make + // // the metadata call work. If we remove the metadata call, then this constructor + // // may be removed. + // System.setProperty("editor.properties.file", "uk.ac.reload.editor.properties.rb"); + + parsePackage(); + } + + /** + * Parse IMS content package expanded out into the supplied directory. Note: the manifest file is expected to be in + * the root of the supplied directory. + * + * @throws ImscpApplicationException + * @throws IMSManifestException + */ + private void parsePackage() throws IMSManifestException, ImscpApplicationException { + + List> resources = XMLMap.getList(manifestFullMap, "/manifest/resources/resource"); + for (Map resource : resources) { + String identifier = XMLMap.getString(resource, "/!identifier"); + if (identifier == null) + continue; + String type = XMLMap.getString(resource, "/!type"); + if (type != null) + types.setProperty(identifier, type); + String href = XMLMap.getString(resource, "/file!href"); + if (href != null) + hrefs.setProperty(identifier, href); + } + + basicLTIItems = new LinkedList(); + try { + List> topItem = XMLMap.getList(manifestFullMap, + "/manifest/organizations/organization/item"); + parseItem(topItem.get(0)); + } catch (IOException e) { + log.error("

    Error displaying navigation from manifest:" + e.getMessage()); + log.error(""); + return; + } + + // String schemaText = getText(manifestDoc, "//metadata/schema"); + // String schemaVersion = getText(manifestDoc, "//metadata/schemaversion"); + // this.schema = (schemaText != null ? schemaText : "unknown") + " " + // + (schemaVersion != null ? schemaVersion : "unknown"); + // + // Document orgs = buildOrganisationList(); + // if (orgs == null) { + // String error = + // "Unable to convert organizations from manifest file to our own structure. Reason unknown - buildOrganisationList returned null"; + // log.error(error); + // throw new ImscpApplicationException(error); + // } + // + // try { + // this.organzationXML = XMLUtils.write2XMLString(orgs); + // } catch (IOException ioe) { + // String error = "Exception thrown converting organization structure (as document) to an XML string." + // + ioe.getMessage(); + // log.error(error, ioe); + // throw new ImscpApplicationException(error, ioe); + // } + // + // XMLPath xmlPath = new XMLPath("//metadata/*:lom/*:general/*:title/*:langstring"); + // this.title = getMetaValue(xmlPath); + // if (this.title == null) { + // // try the old root name - untested + // xmlPath = new XMLPath("//metadata/*:record/*:general/*:title/*:langstring"); + // this.title = getMetaValue(xmlPath); + // } + // + // xmlPath = new XMLPath("//metadata/*:lom/*:general/*:description/*:langstring"); + // this.description = getMetaValue(xmlPath); + // if (this.description == null) { + // // try the old root name - untested + // xmlPath = new XMLPath("//metadata/*:record/*:general/*:description/*:langstring"); + // this.description = getMetaValue(xmlPath); + // } + + } + + private void parseItem(Map item) throws IOException { + String id = XMLMap.getString(item, "/!identifier"); + String ref = XMLMap.getString(item, "/!identifierref"); + String title = XMLMap.getString(item, "/title"); + + // Handle this item + if (ref != null) { + String type = types.getProperty(ref); + String href = hrefs.getProperty(ref); + if (type != null && href != null) { + File basciLTIXml = new File(directoryName, href); + + if (type.equals("webcontent")) { + // content = rawcontent; + } else if (type.equals("imswl_xmlv1p0")) { + // Map xml = null; + // content = "

    Error Parsing Web Link XML

    " + content; + // try { + // xml = XMLMap.getFullMap(rawcontent.trim()); + // String frameref = XMLMap.getString(xml, "/wl:webLink/url!href"); + // if (frameref != null) { + // content = "\n"; + // } + // } catch (Exception e) { + // content = "

    Error Parsing Web Link XML:" + e.getMessage() + "

    " + content; + // } + } else if (type.equals("imsbasiclti_xmlv1p0")) { + String rawcontent = FileUtils.readFileToString(basciLTIXml, "UTF-8"); + Map info = new HashMap(); + Map postProp = new HashMap(); + if (BasicLTIUtil.parseDescriptor(info, postProp, rawcontent)) { + CommonCartridgeItem basicLTI = new CommonCartridgeItem(); + + title = (title != null) ? title : id; + basicLTI.setTitle(title); + basicLTI.setLaunchUrl(info.get("launch_url")); + basicLTI.setSecureLaunchUrl(info.get("secure_launch_url")); + basicLTI.setKey(info.get("key")); + basicLTI.setSecret(info.get("secret")); + + String customStr = ""; + for (String key : postProp.keySet()) { + customStr += key + "=" + postProp.get(key) + "\n"; + } + basicLTI.setCustomStr(customStr); + + basicLTIItems.add(basicLTI); + } + } + } + } + + // Descend recursively to child items + for (Map subItem : XMLMap.getList(item, "/item")) { + parseItem(subItem); + } + + } + + /** + * Finds a value at the given xmlPath. If only one element, uses that value. If more than one element, tries to find + * an English value. + * + * @param xmlPath + * @return Value of the element found at xmlPath. + */ + private String getMetaValue(XMLPath xmlPath) { + Element[] elList = manifestDoc.getElements(xmlPath); + String value = null; + if (elList != null) { + if (elList.length == 0) { + value = "Unknown"; + } else if (elList.length == 1) { + value = elList[0].getTextTrim(); + } else { + value = null; + // TODO check if it is really testing for english + for (int i = 0; value == null && i < elList.length; i++) { + // grab the first English one + Element el = elList[i]; + String attrValue = el.getAttributeValue("lang", Namespace.XML_NAMESPACE); + if (attrValue != null && attrValue.startsWith("en")) { + value = el.getTextTrim(); + } + } + if (value == null) { + // can't seem to find an English one, just pick the first + value = elList[0].getTextTrim(); + } + } + } + return value; + } + + /* Get the text for this element - expect only 1 */ + private String getText(XMLDocument document, String xmlPathString) { + XMLPath xmlPath = new XMLPath(xmlPathString); + Element el = document.getElement(xmlPath); + return el != null ? el.getTextTrim() : null; + } + + private String debug(XMLDocument document, String param, String xmlPathString) { + XMLPath xmlPath = new XMLPath(xmlPathString); + Element[] elList = document.getElements(xmlPath); + if (elList != null) { + log.error(param + " xp: length " + elList.length + " el " + elList); + if (elList.length >= 1) { + log.error("text is " + elList[0].getTextTrim()); + return elList[0].getTextTrim(); + } + } else { + log.error(param + " xp: el is null"); + } + return null; + } + + /** + * @param directoryName + * @return + * @throws JDOMException + * @throws IOException + */ + private XMLDocument getDocument(String directoryName) throws IMSManifestException { + try { + XMLDocument doc = new XMLDocument(); + doc.loadDocument(new File(directoryName, "imsmanifest.xml")); + return doc; + } catch (JDOMException je) { + String error = "Parsing error occured while loading imsmanifest.xml file. Contents of file may be invalid. " + + je.getMessage(); + log.error(error, je); + throw new IMSManifestException(error, je); + } catch (FileNotFoundException e) { + String error = "Unable to find imsmanifest file in the package." + e.getMessage(); + log.error(error, e); + throw new IMSManifestException(error, e); + } catch (IOException ioe) { + String error = "IOException occured while loading imsmanifest file. " + ioe.getMessage(); + log.error(error, ioe); + throw new IMSManifestException(error, ioe); + } + } + + /** + * @param directoryName + * @return + * @throws JDOMException + * @throws IOException + */ + private Map getManifestFullMap() throws IMSManifestException { + + try { + // Parsing manifest + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + org.w3c.dom.Document document = parser.parse(new File(directoryName, "imsmanifest.xml")); + + if (document == null) + return null; + + Map manifestFullMap = XMLMap.getFullMap(document); + + if (manifestFullMap == null) { + log.error("Error parsing manifest XML"); + } + + return manifestFullMap; + + } catch (Exception e) { + log.error("Error parsing manifest XML" + e.getMessage()); + return null; + } + + // out.println("Reading resources from manifest..."); + + // try { + // XMLDocument doc = new XMLDocument(); + // doc.loadDocument(new File(directoryName, "imsmanifest.xml")); + // return doc; + // } catch (JDOMException je) { + // String error = "Parsing error occured while loading imsmanifest.xml file. Contents of file may be invalid. " + // + je.getMessage(); + // log.error(error, je); + // throw new IMSManifestException(error, je); + // } catch (FileNotFoundException e) { + // String error = "Unable to find imsmanifest file in the package." + e.getMessage(); + // log.error(error, e); + // throw new IMSManifestException(error, e); + // } catch (IOException ioe) { + // String error = "IOException occured while loading imsmanifest file. " + ioe.getMessage(); + // log.error(error, ioe); + // throw new IMSManifestException(error, ioe); + // } + } + + /** + * Built an XML document which is a list of organisations/commonCartridge. + */ + private Document buildOrganisationList() throws IMSManifestException { + + Namespace nm = cpCore.getRootManifestElement().getNamespace(); + + Element rootElement = cpCore.getRootManifestElement(); + Element orgsElement = rootElement.getChild(CP_Core.ORGANIZATIONS, nm); + + // set up a list of all the commonCartridge + + // now get all the organizations and set up the new XML document, combining + // the organization and the commonCartridge. + Element defaultOrg = cpCore.getDefaultOrganization(orgsElement); + String defaultOrgIdentifier = null; + if (defaultOrg != null) + defaultOrgIdentifier = defaultOrg.getAttributeValue("identifier"); + + log.debug("cpCore default org id: " + defaultOrgIdentifier); + + Element newRootElement = new Element("organizations"); + setAttribute(newRootElement, "version", "imscp1"); + Document doc = new Document(newRootElement); + + Element[] orgs = cpCore.getOrganizationsAllowed(orgsElement); + Element initOrganizationElement = null; + for (int i = 0; i < orgs.length; i++) { + + Element organizationElement = processItem(orgs[i], nm, defaultOrgIdentifier, null); + if (initOrganizationElement == null) + initOrganizationElement = organizationElement; + + newRootElement.addContent(organizationElement); + } + + if (log.isDebugEnabled()) { + try { + log.debug("Organizations are: " + XMLUtils.write2XMLString(doc)); + } catch (IOException e) { + log.debug("Unable to convert organizations to XML for log. Organizations are: " + doc); + } + } + + return doc; + } + + /** + * Process the given element. Returns a newly formatted Element if the element is a visible item, null otherwise. + * Will also set the value "defaultItemURL" while processing, if it finds the default item. + * + * First time through, the element will be an organization and parentOrgIdentifier will be null. After that, + * elements are expected to be items and parentOrgIdentifier should not be null. + * + * parentOrgIdentifier is the parent organization of an item. An item is the default item if either: (a) the + * defaultOrgIdentifier is null and it is the first item encountered which has a commonCartridge or (b) + * parentOrgIdentifier==defaultOrgIdentifier and it is the first item encountered which has a commonCartridge. + * + * @param element + * @return New version of element combining organization/item/commonCartridge details + */ + private Element processItem(Element element, Namespace nm, String defaultOrgIdentifier, String parentOrgIdentifier) + throws IMSManifestException { + + String isVisibleString = element.getAttributeValue(CP_Core.ISVISIBLE); + if (isVisible(isVisibleString)) { + + String id = element.getAttributeValue(CP_Core.IDENTIFIER); + // only process visible items as we are building the list for display to the user + Element itref = new Element(OrganizationXMLDef.ITEM); + + setAttribute(itref, OrganizationXMLDef.IDENTIFIER, id); // mandatory + setAttribute(itref, OrganizationXMLDef.PARAMETERS, element.getAttributeValue(CP_Core.PARAMETERS)); // optional + setAttribute(itref, OrganizationXMLDef.TITLE, element.getChildText(CP_Core.TITLE, nm)); // optional + String commonCartridgeURL = getCommonCartridgeURL(element); + if (commonCartridgeURL != null) + setAttribute(itref, OrganizationXMLDef.RESOURCE, commonCartridgeURL); // optional + + if (commonCartridgeURL != null && this.defaultItem == null + && (defaultOrgIdentifier == null || defaultOrgIdentifier.equals(parentOrgIdentifier))) { + setAttribute(itref, OrganizationXMLDef.DEFAULT, Boolean.TRUE.toString()); + this.defaultItem = commonCartridgeURL; + } else { + setAttribute(itref, OrganizationXMLDef.DEFAULT, Boolean.FALSE.toString()); + } + + List items = element.getChildren(CP_Core.ITEM, nm); + Iterator iter = items.iterator(); + while (iter.hasNext()) { + Element itrefChild = processItem((Element) iter.next(), nm, defaultOrgIdentifier, + parentOrgIdentifier != null ? parentOrgIdentifier : id); + if (itrefChild != null) + itref.addContent(itrefChild); + } + + return itref; + } + return null; + + } + + /** + * Not sure exactly what format "isVisible" will be in. In the spec, it says Boolean (True|False) yet the + * imslipv1p0cp.zip package has a value of "1". So this code will accept anything as visible except for false (any + * case) or 0. + */ + private boolean isVisible(String value) { + + if (value != null) { + String trimmed = value.trim(); + if (trimmed.equalsIgnoreCase("false") || trimmed.equals("0")) { + return false; + } + } + return true; + } + + private void setAttribute(Element element, String attributeName, String value) { + if (element != null && attributeName != null && value != null) + element.setAttribute(attributeName, value); + } + + /* + * Get the commonCartridge relating to this item. First time called it will get a list of allowed commonCartridge it + * will cache the value in cachedCommonCartridgeList. After that, it will go to the cache. If it doesn't find the + * commonCartridge, then it will regenerate the list of commonCartridge. + * + * This is done for performance - it is assumed that most items will have access to the same commonCartridge. This + * may not be true if sub-manifests are used, hence the regneration of the array if the commonCartridge isn't found + * in the cache. + * + * Note: assumes all reference ids are unique across the whole of the manifest file. + * + * @param item Element of type ITEM + * + * @return relative path of the commonCartridge, null if no IDENTIFIERREF found + * + * @throws IMSManifestException if IDENTIFIERREF is not null but the commonCartridge could not found. + */ + private String getCommonCartridgeURL(Element itemElement) throws IMSManifestException { + + if (cachedCommonCartridgeList == null) { + cachedCommonCartridgeList = cpCore.getReferencedElementsAllowed(itemElement); + if (log.isDebugEnabled()) + log.debug("CommonCartridge are " + cachedCommonCartridgeList); + } + + String identifierRef = itemElement.getAttributeValue(CP_Core.IDENTIFIERREF); + + if (identifierRef == null) { + + return null; + + } else { + + Element commonCartridge = getCommonCartridge2(identifierRef); + + if (commonCartridge == null) { + + // We failed to find a matching commonCartridge so try generating the list again. + // Note: this may case the list to be generated twice first time if the + // commonCartridge is missing. Too bad! + cachedCommonCartridgeList = cpCore.getReferencedElementsAllowed(itemElement); + if (log.isDebugEnabled()) + log.debug("CommonCartridge are " + cachedCommonCartridgeList); + + commonCartridge = getCommonCartridge2(identifierRef); + } + + if (commonCartridge != null) { + return cpCore.getRelativeURL(commonCartridge); + } else { + throw new IMSManifestException("Unable to find commonCartridge for item element " + + itemElement.getAttributeValue(CP_Core.TITLE) + " looking for identifier " + identifierRef); + } + + } + + } + + /** + * @param identifierRef + * @return + */ + private Element getCommonCartridge2(String identifierRef) { + for (int i = 0; i < cachedCommonCartridgeList.length; i++) { + Element commonCartridge = cachedCommonCartridgeList[i]; + if (identifierRef != null && identifierRef.equals(commonCartridge.getAttributeValue(CP_Core.IDENTIFIER))) { + return commonCartridge; + } + } + return null; + } + + /** + * @return Returns the defaultItem. + */ + public String getDefaultItem() { + return defaultItem; + } + + /** + * @param defaultItem + * The defaultItem to set. + */ + public void setDefaultItem(String defaultItem) { + this.defaultItem = defaultItem; + } + + /** + * @return Returns the description. + */ + public String getDescription() { + return description; + } + + /** + * @param description + * The description to set. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return Returns the organzationXML. + */ + public String getOrganzationXML() { + return organzationXML; + } + + /** + * @param organzationXML + * The organzationXML to set. + */ + public void setOrganzationXML(String organzationXML) { + this.organzationXML = organzationXML; + } + + /** + * @return Returns the schema. + */ + public String getSchema() { + return schema; + } + + /** + * @param schema + * The schema to set. + */ + public void setSchema(String schema) { + this.schema = schema; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title + * The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the basicLTIItems. + */ + public List getBasicLTIItems() { + return basicLTIItems; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleContentPackageConverter.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleContentPackageConverter.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/ims/SimpleContentPackageConverter.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,494 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.ims; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jdom.Namespace; + +import uk.ac.reload.jdom.XMLDocument; +import uk.ac.reload.jdom.XMLPath; +import uk.ac.reload.jdom.XMLUtils; +import uk.ac.reload.moonunit.contentpackaging.CP_Core; + +/** + * SimpleContentPackageConverter contains the code required for parsing the IMS Content Package and converting the info + * into our own structures. + * + * Note: this class has instance data, so do not use it as a singleton. + * + * @author Andrey Balan + */ +public class SimpleContentPackageConverter implements IContentPackageConverter { + + private Logger log = Logger.getLogger(SimpleContentPackageConverter.class); + + // manifestDoc and cpCore are set up in the constructor. They are then used + // to generate the rest of the values + private XMLDocument manifestDoc = null; + private CP_Core cpCore = null; + + private String schema = null; + private String title = null; + private String description = null; + private String defaultItem = null; + private String organzationXML = null; + + // cachedCommonCartridgeList is used to avoid building up the list + // every time an item is parsed - otherwise there is a lot + // of processing done by the reload code time and time again. + private Element[] cachedCommonCartridgeList = null; + + /** + * Set up a package converter, using the supplied directory as the package. The package should be parsed + * automatically and the values readied for calls to getSchema(), getTitle(), etc. + * + * @param directoryName + * : directory containing an expanded IMS content package. + * @throws IMSManifestException + * if there is an error in parsing the manifest file due to an error in the file or an unexpected value. + * @throws ImscpApplicationException + * if there is any other error + */ + public SimpleContentPackageConverter(String directoryName) throws IMSManifestException, ImscpApplicationException { + + this.manifestDoc = getDocument(directoryName); + this.cpCore = new CP_Core(manifestDoc); + + // initialise the property file required for the reload code. Needed to make + // the metadata call work. If we remove the metadata call, then this constructor + // may be removed. + System.setProperty("editor.properties.file", "uk.ac.reload.editor.properties.rb"); + + parsePackage(); + } + + /** + * Parse IMS content package expanded out into the supplied directory. Note: the manifest file is expected to be in + * the root of the supplied directory. + * + * @throws ImscpApplicationException + * @throws IMSManifestException + */ + private void parsePackage() throws IMSManifestException, ImscpApplicationException { + + String schemaText = getText(manifestDoc, "//metadata/schema"); + String schemaVersion = getText(manifestDoc, "//metadata/schemaversion"); + this.schema = (schemaText != null ? schemaText : "unknown") + " " + + (schemaVersion != null ? schemaVersion : "unknown"); + + Document orgs = buildOrganisationList(); + if (orgs == null) { + String error = "Unable to convert organizations from manifest file to our own structure. Reason unknown - buildOrganisationList returned null"; + log.error(error); + throw new ImscpApplicationException(error); + } + + try { + this.organzationXML = XMLUtils.write2XMLString(orgs); + } catch (IOException ioe) { + String error = "Exception thrown converting organization structure (as document) to an XML string." + + ioe.getMessage(); + log.error(error, ioe); + throw new ImscpApplicationException(error, ioe); + } + + XMLPath xmlPath = new XMLPath("//metadata/*:lom/*:general/*:title/*:langstring"); + this.title = getMetaValue(xmlPath); + if (this.title == null) { + // try the old root name - untested + xmlPath = new XMLPath("//metadata/*:record/*:general/*:title/*:langstring"); + this.title = getMetaValue(xmlPath); + } + + xmlPath = new XMLPath("//metadata/*:lom/*:general/*:description/*:langstring"); + this.description = getMetaValue(xmlPath); + if (this.description == null) { + // try the old root name - untested + xmlPath = new XMLPath("//metadata/*:record/*:general/*:description/*:langstring"); + this.description = getMetaValue(xmlPath); + } + + } + + /** + * Finds a value at the given xmlPath. If only one element, uses that value. If more than one element, tries to find + * an English value. + * + * @param xmlPath + * @return Value of the element found at xmlPath. + */ + private String getMetaValue(XMLPath xmlPath) { + Element[] elList = manifestDoc.getElements(xmlPath); + String value = null; + if (elList != null) { + if (elList.length == 0) { + value = "Unknown"; + } else if (elList.length == 1) { + value = elList[0].getTextTrim(); + } else { + value = null; + // TODO check if it is really testing for english + for (int i = 0; value == null && i < elList.length; i++) { + // grab the first English one + Element el = elList[i]; + String attrValue = el.getAttributeValue("lang", Namespace.XML_NAMESPACE); + if (attrValue != null && attrValue.startsWith("en")) { + value = el.getTextTrim(); + } + } + if (value == null) { + // can't seem to find an English one, just pick the first + value = elList[0].getTextTrim(); + } + } + } + return value; + } + + /* Get the text for this element - expect only 1 */ + private String getText(XMLDocument document, String xmlPathString) { + XMLPath xmlPath = new XMLPath(xmlPathString); + Element el = document.getElement(xmlPath); + return el != null ? el.getTextTrim() : null; + } + + private String debug(XMLDocument document, String param, String xmlPathString) { + XMLPath xmlPath = new XMLPath(xmlPathString); + Element[] elList = document.getElements(xmlPath); + if (elList != null) { + log.error(param + " xp: length " + elList.length + " el " + elList); + if (elList.length >= 1) { + log.error("text is " + elList[0].getTextTrim()); + return elList[0].getTextTrim(); + } + } else { + log.error(param + " xp: el is null"); + } + return null; + } + + /** + * @param directoryName + * @return + * @throws JDOMException + * @throws IOException + */ + private XMLDocument getDocument(String directoryName) throws IMSManifestException { + try { + XMLDocument doc = new XMLDocument(); + doc.loadDocument(new File(directoryName, "imsmanifest.xml")); + return doc; + } catch (JDOMException je) { + String error = "Parsing error occured while loading imsmanifest.xml file. Contents of file may be invalid. " + + je.getMessage(); + log.error(error, je); + throw new IMSManifestException(error, je); + } catch (FileNotFoundException e) { + String error = "Unable to find imsmanifest file in the package." + e.getMessage(); + log.error(error, e); + throw new IMSManifestException(error, e); + } catch (IOException ioe) { + String error = "IOException occured while loading imsmanifest file. " + ioe.getMessage(); + log.error(error, ioe); + throw new IMSManifestException(error, ioe); + } + } + + /** + * Built an XML document which is a list of organisations/commonCartridge. + */ + private Document buildOrganisationList() throws IMSManifestException { + + Namespace nm = cpCore.getRootManifestElement().getNamespace(); + + Element rootElement = cpCore.getRootManifestElement(); + Element orgsElement = rootElement.getChild(CP_Core.ORGANIZATIONS, nm); + + // set up a list of all the commonCartridge + + // now get all the organizations and set up the new XML document, combining + // the organization and the commonCartridge. + Element defaultOrg = cpCore.getDefaultOrganization(orgsElement); + String defaultOrgIdentifier = null; + if (defaultOrg != null) + defaultOrgIdentifier = defaultOrg.getAttributeValue("identifier"); + + log.debug("cpCore default org id: " + defaultOrgIdentifier); + + Element newRootElement = new Element("organizations"); + setAttribute(newRootElement, "version", "imscp1"); + Document doc = new Document(newRootElement); + + Element[] orgs = cpCore.getOrganizationsAllowed(orgsElement); + Element initOrganizationElement = null; + for (int i = 0; i < orgs.length; i++) { + + Element organizationElement = processItem(orgs[i], nm, defaultOrgIdentifier, null); + if (initOrganizationElement == null) + initOrganizationElement = organizationElement; + + newRootElement.addContent(organizationElement); + } + + if (log.isDebugEnabled()) { + try { + log.debug("Organizations are: " + XMLUtils.write2XMLString(doc)); + } catch (IOException e) { + log.debug("Unable to convert organizations to XML for log. Organizations are: " + doc); + } + } + + return doc; + } + + /** + * Process the given element. Returns a newly formatted Element if the element is a visible item, null otherwise. + * Will also set the value "defaultItemURL" while processing, if it finds the default item. + * + * First time through, the element will be an organization and parentOrgIdentifier will be null. After that, + * elements are expected to be items and parentOrgIdentifier should not be null. + * + * parentOrgIdentifier is the parent organization of an item. An item is the default item if either: (a) the + * defaultOrgIdentifier is null and it is the first item encountered which has a commonCartridge or (b) + * parentOrgIdentifier==defaultOrgIdentifier and it is the first item encountered which has a commonCartridge. + * + * @param element + * @return New version of element combining organization/item/commonCartridge details + */ + private Element processItem(Element element, Namespace nm, String defaultOrgIdentifier, String parentOrgIdentifier) + throws IMSManifestException { + + String isVisibleString = element.getAttributeValue(CP_Core.ISVISIBLE); + if (isVisible(isVisibleString)) { + + String id = element.getAttributeValue(CP_Core.IDENTIFIER); + // only process visible items as we are building the list for display to the user + Element itref = new Element(OrganizationXMLDef.ITEM); + + setAttribute(itref, OrganizationXMLDef.IDENTIFIER, id); // mandatory + setAttribute(itref, OrganizationXMLDef.PARAMETERS, element.getAttributeValue(CP_Core.PARAMETERS)); // optional + setAttribute(itref, OrganizationXMLDef.TITLE, element.getChildText(CP_Core.TITLE, nm)); // optional + String commonCartridgeURL = getCommonCartridgeURL(element); + if (commonCartridgeURL != null) + setAttribute(itref, OrganizationXMLDef.RESOURCE, commonCartridgeURL); // optional + + if (commonCartridgeURL != null && this.defaultItem == null + && (defaultOrgIdentifier == null || defaultOrgIdentifier.equals(parentOrgIdentifier))) { + setAttribute(itref, OrganizationXMLDef.DEFAULT, Boolean.TRUE.toString()); + this.defaultItem = commonCartridgeURL; + } else { + setAttribute(itref, OrganizationXMLDef.DEFAULT, Boolean.FALSE.toString()); + } + + List items = element.getChildren(CP_Core.ITEM, nm); + Iterator iter = items.iterator(); + while (iter.hasNext()) { + Element itrefChild = processItem((Element) iter.next(), nm, defaultOrgIdentifier, + parentOrgIdentifier != null ? parentOrgIdentifier : id); + if (itrefChild != null) + itref.addContent(itrefChild); + } + + return itref; + } + return null; + + } + + /** + * Not sure exactly what format "isVisible" will be in. In the spec, it says Boolean (True|False) yet the + * imslipv1p0cp.zip package has a value of "1". So this code will accept anything as visible except for false (any + * case) or 0. + */ + private boolean isVisible(String value) { + + if (value != null) { + String trimmed = value.trim(); + if (trimmed.equalsIgnoreCase("false") || trimmed.equals("0")) { + return false; + } + } + return true; + } + + private void setAttribute(Element element, String attributeName, String value) { + if (element != null && attributeName != null && value != null) + element.setAttribute(attributeName, value); + } + + /* + * Get the commonCartridge relating to this item. First time called it will get a list of allowed commonCartridge it will cache + * the value in cachedCommonCartridgeList. After that, it will go to the cache. If it doesn't find the commonCartridge, then it + * will regenerate the list of commonCartridge. + * + * This is done for performance - it is assumed that most items will have access to the same commonCartridge. This may not + * be true if sub-manifests are used, hence the regneration of the array if the commonCartridge isn't found in the cache. + * + * Note: assumes all reference ids are unique across the whole of the manifest file. + * + * @param item Element of type ITEM + * + * @return relative path of the commonCartridge, null if no IDENTIFIERREF found + * + * @throws IMSManifestException if IDENTIFIERREF is not null but the commonCartridge could not found. + */ + private String getCommonCartridgeURL(Element itemElement) throws IMSManifestException { + + if (cachedCommonCartridgeList == null) { + cachedCommonCartridgeList = cpCore.getReferencedElementsAllowed(itemElement); + if (log.isDebugEnabled()) + log.debug("CommonCartridge are " + cachedCommonCartridgeList); + } + + String identifierRef = itemElement.getAttributeValue(CP_Core.IDENTIFIERREF); + + if (identifierRef == null) { + + return null; + + } else { + + Element commonCartridge = getCommonCartridge2(identifierRef); + + if (commonCartridge == null) { + + // We failed to find a matching commonCartridge so try generating the list again. + // Note: this may case the list to be generated twice first time if the + // commonCartridge is missing. Too bad! + cachedCommonCartridgeList = cpCore.getReferencedElementsAllowed(itemElement); + if (log.isDebugEnabled()) + log.debug("CommonCartridge are " + cachedCommonCartridgeList); + + commonCartridge = getCommonCartridge2(identifierRef); + } + + if (commonCartridge != null) { + return cpCore.getRelativeURL(commonCartridge); + } else { + throw new IMSManifestException("Unable to find commonCartridge for item element " + + itemElement.getAttributeValue(CP_Core.TITLE) + " looking for identifier " + identifierRef); + } + + } + + } + + /** + * @param identifierRef + * @return + */ + private Element getCommonCartridge2(String identifierRef) { + for (int i = 0; i < cachedCommonCartridgeList.length; i++) { + Element commonCartridge = cachedCommonCartridgeList[i]; + if (identifierRef != null && identifierRef.equals(commonCartridge.getAttributeValue(CP_Core.IDENTIFIER))) { + return commonCartridge; + } + } + return null; + } + + /** + * @return Returns the defaultItem. + */ + public String getDefaultItem() { + return defaultItem; + } + + /** + * @param defaultItem + * The defaultItem to set. + */ + public void setDefaultItem(String defaultItem) { + this.defaultItem = defaultItem; + } + + /** + * @return Returns the description. + */ + public String getDescription() { + return description; + } + + /** + * @param description + * The description to set. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return Returns the organzationXML. + */ + public String getOrganzationXML() { + return organzationXML; + } + + /** + * @param organzationXML + * The organzationXML to set. + */ + public void setOrganzationXML(String organzationXML) { + this.organzationXML = organzationXML; + } + + /** + * @return Returns the schema. + */ + public String getSchema() { + return schema; + } + + /** + * @param schema + * The schema to set. + */ + public void setSchema(String schema) { + this.schema = schema; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title + * The title to set. + */ + public void setTitle(String title) { + this.title = title; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridge.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,546 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeToolContentHandler; + +/** + * CommonCartridge + * + * @author Andrey Balan + * + * @hibernate.class table="tl_laimsc11_commonCartridge" + * + */ +public class CommonCartridge implements Cloneable { + + private static final Logger log = Logger.getLogger(CommonCartridge.class); + + // key + private Long uid; + + // tool contentID + private Long contentId; + + private String title; + + private String instructions; + + // advance + private boolean runOffline; + + private boolean runAuto; + + private int miniViewCommonCartridgeNumber; + + private boolean lockWhenFinished; + + private boolean defineLater; + + private boolean contentInUse; + + // instructions + private String onlineInstructions; + + private String offlineInstructions; + + private Set attachments; + + // general infomation + private Date created; + + private Date updated; + + private CommonCartridgeUser createdBy; + + // commonCartridge Items + private Set commonCartridgeItems; + + private boolean reflectOnActivity; + + private String reflectInstructions; + + // *************** NON Persist Fields ******************** + private IToolContentHandler toolContentHandler; + + private String miniViewNumberStr; + + private List onlineFileList; + + private List offlineFileList; + + /** + * Default contruction method. + * + */ + public CommonCartridge() { + attachments = new HashSet(); + commonCartridgeItems = new HashSet(); + } + + // ********************************************************** + // Function method for CommonCartridge + // ********************************************************** + public static CommonCartridge newInstance(CommonCartridge defaultContent, Long contentId, + CommonCartridgeToolContentHandler commonCartridgeToolContentHandler) { + CommonCartridge toContent = new CommonCartridge(); + defaultContent.toolContentHandler = commonCartridgeToolContentHandler; + toContent = (CommonCartridge) defaultContent.clone(); + toContent.setContentId(contentId); + + // reset user info as well + if (toContent.getCreatedBy() != null) { + toContent.getCreatedBy().setCommonCartridge(toContent); + Set items = toContent.getCommonCartridgeItems(); + for (CommonCartridgeItem item : items) { + item.setCreateBy(toContent.getCreatedBy()); + } + } + return toContent; + } + + @Override + public Object clone() { + + CommonCartridge commonCartridge = null; + try { + commonCartridge = (CommonCartridge) super.clone(); + commonCartridge.setUid(null); + if (commonCartridgeItems != null) { + Iterator iter = commonCartridgeItems.iterator(); + Set set = new HashSet(); + while (iter.hasNext()) { + CommonCartridgeItem item = (CommonCartridgeItem) iter.next(); + CommonCartridgeItem newItem = (CommonCartridgeItem) item.clone(); + // just clone old file without duplicate it in repository + set.add(newItem); + } + commonCartridge.commonCartridgeItems = set; + } + // clone attachment + if (attachments != null) { + Iterator iter = attachments.iterator(); + Set set = new HashSet(); + while (iter.hasNext()) { + CommonCartridgeAttachment file = (CommonCartridgeAttachment) iter.next(); + CommonCartridgeAttachment newFile = (CommonCartridgeAttachment) file.clone(); + // just clone old file without duplicate it in repository + + set.add(newFile); + } + commonCartridge.attachments = set; + } + // clone ReourceUser as well + if (createdBy != null) { + commonCartridge.setCreatedBy((CommonCartridgeUser) createdBy.clone()); + } + } catch (CloneNotSupportedException e) { + CommonCartridge.log.error("When clone " + CommonCartridge.class + " failed"); + } + + return commonCartridge; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CommonCartridge)) { + return false; + } + + final CommonCartridge genericEntity = (CommonCartridge) o; + + return new EqualsBuilder().append(uid, genericEntity.uid).append(title, genericEntity.title) + .append(instructions, genericEntity.instructions) + .append(onlineInstructions, genericEntity.onlineInstructions) + .append(offlineInstructions, genericEntity.offlineInstructions).append(created, genericEntity.created) + .append(updated, genericEntity.updated).append(createdBy, genericEntity.createdBy).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(uid).append(title).append(instructions).append(onlineInstructions) + .append(offlineInstructions).append(created).append(updated).append(createdBy).toHashCode(); + } + + /** + * Updates the modification data for this entity. + */ + public void updateModificationData() { + + long now = System.currentTimeMillis(); + if (created == null) { + this.setCreated(new Date(now)); + } + this.setUpdated(new Date(now)); + } + + public void toDTO() { + onlineFileList = new ArrayList(); + offlineFileList = new ArrayList(); + Set fileSet = this.getAttachments(); + if (fileSet != null) { + for (CommonCartridgeAttachment file : fileSet) { + if (StringUtils.equalsIgnoreCase(file.getFileType(), IToolContentHandler.TYPE_OFFLINE)) { + offlineFileList.add(file); + } else { + onlineFileList.add(file); + } + } + } + } + + // ********************************************************** + // get/set methods + // ********************************************************** + /** + * Returns the object's creation date + * + * @return date + * @hibernate.property column="create_date" + */ + public Date getCreated() { + return created; + } + + /** + * Sets the object's creation date + * + * @param created + */ + public void setCreated(Date created) { + this.created = created; + } + + /** + * Returns the object's date of last update + * + * @return date updated + * @hibernate.property column="update_date" + */ + public Date getUpdated() { + return updated; + } + + /** + * Sets the object's date of last update + * + * @param updated + */ + public void setUpdated(Date updated) { + this.updated = updated; + } + + /** + * @return Returns the userid of the user who created the Share commonCartridge. + * + * @hibernate.many-to-one cascade="save-update" column="create_by" + * + */ + public CommonCartridgeUser getCreatedBy() { + return createdBy; + } + + /** + * @param createdBy + * The userid of the user who created this Share commonCartridge. + */ + public void setCreatedBy(CommonCartridgeUser createdBy) { + this.createdBy = createdBy; + } + + /** + * @hibernate.id column="uid" generator-class="native" + */ + public Long getUid() { + return uid; + } + + public void setUid(Long uid) { + this.uid = uid; + } + + /** + * @return Returns the title. + * + * @hibernate.property column="title" + * + */ + public String getTitle() { + return title; + } + + /** + * @param title + * The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the runOffline. + * + * @hibernate.property column="run_offline" + * + */ + public boolean getRunOffline() { + return runOffline; + } + + /** + * @param runOffline + * The forceOffLine to set. + * + * + */ + public void setRunOffline(boolean forceOffline) { + runOffline = forceOffline; + } + + /** + * @return Returns the lockWhenFinish. + * + * @hibernate.property column="lock_on_finished" + * + */ + public boolean getLockWhenFinished() { + return lockWhenFinished; + } + + /** + * @param lockWhenFinished + * Set to true to lock the commonCartridge for finished users. + */ + public void setLockWhenFinished(boolean lockWhenFinished) { + this.lockWhenFinished = lockWhenFinished; + } + + /** + * @return Returns the instructions set by the teacher. + * + * @hibernate.property column="instructions" type="text" + */ + public String getInstructions() { + return instructions; + } + + public void setInstructions(String instructions) { + this.instructions = instructions; + } + + /** + * @return Returns the onlineInstructions set by the teacher. + * + * @hibernate.property column="online_instructions" type="text" + */ + public String getOnlineInstructions() { + return onlineInstructions; + } + + public void setOnlineInstructions(String onlineInstructions) { + this.onlineInstructions = onlineInstructions; + } + + /** + * @return Returns the onlineInstructions set by the teacher. + * + * @hibernate.property column="offline_instructions" type="text" + */ + public String getOfflineInstructions() { + return offlineInstructions; + } + + public void setOfflineInstructions(String offlineInstructions) { + this.offlineInstructions = offlineInstructions; + } + + /** + * + * @hibernate.set lazy="true" cascade="all" inverse="false" order-by="create_date desc" + * @hibernate.collection-key column="commonCartridge_uid" + * @hibernate.collection-one-to-many + * class="org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeAttachment" + * + * @return a set of Attachments to this Message. + */ + public Set getAttachments() { + return attachments; + } + + /* + * @param attachments The attachments to set. + */ + public void setAttachments(Set attachments) { + this.attachments = attachments; + } + + /** + * + * + * @hibernate.set lazy="true" inverse="false" cascade="all" order-by="create_date desc" + * @hibernate.collection-key column="commonCartridge_uid" + * @hibernate.collection-one-to-many class="org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem" + * + * @return + */ + public Set getCommonCartridgeItems() { + return commonCartridgeItems; + } + + public void setCommonCartridgeItems(Set commonCartridgeItems) { + this.commonCartridgeItems = commonCartridgeItems; + } + + /** + * @hibernate.property column="content_in_use" + * @return + */ + public boolean isContentInUse() { + return contentInUse; + } + + public void setContentInUse(boolean contentInUse) { + this.contentInUse = contentInUse; + } + + /** + * @hibernate.property column="define_later" + * @return + */ + public boolean isDefineLater() { + return defineLater; + } + + public void setDefineLater(boolean defineLater) { + this.defineLater = defineLater; + } + + /** + * @hibernate.property column="content_id" unique="true" + * @return + */ + public Long getContentId() { + return contentId; + } + + public void setContentId(Long contentId) { + this.contentId = contentId; + } + + /** + * @hibernate.property column="mini_view_commonCartridge_number" + * @return + */ + public int getMiniViewCommonCartridgeNumber() { + return miniViewCommonCartridgeNumber; + } + + public void setMiniViewCommonCartridgeNumber(int minViewCommonCartridgeNumber) { + miniViewCommonCartridgeNumber = minViewCommonCartridgeNumber; + } + + /** + * @hibernate.property column="allow_auto_run" + * @return + */ + public boolean isRunAuto() { + return runAuto; + } + + public void setRunAuto(boolean runAuto) { + this.runAuto = runAuto; + } + + /** + * For display use + * + * @return + */ + public String getMiniViewNumberStr() { + return miniViewNumberStr; + } + + public void setMiniViewNumberStr(String minViewNumber) { + miniViewNumberStr = minViewNumber; + } + + public List getOfflineFileList() { + return offlineFileList; + } + + public void setOfflineFileList(List offlineFileList) { + this.offlineFileList = offlineFileList; + } + + public List getOnlineFileList() { + return onlineFileList; + } + + public void setOnlineFileList(List onlineFileList) { + this.onlineFileList = onlineFileList; + } + + public void setToolContentHandler(IToolContentHandler toolContentHandler) { + this.toolContentHandler = toolContentHandler; + } + + /** + * @hibernate.property column="reflect_instructions" + * @return + */ + public String getReflectInstructions() { + return reflectInstructions; + } + + public void setReflectInstructions(String reflectInstructions) { + this.reflectInstructions = reflectInstructions; + } + + /** + * @hibernate.property column="reflect_on_activity" + * @return + */ + public boolean isReflectOnActivity() { + return reflectOnActivity; + } + + public void setReflectOnActivity(boolean reflectOnActivity) { + this.reflectOnActivity = reflectOnActivity; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeAttachment.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,163 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.Date; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.log4j.Logger; + +/** + * @author Andrey Balan + * + * A Wrapper class for uploaded files. An Attachment cannot exist independently + * and must belong to a CommonCartridge. + * + * + * @hibernate.class table="tl_laimsc11_attachment" + * + */ +public class CommonCartridgeAttachment implements Cloneable{ + private static final Logger log = Logger.getLogger(CommonCartridgeAttachment.class); + + private Long uid; + private Long fileUuid; + private Long fileVersionId; + private String fileType; + private String fileName; + private Date created; + + //Default contruction method + public CommonCartridgeAttachment(){ + + } +// ********************************************************** + // Function method for Attachment +// ********************************************************** + public Object clone(){ + Object obj = null; + try { + obj = super.clone(); + ((CommonCartridgeAttachment)obj).setUid(null); + } catch (CloneNotSupportedException e) { + log.error("When clone " + CommonCartridgeAttachment.class + " failed"); + } + + return obj; + } + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof CommonCartridgeAttachment)) + return false; + + final CommonCartridgeAttachment genericEntity = (CommonCartridgeAttachment) o; + + return new EqualsBuilder() + .append(this.uid,genericEntity.uid) + .append(this.fileVersionId,genericEntity.fileVersionId) + .append(this.fileName,genericEntity.fileName) + .append(this.fileType,genericEntity.fileType) + .append(this.created,genericEntity.created) + .isEquals(); + } + + public int hashCode() { + return new HashCodeBuilder().append(uid).append(fileVersionId).append(fileName).append(fileType).append(created) + .toHashCode(); + } + +// ********************************************************** + // get/set methods +// ********************************************************** + /** + * @hibernate.id column="uid" generator-class="native" + */ + public Long getUid() { + return uid; + } + + public void setUid(Long uid) { + this.uid = uid; + } + + /** + * @hibernate.property column="file_version_id" + * + */ + public Long getFileVersionId() { + return fileVersionId; + } + + public void setFileVersionId(Long version) { + this.fileVersionId = version; + } + + /** + * @hibernate.property column="file_type" + */ + public String getFileType() { + return fileType; + } + + public void setFileType(String type) { + this.fileType = type; + } + + /** + * @hibernate.property column="file_name" + */ + public String getFileName() { + return fileName; + } + + public void setFileName(String name) { + this.fileName = name; + } + + + /** + * @hibernate.property column="file_uuid" + * @return + */ + public Long getFileUuid() { + return fileUuid; + } + + public void setFileUuid(Long uuid) { + this.fileUuid = uuid; + } + /** + * @hibernate.property column="create_date" + * @return + */ + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeConfigItem.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,73 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +/** + * @hibernate.class table="tl_laimsc11_configuration" + */ +public class CommonCartridgeConfigItem implements java.io.Serializable { + + private static final long serialVersionUID = 6360672537352753361L; + + public static final String KEY_EXPOSE_USER_NAME = "allowExposeUserName"; + public static final String KEY_EXPOSE_USER_EMAIL = "allowExposeUserEmail"; + + Long id; + String configKey; + String configValue; + + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * + */ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + /** + * @hibernate.property column="config_key" length="30" not-null="false" unique="true" + */ + public String getConfigKey() { + return configKey; + } + + public void setConfigKey(String configKey) { + this.configKey = configKey; + } + + /** + * @hibernate.property column="config_value" length="255" not-null="false" + */ + public String getConfigValue() { + return configValue; + } + + public void setConfigValue(String configValue) { + this.configValue = configValue; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItem.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,433 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; + +/** + * CommonCartridge + * + * @author Andrey Balan + * + * @hibernate.class table="tl_laimsc11_commonCartridge_item" + * + */ +public class CommonCartridgeItem implements Cloneable { + private static final Logger log = Logger.getLogger(CommonCartridgeItem.class); + + private Long uid; + // CommonCartridge Type:1=URL,2=File,3=Website,4=Learning Object + private short type; + + private String title; + + private String description; + + private String url; + + private String imsSchema; + + private String initialItem; + + private String organizationXml; + + private String launchUrl; + private String secureLaunchUrl; + private String key; + private String secret; + private String customStr; + private int frameHeight; + private boolean openUrlNewWindow; + private String buttonText; + + private Long fileUuid; + + private Long fileVersionId; + + private String fileName; + + private String fileType; + + private Set itemInstructions; + + private boolean isHide; + private boolean isCreateByAuthor; + + private Date createDate; + private CommonCartridgeUser createBy; + + // *********************************************** + // DTO fields: + private boolean complete; + + public Object clone() { + CommonCartridgeItem obj = null; + try { + obj = (CommonCartridgeItem) super.clone(); + // clone attachment + if (itemInstructions != null) { + Iterator iter = itemInstructions.iterator(); + Set set = new HashSet(); + while (iter.hasNext()) { + CommonCartridgeItemInstruction instruct = (CommonCartridgeItemInstruction) iter.next(); + CommonCartridgeItemInstruction newInsruct = (CommonCartridgeItemInstruction) instruct.clone(); + set.add(newInsruct); + } + obj.itemInstructions = set; + } + ((CommonCartridgeItem) obj).setUid(null); + // clone ReourceUser as well + if (this.createBy != null) + ((CommonCartridgeItem) obj).setCreateBy((CommonCartridgeUser) this.createBy.clone()); + + } catch (CloneNotSupportedException e) { + log.error("When clone " + CommonCartridgeItem.class + " failed"); + } + + return obj; + } + + // ********************************************************** + // Get/Set methods + // ********************************************************** + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the uid. + */ + public Long getUid() { + return uid; + } + + /** + * @param uid + * The uid to set. + */ + public void setUid(Long userID) { + this.uid = userID; + } + + /** + * @hibernate.property column="file_uuid" + * + * @return + */ + public Long getFileUuid() { + return fileUuid; + } + + public void setFileUuid(Long crUuid) { + this.fileUuid = crUuid; + } + + /** + * @hibernate.property column="file_version_id" + * @return + */ + public Long getFileVersionId() { + return fileVersionId; + } + + public void setFileVersionId(Long crVersionId) { + this.fileVersionId = crVersionId; + } + + /** + * @hibernate.property column="description" + * @return + */ + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + /** + * @hibernate.property column="ims_schema" + * @return + */ + public String getImsSchema() { + return imsSchema; + } + + public void setImsSchema(String imsSchema) { + this.imsSchema = imsSchema; + } + + /** + * @hibernate.property column="init_item" + * @return + */ + public String getInitialItem() { + return initialItem; + } + + public void setInitialItem(String initialItem) { + this.initialItem = initialItem; + } + + /** + * @hibernate.set lazy="false" cascade="all-delete-orphan" inverse="false" order-by="sequence_id asc" + * @hibernate.collection-key column="item_uid" + * @hibernate.collection-one-to-many + * class="org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemInstruction" + * @return + */ + public Set getItemInstructions() { + return itemInstructions; + } + + public void setItemInstructions(Set itemInstructions) { + this.itemInstructions = itemInstructions; + } + + /** + * @hibernate.property column="organization_xml" length="65535" + * @return + */ + public String getOrganizationXml() { + return organizationXml; + } + + public void setOrganizationXml(String organizationXml) { + this.organizationXml = organizationXml; + } + + /** + * @hibernate.property column="title" length="255" + * @return + */ + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + /** + * @hibernate.property column="url" length="65535" + * @return + */ + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + /** + * @hibernate.many-to-one cascade="none" column="create_by" + * + * @return + */ + public CommonCartridgeUser getCreateBy() { + return createBy; + } + + public void setCreateBy(CommonCartridgeUser createBy) { + this.createBy = createBy; + } + + /** + * @hibernate.property column="create_date" + * @return + */ + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + /** + * @hibernate.property column="create_by_author" + * @return + */ + public boolean isCreateByAuthor() { + return isCreateByAuthor; + } + + public void setCreateByAuthor(boolean isCreateByAuthor) { + this.isCreateByAuthor = isCreateByAuthor; + } + + /** + * @hibernate.property column="is_hide" + * @return + */ + public boolean isHide() { + return isHide; + } + + public void setHide(boolean isHide) { + this.isHide = isHide; + } + + /** + * @hibernate.property column="item_type" + * @return + */ + public short getType() { + return type; + } + + public void setType(short type) { + this.type = type; + } + + /** + * @hibernate.property column="file_type" + */ + public String getFileType() { + return fileType; + } + + public void setFileType(String type) { + this.fileType = type; + } + + /** + * @hibernate.property column="file_name" + */ + public String getFileName() { + return fileName; + } + + public void setFileName(String name) { + this.fileName = name; + } + + /** + * @hibernate.property column="open_url_new_window" + * @return + */ + public boolean isOpenUrlNewWindow() { + return openUrlNewWindow; + } + + public void setOpenUrlNewWindow(boolean openUrlNewWindow) { + this.openUrlNewWindow = openUrlNewWindow; + } + + /** + * @hibernate.property column="launch_url" length="255" + * @return + */ + public String getLaunchUrl() { + return launchUrl; + } + + public void setLaunchUrl(String launchUrl) { + this.launchUrl = launchUrl; + } + + /** + * @hibernate.property column="secure_launch_url" length="255" + * @return + */ + public String getSecureLaunchUrl() { + return secureLaunchUrl; + } + + public void setSecureLaunchUrl(String secureLaunchUrl) { + this.secureLaunchUrl = secureLaunchUrl; + } + + /** + * @hibernate.property column="tool_key" length="255" + * @return + */ + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + /** + * @hibernate.property column="tool_secret" length="255" + * @return + */ + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + /** + * @hibernate.property column="custom_str" length="65535" + * @return + */ + public String getCustomStr() { + return customStr; + } + + public void setCustomStr(String customStr) { + this.customStr = customStr; + } + + /** + * @hibernate.property column="button_text" length="255" + * @return + */ + public String getButtonText() { + return buttonText; + } + + public void setButtonText(String buttonText) { + this.buttonText = buttonText; + } + + /** + * @hibernate.property column="frame_height" + * @return + */ + public int getFrameHeight() { + return frameHeight; + } + + public void setFrameHeight(int frameHeight) { + this.frameHeight = frameHeight; + } + + public void setComplete(boolean complete) { + this.complete = complete; + } + + public boolean isComplete() { + return complete; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemInstruction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,86 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import org.apache.log4j.Logger; +/** + * @hibernate.class table="tl_laimsc11_item_instruction" + * @author Andrey Balan + */ +public class CommonCartridgeItemInstruction implements Cloneable{ + private static final Logger log = Logger.getLogger(CommonCartridgeItemInstruction.class); + + private Long uid; + private int sequenceId; + private String description; + + public Object clone(){ + Object obj = null; + try { + obj = super.clone(); + ((CommonCartridgeItemInstruction)obj).setUid(null); + } catch (CloneNotSupportedException e) { + log.error("When clone " + CommonCartridgeItemInstruction.class + " failed"); + } + + return obj; + } +// ********************************************************** + // Get/Set methods +// ********************************************************** + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the uid. + */ + public Long getUid() { + return uid; + } + /** + * @param uid The uid to set. + */ + public void setUid(Long userID) { + this.uid = userID; + } + /** + * @hibernate.property column="description" + * @return + */ + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + /** + * @hibernate.property column="sequence_id" + * @return + */ + public int getSequenceId() { + return sequenceId; + } + public void setSequenceId(int sequenceId) { + this.sequenceId = sequenceId; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeItemVisitLog.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,111 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.Date; +/** + * CommonCartridge + * @author Andrey Balan + * + * @hibernate.class table="tl_laimsc11_item_log" + * + */ +public class CommonCartridgeItemVisitLog { + + private Long uid; + private CommonCartridgeUser user; + private CommonCartridgeItem commonCartridgeItem; + private boolean complete; + private Date accessDate; + private Long sessionId; + + /** + * @hibernate.property column="access_date" + * @return + */ + public Date getAccessDate() { + return accessDate; + } + public void setAccessDate(Date accessDate) { + this.accessDate = accessDate; + } + /** + * @hibernate.many-to-one column="commonCartridge_item_uid" + * cascade="none" + * @return + */ + public CommonCartridgeItem getCommonCartridgeItem() { + return commonCartridgeItem; + } + public void setCommonCartridgeItem(CommonCartridgeItem item) { + this.commonCartridgeItem = item; + } + + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the log Uid. + */ + public Long getUid() { + return uid; + } + public void setUid(Long uid) { + this.uid = uid; + } + /** + * @hibernate.many-to-one column="user_uid" + * cascade="none" + * @return + */ + public CommonCartridgeUser getUser() { + return user; + } + public void setUser(CommonCartridgeUser user) { + this.user = user; + } + /** + * @hibernate.property column="complete" + * @return + */ + public boolean isComplete() { + return complete; + } + public void setComplete(boolean complete) { + this.complete = complete; + } + /** + * @hibernate.property column="session_id" + * @return + */ + public Long getSessionId() { + return sessionId; + } + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + + + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeSession.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,158 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.Date; +import java.util.Set; + +import org.apache.log4j.Logger; + +/** + * CommonCartridge + * @author Andrey Balan + * + * @hibernate.class table="tl_laimsc11_session" + * + */ +public class CommonCartridgeSession{ + + private static Logger log = Logger.getLogger(CommonCartridgeSession.class); + + private Long uid; + private Long sessionId; + private String sessionName; + private CommonCartridge commonCartridge; + private Date sessionStartDate; + private Date sessionEndDate; + //finish or not + private int status; + //commonCartridge Items + private Set commonCartridgeItems; + + +// ********************************************************** + // Get/Set methods +// ********************************************************** + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the learnerID. + */ + public Long getUid() { + return uid; + } + public void setUid(Long uuid) { + this.uid = uuid; + } + + /** + * @hibernate.property column="session_end_date" + * @return + */ + public Date getSessionEndDate() { + return sessionEndDate; + } + public void setSessionEndDate(Date sessionEndDate) { + this.sessionEndDate = sessionEndDate; + } + /** + * @hibernate.property column="session_start_date" + * + * @return + */ + public Date getSessionStartDate() { + return sessionStartDate; + } + public void setSessionStartDate(Date sessionStartDate) { + this.sessionStartDate = sessionStartDate; + } + /** + * @hibernate.property + * @return + */ + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + + /** + * @hibernate.many-to-one column="commonCartridge_uid" + * cascade="none" + * @return + */ + public CommonCartridge getCommonCartridge() { + return commonCartridge; + } + public void setCommonCartridge(CommonCartridge commonCartridge) { + this.commonCartridge = commonCartridge; + } + /** + * @hibernate.property column="session_id" + * @return + */ + public Long getSessionId() { + return sessionId; + } + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + /** + * @hibernate.property column="session_name" length="250" + * @return Returns the session name + */ + public String getSessionName() { + return sessionName; + } + + /** + * + * @param sessionName The session name to set. + */ + public void setSessionName(String sessionName) { + this.sessionName = sessionName; + } + + /** + * + * + * @hibernate.set lazy="true" + * inverse="false" + * cascade="all" + * order-by="create_date desc" + * @hibernate.collection-key column="session_uid" + * @hibernate.collection-one-to-many class="org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem" + * + * @return + */ + public Set getCommonCartridgeItems() { + return commonCartridgeItems; + } + public void setCommonCartridgeItems(Set commonCartridgeItems) { + this.commonCartridgeItems= commonCartridgeItems; + } + + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.hbm.xml =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.hbm.xml (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.hbm.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/model/CommonCartridgeUser.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,220 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.model; + +import java.util.Date; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +/** + * CommonCartridge + * @author Andrey Balan + * + * @hibernate.class table="tl_laimsc11_user" + * + */ +public class CommonCartridgeUser implements Cloneable{ + private static final long serialVersionUID = -7043502180037866257L; + private static Logger log = Logger.getLogger(CommonCartridgeUser.class); + + private Long uid; + private Long userId; + private String firstName; + private String lastName; + private String loginName; + private boolean sessionFinished; + + private CommonCartridgeSession session; + private CommonCartridge commonCartridge; + + //=============== NON Persisit value: for display use =========== + //the user access some reousrce item date time. Use in monitoring summary page + private Date accessDate; + + public CommonCartridgeUser(){ + } + public CommonCartridgeUser(UserDTO user, CommonCartridgeSession session){ + this.userId = new Long(user.getUserID().intValue()); + this.firstName = user.getFirstName(); + this.lastName = user.getLastName(); + this.loginName = user.getLogin(); + this.session = session; + this.commonCartridge = null; + this.sessionFinished = false; + } + public CommonCartridgeUser(UserDTO user, CommonCartridge content){ + this.userId = new Long(user.getUserID().intValue()); + this.firstName = user.getFirstName(); + this.lastName = user.getLastName(); + this.loginName = user.getLogin(); + this.session = null; + this.commonCartridge = content; + this.sessionFinished = false; + } + /** + * Clone method from java.lang.Object + */ + public Object clone(){ + + CommonCartridgeUser user = null; + try{ + user = (CommonCartridgeUser) super.clone(); + user.setUid(null); + //never clone session + user.setSession(null); + } catch (CloneNotSupportedException e) { + log.error("When clone " + CommonCartridgeUser.class + " failed"); + } + + return user; + } +// ********************************************************** + // Get/Set methods +// ********************************************************** + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the uid. + */ + public Long getUid() { + return uid; + } + /** + * @param uid The uid to set. + */ + public void setUid(Long userID) { + this.uid = userID; + } + + /** + * @hibernate.property column="user_id" length="20" + * @return Returns the userId. + */ + public Long getUserId() { + return userId; + } + /** + * @param userId + * The userId to set. + */ + public void setUserId(Long userID) { + this.userId = userID; + } + + /** + * @hibernate.property length="255" column="last_name" + * @return + */ + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + /** + * @hibernate.property length="255" column="first_name" + * @return + */ + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + + /** + * @hibernate.property column="login_name" + * @return + */ + public String getLoginName() { + return loginName; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + /** + * @hibernate.many-to-one column="session_uid" + * cascade="none" + * @return + */ + public CommonCartridgeSession getSession() { + return session; + } + + public void setSession(CommonCartridgeSession session) { + this.session = session; + } + /** + * @hibernate.many-to-one column="commonCartridge_uid" + * cascade="none" + * @return + */ + public CommonCartridge getCommonCartridge() { + return commonCartridge; + } + public void setCommonCartridge(CommonCartridge content) { + this.commonCartridge = content; + } + /** + * @hibernate.property column="session_finished" + * @return + */ + public boolean isSessionFinished() { + return sessionFinished; + } + + public void setSessionFinished(boolean sessionFinished) { + this.sessionFinished = sessionFinished; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof CommonCartridgeUser)) + return false; + + final CommonCartridgeUser user = (CommonCartridgeUser) obj; + + return new EqualsBuilder().append(this.uid, user.uid).append(this.firstName, user.firstName) + .append(this.lastName,user.lastName).append(this.loginName, user.loginName).isEquals(); + + } + + public int hashCode() { + return new HashCodeBuilder().append(uid).append(firstName) + .append(lastName).append(loginName) + .toHashCode(); + } + public Date getAccessDate() { + return accessDate; + } + public void setAccessDate(Date accessDate) { + this.accessDate = accessDate; + } + + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeApplicationException.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeApplicationException.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeApplicationException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,48 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.service; + +public class CommonCartridgeApplicationException extends Exception { + + public CommonCartridgeApplicationException() { + super(); + + } + + public CommonCartridgeApplicationException(String message, Throwable cause) { + super(message, cause); + + } + + public CommonCartridgeApplicationException(String message) { + super(message); + + } + + public CommonCartridgeApplicationException(Throwable cause) { + super(cause); + + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceImpl.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceImpl.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceImpl.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,1272 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.service; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Vector; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.contentrepository.AccessDeniedException; +import org.lamsfoundation.lams.contentrepository.ICredentials; +import org.lamsfoundation.lams.contentrepository.ITicket; +import org.lamsfoundation.lams.contentrepository.IVersionedNode; +import org.lamsfoundation.lams.contentrepository.InvalidParameterException; +import org.lamsfoundation.lams.contentrepository.LoginException; +import org.lamsfoundation.lams.contentrepository.NodeKey; +import org.lamsfoundation.lams.contentrepository.RepositoryCheckedException; +import org.lamsfoundation.lams.contentrepository.WorkspaceNotFoundException; +import org.lamsfoundation.lams.contentrepository.service.IRepositoryService; +import org.lamsfoundation.lams.contentrepository.service.SimpleCredentials; +import org.lamsfoundation.lams.events.IEventNotificationService; +import org.lamsfoundation.lams.learning.service.ILearnerService; +import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; +import org.lamsfoundation.lams.learningdesign.service.IExportToolContentService; +import org.lamsfoundation.lams.learningdesign.service.ImportToolContentException; +import org.lamsfoundation.lams.lesson.service.ILessonService; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.notebook.service.ICoreNotebookService; +import org.lamsfoundation.lams.tool.ToolContentImport102Manager; +import org.lamsfoundation.lams.tool.ToolContentManager; +import org.lamsfoundation.lams.tool.ToolOutput; +import org.lamsfoundation.lams.tool.ToolOutputDefinition; +import org.lamsfoundation.lams.tool.ToolSessionExportOutputData; +import org.lamsfoundation.lams.tool.ToolSessionManager; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeAttachmentDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeConfigItemDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeItemDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeItemVisitDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeSessionDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dao.CommonCartridgeUserDAO; +import org.lamsfoundation.lams.tool.commonCartridge.dto.ReflectDTO; +import org.lamsfoundation.lams.tool.commonCartridge.dto.Summary; +import org.lamsfoundation.lams.tool.commonCartridge.ims.IMSManifestException; +import org.lamsfoundation.lams.tool.commonCartridge.ims.ImscpApplicationException; +import org.lamsfoundation.lams.tool.commonCartridge.ims.SimpleCommonCartridgeConverter; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeAttachment; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemInstruction; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItemVisitLog; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeToolContentHandler; +import org.lamsfoundation.lams.tool.commonCartridge.util.ReflectDTOComparator; +import org.lamsfoundation.lams.tool.exception.DataMissingException; +import org.lamsfoundation.lams.tool.exception.SessionDataExistsException; +import org.lamsfoundation.lams.tool.exception.ToolException; +import org.lamsfoundation.lams.tool.service.ILamsToolService; +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.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.audit.IAuditService; +import org.lamsfoundation.lams.util.wddx.WDDXProcessor; +import org.lamsfoundation.lams.util.wddx.WDDXProcessorConversionException; +import org.lamsfoundation.lams.util.zipfile.ZipFileUtil; +import org.lamsfoundation.lams.util.zipfile.ZipFileUtilException; + +/** + * + * @author Andrey Balan + * + */ +public class CommonCartridgeServiceImpl implements ICommonCartridgeService, ToolContentManager, ToolSessionManager, + ToolContentImport102Manager + +{ + static Logger log = Logger.getLogger(CommonCartridgeServiceImpl.class.getName()); + + private CommonCartridgeDAO commonCartridgeDao; + + private CommonCartridgeItemDAO commonCartridgeItemDao; + + private CommonCartridgeAttachmentDAO commonCartridgeAttachmentDao; + + private CommonCartridgeUserDAO commonCartridgeUserDao; + + private CommonCartridgeSessionDAO commonCartridgeSessionDao; + + private CommonCartridgeItemVisitDAO commonCartridgeItemVisitDao; + + private CommonCartridgeConfigItemDAO commonCartridgeConfigItemDao; + + // tool service + private CommonCartridgeToolContentHandler commonCartridgeToolContentHandler; + + private MessageService messageService; + + // system services + private IRepositoryService repositoryService; + + private ILamsToolService toolService; + + private ILearnerService learnerService; + + private IAuditService auditService; + + private IUserManagementService userManagementService; + + private IExportToolContentService exportContentService; + + private ICoreNotebookService coreNotebookService; + + private IEventNotificationService eventNotificationService; + + private ILessonService lessonService; + + public IVersionedNode getFileNode(Long itemUid, String relPathString) throws CommonCartridgeApplicationException { + CommonCartridgeItem item = (CommonCartridgeItem) commonCartridgeItemDao.getObject(CommonCartridgeItem.class, + itemUid); + if (item == null) { + throw new CommonCartridgeApplicationException("Reource item " + itemUid + " not found."); + } + + return getFile(item.getFileUuid(), item.getFileVersionId(), relPathString); + } + + // ******************************************************************************* + // Service method + // ******************************************************************************* + /** + * Try to get the file. If forceLogin = false and an access denied exception occurs, call this method again to get a + * new ticket and retry file lookup. If forceLogin = true and it then fails then throw exception. + * + * @param uuid + * @param versionId + * @param relativePath + * @param attemptCount + * @return file node + * @throws ImscpApplicationException + */ + private IVersionedNode getFile(Long uuid, Long versionId, String relativePath) + throws CommonCartridgeApplicationException { + + ITicket tic = getRepositoryLoginTicket(); + + try { + + return repositoryService.getFileItem(tic, uuid, versionId, relativePath); + + } catch (AccessDeniedException e) { + + String error = "Unable to access repository to get file uuid " + uuid + " version id " + versionId + + " path " + relativePath + "."; + + error = error + "AccessDeniedException: " + e.getMessage() + " Unable to retry further."; + CommonCartridgeServiceImpl.log.error(error); + throw new CommonCartridgeApplicationException(error, e); + + } catch (Exception e) { + + String error = "Unable to access repository to get file uuid " + uuid + " version id " + versionId + + " path " + relativePath + "." + " Exception: " + e.getMessage(); + CommonCartridgeServiceImpl.log.error(error); + throw new CommonCartridgeApplicationException(error, e); + + } + } + + /** + * This method verifies the credentials of the CommonCartridge Tool and gives it the Ticket to login + * and access the Content Repository. + * + * A valid ticket is needed in order to access the content from the repository. This method would be called evertime + * the tool needs to upload/download files from the content repository. + * + * @return ITicket The ticket for repostory access + * @throws CommonCartridgeApplicationException + */ + private ITicket getRepositoryLoginTicket() throws CommonCartridgeApplicationException { + ICredentials credentials = new SimpleCredentials(commonCartridgeToolContentHandler.getRepositoryUser(), + commonCartridgeToolContentHandler.getRepositoryId()); + try { + ITicket ticket = repositoryService.login(credentials, + commonCartridgeToolContentHandler.getRepositoryWorkspaceName()); + return ticket; + } catch (AccessDeniedException ae) { + throw new CommonCartridgeApplicationException("Access Denied to repository." + ae.getMessage()); + } catch (WorkspaceNotFoundException we) { + throw new CommonCartridgeApplicationException("Workspace not found." + we.getMessage()); + } catch (LoginException e) { + throw new CommonCartridgeApplicationException("Login failed." + e.getMessage()); + } + } + + public CommonCartridge getCommonCartridgeByContentId(Long contentId) { + CommonCartridge rs = commonCartridgeDao.getByContentId(contentId); + if (rs == null) { + CommonCartridgeServiceImpl.log.error("Could not find the content by given ID:" + contentId); + } + return rs; + } + + public CommonCartridge getDefaultContent(Long contentId) throws CommonCartridgeApplicationException { + if (contentId == null) { + String error = messageService.getMessage("error.msg.default.content.not.find"); + CommonCartridgeServiceImpl.log.error(error); + throw new CommonCartridgeApplicationException(error); + } + + CommonCartridge defaultContent = getDefaultCommonCartridge(); + // save default content by given ID. + CommonCartridge content = new CommonCartridge(); + content = CommonCartridge.newInstance(defaultContent, contentId, commonCartridgeToolContentHandler); + return content; + } + + public List getAuthoredItems(Long commonCartridgeUid) { + return commonCartridgeItemDao.getAuthoringItems(commonCartridgeUid); + } + + public CommonCartridgeAttachment uploadInstructionFile(FormFile uploadFile, String fileType) + throws UploadCommonCartridgeFileException { + if (uploadFile == null || StringUtils.isEmpty(uploadFile.getFileName())) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.upload.file.not.found", + new Object[] { uploadFile })); + } + + // upload file to repository + NodeKey nodeKey = processFile(uploadFile, fileType); + + // create new attachement + CommonCartridgeAttachment file = new CommonCartridgeAttachment(); + file.setFileType(fileType); + file.setFileUuid(nodeKey.getUuid()); + file.setFileVersionId(nodeKey.getVersion()); + file.setFileName(uploadFile.getFileName()); + file.setCreated(new Date()); + + return file; + } + + public void createUser(CommonCartridgeUser commonCartridgeUser) { + commonCartridgeUserDao.saveObject(commonCartridgeUser); + } + + public CommonCartridgeUser getUserByIDAndContent(Long userId, Long contentId) { + + return commonCartridgeUserDao.getUserByUserIDAndContentID(userId, contentId); + + } + + public CommonCartridgeUser getUserByIDAndSession(Long userId, Long sessionId) { + + return commonCartridgeUserDao.getUserByUserIDAndSessionID(userId, sessionId); + + } + + public void deleteFromRepository(Long fileUuid, Long fileVersionId) throws CommonCartridgeApplicationException { + ITicket ticket = getRepositoryLoginTicket(); + try { + repositoryService.deleteVersion(ticket, fileUuid, fileVersionId); + } catch (Exception e) { + throw new CommonCartridgeApplicationException("Exception occured while deleting files from" + + " the repository " + e.getMessage()); + } + } + + public void saveOrUpdateCommonCartridge(CommonCartridge commonCartridge) { + commonCartridgeDao.saveObject(commonCartridge); + } + + public void deleteCommonCartridgeAttachment(Long attachmentUid) { + commonCartridgeAttachmentDao.removeObject(CommonCartridgeAttachment.class, attachmentUid); + + } + + public void saveOrUpdateCommonCartridgeItem(CommonCartridgeItem item) { + commonCartridgeItemDao.saveObject(item); + } + + public void deleteCommonCartridgeItem(Long uid) { + commonCartridgeItemDao.removeObject(CommonCartridgeItem.class, uid); + } + + public List getCommonCartridgeItemsBySessionId(Long sessionId) { + CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(sessionId); + if (session == null) { + CommonCartridgeServiceImpl.log.error("Failed get CommonCartridgeSession by ID [" + sessionId + "]"); + return null; + } + // add commonCartridge items from Authoring + CommonCartridge commonCartridge = session.getCommonCartridge(); + List items = new ArrayList(); + items.addAll(commonCartridge.getCommonCartridgeItems()); + + // add commonCartridge items from CommonCartridgeSession + items.addAll(session.getCommonCartridgeItems()); + + return items; + } + + public List exportBySessionId(Long sessionId, boolean skipHide) { + CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(sessionId); + if (session == null) { + CommonCartridgeServiceImpl.log.error("Failed get CommonCartridgeSession by ID [" + sessionId + "]"); + return null; + } + // initial commonCartridge items list + List itemList = new ArrayList(); + Set resList = session.getCommonCartridge().getCommonCartridgeItems(); + for (CommonCartridgeItem item : resList) { + if (skipHide && item.isHide()) { + continue; + } + // if item is create by author + if (item.isCreateByAuthor()) { + Summary sum = new Summary(session.getSessionId(), session.getSessionName(), item, false); + itemList.add(sum); + } + } + + // get this session's all commonCartridge items + Set sessList = session.getCommonCartridgeItems(); + for (CommonCartridgeItem item : sessList) { + if (skipHide && item.isHide()) { + continue; + } + + // to skip all item create by author + if (!item.isCreateByAuthor()) { + Summary sum = new Summary(session.getSessionId(), session.getSessionName(), item, false); + itemList.add(sum); + } + } + + return itemList; + } + + public List> exportByContentId(Long contentId) { + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(contentId); + List> groupList = new ArrayList(); + + // create init commonCartridge items list + List initList = new ArrayList(); + groupList.add(initList); + Set resList = commonCartridge.getCommonCartridgeItems(); + for (CommonCartridgeItem item : resList) { + if (item.isCreateByAuthor()) { + Summary sum = new Summary(null, null, item, true); + initList.add(sum); + } + } + + // session by session + List sessionList = commonCartridgeSessionDao.getByContentId(contentId); + for (CommonCartridgeSession session : sessionList) { + List group = new ArrayList(); + // get this session's all commonCartridge items + Set sessList = session.getCommonCartridgeItems(); + for (CommonCartridgeItem item : sessList) { + // to skip all item create by author + if (!item.isCreateByAuthor()) { + Summary sum = new Summary(session.getSessionId(), session.getSessionName(), item, false); + group.add(sum); + } + } + if (group.size() == 0) { + group.add(new Summary(session.getSessionId(), session.getSessionName(), null, false)); + } + groupList.add(group); + } + + return groupList; + } + + public CommonCartridge getCommonCartridgeBySessionId(Long sessionId) { + CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(sessionId); + // to skip CGLib problem + Long contentId = session.getCommonCartridge().getContentId(); + CommonCartridge res = commonCartridgeDao.getByContentId(contentId); + int miniView = res.getMiniViewCommonCartridgeNumber(); + // construct dto fields; + res.setMiniViewNumberStr(messageService.getMessage("label.learning.minimum.review", new Object[] { new Integer( + miniView) })); + return res; + } + + public CommonCartridgeSession getCommonCartridgeSessionBySessionId(Long sessionId) { + return commonCartridgeSessionDao.getSessionBySessionId(sessionId); + } + + public void saveOrUpdateCommonCartridgeSession(CommonCartridgeSession resSession) { + commonCartridgeSessionDao.saveObject(resSession); + } + + public void retrieveComplete(SortedSet commonCartridgeItemList, CommonCartridgeUser user) { + for (CommonCartridgeItem item : commonCartridgeItemList) { + CommonCartridgeItemVisitLog log = commonCartridgeItemVisitDao.getCommonCartridgeItemLog(item.getUid(), + user.getUserId()); + if (log == null) { + item.setComplete(false); + } else { + item.setComplete(log.isComplete()); + } + } + } + + public void setItemComplete(Long commonCartridgeItemUid, Long userId, Long sessionId) { + CommonCartridgeItemVisitLog log = commonCartridgeItemVisitDao.getCommonCartridgeItemLog(commonCartridgeItemUid, + userId); + if (log == null) { + log = new CommonCartridgeItemVisitLog(); + CommonCartridgeItem item = commonCartridgeItemDao.getByUid(commonCartridgeItemUid); + log.setCommonCartridgeItem(item); + CommonCartridgeUser user = commonCartridgeUserDao.getUserByUserIDAndSessionID(userId, sessionId); + log.setUser(user); + log.setSessionId(sessionId); + log.setAccessDate(new Timestamp(new Date().getTime())); + } + log.setComplete(true); + commonCartridgeItemVisitDao.saveObject(log); + } + + public void setItemAccess(Long commonCartridgeItemUid, Long userId, Long sessionId) { + CommonCartridgeItemVisitLog log = commonCartridgeItemVisitDao.getCommonCartridgeItemLog(commonCartridgeItemUid, + userId); + if (log == null) { + log = new CommonCartridgeItemVisitLog(); + CommonCartridgeItem item = commonCartridgeItemDao.getByUid(commonCartridgeItemUid); + log.setCommonCartridgeItem(item); + CommonCartridgeUser user = commonCartridgeUserDao.getUserByUserIDAndSessionID(userId, sessionId); + log.setUser(user); + log.setComplete(false); + log.setSessionId(sessionId); + log.setAccessDate(new Timestamp(new Date().getTime())); + commonCartridgeItemVisitDao.saveObject(log); + } + } + + public String finishToolSession(Long toolSessionId, Long userId) throws CommonCartridgeApplicationException { + CommonCartridgeUser user = commonCartridgeUserDao.getUserByUserIDAndSessionID(userId, toolSessionId); + user.setSessionFinished(true); + commonCartridgeUserDao.saveObject(user); + + // CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(toolSessionId); + // session.setStatus(CommonCartridgeConstants.COMPLETED); + // commonCartridgeSessionDao.saveObject(session); + + String nextUrl = null; + try { + nextUrl = this.leaveToolSession(toolSessionId, userId); + } catch (DataMissingException e) { + throw new CommonCartridgeApplicationException(e); + } catch (ToolException e) { + throw new CommonCartridgeApplicationException(e); + } + return nextUrl; + } + + public int checkMiniView(Long toolSessionId, Long userUid) { + int miniView = commonCartridgeItemVisitDao.getUserViewLogCount(toolSessionId, userUid); + CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(toolSessionId); + if (session == null) { + CommonCartridgeServiceImpl.log.error("Failed get session by ID [" + toolSessionId + "]"); + return 0; + } + int reqView = session.getCommonCartridge().getMiniViewCommonCartridgeNumber(); + + return reqView - miniView; + } + + public CommonCartridgeItem getCommonCartridgeItemByUid(Long itemUid) { + return commonCartridgeItemDao.getByUid(itemUid); + } + + public List> getSummary(Long contentId) { + List> groupList = new ArrayList>(); + List group = new ArrayList(); + + // get all item which is accessed by user + Map visitCountMap = commonCartridgeItemVisitDao.getSummary(contentId); + + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(contentId); + Set resItemList = commonCartridge.getCommonCartridgeItems(); + + // get all sessions in a commonCartridge and retrieve all commonCartridge items under this session + // plus initial commonCartridge items by author creating (resItemList) + List sessionList = commonCartridgeSessionDao.getByContentId(contentId); + for (CommonCartridgeSession session : sessionList) { + // one new group for one session. + group = new ArrayList(); + // firstly, put all initial commonCartridge item into this group. + for (CommonCartridgeItem item : resItemList) { + Summary sum = new Summary(session.getSessionId(), session.getSessionName(), item); + // set viewNumber according visit log + if (visitCountMap.containsKey(item.getUid())) { + sum.setViewNumber(visitCountMap.get(item.getUid()).intValue()); + } + group.add(sum); + } + // get this session's all commonCartridge items + Set sessItemList = session.getCommonCartridgeItems(); + for (CommonCartridgeItem item : sessItemList) { + // to skip all item create by author + if (!item.isCreateByAuthor()) { + Summary sum = new Summary(session.getSessionId(), session.getSessionName(), item); + // set viewNumber according visit log + if (visitCountMap.containsKey(item.getUid())) { + sum.setViewNumber(visitCountMap.get(item.getUid()).intValue()); + } + group.add(sum); + } + } + // so far no any item available, so just put session name info to Summary + if (group.size() == 0) { + group.add(new Summary(session.getSessionId(), session.getSessionName(), null)); + } + groupList.add(group); + } + + return groupList; + + } + + public Map> getReflectList(Long contentId, boolean setEntry) { + Map> map = new HashMap>(); + + List sessionList = commonCartridgeSessionDao.getByContentId(contentId); + for (CommonCartridgeSession session : sessionList) { + Long sessionId = session.getSessionId(); + boolean hasRefection = session.getCommonCartridge().isReflectOnActivity(); + Set list = new TreeSet(new ReflectDTOComparator()); + // get all users in this session + List users = commonCartridgeUserDao.getBySessionID(sessionId); + for (CommonCartridgeUser user : users) { + ReflectDTO ref = new ReflectDTO(user); + + if (setEntry) { + NotebookEntry entry = getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, user.getUserId().intValue()); + if (entry != null) { + ref.setReflect(entry.getEntry()); + } + } + + ref.setHasRefection(hasRefection); + list.add(ref); + } + map.put(sessionId, list); + } + + return map; + } + + public List getUserListBySessionItem(Long sessionId, Long itemUid) { + List logList = commonCartridgeItemVisitDao.getCommonCartridgeItemLogBySession( + sessionId, itemUid); + List userList = new ArrayList(logList.size()); + for (CommonCartridgeItemVisitLog visit : logList) { + CommonCartridgeUser user = visit.getUser(); + user.setAccessDate(visit.getAccessDate()); + userList.add(user); + } + return userList; + } + + public void setItemVisible(Long itemUid, boolean visible) { + CommonCartridgeItem item = commonCartridgeItemDao.getByUid(itemUid); + if (item != null) { + // createBy should be null for system default value. + Long userId = 0L; + String loginName = "No user"; + if (item.getCreateBy() != null) { + userId = item.getCreateBy().getUserId(); + loginName = item.getCreateBy().getLoginName(); + } + if (visible) { + auditService.logShowEntry(CommonCartridgeConstants.TOOL_SIGNATURE, userId, loginName, item.toString()); + } else { + auditService.logHideEntry(CommonCartridgeConstants.TOOL_SIGNATURE, userId, loginName, item.toString()); + } + item.setHide(!visible); + commonCartridgeItemDao.saveObject(item); + } + } + + public Long createNotebookEntry(Long sessionId, Integer notebookToolType, String toolSignature, Integer userId, + String entryText) { + return coreNotebookService.createNotebookEntry(sessionId, notebookToolType, toolSignature, userId, "", + entryText); + } + + public NotebookEntry getEntry(Long sessionId, Integer idType, String signature, Integer userID) { + List list = coreNotebookService.getEntry(sessionId, idType, signature, userID); + if (list == null || list.isEmpty()) { + return null; + } else { + return list.get(0); + } + } + + /** + * @param notebookEntry + */ + public void updateEntry(NotebookEntry notebookEntry) { + coreNotebookService.updateEntry(notebookEntry); + } + + public CommonCartridgeUser getUser(Long uid) { + return (CommonCartridgeUser) commonCartridgeUserDao.getObject(CommonCartridgeUser.class, uid); + } + + // ***************************************************************************** + // private methods + // ***************************************************************************** + private CommonCartridge getDefaultCommonCartridge() throws CommonCartridgeApplicationException { + Long defaultCommonCartridgeId = getToolDefaultContentIdBySignature(CommonCartridgeConstants.TOOL_SIGNATURE); + CommonCartridge defaultCommonCartridge = getCommonCartridgeByContentId(defaultCommonCartridgeId); + if (defaultCommonCartridge == null) { + String error = messageService.getMessage("error.msg.default.content.not.find"); + CommonCartridgeServiceImpl.log.error(error); + throw new CommonCartridgeApplicationException(error); + } + + return defaultCommonCartridge; + } + + private Long getToolDefaultContentIdBySignature(String toolSignature) throws CommonCartridgeApplicationException { + Long contentId = null; + contentId = new Long(toolService.getToolDefaultContentIdBySignature(toolSignature)); + if (contentId == null) { + String error = messageService.getMessage("error.msg.default.content.not.find"); + CommonCartridgeServiceImpl.log.error(error); + throw new CommonCartridgeApplicationException(error); + } + return contentId; + } + + /** + * Process an uploaded file. + * + * @throws CommonCartridgeApplicationException + * @throws FileNotFoundException + * @throws IOException + * @throws RepositoryCheckedException + * @throws InvalidParameterException + */ + private NodeKey processFile(FormFile file, String fileType) throws UploadCommonCartridgeFileException { + NodeKey node = null; + if (file != null && !StringUtils.isEmpty(file.getFileName())) { + String fileName = file.getFileName(); + try { + node = commonCartridgeToolContentHandler.uploadFile(file.getInputStream(), fileName, + file.getContentType(), fileType); + } catch (InvalidParameterException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.invaid.param.upload")); + } catch (FileNotFoundException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.file.not.found")); + } catch (RepositoryCheckedException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.repository")); + } catch (IOException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.io.exception")); + } + } + return node; + } + + private NodeKey processPackage(String packageDirectory, String initFile) throws UploadCommonCartridgeFileException { + NodeKey node = null; + try { + node = commonCartridgeToolContentHandler.uploadPackage(packageDirectory, initFile); + } catch (InvalidParameterException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.invaid.param.upload")); + } catch (RepositoryCheckedException e) { + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.repository")); + } + return node; + } + + public List uploadCommonCartridgeFile(CommonCartridgeItem item, FormFile file) + throws UploadCommonCartridgeFileException { + try { + InputStream is = file.getInputStream(); + String fileName = file.getFileName(); + String fileType = file.getContentType(); + // need unzip upload, and parse learning object information from XML file. + String packageDirectory = ZipFileUtil.expandZip(is, fileName); + SimpleCommonCartridgeConverter cpConverter = new SimpleCommonCartridgeConverter(packageDirectory); + String initFile = cpConverter.getDefaultItem(); + item.setInitialItem(initFile); + item.setImsSchema(cpConverter.getSchema()); + item.setOrganizationXml(cpConverter.getOrganzationXML()); +// // upload package +// NodeKey nodeKey = processPackage(packageDirectory, initFile); +// item.setFileUuid(nodeKey.getUuid()); +// item.setFileVersionId(nodeKey.getVersion()); +// item.setFileType(fileType); +// item.setFileName(fileName); + + List items = cpConverter.getBasicLTIItems(); + return items; + + } catch (ZipFileUtilException e) { + CommonCartridgeServiceImpl.log.error(messageService.getMessage("error.msg.zip.file.exception") + " : " + + e.toString()); + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.zip.file.exception")); + } catch (FileNotFoundException e) { + CommonCartridgeServiceImpl.log.error(messageService.getMessage("error.msg.file.not.found") + ":" + + e.toString()); + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.file.not.found")); + } catch (IOException e) { + CommonCartridgeServiceImpl.log.error(messageService.getMessage("error.msg.io.exception") + ":" + + e.toString()); + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.io.exception")); + } catch (IMSManifestException e) { + CommonCartridgeServiceImpl.log.error(messageService.getMessage("error.msg.ims.package") + ":" + + e.toString()); + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.ims.package")); + } catch (ImscpApplicationException e) { + CommonCartridgeServiceImpl.log.error(messageService.getMessage("error.msg.ims.application") + ":" + + e.toString()); + throw new UploadCommonCartridgeFileException(messageService.getMessage("error.msg.ims.application")); + } + } + + public CommonCartridgeConfigItem getConfigItem(String key) { + return commonCartridgeConfigItemDao.getConfigItemByKey(key); + } + + public void saveOrUpdateConfigItem(CommonCartridgeConfigItem item) { + commonCartridgeConfigItemDao.saveOrUpdate(item); + } + + // ***************************************************************************** + // set methods for Spring Bean + // ***************************************************************************** + public void setAuditService(IAuditService auditService) { + this.auditService = auditService; + } + + public void setLearnerService(ILearnerService learnerService) { + this.learnerService = learnerService; + } + + public void setMessageService(MessageService messageService) { + this.messageService = messageService; + } + + public void setRepositoryService(IRepositoryService repositoryService) { + this.repositoryService = repositoryService; + } + + public void setCommonCartridgeAttachmentDao(CommonCartridgeAttachmentDAO commonCartridgeAttachmentDao) { + this.commonCartridgeAttachmentDao = commonCartridgeAttachmentDao; + } + + public void setCommonCartridgeDao(CommonCartridgeDAO commonCartridgeDao) { + this.commonCartridgeDao = commonCartridgeDao; + } + + public void setCommonCartridgeItemDao(CommonCartridgeItemDAO commonCartridgeItemDao) { + this.commonCartridgeItemDao = commonCartridgeItemDao; + } + + public void setCommonCartridgeSessionDao(CommonCartridgeSessionDAO commonCartridgeSessionDao) { + this.commonCartridgeSessionDao = commonCartridgeSessionDao; + } + + public void setCommonCartridgeToolContentHandler(CommonCartridgeToolContentHandler commonCartridgeToolContentHandler) { + this.commonCartridgeToolContentHandler = commonCartridgeToolContentHandler; + } + + public void setCommonCartridgeUserDao(CommonCartridgeUserDAO commonCartridgeUserDao) { + this.commonCartridgeUserDao = commonCartridgeUserDao; + } + + public void setToolService(ILamsToolService toolService) { + this.toolService = toolService; + } + + public CommonCartridgeItemVisitDAO getCommonCartridgeItemVisitDao() { + return commonCartridgeItemVisitDao; + } + + public void setCommonCartridgeItemVisitDao(CommonCartridgeItemVisitDAO commonCartridgeItemVisitDao) { + this.commonCartridgeItemVisitDao = commonCartridgeItemVisitDao; + } + + public CommonCartridgeConfigItemDAO getCommonCartridgeConfigItemDao() { + return commonCartridgeConfigItemDao; + } + + public void setCommonCartridgeConfigItemDao(CommonCartridgeConfigItemDAO commonCartridgeConfigItemDao) { + this.commonCartridgeConfigItemDao = commonCartridgeConfigItemDao; + } + + // ******************************************************************************* + // ToolContentManager, ToolSessionManager methods + // ******************************************************************************* + + public void exportToolContent(Long toolContentId, String rootPath) throws DataMissingException, ToolException { + CommonCartridge toolContentObj = commonCartridgeDao.getByContentId(toolContentId); + if (toolContentObj == null) { + try { + toolContentObj = getDefaultCommonCartridge(); + } catch (CommonCartridgeApplicationException e) { + throw new DataMissingException(e.getMessage()); + } + } + if (toolContentObj == null) { + throw new DataMissingException("Unable to find default content for the commonCartridge tool"); + } + + // set CommonCartridgeToolContentHandler as null to avoid copy file node in repository again. + toolContentObj = CommonCartridge.newInstance(toolContentObj, toolContentId, null); + toolContentObj.setToolContentHandler(null); + toolContentObj.setOfflineFileList(null); + toolContentObj.setOnlineFileList(null); + toolContentObj.setMiniViewNumberStr(null); + try { + exportContentService.registerFileClassForExport(CommonCartridgeAttachment.class.getName(), "fileUuid", + "fileVersionId"); + exportContentService.registerFileClassForExport(CommonCartridgeItem.class.getName(), "fileUuid", + "fileVersionId"); + exportContentService.exportToolContent(toolContentId, toolContentObj, commonCartridgeToolContentHandler, + rootPath); + } catch (ExportToolContentException e) { + throw new ToolException(e); + } + } + + public void importToolContent(Long toolContentId, Integer newUserUid, String toolContentPath, String fromVersion, + String toVersion) throws ToolException { + + try { + exportContentService.registerFileClassForImport(CommonCartridgeAttachment.class.getName(), "fileUuid", + "fileVersionId", "fileName", "fileType", null, null); + exportContentService.registerFileClassForImport(CommonCartridgeItem.class.getName(), "fileUuid", + "fileVersionId", "fileName", "fileType", null, "initialItem"); + + Object toolPOJO = exportContentService.importToolContent(toolContentPath, + commonCartridgeToolContentHandler, fromVersion, toVersion); + if (!(toolPOJO instanceof CommonCartridge)) { + throw new ImportToolContentException( + "Import Share commonCartridge tool content failed. Deserialized object is " + toolPOJO); + } + CommonCartridge toolContentObj = (CommonCartridge) toolPOJO; + + // reset it to new toolContentId + toolContentObj.setContentId(toolContentId); + CommonCartridgeUser user = commonCartridgeUserDao.getUserByUserIDAndContentID( + new Long(newUserUid.longValue()), toolContentId); + if (user == null) { + user = new CommonCartridgeUser(); + UserDTO sysUser = ((User) userManagementService.findById(User.class, newUserUid)).getUserDTO(); + user.setFirstName(sysUser.getFirstName()); + user.setLastName(sysUser.getLastName()); + user.setLoginName(sysUser.getLogin()); + user.setUserId(new Long(newUserUid.longValue())); + user.setCommonCartridge(toolContentObj); + } + toolContentObj.setCreatedBy(user); + + // reset all commonCartridgeItem createBy user + Set items = toolContentObj.getCommonCartridgeItems(); + for (CommonCartridgeItem item : items) { + item.setCreateBy(user); + } + commonCartridgeDao.saveObject(toolContentObj); + } catch (ImportToolContentException e) { + throw new ToolException(e); + } + } + + /** + * Get the definitions for possible output for an activity, based on the toolContentId. These may be definitions + * that are always available for the tool (e.g. number of marks for Multiple Choice) or a custom definition created + * for a particular activity such as the answer to the third question contains the word Koala and hence the need for + * the toolContentId + * + * @return SortedMap of ToolOutputDefinitions with the key being the name of each definition + */ + public SortedMap getToolOutputDefinitions(Long toolContentId) throws ToolException { + return new TreeMap(); + } + + public void copyToolContent(Long fromContentId, Long toContentId) throws ToolException { + if (toContentId == null) { + throw new ToolException("Failed to create the SharedCommonCartridgeFiles tool seession"); + } + + CommonCartridge commonCartridge = null; + if (fromContentId != null) { + commonCartridge = commonCartridgeDao.getByContentId(fromContentId); + } + if (commonCartridge == null) { + try { + commonCartridge = getDefaultCommonCartridge(); + } catch (CommonCartridgeApplicationException e) { + throw new ToolException(e); + } + } + + CommonCartridge toContent = CommonCartridge.newInstance(commonCartridge, toContentId, + commonCartridgeToolContentHandler); + commonCartridgeDao.saveObject(toContent); + + // save commonCartridge items as well + Set items = toContent.getCommonCartridgeItems(); + if (items != null) { + Iterator iter = items.iterator(); + while (iter.hasNext()) { + CommonCartridgeItem item = (CommonCartridgeItem) iter.next(); + // createRootTopic(toContent.getUid(),null,msg); + } + } + } + + public void setAsDefineLater(Long toolContentId, boolean value) throws DataMissingException, ToolException { + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(toolContentId); + if (commonCartridge == null) { + throw new ToolException("No found tool content by given content ID:" + toolContentId); + } + commonCartridge.setDefineLater(value); + } + + public void setAsRunOffline(Long toolContentId, boolean value) throws DataMissingException, ToolException { + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(toolContentId); + if (commonCartridge == null) { + throw new ToolException("No found tool content by given content ID:" + toolContentId); + } + commonCartridge.setRunOffline(value); + } + + public void removeToolContent(Long toolContentId, boolean removeSessionData) throws SessionDataExistsException, + ToolException { + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(toolContentId); + if (removeSessionData) { + List list = commonCartridgeSessionDao.getByContentId(toolContentId); + Iterator iter = list.iterator(); + while (iter.hasNext()) { + CommonCartridgeSession session = (CommonCartridgeSession) iter.next(); + commonCartridgeSessionDao.delete(session); + } + } + commonCartridgeDao.delete(commonCartridge); + } + + public void createToolSession(Long toolSessionId, String toolSessionName, Long toolContentId) throws ToolException { + CommonCartridgeSession session = new CommonCartridgeSession(); + session.setSessionId(toolSessionId); + session.setSessionName(toolSessionName); + CommonCartridge commonCartridge = commonCartridgeDao.getByContentId(toolContentId); + session.setCommonCartridge(commonCartridge); + commonCartridgeSessionDao.saveObject(session); + } + + public String leaveToolSession(Long toolSessionId, Long learnerId) throws DataMissingException, ToolException { + if (toolSessionId == null) { + CommonCartridgeServiceImpl.log.error("Fail to leave tool Session based on null tool session id."); + throw new ToolException("Fail to remove tool Session based on null tool session id."); + } + if (learnerId == null) { + CommonCartridgeServiceImpl.log.error("Fail to leave tool Session based on null learner."); + throw new ToolException("Fail to remove tool Session based on null learner."); + } + + CommonCartridgeSession session = commonCartridgeSessionDao.getSessionBySessionId(toolSessionId); + if (session != null) { + session.setStatus(CommonCartridgeConstants.COMPLETED); + commonCartridgeSessionDao.saveObject(session); + } else { + CommonCartridgeServiceImpl.log.error("Fail to leave tool Session.Could not find shared commonCartridge " + + "session by given session id: " + toolSessionId); + throw new DataMissingException("Fail to leave tool Session." + + "Could not find shared commonCartridge session by given session id: " + toolSessionId); + } + return learnerService.completeToolSession(toolSessionId, learnerId); + } + + public ToolSessionExportOutputData exportToolSession(Long toolSessionId) throws DataMissingException, ToolException { + return null; + } + + public ToolSessionExportOutputData exportToolSession(List toolSessionIds) throws DataMissingException, + ToolException { + return null; + } + + public void removeToolSession(Long toolSessionId) throws DataMissingException, ToolException { + commonCartridgeSessionDao.deleteBySessionId(toolSessionId); + } + + /** + * Get the tool output for the given tool output names. + * + * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.util.List, java.lang.Long, + * java.lang.Long) + */ + public SortedMap getToolOutput(List names, Long toolSessionId, Long learnerId) { + return new TreeMap(); + } + + /** + * Get the tool output for the given tool output name. + * + * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.lang.String, java.lang.Long, + * java.lang.Long) + */ + public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { + return null; + } + + /* ===============Methods implemented from ToolContentImport102Manager =============== */ + + /** + * Import the data for a 1.0.2 Noticeboard or HTMLNoticeboard + */ + public void import102ToolContent(Long toolContentId, UserDTO user, Hashtable importValues) { + Date now = new Date(); + CommonCartridge toolContentObj = new CommonCartridge(); + + try { + toolContentObj.setTitle((String) importValues.get(ToolContentImport102Manager.CONTENT_TITLE)); + toolContentObj.setContentId(toolContentId); + toolContentObj.setContentInUse(Boolean.FALSE); + toolContentObj.setCreated(now); + toolContentObj.setDefineLater(Boolean.FALSE); + toolContentObj.setInstructions(WebUtil.convertNewlines((String) importValues + .get(ToolContentImport102Manager.CONTENT_BODY))); + toolContentObj.setOfflineInstructions(null); + toolContentObj.setOnlineInstructions(null); + toolContentObj.setRunOffline(Boolean.FALSE); + toolContentObj.setUpdated(now); + toolContentObj.setReflectOnActivity(Boolean.FALSE); + toolContentObj.setReflectInstructions(null); + + toolContentObj.setRunAuto(Boolean.FALSE); + Integer minToComplete = WDDXProcessor.convertToInteger(importValues, + ToolContentImport102Manager.CONTENT_URL_MIN_NUMBER_COMPLETE); + toolContentObj.setMiniViewCommonCartridgeNumber(minToComplete != null ? minToComplete.intValue() : 0); + toolContentObj.setLockWhenFinished(Boolean.FALSE); + toolContentObj.setRunAuto(Boolean.FALSE); + + // leave as empty, no need to set them to anything. + // toolContentObj.setAttachments(attachments); + + /* + * unused entries from 1.0.2 [directoryName=] no equivalent in 2.0 [runtimeSubmissionStaffFile=true] no + * equivalent in 2.0 [contentShowUser=false] no equivalent in 2.0 [isHTML=false] no equivalent in 2.0 + * [showbuttons=false] no equivalent in 2.0 [isReusable=false] not used in 1.0.2 (would be lock when + * finished) + */ + CommonCartridgeUser ruser = new CommonCartridgeUser(); + ruser.setUserId(new Long(user.getUserID().longValue())); + ruser.setFirstName(user.getFirstName()); + ruser.setLastName(user.getLastName()); + ruser.setLoginName(user.getLogin()); + createUser(ruser); + toolContentObj.setCreatedBy(ruser); + + // CommonCartridge Items. They are ordered on the screen by create date so they need to be saved in the + // right + // order. + // So read them all in first, then go through and assign the dates in the correct order and then save. + Vector urls = (Vector) importValues.get(ToolContentImport102Manager.CONTENT_URL_URLS); + SortedMap items = new TreeMap(); + if (urls != null) { + Iterator iter = urls.iterator(); + while (iter.hasNext()) { + Hashtable urlMap = (Hashtable) iter.next(); + Integer itemOrder = WDDXProcessor.convertToInteger(urlMap, + ToolContentImport102Manager.CONTENT_URL_URL_VIEW_ORDER); + CommonCartridgeItem item = new CommonCartridgeItem(); + item.setTitle((String) urlMap.get(ToolContentImport102Manager.CONTENT_TITLE)); + item.setCreateBy(ruser); + item.setCreateByAuthor(true); + item.setHide(false); + + Vector instructions = (Vector) urlMap + .get(ToolContentImport102Manager.CONTENT_URL_URL_INSTRUCTION_ARRAY); + if (instructions != null && instructions.size() > 0) { + item.setItemInstructions(new HashSet()); + Iterator insIter = instructions.iterator(); + while (insIter.hasNext()) { + item.getItemInstructions().add(createInstruction((Hashtable) insIter.next())); + } + } + + String commonCartridgeType = (String) urlMap.get(ToolContentImport102Manager.CONTENT_URL_URL_TYPE); + if (ToolContentImport102Manager.URL_RESOURCE_TYPE_URL.equals(commonCartridgeType)) { + item.setType(CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI); + item.setUrl((String) urlMap.get(ToolContentImport102Manager.CONTENT_URL_URL_URL)); + item.setOpenUrlNewWindow(false); + } else if (ToolContentImport102Manager.URL_RESOURCE_TYPE_FILE.equals(commonCartridgeType)) { + item.setType(CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE); + } else { + throw new ToolException("Invalid shared commonCartridge type. Type was " + commonCartridgeType); + } + + items.put(itemOrder, item); + } + } + + Iterator iter = items.values().iterator(); + Date itemDate = null; + while (iter.hasNext()) { + if (itemDate != null) { + try { + Thread.sleep(1000); + } catch (Exception e) { + } + } + itemDate = new Date(); + + CommonCartridgeItem item = (CommonCartridgeItem) iter.next(); + item.setCreateDate(itemDate); + toolContentObj.getCommonCartridgeItems().add(item); + } + + } catch (WDDXProcessorConversionException e) { + CommonCartridgeServiceImpl.log.error("Unable to content for activity " + toolContentObj.getTitle() + + "properly due to a WDDXProcessorConversionException.", e); + throw new ToolException( + "Invalid import data format for activity " + + toolContentObj.getTitle() + + "- WDDX caused an exception. Some data from the design will have been lost. See log for more details."); + } + + commonCartridgeDao.saveObject(toolContentObj); + + } + + private CommonCartridgeItemInstruction createInstruction(Hashtable instructionEntry) + throws WDDXProcessorConversionException { + + Integer instructionOrder = WDDXProcessor.convertToInteger(instructionEntry, + ToolContentImport102Manager.CONTENT_URL_URL_VIEW_ORDER); + + // the description column in 1.0.2 was longer than 255 chars, so truncate. + String instructionText = (String) instructionEntry.get(ToolContentImport102Manager.CONTENT_URL_INSTRUCTION); + if (instructionText != null && instructionText.length() > 255) { + if (CommonCartridgeServiceImpl.log.isDebugEnabled()) { + CommonCartridgeServiceImpl.log + .debug("1.0.2 Import truncating Item Instruction to 255 characters. Original text was\'" + + instructionText + "\'"); + } + instructionText = instructionText.substring(0, 255); + } + + CommonCartridgeItemInstruction instruction = new CommonCartridgeItemInstruction(); + instruction.setDescription(instructionText); + instruction.setSequenceId(instructionOrder); + + return instruction; + } + + /** Set the description, throws away the title value as this is not supported in 2.0 */ + public void setReflectiveData(Long toolContentId, String title, String description) throws ToolException, + DataMissingException { + + CommonCartridge toolContentObj = getCommonCartridgeByContentId(toolContentId); + if (toolContentObj == null) { + throw new DataMissingException("Unable to set reflective data titled " + title + + " on activity toolContentId " + toolContentId + " as the tool content does not exist."); + } + + toolContentObj.setReflectOnActivity(Boolean.TRUE); + toolContentObj.setReflectInstructions(description); + } + + /* =================================================================================== */ + + public IExportToolContentService getExportContentService() { + return exportContentService; + } + + public void setExportContentService(IExportToolContentService exportContentService) { + this.exportContentService = exportContentService; + } + + public IUserManagementService getUserManagementService() { + return userManagementService; + } + + public void setUserManagementService(IUserManagementService userManagementService) { + this.userManagementService = userManagementService; + } + + public ICoreNotebookService getCoreNotebookService() { + return coreNotebookService; + } + + public void setCoreNotebookService(ICoreNotebookService coreNotebookService) { + this.coreNotebookService = coreNotebookService; + } + + public IEventNotificationService getEventNotificationService() { + return eventNotificationService; + } + + public void setEventNotificationService(IEventNotificationService eventNotificationService) { + this.eventNotificationService = eventNotificationService; + } + + public String getLocalisedMessage(String key, Object[] args) { + return messageService.getMessage(key, args); + } + + public ILessonService getLessonService() { + return lessonService; + } + + public void setLessonService(ILessonService lessonService) { + this.lessonService = lessonService; + } + + /** + * Finds out which lesson the given tool content belongs to and returns its monitoring users. + * + * @param sessionId + * tool session ID + * @return list of teachers that monitor the lesson which contains the tool with given session ID + */ + public List getMonitorsByToolSessionId(Long sessionId) { + return getLessonService().getMonitorsByToolSessionId(sessionId); + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceProxy.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceProxy.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/CommonCartridgeServiceProxy.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,75 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.service; + +import javax.servlet.ServletContext; + +import org.lamsfoundation.lams.tool.ToolContentManager; +import org.lamsfoundation.lams.tool.ToolSessionManager; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + + + + +/** + * @author Andrey Balan + * + *

    This class act as the proxy between web layer and service layer. It is + * designed to decouple the presentation logic and business logic completely. + * In this way, the presentation tier will no longer be aware of the changes in + * service layer. Therefore we can feel free to switch the business logic + * implementation.

    + */ +public class CommonCartridgeServiceProxy +{ + /** + * Return the domain service object. It will delegate to the Spring + * helper method to retrieve the proper bean from Spring bean factory. + * @param servletContext the servletContext for current application + * @return Shared commonCartridge service object. + */ + public static final ICommonCartridgeService getCommonCartridgeService(ServletContext servletContext) + { + return (ICommonCartridgeService)getCommonCartridgeDomainService(servletContext); + } + + public static final ToolSessionManager getSessionManager(ServletContext servletContext) + { + return (ToolSessionManager)getCommonCartridgeDomainService(servletContext); + } + + public static final ToolContentManager getContentManager(ServletContext servletContext) + { + return (ToolContentManager)getCommonCartridgeDomainService(servletContext); + } + + private static Object getCommonCartridgeDomainService(ServletContext servletContext) + { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); + return wac.getBean(CommonCartridgeConstants.RESOURCE_SERVICE); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/ICommonCartridgeService.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/ICommonCartridgeService.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/ICommonCartridgeService.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,327 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.service; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; + +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.contentrepository.IVersionedNode; +import org.lamsfoundation.lams.events.IEventNotificationService; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.tool.commonCartridge.dto.ReflectDTO; +import org.lamsfoundation.lams.tool.commonCartridge.dto.Summary; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeAttachment; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.usermanagement.User; + +/** + * @author Andrey Balan + * + * Interface that defines the contract that all ShareCommonCartridge service provider must follow. + */ +public interface ICommonCartridgeService { + + /** + * Get file IVersiondNode by given package id and path. + * + * @param packageId + * @param relPathString + * @return + * @throws CommonCartridgeApplicationException + */ + IVersionedNode getFileNode(Long packageId, String relPathString) throws CommonCartridgeApplicationException; + + /** + * Get CommonCartridge by toolContentID. + * + * @param contentId + * @return + */ + CommonCartridge getCommonCartridgeByContentId(Long contentId); + + /** + * Get a cloned copy of tool default tool content (CommonCartridge) and assign the toolContentId of that copy as the given + * contentId + * + * @param contentId + * @return + * @throws CommonCartridgeApplicationException + */ + CommonCartridge getDefaultContent(Long contentId) throws CommonCartridgeApplicationException; + + /** + * Get list of commonCartridge items by given commonCartridgeUid. These commonCartridge items must be created by author. + * + * @param commonCartridgeUid + * @return + */ + List getAuthoredItems(Long commonCartridgeUid); + + /** + * Upload instruciton file into repository. + * + * @param file + * @param type + * @return + * @throws UploadCommonCartridgeFileException + */ + CommonCartridgeAttachment uploadInstructionFile(FormFile file, String type) throws UploadCommonCartridgeFileException; + + /** + * Upload commonCartridge item file to repository. i.e., single file, websize zip file, or learning object zip file. + * + * @param item + * @param file + * @return + * @throws UploadCommonCartridgeFileException + */ + List uploadCommonCartridgeFile(CommonCartridgeItem item, FormFile file) throws UploadCommonCartridgeFileException; + + // ********** for user methods ************* + /** + * Create a new user in database. + */ + void createUser(CommonCartridgeUser commonCartridgeUser); + + /** + * Get user by given userID and toolContentID. + * + * @param long1 + * @return + */ + CommonCartridgeUser getUserByIDAndContent(Long userID, Long contentId); + + /** + * Get user by sessionID and UserID + * + * @param long1 + * @param sessionId + * @return + */ + CommonCartridgeUser getUserByIDAndSession(Long long1, Long sessionId); + + // ********** Repository methods *********************** + /** + * Delete file from repository. + */ + void deleteFromRepository(Long fileUuid, Long fileVersionId) throws CommonCartridgeApplicationException; + + /** + * Save or update commonCartridge into database. + * + * @param CommonCartridge + */ + void saveOrUpdateCommonCartridge(CommonCartridge CommonCartridge); + + /** + * Delete reource attachment(i.e., offline/online instruction file) from database. This method does not delete the + * file from repository. + * + * @param attachmentUid + */ + void deleteCommonCartridgeAttachment(Long attachmentUid); + + /** + * Delete resoruce item from database. + * + * @param uid + */ + void deleteCommonCartridgeItem(Long uid); + + /** + * Return all reource items within the given toolSessionID. + * + * @param sessionId + * @return + */ + List getCommonCartridgeItemsBySessionId(Long sessionId); + + /** + * Get commonCartridge which is relative with the special toolSession. + * + * @param sessionId + * @return + */ + CommonCartridge getCommonCartridgeBySessionId(Long sessionId); + + /** + * Get commonCartridge toolSession by toolSessionId + * + * @param sessionId + * @return + */ + CommonCartridgeSession getCommonCartridgeSessionBySessionId(Long sessionId); + + /** + * Save or update commonCartridge session. + * + * @param resSession + */ + void saveOrUpdateCommonCartridgeSession(CommonCartridgeSession resSession); + + void retrieveComplete(SortedSet commonCartridgeItemList, CommonCartridgeUser user); + + void setItemComplete(Long commonCartridgeItemUid, Long userId, Long sessionId); + + void setItemAccess(Long commonCartridgeItemUid, Long userId, Long sessionId); + + /** + * the reqired number minus the count of view of the given user. + * + * @param userUid + * @return + */ + int checkMiniView(Long toolSessionId, Long userId); + + /** + * If success return next activity's url, otherwise return null. + * + * @param toolSessionId + * @param userId + * @return + */ + String finishToolSession(Long toolSessionId, Long userId) throws CommonCartridgeApplicationException; + + CommonCartridgeItem getCommonCartridgeItemByUid(Long itemUid); + + /** + * Return monitoring summary list. The return value is list of commonCartridge summaries for each groups. + * + * @param contentId + * @return + */ + List> getSummary(Long contentId); + + List getUserListBySessionItem(Long sessionId, Long itemUid); + + /** + * Set a commonCartridge item visible or not. + * + * @param itemUid + * @param visible + * true, item is visible. False, item is invisible. + */ + void setItemVisible(Long itemUid, boolean visible); + + /** + * Get commonCartridge item Summary list according to sessionId and skipHide flag. + * + * @param sessionId + * @param skipHide + * true, don't get commonCartridge item if its isHide flag is true. Otherwise, get all + * commonCartridge item + * @return + */ + public List exportBySessionId(Long sessionId, boolean skipHide); + + public List> exportByContentId(Long contentId); + + /** + * Create refection entry into notebook tool. + * + * @param sessionId + * @param notebook_tool + * @param tool_signature + * @param userId + * @param entryText + */ + public Long createNotebookEntry(Long sessionId, Integer notebookToolType, String toolSignature, Integer userId, + String entryText); + + /** + * Get reflection entry from notebook tool. + * + * @param sessionId + * @param idType + * @param signature + * @param userID + * @return + */ + public NotebookEntry getEntry(Long sessionId, Integer idType, String signature, Integer userID); + + /** + * @param notebookEntry + */ + public void updateEntry(NotebookEntry notebookEntry); + + /** + * Get Reflect DTO list grouped by sessionID. + * + * @param contentId + * @return + */ + Map> getReflectList(Long contentId, boolean setEntry); + + /** + * Get user by UID + * + * @param uid + * @return + */ + CommonCartridgeUser getUser(Long uid); + + public IEventNotificationService getEventNotificationService(); + + /** + * Get the CommonCartridge config item by key + * + * @param key + * @return + */ + public CommonCartridgeConfigItem getConfigItem(String key); + + /** + * Save a CommonCartridge configItem + * + * @param item + */ + public void saveOrUpdateConfigItem(CommonCartridgeConfigItem item); + + /** + * Gets a message from commonCartridge bundle. Same as in JSP pages. + * + * @param key + * key of the message + * @param args + * arguments for the message + * @return message content + */ + String getLocalisedMessage(String key, Object[] args); + + /** + * Finds out which lesson the given tool content belongs to and returns its monitoring users. + * + * @param sessionId + * tool session ID + * @return list of teachers that monitor the lesson which contains the tool with given session ID + */ + public List getMonitorsByToolSessionId(Long sessionId); +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/UploadCommonCartridgeFileException.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/UploadCommonCartridgeFileException.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/service/UploadCommonCartridgeFileException.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,48 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.service; + +public class UploadCommonCartridgeFileException extends Exception { + + public UploadCommonCartridgeFileException() { + super(); + + } + + public UploadCommonCartridgeFileException(String message, Throwable cause) { + super(message, cause); + + } + + public UploadCommonCartridgeFileException(String message) { + super(message); + + } + + public UploadCommonCartridgeFileException(Throwable cause) { + super(cause); + + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeItemComparator.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeItemComparator.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeItemComparator.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,23 @@ +package org.lamsfoundation.lams.tool.commonCartridge.util; + +import java.util.Comparator; + +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; + +/** + * + * @author Andrey Balan + * + */ +public class CommonCartridgeItemComparator implements Comparator { + + public int compare(CommonCartridgeItem o1, CommonCartridgeItem o2) { + if (o1 != null && o2 != null & o1.getCreateDate() != null && o2.getCreateDate() != null) { + return (o1.getCreateDate().getTime() - o2.getCreateDate().getTime()) > 0 ? 1 : -1; + } else if (o1 != null) + return 1; + else + return -1; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeToolContentHandler.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeToolContentHandler.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeToolContentHandler.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,68 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.util; + +import org.lamsfoundation.lams.contentrepository.client.ToolContentHandler; + +/** + * Simple client for accessing the content repository. + * + * @author Andrey Balan + */ +public class CommonCartridgeToolContentHandler extends ToolContentHandler { + + private static String repositoryWorkspaceName = "sharedcommonCartridgeworkspace"; + private static String repositoryUser = "sharedcommonCartridge"; + //sharedcommonCartridge + private static char[] repositoryId = {'l','a','m','s','-','s','h','a','r','e','d','r','e','s','o','u','r','c','e','s'}; + + /** + * + */ + public CommonCartridgeToolContentHandler() { + super(); + } + + /* (non-Javadoc) + * @see org.lamsfoundation.lams.contentrepository.client.ToolContentHandler#getRepositoryWorkspaceName() + */ + public String getRepositoryWorkspaceName() { + return repositoryWorkspaceName; + } + + /* (non-Javadoc) + * @see org.lamsfoundation.lams.contentrepository.client.ToolContentHandler#getRepositoryUser() + */ + public String getRepositoryUser() { + return repositoryUser; + } + + /* (non-Javadoc) + * @see org.lamsfoundation.lams.contentrepository.client.ToolContentHandler#getRepositoryId() + */ + public char[] getRepositoryId() { + return repositoryId; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeWebUtils.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeWebUtils.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/CommonCartridgeWebUtils.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,53 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.util; + +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; + +/** + * Contains helper methods used by the Action Servlets + * + * @author Andrey Balan + * + */ +public class CommonCartridgeWebUtils { + + /** + * If there is not url prefix, such as http://, https:// or ftp:// etc, this method will add default url protocol. + * + * @param url + * @return + */ + public static String protocol(String url) { + if (url == null) + return ""; + + if (!url.matches("^" + CommonCartridgeConstants.ALLOW_PROTOCOL_REFIX + ".*")) + url = CommonCartridgeConstants.DEFUALT_PROTOCOL_REFIX + url; + + return url; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/LamsBasicLTIUtil.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/LamsBasicLTIUtil.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/LamsBasicLTIUtil.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,363 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.util; + +import java.util.Properties; + +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.imsglobal.basiclti.BasicLTIConstants; +import org.imsglobal.basiclti.BasicLTIUtil; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** + * Utility code for IMS Basic LTI. This is mostly code to support making and + * launching BLTI resources. + */ +@SuppressWarnings("deprecation") +public class LamsBasicLTIUtil { + + private static Logger log = Logger.getLogger(LamsBasicLTIUtil.class); + + /** + * Look at a Placement and come up with the launch urls, and other launch parameters to drive the launch. + * + * @param info + * @param launch + * @param placement + * @return + */ + public static Properties loadFromPlacement(Properties launch, CommonCartridgeItem basicLTIItem) { + Properties info = new Properties(); + + setProperty(info, "launch_url", basicLTIItem.getLaunchUrl()); + setProperty(info, "secure_launch_url", basicLTIItem.getSecureLaunchUrl()); + setProperty(info, "secret", basicLTIItem.getSecret()); + setProperty(info, "key", basicLTIItem.getKey()); + setProperty(info, "debug", "false"); + setProperty(info, "frameheight", new Integer(basicLTIItem.getFrameHeight()).toString()); + setProperty(info, "newwindow", new Boolean(basicLTIItem.isOpenUrlNewWindow()).toString()); + setProperty(info, "title", basicLTIItem.getTitle()); + setProperty(info, BasicLTIUtil.BASICLTI_SUBMIT, basicLTIItem.getButtonText()); + + // Pull in and parse the custom parameters + String customstr = toNull(basicLTIItem.getCustomStr()); + if (customstr != null) { + String[] params = customstr.split("[\n;]"); + for (int i = 0; i < params.length; i++) { + String param = params[i]; + if (param == null) + continue; + if (param.length() < 1) + continue; + int pos = param.indexOf("="); + if (pos < 1) + continue; + if (pos + 1 > param.length()) + continue; + String key = BasicLTIUtil.mapKeyName(param.substring(0, pos)); + if (key == null) + continue; + String value = param.substring(pos + 1); + value = value.trim(); + if (value.length() < 1) + continue; + if (value == null) + continue; + setProperty(info, "custom_" + key, value); + } + } + + if (info.getProperty("launch_url", null) != null || info.getProperty("secure_launch_url", null) != null) { + return info; + } + return null; + } + + /** + * Retrieve the LAMS information about users, etc. + * + * @param basicLTIItem + * @return launch Properties + */ + public static Properties inititializeLaunchProperties(ICommonCartridgeService service, CommonCartridgeItem basicLTIItem) { + Properties launchProperties = new Properties(); + // Start setting the Basic LTI parameters + String resourceLinkId = (basicLTIItem.getUid() != null) ? basicLTIItem.getUid().toString() : "" + basicLTIItem.getCreateDate().getTime(); + setProperty(launchProperties, BasicLTIConstants.RESOURCE_LINK_ID, resourceLinkId); + + setProperty(launchProperties, BasicLTIConstants.RESOURCE_LINK_TITLE, basicLTIItem.getTitle()); + setProperty(launchProperties, BasicLTIConstants.RESOURCE_LINK_DESCRIPTION, basicLTIItem.getDescription()); + + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + if (user != null) { + setProperty(launchProperties, BasicLTIConstants.USER_ID, user.getUserID().toString()); + setProperty(launchProperties, BasicLTIConstants.LAUNCH_PRESENTATION_LOCALE, Configuration.get(ConfigurationKeys.SERVER_LANGUAGE)); + + String isExposeUserName = service.getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_NAME).getConfigValue(); + if (Boolean.parseBoolean(isExposeUserName)) { + setProperty(launchProperties, BasicLTIConstants.LIS_PERSON_NAME_GIVEN, user.getFirstName()); + setProperty(launchProperties, BasicLTIConstants.LIS_PERSON_NAME_FAMILY, user.getLastName()); + setProperty(launchProperties, BasicLTIConstants.LIS_PERSON_NAME_FULL, user.getLastName() + " " + user.getFirstName()); + } + + String isExposeUserEmail = service.getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_EMAIL).getConfigValue(); + if (Boolean.parseBoolean(isExposeUserEmail)) { + setProperty(launchProperties, BasicLTIConstants.LIS_PERSON_CONTACT_EMAIL_PRIMARY, user.getEmail()); + } + } + + String theRole = "Learner"; + //TODO check if we need instructor +// if (SecurityService.isSuperUser()) { +// theRole = "Instructor"; +// } else if (SiteService.allowUpdateSite(context)) { +// theRole = "Instructor"; +// } + setProperty(launchProperties, "roles", theRole); + + //TODO check if the next statement is correct and we don't need the following parameters: + //Lams tools doesn't have info on the context(Lesson) so we can't provide with this info +// if (site != null) { +// String context_type = site.getType(); +// if (context_type != null && context_type.toLowerCase().contains("course")) { +// setProperty(props, BasicLTIConstants.CONTEXT_TYPE, BasicLTIConstants.CONTEXT_TYPE_COURSE_SECTION); +// } +// setProperty(props, BasicLTIConstants.CONTEXT_ID, site.getId()); +// setProperty(props, BasicLTIConstants.CONTEXT_LABEL, site.getTitle()); +// setProperty(props, BasicLTIConstants.CONTEXT_TITLE, site.getTitle()); +// String courseRoster = getExternalRealmId(site.getId()); +// if (courseRoster != null) { +// setProperty(props, BasicLTIConstants.LIS_COURSE_OFFERING_SOURCEDID, courseRoster); +// } +// } + + // Get the organizational information + //TODO if we need this? + setProperty(launchProperties, BasicLTIConstants.TOOL_CONSUMER_INSTANCE_GUID, + Configuration.get(ConfigurationKeys.SERVER_URL)); + setProperty(launchProperties, BasicLTIConstants.TOOL_CONSUMER_INSTANCE_NAME, "SchoolU"); + setProperty(launchProperties, BasicLTIConstants.TOOL_CONSUMER_INSTANCE_DESCRIPTION, "University of School (LMSng) "); + setProperty(launchProperties, BasicLTIConstants.TOOL_CONSUMER_INSTANCE_CONTACT_EMAIL, "System.Admin@school.edu"); + setProperty(launchProperties, BasicLTIConstants.TOOL_CONSUMER_INSTANCE_URL, ""); + setProperty(launchProperties, BasicLTIConstants.LAUNCH_PRESENTATION_RETURN_URL, "launch_presentation_return_url"); + + // Let tools know we are coming from Lams + setProperty(launchProperties, "ext_lms", "lams"); + return launchProperties; + } + +// /** +// * Generate HTML from a descriptor and properties from +// * +// * @param descriptor +// * @param contextId +// * @param basicLTIItem +// * @param props +// * @param messageService +// * @param service +// * @return +// */ +// public static String postLaunchHTML(String descriptor, String contextId, CommonCartridgeItem basicLTIItem, +// MessageService messageService, ICommonCartridgeService service) { +// if (descriptor == null || contextId == null) +// return "

    " + messageService.getMessage("error.descriptor", "Error, missing contextId, resourceid or descriptor") + "

    "; +// +// // Add user, course, etc to the launch parameters +// Properties launch = inititializeLaunchProperties(service, basicLTIItem); +// +// Properties info = new Properties(); +// if (!BasicLTIUtil.parseDescriptor(info, launch, descriptor)) { +// return "

    " + messageService.getMessage("error.badxml.resource", "Error, cannot parse descriptor for resource=") +// + basicLTIItem.getUid() + ".

    "; +// } +// +// return postLaunchHTML(info, launch, messageService); +// } + + /** + * This must return an HTML message as the [0] in the array + * + * @param service + * @param messageService + * @param basicLTIItem + * @return + */ + public static String postLaunchHTML(ICommonCartridgeService service, MessageService messageService, CommonCartridgeItem basicLTIItem) { + + // Add user, course, etc to the launch parameters + Properties launch = inititializeLaunchProperties(service, basicLTIItem); + + // Retrieve the launch detail + Properties info = loadFromPlacement(launch, basicLTIItem); + if (info == null) { + return "

    " + messageService.getMessage("error.nolaunch", "Not Configured.") + "

    "; + } + return postLaunchHTML(info, launch, messageService); + } + + public static String postLaunchHTML(Properties info, Properties launch, MessageService messageService) { + + String launch_url = info.getProperty("secure_launch_url"); + if (launch_url == null) { + launch_url = info.getProperty("launch_url"); + } + if (launch_url == null) { + return "

    " + messageService.getMessage("error.missing", "Not configured") + "

    "; + } + + String org_guid = info.getProperty(BasicLTIConstants.TOOL_CONSUMER_INSTANCE_GUID); + String org_desc = info.getProperty(BasicLTIConstants.TOOL_CONSUMER_INSTANCE_DESCRIPTION); + String org_url = info.getProperty(BasicLTIConstants.LAUNCH_PRESENTATION_RETURN_URL); + + // Look up the LMS-wide secret and key - default key is guid + String key = getToolConsumerInfo(launch_url, "key"); + if (key == null) + key = org_guid; + String secret = getToolConsumerInfo(launch_url, "secret"); + + // Demand key/secret in a pair + if (key == null || secret == null) { + key = null; + secret = null; + } + + // If we do not have LMS-wide info, use the local key/secret + if (secret == null) { + secret = toNull(info.getProperty("secret")); + key = toNull(info.getProperty("key")); + } + + // Pull in all of the custom parameters + for (Object okey : info.keySet()) { + String skey = (String) okey; + if (!skey.startsWith(BasicLTIConstants.CUSTOM_PREFIX)) + continue; + String value = info.getProperty(skey); + if (value == null) + continue; + setProperty(launch, skey, value); + } + + setProperty(launch, "oauth_callback", "about:blank"); + String buttonLabel = StringUtils.isBlank(info.getProperty(BasicLTIUtil.BASICLTI_SUBMIT)) + ? messageService.getMessage("launch.button", "Press to Launch External Tool") + : info.getProperty(BasicLTIUtil.BASICLTI_SUBMIT); + setProperty(launch, BasicLTIUtil.BASICLTI_SUBMIT, buttonLabel); + + // Sanity checks + if (secret == null) { + return "

    " + messageService.getMessage("error.nosecret", "Error - must have a secret.") + "

    "; + } + if (secret != null && key == null) { + return "

    " + messageService.getMessage("error.nokey", "Error - must have a secret and a key.") + "

    "; + } + + launch = BasicLTIUtil.signProperties(launch, launch_url, "POST", key, secret, org_guid, org_desc, org_url); + + if (launch == null) { + return "

    " + messageService.getMessage("error.sign", "Error signing message.") + "

    "; + } + + boolean dodebug = toNull(info.getProperty("debug")) != null; + String postData = BasicLTIUtil.postLaunchHTML(launch, launch_url, dodebug); + return postData; + } + + // To make absolutely sure we never send an XSS, we clean these values + public static void setProperty(Properties props, String key, String value) { + if (value == null) + return; +// value = Web.cleanHtml(value); + if (value.trim().length() < 1) + return; + props.setProperty(key, value); + } + + /** + *TODO use external service proposed by Ernie + * + * Look through a series of secrets from the properties based on the launchUrl + * + * @param launchUrl + * @param data "key" or "secret" + * @return + */ + + private static String getToolConsumerInfo(String launchUrl, String data) { +// String default_data = ServerConfigurationService.getString("basiclti.consumer_instance_" + data, null); +// URL url = null; +// try { +// url = new URL(launchUrl); +// } catch (Exception e) { +// url = null; +// } +// if (url == null) +// return default_data; +// String hostName = url.getHost(); +// if (hostName == null || hostName.length() < 1) +// return default_data; +// +// // Look for the property starting with the full name +// String org_info = ServerConfigurationService.getString("basiclti.consumer_instance_" + data + "." + hostName, +// null); +// if (org_info != null) +// return org_info; +// +// // Look for the property starting with the part name +// for (int i = 0; i < hostName.length(); i++) { +// if (hostName.charAt(i) != '.') +// continue; +// if (i > hostName.length() - 2) +// continue; +// String hostPart = hostName.substring(i + 1); +// String propName = "basiclti.consumer_instance_" + data + "." + hostPart; +// org_info = ServerConfigurationService.getString(propName, null); +// if (org_info != null) +// return org_info; +// } +// return default_data; + return null; + } + + public static String toNull(String str) { + if (str == null) + return null; + if (str.trim().length() < 1) + return null; + return str; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/ReflectDTOComparator.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/ReflectDTOComparator.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/util/ReflectDTOComparator.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,38 @@ +/**************************************************************** + * 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 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.commonCartridge.util; + +import java.util.Comparator; + +import org.lamsfoundation.lams.tool.commonCartridge.dto.ReflectDTO; + +public class ReflectDTOComparator implements Comparator { + public int compare(ReflectDTO o1, ReflectDTO o2) { + if (o1 != null && o2 != null) { + return o1.getFullName().compareTo(o2.getFullName()); + } else if (o1 != null) + return 1; + else + return -1; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AdminAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AdminAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AdminAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,145 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeConfigItem; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeServiceProxy; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.web.form.AdminForm; + +/** + * @author Andrey Balan + */ +public class AdminAction extends Action { + private ICommonCartridgeService commonCartridgeService; + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String param = mapping.getParameter(); + // -----------------------BasicLTI Author function --------------------------- + if (param.equals("start")) { + return start(mapping, form, request, response); + } + if (param.equals("saveContent")) { + return saveContent(mapping, form, request, response); + } + + return start(mapping, form, request, response); + } + + public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + // set up commonCartridgeService + if (commonCartridgeService == null) { + commonCartridgeService = CommonCartridgeServiceProxy.getCommonCartridgeService(this.getServlet().getServletContext()); + } + + AdminForm adminForm = (AdminForm) form; + + CommonCartridgeConfigItem allowExposeUserName = commonCartridgeService.getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_NAME); + if (allowExposeUserName != null) { + adminForm.setAllowExposeUserName(Boolean.parseBoolean(allowExposeUserName.getConfigValue())); + } + + CommonCartridgeConfigItem allowExposeUserEmail = commonCartridgeService + .getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_EMAIL); + if (allowExposeUserEmail != null) { + adminForm.setAllowExposeUserEmail(Boolean.parseBoolean(allowExposeUserEmail.getConfigValue())); + } + + request.setAttribute("error", false); + return mapping.findForward("config"); + } + + public ActionForward saveContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + AdminForm adminForm = (AdminForm) form; + + ActionErrors errors = validateAdminForm(adminForm); + if (!errors.isEmpty()) { + this.addErrors(request, errors); + return mapping.findForward("config"); + } + + // set up commonCartridgeService + if (commonCartridgeService == null) { + commonCartridgeService = CommonCartridgeServiceProxy.getCommonCartridgeService(this.getServlet().getServletContext()); + } + + CommonCartridgeConfigItem allowExposeUserName = commonCartridgeService.getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_NAME); + allowExposeUserName.setConfigValue(String.valueOf(adminForm.isAllowExposeUserName())); + commonCartridgeService.saveOrUpdateConfigItem(allowExposeUserName); + + CommonCartridgeConfigItem allowExposeUserEmail = commonCartridgeService + .getConfigItem(CommonCartridgeConfigItem.KEY_EXPOSE_USER_EMAIL); + allowExposeUserEmail.setConfigValue(String.valueOf(adminForm.isAllowExposeUserEmail())); + commonCartridgeService.saveOrUpdateConfigItem(allowExposeUserEmail); + + request.setAttribute("savedSuccess", true); + return mapping.findForward("config"); + + } + + /** + * Validate BasicLTIConfigItems. + * + * @param adminForm + * @return + */ + private ActionErrors validateAdminForm(AdminForm adminForm) { + ActionErrors errors = new ActionErrors(); + + // if ((adminForm.isAllowExposeUserName() == null) || adminForm.isAllowExposeUserName().equals("")) { + // if (!isParsableToInt(adminForm.isAllowExposeUserName())) { + // errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + // BasicLTIConstants.ERROR_MSG_ENTERED_VALUES_NOT_INTEGERS)); + // } + // } else { + // errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + // BasicLTIConstants.ERROR_MSG_REQUIRED_FIELDS_MISSING)); + // } + // + // if ((adminForm.isAllowExposeUserEmail() != null) && !adminForm.isAllowExposeUserEmail().equals("")) { + // if (!isParsableToInt(adminForm.isAllowExposeUserEmail())) { + // errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + // BasicLTIConstants.ERROR_MSG_ENTERED_VALUES_NOT_INTEGERS)); + // } + // } else { + // errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + // BasicLTIConstants.ERROR_MSG_REQUIRED_FIELDS_MISSING)); + // } + + return errors; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AuthoringAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AuthoringAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/AuthoringAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,1213 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import java.io.IOException; +import java.io.PrintWriter; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +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.apache.struts.action.Action; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionMessage; +import org.apache.struts.action.ActionMessages; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeAttachment; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeApplicationException; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.service.UploadCommonCartridgeFileException; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeItemComparator; +import org.lamsfoundation.lams.tool.commonCartridge.web.form.CommonCartridgeForm; +import org.lamsfoundation.lams.tool.commonCartridge.web.form.CommonCartridgeItemForm; +import org.lamsfoundation.lams.tool.commonCartridge.web.form.CommonCartridgePedagogicalPlannerForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.FileValidatorUtil; +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.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * @author Andrey Balan + */ +public class AuthoringAction extends Action { + private static final String ITEM_TYPE = "itemType"; + + private static Logger log = Logger.getLogger(AuthoringAction.class); + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String param = mapping.getParameter(); + // -----------------------CommonCartridge Author function --------------------------- + if (param.equals("start")) { + ToolAccessMode mode = getAccessMode(request); + // teacher mode "check for new" button enter. + if (mode != null) { + request.setAttribute(AttributeNames.ATTR_MODE, mode.toString()); + } else { + request.setAttribute(AttributeNames.ATTR_MODE, ToolAccessMode.AUTHOR.toString()); + } + return start(mapping, form, request, response); + } + if (param.equals("definelater")) { + // update define later flag to true + Long contentId = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID)); + ICommonCartridgeService service = getCommonCartridgeService(); + CommonCartridge commonCartridge = service.getCommonCartridgeByContentId(contentId); + + commonCartridge.setDefineLater(true); + service.saveOrUpdateCommonCartridge(commonCartridge); + + request.setAttribute(AttributeNames.ATTR_MODE, ToolAccessMode.TEACHER.toString()); + return start(mapping, form, request, response); + } + if (param.equals("initPage")) { + return initPage(mapping, form, request, response); + } + + if (param.equals("updateContent")) { + return updateContent(mapping, form, request, response); + } + if (param.equals("uploadOnlineFile")) { + return uploadOnline(mapping, form, request, response); + } + if (param.equals("uploadOfflineFile")) { + return uploadOffline(mapping, form, request, response); + } + if (param.equals("deleteOnlineFile")) { + return deleteOnlineFile(mapping, form, request, response); + } + if (param.equals("deleteOfflineFile")) { + return deleteOfflineFile(mapping, form, request, response); + } + // ----------------------- Add commonCartridge item function --------------------------- + if (param.equals("newItemInit")) { + return newItemlInit(mapping, form, request, response); + } + if (param.equals("editItemInit")) { + return editItemInit(mapping, form, request, response); + } + if (param.equals("saveOrUpdateItem")) { + return saveOrUpdateItem(mapping, form, request, response); + } + if (param.equals("removeItem")) { + return removeItem(mapping, form, request, response); + } + // -----------------------CommonCartridge Item Instruction function --------------------------- + if (param.equals("removeItemAttachment")) { + return removeItemAttachment(mapping, form, request, response); + } + if (param.equals("initPedagogicalPlannerForm")) { + return initPedagogicalPlannerForm(mapping, form, request, response); + } + if (param.equals("createPedagogicalPlannerItem")) { + return createPedagogicalPlannerItem(mapping, form, request, response); + } + if (param.equals("saveOrUpdatePedagogicalPlannerForm")) { + return saveOrUpdatePedagogicalPlannerForm(mapping, form, request, response); + } + + return mapping.findForward(CommonCartridgeConstants.ERROR); + } + + /** + * Remove commonCartridge item attachment, such as single file, learning object ect. It is a ajax call and just + * temporarily remove from page, all permenant change will happen only when user sumbit this commonCartridge item + * again. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward removeItemAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + request.setAttribute("itemAttachment", null); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Remove commonCartridge item from HttpSession list and update page display. As authoring rule, all persist only + * happen when user submit whole page. So this remove is just impact HttpSession values. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward removeItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int itemIdx = NumberUtils.stringToInt(request.getParameter(CommonCartridgeConstants.PARAM_ITEM_INDEX), -1); + if (itemIdx != -1) { + SortedSet commonCartridgeList = getCommonCartridgeItemList(sessionMap); + List rList = new ArrayList(commonCartridgeList); + CommonCartridgeItem item = rList.remove(itemIdx); + commonCartridgeList.clear(); + commonCartridgeList.addAll(rList); + // add to delList + List delList = getDeletedCommonCartridgeItemList(sessionMap); + delList.add(item); + } + + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Display edit page for existed commonCartridge item. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward editItemInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int itemIdx = NumberUtils.stringToInt(request.getParameter(CommonCartridgeConstants.PARAM_ITEM_INDEX), -1); + CommonCartridgeItem item = null; + if (itemIdx != -1) { + SortedSet commonCartridgeList = getCommonCartridgeItemList(sessionMap); + List rList = new ArrayList(commonCartridgeList); + item = rList.get(itemIdx); + if (item != null) { + populateItemToForm(itemIdx, item, (CommonCartridgeItemForm) form, request); + } + } + return findForward(item == null ? -1 : item.getType(), mapping); + } + + /** + * Display empty page for new commonCartridge item. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward newItemlInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + ((CommonCartridgeItemForm) form).setSessionMapID(sessionMapID); + + short type = (short) NumberUtils.stringToInt(request.getParameter(AuthoringAction.ITEM_TYPE)); + return findForward(type, mapping); + } + + /** + * This method will get necessary information from commonCartridge item form and save or update into + * HttpSession CommonCartridgeItemList. Notice, this save is not persist them into database, just save + * HttpSession temporarily. Only they will be persist when the entire authoring page is being + * persisted. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward saveOrUpdateItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + CommonCartridgeItemForm itemForm = (CommonCartridgeItemForm) form; + ActionErrors errors = validateCommonCartridgeItem(itemForm); + + if (!errors.isEmpty()) { + this.addErrors(request, errors); + return findForward(itemForm.getItemType(), mapping); + } + + try { + short type = itemForm.getItemType(); + if (type == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE) { + uploadCommonCartridge(request, itemForm); + } else { + extractFormToCommonCartridgeItem(request, itemForm); + } + } catch (Exception e) { + // any upload exception will display as normal error message rather then throw exception directly + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + CommonCartridgeConstants.ERROR_MSG_UPLOAD_FAILED, e.getMessage())); + if (!errors.isEmpty()) { + this.addErrors(request, errors); + return findForward(itemForm.getItemType(), mapping); + } + } + // set session map ID so that itemlist.jsp can get sessionMAP + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, itemForm.getSessionMapID()); + // return null to close this window + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Read commonCartridge data from database and put them into HttpSession. It will redirect to init.do directly after + * this method run successfully. + * + * This method will avoid read database again and lost un-saved resouce item lost when user "refresh page", + * + * @throws ServletException + * + */ + private ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { + + // save toolContentID into HTTPSession + Long contentId = new Long(WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_TOOL_CONTENT_ID)); + + // get back the commonCartridge and item list and display them on page + ICommonCartridgeService service = getCommonCartridgeService(); + + List items = null; + CommonCartridge commonCartridge = null; + CommonCartridgeForm commonCartridgeForm = (CommonCartridgeForm) form; + + // Get contentFolderID and save to form. + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + commonCartridgeForm.setContentFolderID(contentFolderID); + + // initial Session Map + SessionMap sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + commonCartridgeForm.setSessionMapID(sessionMap.getSessionID()); + + try { + commonCartridge = service.getCommonCartridgeByContentId(contentId); + // if commonCartridge does not exist, try to use default content instead. + if (commonCartridge == null) { + commonCartridge = service.getDefaultContent(contentId); + if (commonCartridge.getCommonCartridgeItems() != null) { + items = new ArrayList(commonCartridge.getCommonCartridgeItems()); + } else { + items = null; + } + } else { + items = service.getAuthoredItems(commonCartridge.getUid()); + } + + commonCartridgeForm.setCommonCartridge(commonCartridge); + + // initialize instruction attachment list + List attachmentList = getAttachmentList(sessionMap); + attachmentList.clear(); + attachmentList.addAll(commonCartridge.getAttachments()); + } catch (Exception e) { + AuthoringAction.log.error(e); + throw new ServletException(e); + } + + // init it to avoid null exception in following handling + if (items == null) { + items = new ArrayList(); + } else { + CommonCartridgeUser commonCartridgeUser = null; + // handle system default question: createBy is null, now set it to current user + for (CommonCartridgeItem item : items) { + if (item.getCreateBy() == null) { + if (commonCartridgeUser == null) { + // get back login user DTO + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + commonCartridgeUser = new CommonCartridgeUser(user, commonCartridge); + } + item.setCreateBy(commonCartridgeUser); + } + } + } + // init commonCartridge item list + SortedSet commonCartridgeItemList = getCommonCartridgeItemList(sessionMap); + commonCartridgeItemList.clear(); + commonCartridgeItemList.addAll(items); + + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_FORM, commonCartridgeForm); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Display same entire authoring page content from HttpSession variable. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward initPage(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + CommonCartridgeForm existForm = (CommonCartridgeForm) sessionMap + .get(CommonCartridgeConstants.ATTR_RESOURCE_FORM); + + CommonCartridgeForm commonCartridgeForm = (CommonCartridgeForm) form; + try { + PropertyUtils.copyProperties(commonCartridgeForm, existForm); + } catch (Exception e) { + throw new ServletException(e); + } + + ToolAccessMode mode = getAccessMode(request); + if (mode.isAuthor()) { + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } else { + return mapping.findForward(CommonCartridgeConstants.DEFINE_LATER); + } + } + + /** + * This method will persist all inforamtion in this authoring page, include all commonCartridge item, information + * etc. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward updateContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + CommonCartridgeForm commonCartridgeForm = (CommonCartridgeForm) form; + + // get back sessionMAP + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(commonCartridgeForm.getSessionMapID()); + + ToolAccessMode mode = getAccessMode(request); + + ActionMessages errors = validate(commonCartridgeForm, mapping, request); + if (!errors.isEmpty()) { + saveErrors(request, errors); + if (mode.isAuthor()) { + return mapping.findForward("author"); + } else { + return mapping.findForward("monitor"); + } + } + + CommonCartridge commonCartridge = commonCartridgeForm.getCommonCartridge(); + ICommonCartridgeService service = getCommonCartridgeService(); + + // **********************************Get CommonCartridge PO********************* + CommonCartridge commonCartridgePO = service.getCommonCartridgeByContentId(commonCartridgeForm + .getCommonCartridge().getContentId()); + if (commonCartridgePO == null) { + // new CommonCartridge, create it. + commonCartridgePO = commonCartridge; + commonCartridgePO.setCreated(new Timestamp(new Date().getTime())); + commonCartridgePO.setUpdated(new Timestamp(new Date().getTime())); + } else { + if (mode.isAuthor()) { + Long uid = commonCartridgePO.getUid(); + PropertyUtils.copyProperties(commonCartridgePO, commonCartridge); + // get back UID + commonCartridgePO.setUid(uid); + } else { // if it is Teacher, then just update basic tab content (definelater) + commonCartridgePO.setInstructions(commonCartridge.getInstructions()); + commonCartridgePO.setTitle(commonCartridge.getTitle()); + // change define later status + commonCartridgePO.setDefineLater(false); + } + commonCartridgePO.setUpdated(new Timestamp(new Date().getTime())); + } + + // *******************************Handle user******************* + // try to get form system session + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + CommonCartridgeUser commonCartridgeUser = service.getUserByIDAndContent(new Long(user.getUserID().intValue()), + commonCartridgeForm.getCommonCartridge().getContentId()); + if (commonCartridgeUser == null) { + commonCartridgeUser = new CommonCartridgeUser(user, commonCartridgePO); + } + + commonCartridgePO.setCreatedBy(commonCartridgeUser); + + // **********************************Handle Authoring Instruction Attachement ********************* + // merge attachment info + // so far, attPOSet will be empty if content is existed. because PropertyUtils.copyProperties() is executed + Set attPOSet = commonCartridgePO.getAttachments(); + if (attPOSet == null) { + attPOSet = new HashSet(); + } + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + + // current attachemnt in authoring instruction tab. + Iterator iter = attachmentList.iterator(); + while (iter.hasNext()) { + CommonCartridgeAttachment newAtt = (CommonCartridgeAttachment) iter.next(); + attPOSet.add(newAtt); + } + attachmentList.clear(); + + // deleted attachment. 2 possible types: one is persist another is non-persist before. + iter = deleteAttachmentList.iterator(); + while (iter.hasNext()) { + CommonCartridgeAttachment delAtt = (CommonCartridgeAttachment) iter.next(); + iter.remove(); + // it is an existed att, then delete it from current attachmentPO + if (delAtt.getUid() != null) { + Iterator attIter = attPOSet.iterator(); + while (attIter.hasNext()) { + CommonCartridgeAttachment att = (CommonCartridgeAttachment) attIter.next(); + if (delAtt.getUid().equals(att.getUid())) { + attIter.remove(); + break; + } + } + service.deleteCommonCartridgeAttachment(delAtt.getUid()); + }// end remove from persist value + } + + // copy back + commonCartridgePO.setAttachments(attPOSet); + + // ************************* Handle commonCartridge items ******************* + + Set itemList = new LinkedHashSet(); + SortedSet topics = getCommonCartridgeItemList(sessionMap); + iter = topics.iterator(); + while (iter.hasNext()) { + CommonCartridgeItem item = (CommonCartridgeItem) iter.next(); + if (item != null) { + // This flushs user UID info to message if this user is a new user. + item.setCreateBy(commonCartridgeUser); + itemList.add(item); + } + } + commonCartridgePO.setCommonCartridgeItems(itemList); + // delete instructino file from database. + List delCommonCartridgeItemList = getDeletedCommonCartridgeItemList(sessionMap); + iter = delCommonCartridgeItemList.iterator(); + while (iter.hasNext()) { + CommonCartridgeItem item = (CommonCartridgeItem) iter.next(); + iter.remove(); + if (item.getUid() != null) { + service.deleteCommonCartridgeItem(item.getUid()); + } + } + // handle commonCartridge item attachment file: + List delItemAttList = getDeletedItemAttachmentList(sessionMap); + iter = delItemAttList.iterator(); + while (iter.hasNext()) { + CommonCartridgeItem delAtt = (CommonCartridgeItem) iter.next(); + iter.remove(); + } + + // if miniview number is bigger than available items, then set it topics size + if (commonCartridgePO.getMiniViewCommonCartridgeNumber() > topics.size()) { + commonCartridgePO.setMiniViewCommonCartridgeNumber(topics.size()); + } + // ********************************************** + // finally persist commonCartridgePO again + service.saveOrUpdateCommonCartridge(commonCartridgePO); + + // initialize attachmentList again + attachmentList = getAttachmentList(sessionMap); + attachmentList.addAll(commonCartridge.getAttachments()); + commonCartridgeForm.setCommonCartridge(commonCartridgePO); + + request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + if (mode.isAuthor()) { + return mapping.findForward("author"); + } else { + return mapping.findForward("monitor"); + } + } + + /** + * Handle upload online instruction files request. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws UploadCommonCartridgeFileException + */ + public ActionForward uploadOnline(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws UploadCommonCartridgeFileException { + return uploadFile(mapping, form, IToolContentHandler.TYPE_ONLINE, request); + } + + /** + * Handle upload offline instruction files request. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws UploadCommonCartridgeFileException + */ + public ActionForward uploadOffline(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws UploadCommonCartridgeFileException { + return uploadFile(mapping, form, IToolContentHandler.TYPE_OFFLINE, request); + } + + /** + * Common method to upload online or offline instruction files request. + * + * @param mapping + * @param form + * @param type + * @param request + * @return + * @throws UploadCommonCartridgeFileException + */ + private ActionForward uploadFile(ActionMapping mapping, ActionForm form, String type, HttpServletRequest request) + throws UploadCommonCartridgeFileException { + + CommonCartridgeForm commonCartridgeForm = (CommonCartridgeForm) form; + // get back sessionMAP + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(commonCartridgeForm.getSessionMapID()); + + FormFile file; + if (StringUtils.equals(IToolContentHandler.TYPE_OFFLINE, type)) { + file = commonCartridgeForm.getOfflineFile(); + } else { + file = commonCartridgeForm.getOnlineFile(); + } + + if (file == null || StringUtils.isBlank(file.getFileName())) { + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + // validate file size + ActionMessages errors = new ActionMessages(); + FileValidatorUtil.validateFileSize(file, true, errors); + if (!errors.isEmpty()) { + this.saveErrors(request, errors); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + ICommonCartridgeService service = getCommonCartridgeService(); + // upload to repository + CommonCartridgeAttachment att = service.uploadInstructionFile(file, type); + // handle session value + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + // first check exist attachment and delete old one (if exist) to deletedAttachmentList + Iterator iter = attachmentList.iterator(); + CommonCartridgeAttachment existAtt; + while (iter.hasNext()) { + existAtt = (CommonCartridgeAttachment) iter.next(); + if (StringUtils.equals(existAtt.getFileName(), att.getFileName()) + && StringUtils.equals(existAtt.getFileType(), att.getFileType())) { + // if there is same name attachment, delete old one + deleteAttachmentList.add(existAtt); + iter.remove(); + break; + } + } + // add to attachmentList + attachmentList.add(att); + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + + } + + /** + * Delete offline instruction file from current CommonCartridge authoring page. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + public ActionForward deleteOfflineFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return deleteFile(mapping, request, response, form, IToolContentHandler.TYPE_OFFLINE); + } + + /** + * Delete online instruction file from current CommonCartridge authoring page. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + public ActionForward deleteOnlineFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return deleteFile(mapping, request, response, form, IToolContentHandler.TYPE_ONLINE); + } + + /** + * General method to delete file (online or offline) + * + * @param mapping + * @param request + * @param response + * @param form + * @param type + * @return + */ + private ActionForward deleteFile(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response, + ActionForm form, String type) { + Long versionID = new Long(WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_FILE_VERSION_ID)); + Long uuID = new Long(WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_FILE_UUID)); + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + // handle session value + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + // first check exist attachment and delete old one (if exist) to deletedAttachmentList + Iterator iter = attachmentList.iterator(); + CommonCartridgeAttachment existAtt; + while (iter.hasNext()) { + existAtt = (CommonCartridgeAttachment) iter.next(); + if (existAtt.getFileUuid().equals(uuID) && existAtt.getFileVersionId().equals(versionID)) { + // if there is same name attachment, delete old one + deleteAttachmentList.add(existAtt); + iter.remove(); + } + } + + request.setAttribute(CommonCartridgeConstants.ATTR_FILE_TYPE_FLAG, type); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + + } + + // ************************************************************************************* + // Private method + // ************************************************************************************* + /** + * Return CommonCartridgeService bean. + */ + private ICommonCartridgeService getCommonCartridgeService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (ICommonCartridgeService) wac.getBean(CommonCartridgeConstants.RESOURCE_SERVICE); + } + + /** + * @param request + * @return + */ + private List getAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, CommonCartridgeConstants.ATT_ATTACHMENT_LIST); + } + + /** + * @param request + * @return + */ + private List getDeletedAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, CommonCartridgeConstants.ATTR_DELETED_ATTACHMENT_LIST); + } + + /** + * List save current commonCartridge items. + * + * @param request + * @return + */ + private SortedSet getCommonCartridgeItemList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST); + if (list == null) { + list = new TreeSet(new CommonCartridgeItemComparator()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST, list); + } + return list; + } + + /** + * List save deleted commonCartridge items, which could be persisted or non-persisted items. + * + * @param request + * @return + */ + private List getDeletedCommonCartridgeItemList(SessionMap sessionMap) { + return getListFromSession(sessionMap, CommonCartridgeConstants.ATTR_DELETED_RESOURCE_ITEM_LIST); + } + + /** + * If a commonCartridge item has attahment file, and the user edit this item and change the attachment to new file, + * then the old file need be deleted when submitting the whole authoring page. Save the file uuid and version id + * into CommonCartridgeItem object for temporarily use. + * + * @param request + * @return + */ + private List getDeletedItemAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, CommonCartridgeConstants.ATTR_DELETED_RESOURCE_ITEM_ATTACHMENT_LIST); + } + + /** + * Get java.util.List from HttpSession by given name. + * + * @param request + * @param name + * @return + */ + private List getListFromSession(SessionMap sessionMap, String name) { + List list = (List) sessionMap.get(name); + if (list == null) { + list = new ArrayList(); + sessionMap.put(name, list); + } + return list; + } + + /** + * Get back relative ActionForward from request. + * + * @param type + * @param mapping + * @return + */ + private ActionForward findForward(short type, ActionMapping mapping) { + ActionForward forward; + switch (type) { + case CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI: + forward = mapping.findForward("basiclti"); + break; + case CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE: + forward = mapping.findForward("commoncartridge"); + break; + default: + forward = null; + break; + } + return forward; + } + + /** + * This method will populate commonCartridge item information to its form for edit use. + * + * @param itemIdx + * @param item + * @param form + * @param request + */ + private void populateItemToForm(int itemIdx, CommonCartridgeItem item, CommonCartridgeItemForm form, + HttpServletRequest request) { + form.setDescription(item.getDescription()); + form.setTitle(item.getTitle()); + if (itemIdx >= 0) { + form.setItemIndex(new Integer(itemIdx).toString()); + } + + if (StringUtils.isBlank(item.getLaunchUrl()) && StringUtils.isNotBlank(item.getSecureLaunchUrl())) { + form.setUrl(item.getSecureLaunchUrl()); + } else { + form.setUrl(item.getLaunchUrl()); + } + form.setKey(item.getKey()); + form.setSecret(item.getSecret()); + form.setCustomStr(item.getCustomStr()); + form.setButtonText(item.getButtonText()); + form.setOpenUrlNewWindow(item.isOpenUrlNewWindow()); + form.setFrameHeight(item.getFrameHeight()); + + // FOR requirment from LDEV-754 + // add extra blank line for instructions + // for(int idx=0;idx items = null; + if (itemForm.getFile() != null) { + try { + CommonCartridgeItem itemTemp = new CommonCartridgeItem(); + ICommonCartridgeService service = getCommonCartridgeService(); + items = service.uploadCommonCartridgeFile(itemTemp, itemForm.getFile()); + } catch (UploadCommonCartridgeFileException e) { + throw e; + } + } + + for (CommonCartridgeItem item : items) { + item.setCreateDate(new Timestamp(new Date().getTime())); + item.setType(CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI); + item.setCreateByAuthor(true); + item.setHide(false); + //item.setDescription(itemForm.getDescription()); + } + + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(itemForm.getSessionMapID()); + SortedSet commonCartridgeList = getCommonCartridgeItemList(sessionMap); + commonCartridgeList.addAll(items); + } + + /** + * Extract web from content to commonCartridge item. + * + * @param request + * @param itemForm + * @throws CommonCartridgeApplicationException + */ + private void extractFormToCommonCartridgeItem(HttpServletRequest request, CommonCartridgeItemForm itemForm) + throws Exception { + /* + * BE CAREFUL: This method will copy nessary info from request form to a old or new CommonCartridgeItem + * instance. It gets all info EXCEPT CommonCartridgeItem.createDate and CommonCartridgeItem.createBy, which need + * be set when persisting this commonCartridge item. + */ + + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(itemForm.getSessionMapID()); + // check whether it is "edit(old item)" or "add(new item)" + SortedSet commonCartridgeList = getCommonCartridgeItemList(sessionMap); + int itemIdx = NumberUtils.stringToInt(itemForm.getItemIndex(), -1); + CommonCartridgeItem item = null; + + if (itemIdx == -1) { // add + item = new CommonCartridgeItem(); + item.setCreateDate(new Timestamp(new Date().getTime())); + commonCartridgeList.add(item); + } else { // edit + List rList = new ArrayList(commonCartridgeList); + item = rList.get(itemIdx); + } + short type = itemForm.getItemType(); + item.setType(itemForm.getItemType()); + + item.setTitle(itemForm.getTitle()); + item.setCreateByAuthor(true); + item.setHide(false); + + if (type == CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI) { + + if (StringUtils.isBlank(item.getLaunchUrl()) && StringUtils.isNotBlank(item.getSecureLaunchUrl())) { + item.setSecureLaunchUrl(itemForm.getUrl()); + } else { + item.setLaunchUrl(itemForm.getUrl()); + } + + item.setKey(itemForm.getKey()); + item.setSecret(itemForm.getSecret()); + item.setButtonText(itemForm.getButtonText()); + item.setOpenUrlNewWindow(itemForm.isOpenUrlNewWindow()); + item.setFrameHeight(itemForm.getFrameHeight()); + item.setCustomStr(itemForm.getCustomStr()); + } + // if(type == CommonCartridgeConstants.RESOURCE_TYPE_WEBSITE + // ||itemForm.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_LEARNING_OBJECT){ + item.setDescription(itemForm.getDescription()); + // } + + } + + /** + * Vaidate commonCartridge item regards to their type (url/file/learning object/website zip file) + * + * @param itemForm + * @return + */ + private ActionErrors validateCommonCartridgeItem(CommonCartridgeItemForm itemForm) { + ActionErrors errors = new ActionErrors(); + if (StringUtils.isBlank(itemForm.getTitle())) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(CommonCartridgeConstants.ERROR_MSG_TITLE_BLANK)); + } + + if (itemForm.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI) { + if (StringUtils.isBlank(itemForm.getUrl())) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + CommonCartridgeConstants.ERROR_MSG_URL_BLANK)); + // URL validation: Commom URL validate(1.3.0) work not very well: it can not support http:// + // address:port format!!! + // UrlValidator validator = new UrlValidator(); + // if(!validator.isValid(itemForm.getUrl())) + // errors.add(ActionMessages.GLOBAL_MESSAGE,new + // ActionMessage(CommonCartridgeConstants.ERROR_MSG_INVALID_URL)); + } + } + // if(itemForm.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_WEBSITE + // ||itemForm.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_LEARNING_OBJECT){ + // if(StringUtils.isBlank(itemForm.getDescription())) + // errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(CommonCartridgeConstants.ERROR_MSG_DESC_BLANK)); + // } + if (itemForm.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE) { + // validate item size + FileValidatorUtil.validateFileSize(itemForm.getFile(), true, errors); + // for edit validate: file already exist + if (!itemForm.isHasFile() + && (itemForm.getFile() == null || StringUtils.isEmpty(itemForm.getFile().getFileName()))) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + CommonCartridgeConstants.ERROR_MSG_FILE_BLANK)); + } + } + return errors; + } + + /** + * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. + * + * @param request + * @return + */ + private ToolAccessMode getAccessMode(HttpServletRequest request) { + ToolAccessMode mode; + String modeStr = request.getParameter(AttributeNames.ATTR_MODE); + if (StringUtils.equalsIgnoreCase(modeStr, ToolAccessMode.TEACHER.toString())) { + mode = ToolAccessMode.TEACHER; + } else { + mode = ToolAccessMode.AUTHOR; + } + return mode; + } + + private ActionMessages validate(CommonCartridgeForm commonCartridgeForm, ActionMapping mapping, + HttpServletRequest request) { + ActionMessages errors = new ActionMessages(); + // if (StringUtils.isBlank(commonCartridgeForm.getCommonCartridge().getTitle())) { + // ActionMessage error = new ActionMessage("error.resource.item.title.blank"); + // errors.add(ActionMessages.GLOBAL_MESSAGE, error); + // } + + // define it later mode(TEACHER) skip below validation. + String modeStr = request.getParameter(AttributeNames.ATTR_MODE); + if (StringUtils.equals(modeStr, ToolAccessMode.TEACHER.toString())) { + return errors; + } + + // Some other validation outside basic Tab. + + return errors; + } + + public ActionForward initPedagogicalPlannerForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + CommonCartridgePedagogicalPlannerForm plannerForm = (CommonCartridgePedagogicalPlannerForm) form; + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + CommonCartridge taskList = getCommonCartridgeService().getCommonCartridgeByContentId(toolContentID); + String command = WebUtil.readStrParam(request, AttributeNames.PARAM_COMMAND, true); + if (command == null) { + plannerForm.fillForm(taskList); + String contentFolderId = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + plannerForm.setContentFolderID(contentFolderId); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } else { + try { + String onlineInstructions = taskList.getOnlineInstructions(); + response.setContentType("text/html;charset=utf-8"); + PrintWriter writer = response.getWriter(); + + if (AttributeNames.COMMAND_CHECK_EDITING_ADVICE.equals(command)) { + Integer activityIndex = WebUtil.readIntParam(request, AttributeNames.PARAM_ACTIVITY_INDEX); + String responseText = (StringUtils.isEmpty(taskList.getOnlineInstructions()) ? "NO" : "OK") + '&' + + activityIndex; + writer.print(responseText); + + } else if (AttributeNames.COMMAND_GET_EDITING_ADVICE.equals(command)) { + writer.print(onlineInstructions); + } + } catch (IOException e) { + AuthoringAction.log.error(e); + } + return null; + } + + } + + public ActionForward saveOrUpdatePedagogicalPlannerForm(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) throws IOException { + CommonCartridgePedagogicalPlannerForm plannerForm = (CommonCartridgePedagogicalPlannerForm) form; + ActionMessages errors = plannerForm.validate(); + if (errors.isEmpty()) { + CommonCartridge taskList = getCommonCartridgeService().getCommonCartridgeByContentId( + plannerForm.getToolContentID()); + taskList.setInstructions(plannerForm.getInstructions()); + + int itemIndex = 0; + String title = null; + CommonCartridgeItem commonCartridgeItem = null; + List newItems = new LinkedList(); + Set commonCartridgeItems = taskList.getCommonCartridgeItems(); + Iterator taskListItemIterator = commonCartridgeItems.iterator(); + // We need to reverse the order, since the items are delivered newest-first + LinkedList reversedCommonCartridgeItems = new LinkedList(); + while (taskListItemIterator.hasNext()) { + reversedCommonCartridgeItems.addFirst(taskListItemIterator.next()); + } + taskListItemIterator = reversedCommonCartridgeItems.iterator(); + do { + title = plannerForm.getTitle(itemIndex); + if (StringUtils.isEmpty(title)) { + plannerForm.removeItem(itemIndex); + } else { + if (taskListItemIterator.hasNext()) { + commonCartridgeItem = taskListItemIterator.next(); + } else { + commonCartridgeItem = new CommonCartridgeItem(); + commonCartridgeItem.setCreateByAuthor(true); + Date currentDate = new Date(); + commonCartridgeItem.setCreateDate(currentDate); + + HttpSession session = SessionManager.getSession(); + UserDTO user = (UserDTO) session.getAttribute(AttributeNames.USER); + CommonCartridgeUser taskListUser = getCommonCartridgeService().getUserByIDAndContent( + new Long(user.getUserID().intValue()), plannerForm.getToolContentID()); + commonCartridgeItem.setCreateBy(taskListUser); + + newItems.add(commonCartridgeItem); + } + commonCartridgeItem.setTitle(title); + Short type = plannerForm.getType(itemIndex); + commonCartridgeItem.setType(type); + boolean hasFile = commonCartridgeItem.getFileUuid() != null; + if (type.equals(CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI)) { + commonCartridgeItem.setUrl(plannerForm.getUrl(itemIndex)); + if (hasFile) { + commonCartridgeItem.setFileName(null); + commonCartridgeItem.setFileUuid(null); + commonCartridgeItem.setFileVersionId(null); + commonCartridgeItem.setFileType(null); + } + } else if (type.equals(CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE)) { + FormFile file = plannerForm.getFile(itemIndex); + commonCartridgeItem.setUrl(null); + ICommonCartridgeService service = getCommonCartridgeService(); + if (file != null) { + try { + if (hasFile) { + // delete the old file + service.deleteFromRepository(commonCartridgeItem.getFileUuid(), + commonCartridgeItem.getFileVersionId()); + } + service.uploadCommonCartridgeFile(commonCartridgeItem, file); + } catch (Exception e) { + AuthoringAction.log.error(e); + ActionMessage error = new ActionMessage("error.msg.io.exception"); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + saveErrors(request, errors); + plannerForm.setValid(false); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + } + plannerForm.setFileName(itemIndex, commonCartridgeItem.getFileName()); + plannerForm.setFileUuid(itemIndex, commonCartridgeItem.getFileUuid()); + plannerForm.setFileVersion(itemIndex, commonCartridgeItem.getFileVersionId()); + plannerForm.setFile(itemIndex, null); + } + itemIndex++; + } + + } while (title != null); + // we need to clear it now, otherwise we get Hibernate error (item re-saved by cascade) + taskList.getCommonCartridgeItems().clear(); + while (taskListItemIterator.hasNext()) { + commonCartridgeItem = taskListItemIterator.next(); + taskListItemIterator.remove(); + getCommonCartridgeService().deleteCommonCartridgeItem(commonCartridgeItem.getUid()); + } + reversedCommonCartridgeItems.addAll(newItems); + + taskList.getCommonCartridgeItems().addAll(reversedCommonCartridgeItems); + getCommonCartridgeService().saveOrUpdateCommonCartridge(taskList); + } else { + saveErrors(request, errors); + } + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + public ActionForward createPedagogicalPlannerItem(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + CommonCartridgePedagogicalPlannerForm plannerForm = (CommonCartridgePedagogicalPlannerForm) form; + int insertIndex = plannerForm.getItemCount(); + plannerForm.setTitle(insertIndex, ""); + plannerForm.setType(insertIndex, + new Short(request.getParameter(CommonCartridgeConstants.ATTR_ADD_RESOURCE_TYPE))); + plannerForm.setUrl(insertIndex, null); + plannerForm.setFileName(insertIndex, null); + plannerForm.setFile(insertIndex, null); + plannerForm.setFileUuid(insertIndex, null); + plannerForm.setFileVersion(insertIndex, null); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ClearSessionAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ClearSessionAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ClearSessionAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,46 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import javax.servlet.http.HttpSession; + +import org.lamsfoundation.lams.authoring.web.LamsAuthoringFinishAction; +import org.lamsfoundation.lams.tool.ToolAccessMode; + +/** + * This class give a chance to clear HttpSession when user save/close authoring page. + * @author Andrey Balan + */ +public class ClearSessionAction extends LamsAuthoringFinishAction { + + @Override + public void clearSession(String customiseSessionID, HttpSession session, ToolAccessMode mode) { + if(mode.isAuthor()){ + session.removeAttribute(customiseSessionID); + } + } + + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/LearningAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/LearningAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/LearningAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,487 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionMessage; +import org.apache.struts.action.ActionMessages; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeApplicationException; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeItemComparator; +import org.lamsfoundation.lams.tool.commonCartridge.web.form.ReflectionForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.MessageService; +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.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * + * @author Andrey Balan + */ +public class LearningAction extends Action { + + private static Logger log = Logger.getLogger(LearningAction.class); + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + String param = mapping.getParameter(); + // -----------------------CommonCartridge Learner function --------------------------- + if (param.equals("start")) { + return start(mapping, form, request, response); + } + if (param.equals("finish")) { + return finish(mapping, form, request, response); + } + + // ================ Reflection ======================= + if (param.equals("newReflection")) { + return newReflection(mapping, form, request, response); + } + if (param.equals("submitReflection")) { + return submitReflection(mapping, form, request, response); + } + + return mapping.findForward(CommonCartridgeConstants.ERROR); + } + + /** + * Read commonCartridge data from database and put them into HttpSession. It will redirect to init.do directly after this + * method run successfully. + * + * This method will avoid read database again and lost un-saved resouce item lost when user "refresh page", + * + */ + private ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // initial Session Map + SessionMap sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + + // save toolContentID into HTTPSession + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, true); + + Long sessionId = new Long(request.getParameter(CommonCartridgeConstants.PARAM_TOOL_SESSION_ID)); + + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + request.setAttribute(AttributeNames.ATTR_MODE, mode); + request.setAttribute(AttributeNames.PARAM_TOOL_SESSION_ID, sessionId); + + // get back the commonCartridge and item list and display them on page + ICommonCartridgeService service = getCommonCartridgeService(); + CommonCartridgeUser commonCartridgeUser = null; + if (mode != null && mode.isTeacher()) { + // monitoring mode - user is specified in URL + // commonCartridgeUser may be null if the user was force completed. + commonCartridgeUser = getSpecifiedUser(service, sessionId, WebUtil.readIntParam(request, + AttributeNames.PARAM_USER_ID, false)); + } else { + commonCartridgeUser = getCurrentUser(service, sessionId); + } + + List items = null; + CommonCartridge commonCartridge; + items = service.getCommonCartridgeItemsBySessionId(sessionId); + commonCartridge = service.getCommonCartridgeBySessionId(sessionId); + + // check whehter finish lock is on/off + boolean lock = commonCartridge.getLockWhenFinished() && commonCartridgeUser != null && commonCartridgeUser.isSessionFinished(); + + // check whether there is only one commonCartridge item and run auto flag is true or not. + boolean runAuto = false; + int itemsNumber = 0; + if (commonCartridge.getCommonCartridgeItems() != null) { + itemsNumber = commonCartridge.getCommonCartridgeItems().size(); + if (commonCartridge.isRunAuto() && itemsNumber == 1) { + CommonCartridgeItem item = (CommonCartridgeItem) commonCartridge.getCommonCartridgeItems().iterator().next(); + // only visible item can be run auto. + if (!item.isHide()) { + runAuto = true; + request.setAttribute(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_UID, item.getUid()); + } + } + } + + // get notebook entry + String entryText = new String(); + if (commonCartridgeUser != null) { + NotebookEntry notebookEntry = service.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, commonCartridgeUser.getUserId().intValue()); + if (notebookEntry != null) { + entryText = notebookEntry.getEntry(); + } + } + + // basic information + sessionMap.put(CommonCartridgeConstants.ATTR_TITLE, commonCartridge.getTitle()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_INSTRUCTION, commonCartridge.getInstructions()); + sessionMap.put(CommonCartridgeConstants.ATTR_FINISH_LOCK, lock); + sessionMap.put(CommonCartridgeConstants.ATTR_LOCK_ON_FINISH, commonCartridge.getLockWhenFinished()); + sessionMap.put(CommonCartridgeConstants.ATTR_USER_FINISHED, commonCartridgeUser != null && commonCartridgeUser.isSessionFinished()); + + sessionMap.put(AttributeNames.PARAM_TOOL_SESSION_ID, sessionId); + sessionMap.put(AttributeNames.ATTR_MODE, mode); + // reflection information + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECTION_ON, commonCartridge.isReflectOnActivity()); + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECTION_INSTRUCTION, commonCartridge.getReflectInstructions()); + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECTION_ENTRY, entryText); + sessionMap.put(CommonCartridgeConstants.ATTR_RUN_AUTO, new Boolean(runAuto)); + + // add define later support + if (commonCartridge.isDefineLater()) { + return mapping.findForward("defineLater"); + } + + // set contentInUse flag to true! + commonCartridge.setContentInUse(true); + commonCartridge.setDefineLater(false); + service.saveOrUpdateCommonCartridge(commonCartridge); + + // add run offline support + if (commonCartridge.getRunOffline()) { + sessionMap.put(CommonCartridgeConstants.PARAM_RUN_OFFLINE, true); + return mapping.findForward("runOffline"); + } else { + sessionMap.put(CommonCartridgeConstants.PARAM_RUN_OFFLINE, false); + } + + // init commonCartridge item list + SortedSet commonCartridgeItemList = getCommonCartridgeItemList(sessionMap); + commonCartridgeItemList.clear(); + if (items != null) { + // remove hidden items. + for (CommonCartridgeItem item : items) { + // becuase in webpage will use this login name. Here is just + // initial it to avoid session close error in proxy object. + if (item.getCreateBy() != null) { + item.getCreateBy().getLoginName(); + } + if (!item.isHide()) { + commonCartridgeItemList.add(item); + } + } + } + + // set complete flag for display purpose + if (commonCartridgeUser != null) { + service.retrieveComplete(commonCartridgeItemList, commonCartridgeUser); + } + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE, commonCartridge); + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Finish learning session. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward finish(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back SessionMap + String sessionMapID = request.getParameter(CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + // get mode and ToolSessionID from sessionMAP + ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + + // auto run mode, when use finish the only one commonCartridge item, mark it as complete then finish this activity as + // well. + String commonCartridgeItemUid = request.getParameter(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID); + if (commonCartridgeItemUid != null) { + doComplete(request); + // NOTE:So far this flag is useless(31/08/2006). + // set flag, then finish page can know redir target is parent(AUTO_RUN) or self(normal) + request.setAttribute(CommonCartridgeConstants.ATTR_RUN_AUTO, true); + } else { + request.setAttribute(CommonCartridgeConstants.ATTR_RUN_AUTO, false); + } + + if (!validateBeforeFinish(request, sessionMapID)) { + return mapping.getInputForward(); + } + + ICommonCartridgeService service = getCommonCartridgeService(); + // get sessionId from HttpServletRequest + String nextActivityUrl = null; + try { + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + + nextActivityUrl = service.finishToolSession(sessionId, userID); + request.setAttribute(CommonCartridgeConstants.ATTR_NEXT_ACTIVITY_URL, nextActivityUrl); + } catch (CommonCartridgeApplicationException e) { + LearningAction.log.error("Failed get next activity url:" + e.getMessage()); + } + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Display empty reflection form. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward newReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get session value + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + if (!validateBeforeFinish(request, sessionMapID)) { + return mapping.getInputForward(); + } + + ReflectionForm refForm = (ReflectionForm) form; + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + + refForm.setUserID(user.getUserID()); + refForm.setSessionMapID(sessionMapID); + + // get the existing reflection entry + ICommonCartridgeService submitFilesService = getCommonCartridgeService(); + + SessionMap map = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long toolSessionID = (Long) map.get(AttributeNames.PARAM_TOOL_SESSION_ID); + NotebookEntry entry = submitFilesService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, user.getUserID()); + + if (entry != null) { + refForm.setEntryText(entry.getEntry()); + } + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Submit reflection form input database. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + ReflectionForm refForm = (ReflectionForm) form; + Integer userId = refForm.getUserID(); + + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + + ICommonCartridgeService service = getCommonCartridgeService(); + + // check for existing notebook entry + NotebookEntry entry = service.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, userId); + + if (entry == null) { + // create new entry + service.createNotebookEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, userId, refForm.getEntryText()); + } else { + // update existing entry + entry.setEntry(refForm.getEntryText()); + entry.setLastModified(new Date()); + service.updateEntry(entry); + } + + return finish(mapping, form, request, response); + } + + // ************************************************************************************* + // Private method + // ************************************************************************************* + private boolean validateBeforeFinish(HttpServletRequest request, String sessionMapID) { + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + + ICommonCartridgeService service = getCommonCartridgeService(); + int miniViewFlag = service.checkMiniView(sessionId, userID); + // if current user view less than reqired view count number, then just return error message. + // if it is runOffline content, then need not check minimum view count + Boolean runOffline = (Boolean) sessionMap.get(CommonCartridgeConstants.PARAM_RUN_OFFLINE); + if (miniViewFlag > 0 && !runOffline) { + ActionErrors errors = new ActionErrors(); + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("lable.learning.minimum.view.number.less", + miniViewFlag)); + this.addErrors(request, errors); + return false; + } + + return true; + } + + private ICommonCartridgeService getCommonCartridgeService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (ICommonCartridgeService) wac.getBean(CommonCartridgeConstants.RESOURCE_SERVICE); + } + + /** + * List save current commonCartridge items. + * + * @param request + * @return + */ + private SortedSet getCommonCartridgeItemList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST); + if (list == null) { + list = new TreeSet(new CommonCartridgeItemComparator()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST, list); + } + return list; + } + + /** + * Get java.util.List from HttpSession by given name. + * + * @param request + * @param name + * @return + */ + private List getListFromSession(SessionMap sessionMap, String name) { + List list = (List) sessionMap.get(name); + if (list == null) { + list = new ArrayList(); + sessionMap.put(name, list); + } + return list; + } + + private CommonCartridgeUser getCurrentUser(ICommonCartridgeService service, Long sessionId) { + // try to get form system session + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + CommonCartridgeUser commonCartridgeUser = service.getUserByIDAndSession(new Long(user.getUserID().intValue()), sessionId); + + if (commonCartridgeUser == null) { + CommonCartridgeSession session = service.getCommonCartridgeSessionBySessionId(sessionId); + commonCartridgeUser = new CommonCartridgeUser(user, session); + service.createUser(commonCartridgeUser); + } + return commonCartridgeUser; + } + + private CommonCartridgeUser getSpecifiedUser(ICommonCartridgeService service, Long sessionId, Integer userId) { + CommonCartridgeUser commonCartridgeUser = service.getUserByIDAndSession(new Long(userId.intValue()), sessionId); + if (commonCartridgeUser == null) { + LearningAction.log + .error("Unable to find specified user for commonCartridge activity. Screens are likely to fail. SessionId=" + + sessionId + " UserId=" + userId); + } + return commonCartridgeUser; + } + + /** + * Set complete flag for given commonCartridge item. + * + * @param request + * @param sessionId + */ + private void doComplete(HttpServletRequest request) { + // get back sessionMap + String sessionMapID = request.getParameter(CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + Long commonCartridgeItemUid = new Long(request.getParameter(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID)); + ICommonCartridgeService service = getCommonCartridgeService(); + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + + Long sessionId = (Long) sessionMap.get(CommonCartridgeConstants.ATTR_TOOL_SESSION_ID); + service.setItemComplete(commonCartridgeItemUid, new Long(user.getUserID().intValue()), sessionId); + + // set commonCartridge item complete tag + SortedSet commonCartridgeItemList = getCommonCartridgeItemList(sessionMap); + for (CommonCartridgeItem item : commonCartridgeItemList) { + if (item.getUid().equals(commonCartridgeItemUid)) { + item.setComplete(true); + break; + } + } + } + + /** + * Return ResourceService bean. + */ + private MessageService getMessageService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (MessageService) wac.getBean("basicLTIMessageService"); + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/MonitoringAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/MonitoringAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/MonitoringAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,217 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.dto.ReflectDTO; +import org.lamsfoundation.lams.tool.commonCartridge.dto.Summary; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +public class MonitoringAction extends Action { + public static Logger log = Logger.getLogger(MonitoringAction.class); + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + String param = mapping.getParameter(); + + request.setAttribute("initialTabId", WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); + + if (param.equals("summary")) { + return summary(mapping, form, request, response); + } + + if (param.equals("listuser")) { + return listuser(mapping, form, request, response); + } + if (param.equals("showitem")) { + return showitem(mapping, form, request, response); + } + if (param.equals("hideitem")) { + return hideitem(mapping, form, request, response); + } + if (param.equals("viewReflection")) { + return viewReflection(mapping, form, request, response); + } + + return mapping.findForward(CommonCartridgeConstants.ERROR); + } + + private ActionForward hideitem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + Long itemUid = WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID); + ICommonCartridgeService service = getCommonCartridgeService(); + service.setItemVisible(itemUid, false); + + // get back SessionMap + String sessionMapID = request.getParameter(CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + + // update session value + List groupList = (List) sessionMap.get(CommonCartridgeConstants.ATTR_SUMMARY_LIST); + if (groupList != null) { + for (List group : groupList) { + for (Summary sum : group) { + if (itemUid.equals(sum.getItemUid())) { + sum.setItemHide(true); + break; + } + } + } + } + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + private ActionForward showitem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + Long itemUid = WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID); + ICommonCartridgeService service = getCommonCartridgeService(); + service.setItemVisible(itemUid, true); + + // get back SessionMap + String sessionMapID = request.getParameter(CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + + // update session value + List groupList = (List) sessionMap.get(CommonCartridgeConstants.ATTR_SUMMARY_LIST); + if (groupList != null) { + for (List group : groupList) { + for (Summary sum : group) { + if (itemUid.equals(sum.getItemUid())) { + sum.setItemHide(false); + break; + } + } + } + } + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + private ActionForward summary(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + // initial Session Map + SessionMap sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + // save contentFolderID into session + sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, + WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID)); + + Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + ICommonCartridgeService service = getCommonCartridgeService(); + List> groupList = service.getSummary(contentId); + + CommonCartridge commonCartridge = service.getCommonCartridgeByContentId(contentId); + commonCartridge.toDTO(); + + Map> relectList = service.getReflectList(contentId, false); + + // cache into sessionMap + sessionMap.put(CommonCartridgeConstants.ATTR_SUMMARY_LIST, groupList); + sessionMap.put(CommonCartridgeConstants.PAGE_EDITABLE, commonCartridge.isContentInUse()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE, commonCartridge); + sessionMap.put(CommonCartridgeConstants.ATTR_TOOL_CONTENT_ID, contentId); + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECT_LIST, relectList); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + private ActionForward listuser(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + Long itemUid = WebUtil.readLongParam(request, CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID); + + // get user list by given item uid + ICommonCartridgeService service = getCommonCartridgeService(); + List list = service.getUserListBySessionItem(sessionId, itemUid); + + // set to request + request.setAttribute(CommonCartridgeConstants.ATTR_USER_LIST, list); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + private ActionForward viewReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + Long uid = WebUtil.readLongParam(request, CommonCartridgeConstants.ATTR_USER_UID); + Long sessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + + ICommonCartridgeService service = getCommonCartridgeService(); + CommonCartridgeUser user = service.getUser(uid); + NotebookEntry notebookEntry = service.getEntry(sessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + CommonCartridgeConstants.TOOL_SIGNATURE, user.getUserId().intValue()); + + CommonCartridgeSession session = service.getCommonCartridgeSessionBySessionId(sessionID); + + ReflectDTO refDTO = new ReflectDTO(user); + if (notebookEntry == null) { + refDTO.setFinishReflection(false); + refDTO.setReflect(null); + } else { + refDTO.setFinishReflection(true); + refDTO.setReflect(notebookEntry.getEntry()); + } + refDTO.setReflectInstrctions(session.getCommonCartridge().getReflectInstructions()); + + request.setAttribute("userDTO", refDTO); + return mapping.findForward("success"); + } + + // ************************************************************************************* + // Private method + // ************************************************************************************* + private ICommonCartridgeService getCommonCartridgeService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (ICommonCartridgeService) wac.getBean(CommonCartridgeConstants.RESOURCE_SERVICE); + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ViewItemAction.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ViewItemAction.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/action/ViewItemAction.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,341 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.action; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Pattern; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.math.NumberUtils; +import org.apache.log4j.Logger; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeItemComparator; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeWebUtils; +import org.lamsfoundation.lams.tool.commonCartridge.util.LamsBasicLTIUtil; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.MessageService; +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.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +public class ViewItemAction extends Action { + + private static final Logger log = Logger.getLogger(ViewItemAction.class); + + private static ICommonCartridgeService commonCartridgeService; + + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + String param = mapping.getParameter(); + // -----------------------Display Learning Object function --------------------------- + if (param.equals("reviewItem")) { + return reviewItem(mapping, form, request, response); + } + // for preview top frame html page use: + if (param.equals("nextInstruction")) { + return nextInstruction(mapping, form, request, response); + } + // for preview top frame html page use: + if (param.equals("openUrlPopup")) { + return openUrlPopup(mapping, form, request, response); + } + // for launchBasicLTI + if (param.equals("launchBasicLTI")) { + return launchBasicLTI(mapping, form, request, response); + } + + return mapping.findForward(CommonCartridgeConstants.ERROR); + } + + /** + * Open url in popup window page. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward openUrlPopup(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String mode = request.getParameter(AttributeNames.ATTR_MODE); + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + CommonCartridgeItem item = getCommonCartridgeItem(request, sessionMap, mode); + int itemIdx = NumberUtils.stringToInt(request.getParameter(CommonCartridgeConstants.PARAM_ITEM_INDEX)); + + String launchBasicLTIUrl; + if (CommonCartridgeConstants.MODE_AUTHOR_SESSION.equals(mode)) { + launchBasicLTIUrl = "/launchBasicLTI.do?" + AttributeNames.ATTR_MODE + "=" + mode + "&" + + CommonCartridgeConstants.PARAM_ITEM_INDEX + "=" + itemIdx + "&" + + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } else { + launchBasicLTIUrl = "/launchBasicLTI.do?" + CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID + "=" + item.getUid() + + "&" + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } + request.setAttribute(CommonCartridgeConstants.PARAM_OPEN_URL_POPUP, launchBasicLTIUrl); + request.setAttribute(CommonCartridgeConstants.PARAM_TITLE, item.getTitle()); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Return next instrucion to page. It need four input parameters, mode, itemIndex or itemUid, and insIdx. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward nextInstruction(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + } + + /** + * Display main frame to display instrcution and item content. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + */ + private ActionForward reviewItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException { + String mode = request.getParameter(AttributeNames.ATTR_MODE); + + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + CommonCartridgeItem item = getCommonCartridgeItem(request, sessionMap, mode); + + String idStr = request.getParameter(CommonCartridgeConstants.ATTR_TOOL_SESSION_ID); + Long sessionId = NumberUtils.createLong(idStr); + // mark this item access flag if it is learner + if (ToolAccessMode.LEARNER.toString().equals(mode)) { + ICommonCartridgeService service = getCommonCartridgeService(); + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + service.setItemAccess(item.getUid(), new Long(user.getUserID().intValue()), sessionId); + } + + if (item == null) { + return mapping.findForward(CommonCartridgeConstants.ERROR); + } + // set url to content frame + + int itemIdx = NumberUtils.stringToInt(request.getParameter(CommonCartridgeConstants.PARAM_ITEM_INDEX)); + + + short type = item.getType(); + String url = null; + switch (type) { + case CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI: + if (item.isOpenUrlNewWindow()) { + url = "/openUrlPopup.do?"; + } else { + url = "/launchBasicLTI.do?"; + } + if (CommonCartridgeConstants.MODE_AUTHOR_SESSION.equals(mode)) { + url += AttributeNames.ATTR_MODE + "=" + mode + "&" + CommonCartridgeConstants.PARAM_ITEM_INDEX + "=" + + itemIdx + "&" + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } else { + url += CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID + "=" + item.getUid() + "&" + + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } + + break; + case CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE: + url = "/download/?uuid=" + item.getFileUuid() + "&preferDownload=false"; + break; + } + request.setAttribute(CommonCartridgeConstants.ATTR_RESOURCE_REVIEW_URL, url); + + // these attribute will be use to instruction navigator page + request.setAttribute(AttributeNames.ATTR_MODE, mode); + request.setAttribute(CommonCartridgeConstants.PARAM_ITEM_INDEX, itemIdx); + Long itemUid = NumberUtils.createLong(request.getParameter(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID)); + request.setAttribute(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID, itemUid); + request.setAttribute(CommonCartridgeConstants.ATTR_TOOL_SESSION_ID, sessionId); + request.setAttribute(CommonCartridgeConstants.ATTR_SESSION_MAP_ID, sessionMapID); + + return mapping.findForward(CommonCartridgeConstants.SUCCESS); + + } + + // ************************************************************************************* + // Private method + // ************************************************************************************* + /** + * Submit reflection form input database. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws Exception + */ + private ActionForward launchBasicLTI(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException { + String mode = request.getParameter(AttributeNames.ATTR_MODE); + String sessionMapID = WebUtil.readStrParam(request, CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + CommonCartridgeItem item = getCommonCartridgeItem(request, sessionMap, mode); + + ICommonCartridgeService service = getCommonCartridgeService(); + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + MessageService messageService = (MessageService) wac.getBean("commonCartridgeMessageService"); + + // Get the post data for the placement + String returnValues = LamsBasicLTIUtil.postLaunchHTML(service, messageService, item); + + try { + response.setContentType("text/html; charset=UTF-8"); + response.setCharacterEncoding("utf-8"); + response.addDateHeader("Expires", System.currentTimeMillis() - (1000L * 60L * 60L * 24L * 365L)); + response.addDateHeader("Last-Modified", System.currentTimeMillis()); + response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0"); + response.addHeader("Pragma", "no-cache"); + ServletOutputStream out = response.getOutputStream(); + + out.println(""); + out.println(""); + out.println("\n"); + out.println(""); + out.println("\n"); + out.println(returnValues); + out.println("\n"); + + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + + return null; + } + + /** + * Return resoruce item according to ToolAccessMode. + * + * @param request + * @param sessionMap + * @param mode + * @return + */ + private CommonCartridgeItem getCommonCartridgeItem(HttpServletRequest request, SessionMap sessionMap, String mode) { + CommonCartridgeItem item = null; + if (CommonCartridgeConstants.MODE_AUTHOR_SESSION.equals(mode)) { + int itemIdx = NumberUtils.stringToInt(request.getParameter(CommonCartridgeConstants.PARAM_ITEM_INDEX), 0); + // authoring: does not save item yet, so only has ItemList from session and identity by Index + List commonCartridgeList = new ArrayList( + getCommonCartridgeItemList(sessionMap)); + item = commonCartridgeList.get(itemIdx); + } else { + Long itemUid = NumberUtils.createLong(request + .getParameter(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID)); + // get back the commonCartridge and item list and display them on page + ICommonCartridgeService service = getCommonCartridgeService(); + item = service.getCommonCartridgeItemByUid(itemUid); + } + return item; + } + + private ICommonCartridgeService getCommonCartridgeService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (ICommonCartridgeService) wac.getBean(CommonCartridgeConstants.RESOURCE_SERVICE); + } + + private static Pattern wikipediaPattern = Pattern.compile("wikipedia", Pattern.CASE_INSENSITIVE + | Pattern.UNICODE_CASE); + + private Object getReviewUrl(CommonCartridgeItem item, String sessionMapID, String mode, int itemIdx) { + short type = item.getType(); + String url = null; + switch (type) { + case CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI: + if (item.isOpenUrlNewWindow()) { + if (CommonCartridgeConstants.MODE_AUTHOR_SESSION.equals(mode)) { + url = "/openUrlPopup.do?" + AttributeNames.ATTR_MODE + "=" + mode + "&" + + CommonCartridgeConstants.PARAM_ITEM_INDEX + "=" + itemIdx + "&" + + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } else { + url = "/openUrlPopup.do?" + CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID + "=" + item.getUid() + + "&" + CommonCartridgeConstants.ATTR_SESSION_MAP_ID + "=" + sessionMapID; + } + } else + url = CommonCartridgeWebUtils.protocol(item.getUrl()); + break; + case CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE: + url = "/download/?uuid=" + item.getFileUuid() + "&preferDownload=false"; + break; + } + return url; + } + + /** + * List save current commonCartridge items. + * + * @param request + * @return + */ + private SortedSet getCommonCartridgeItemList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST); + if (list == null) { + list = new TreeSet(new CommonCartridgeItemComparator()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST, list); + } + return list; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/AdminForm.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/AdminForm.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/AdminForm.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,68 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.form; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionMessage; +import org.apache.struts.action.ActionMessages; + +/** + * @struts.form name="commonCartridgeAdminForm" + * + * @author Andrey Balan + */ +public class AdminForm extends ActionForm { + private static final long serialVersionUID = 414425664356226L; + + private boolean allowExposeUserName; + + private boolean allowExposeUserEmail; + + @Override + public ActionErrors validate(ActionMapping arg0, HttpServletRequest arg1) { + ActionErrors ac = new ActionErrors(); + ac.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("this is an error")); + return ac; + } + + public boolean isAllowExposeUserName() { + return allowExposeUserName; + } + + public void setAllowExposeUserName(boolean allowExposeUserName) { + this.allowExposeUserName = allowExposeUserName; + } + + public boolean isAllowExposeUserEmail() { + return allowExposeUserEmail; + } + + public void setAllowExposeUserEmail(boolean allowExposeUserEmail) { + this.allowExposeUserEmail = allowExposeUserEmail; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeForm.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeForm.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeForm.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,128 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.form; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; + +/** + * + * CommonCartridge Form. + * + * @struts.form name="commonCartridgeForm" + * + * User: Dapeng.Ni + */ +public class CommonCartridgeForm extends ActionForm { + private static final long serialVersionUID = 3599879328307492312L; + + private static Logger logger = Logger.getLogger(CommonCartridgeForm.class.getName()); + + // Forum fields + private String sessionMapID; + private String contentFolderID; + private int currentTab; + private FormFile offlineFile; + private FormFile onlineFile; + + private CommonCartridge commonCartridge; + + public CommonCartridgeForm() { + commonCartridge = new CommonCartridge(); + commonCartridge.setTitle("Common Cartridge"); + currentTab = 1; + } + + public void setCommonCartridge(CommonCartridge commonCartridge) { + this.commonCartridge = commonCartridge; + // set Form special varaible from given forum + if (commonCartridge == null) { + logger.error("Initial Common Cartridge failed by null value of CommonCartridge."); + } + } + + public void reset(ActionMapping mapping, HttpServletRequest request) { + String param = mapping.getParameter(); + // if it is start page, all data read out from database or current session + // so need not reset checkbox to refresh value! + if (!StringUtils.equals(param, "start") && !StringUtils.equals(param, "initPage")) { + commonCartridge.setLockWhenFinished(false); + commonCartridge.setDefineLater(false); + commonCartridge.setRunAuto(false); + commonCartridge.setRunOffline(false); + commonCartridge.setReflectOnActivity(false); + } + } + + public int getCurrentTab() { + return currentTab; + } + + public void setCurrentTab(int currentTab) { + this.currentTab = currentTab; + } + + public FormFile getOfflineFile() { + return offlineFile; + } + + public void setOfflineFile(FormFile offlineFile) { + this.offlineFile = offlineFile; + } + + public FormFile getOnlineFile() { + return onlineFile; + } + + public void setOnlineFile(FormFile onlineFile) { + this.onlineFile = onlineFile; + } + + public CommonCartridge getCommonCartridge() { + return commonCartridge; + } + + public String getSessionMapID() { + return sessionMapID; + } + + public void setSessionMapID(String sessionMapID) { + this.sessionMapID = sessionMapID; + } + + public String getContentFolderID() { + return contentFolderID; + } + + public void setContentFolderID(String contentFolderID) { + this.contentFolderID = contentFolderID; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeItemForm.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeItemForm.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgeItemForm.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,206 @@ +/**************************************************************** + * 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 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 + * **************************************************************** + */ +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.form; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.upload.FormFile; + +/** + * CommonCartridge Item Form. + * + * @struts.form name="commonCartridgeItemForm" + * @author Steve.Ni + */ +public class CommonCartridgeItemForm extends ActionForm { + private String itemIndex; + private String sessionMapID; + + // tool access mode; + private String mode; + + private String title; + private short itemType; + private String description; + private String url; + private boolean openUrlNewWindow; + // flag of this item has attachment or not + private boolean hasFile; + private Long fileUuid; + private Long fileVersionId; + private String fileName; + private FormFile file; + + private String launchUrl; + private String secureLaunchUrl; + private String key; + private String secret; + private String customStr; + private int frameHeight; + private String buttonText; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public FormFile getFile() { + return file; + } + + public void setFile(FormFile file) { + this.file = file; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getItemIndex() { + return itemIndex; + } + + public void setItemIndex(String itemIndex) { + this.itemIndex = itemIndex; + } + + public short getItemType() { + return itemType; + } + + public void setItemType(short type) { + this.itemType = type; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Long getFileUuid() { + return fileUuid; + } + + public void setFileUuid(Long fileUuid) { + this.fileUuid = fileUuid; + } + + public Long getFileVersionId() { + return fileVersionId; + } + + public void setFileVersionId(Long fileVersionId) { + this.fileVersionId = fileVersionId; + } + + public boolean isHasFile() { + return hasFile; + } + + public void setHasFile(boolean hasFile) { + this.hasFile = hasFile; + } + + public boolean isOpenUrlNewWindow() { + return openUrlNewWindow; + } + + public void setOpenUrlNewWindow(boolean openUrlNewWindow) { + this.openUrlNewWindow = openUrlNewWindow; + } + + public String getSessionMapID() { + return sessionMapID; + } + + public void setSessionMapID(String sessionMapID) { + this.sessionMapID = sessionMapID; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public String getCustomStr() { + return customStr; + } + + public void setCustomStr(String customStr) { + this.customStr = customStr; + } + + public String getButtonText() { + return buttonText; + } + + public void setButtonText(String buttonText) { + this.buttonText = buttonText; + } + + public int getFrameHeight() { + return frameHeight; + } + + public void setFrameHeight(int frameHeight) { + this.frameHeight = frameHeight; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgePedagogicalPlannerForm.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgePedagogicalPlannerForm.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/CommonCartridgePedagogicalPlannerForm.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,317 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.form; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.struts.action.ActionMessage; +import org.apache.struts.action.ActionMessages; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.util.FileValidatorUtil; +import org.lamsfoundation.lams.web.planner.PedagogicalPlannerActivityForm; + +/** + * @struts.form name="pedagogicalPlannerForm" + */ +public class CommonCartridgePedagogicalPlannerForm extends PedagogicalPlannerActivityForm { + private List title; + private List url; + private List file; + private List fileName; + private List fileUuid; + private List fileVersion; + private List type; + private String instructions; + private String contentFolderID; + + @Override + public ActionMessages validate() { + ActionMessages errors = new ActionMessages(); + boolean allEmpty = true; + if (title != null && !title.isEmpty()) { + for (int index = 0; index < title.size(); index++) { + if (!StringUtils.isEmpty(title.get(index))) { + // at least one item exists and it has non-blank title + allEmpty = false; + Short itemType = type.get(index); + // URL should not be blank + if (itemType.equals(CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI) + && StringUtils.isEmpty(url.get(index))) { + ActionMessage error = new ActionMessage("error.planner.url.blank", index + 1); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + + } else if (itemType.equals(CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE)) { + /* + * File should be saved already or it should be provided. This functionality required some + * changes in pedagogicalPlanner.js in lams_central (see prepareFormData() there) + */ + FileValidatorUtil.validateFileSize(file.get(index), true, errors); + if (fileUuid.get(index) == null && file.get(index) == null) { + ActionMessage error = new ActionMessage("error.planner.file.blank", index + 1); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + } + } + } + } + } + if (allEmpty) { + ActionMessage error = new ActionMessage("error.planner.no.resource.save"); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + title = null; + url = null; + fileName = null; + fileUuid = null; + fileVersion = null; + type = null; + } + + setValid(errors.isEmpty()); + return errors; + } + + public void fillForm(CommonCartridge commonCartridge) { + if (commonCartridge != null) { + setToolContentID(commonCartridge.getContentId()); + setInstructions(commonCartridge.getInstructions()); + + title = new ArrayList(); + url = new ArrayList(); + fileName = new ArrayList(); + file = new ArrayList(); + type = new ArrayList(); + Set items = commonCartridge.getCommonCartridgeItems(); + if (items != null) { + int topicIndex = 0; + for (CommonCartridgeItem item : items) { + short itemType = item.getType(); + setTitle(topicIndex, item.getTitle()); + setType(topicIndex, itemType); + setUrl(topicIndex, itemType == CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI ? item.getUrl() + : null); + setFileName(topicIndex, + itemType == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE ? item.getFileName() + : null); + setFileUuid(topicIndex, + itemType == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE ? item.getFileUuid() + : null); + setFileVersion( + topicIndex, + itemType == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE ? item + .getFileVersionId() : null); + topicIndex++; + } + } + } + } + + public void setTitle(int number, String formTitle) { + if (title == null) { + title = new ArrayList(); + } + while (number >= title.size()) { + title.add(null); + } + title.set(number, formTitle); + // URL items do not declare the file field, but addition is required for consistency + if (file == null || file.size() <= number) { + setFile(number, null); + } + } + + public String getTitle(int number) { + if (title == null || number >= title.size()) { + return null; + } + return title.get(number); + } + + public void setUrl(int number, String formUrl) { + if (url == null) { + url = new ArrayList(); + } + while (number >= url.size()) { + url.add(null); + } + url.set(number, formUrl); + } + + public String getUrl(int number) { + if (url == null || number >= url.size()) { + return null; + } + return url.get(number); + } + + public void setType(int number, Short formType) { + if (type == null) { + type = new ArrayList(); + } + while (number >= type.size()) { + type.add(null); + } + type.set(number, formType); + } + + public Short getType(int number) { + if (type == null || number >= type.size()) { + return null; + } + return type.get(number); + } + + public void setFile(int number, FormFile formFile) { + if (file == null) { + file = new ArrayList(); + } + while (number >= file.size()) { + file.add(null); + } + file.set(number, formFile); + } + + public FormFile getFile(int number) { + if (file == null || number >= file.size()) { + return null; + } + return file.get(number); + } + + public void setFileName(int number, String formFileName) { + if (fileName == null) { + fileName = new ArrayList(); + } + while (number >= fileName.size()) { + fileName.add(null); + } + fileName.set(number, formFileName); + } + + public String getFileName(int number) { + if (fileName == null || number >= fileName.size()) { + return null; + } + return fileName.get(number); + } + + public void setFileVersion(int number, Long formFileVersion) { + if (fileVersion == null) { + fileVersion = new ArrayList(); + } + while (number >= fileVersion.size()) { + fileVersion.add(null); + } + fileVersion.set(number, formFileVersion); + } + + public Long getFileVersion(int number) { + if (fileVersion == null || number >= fileVersion.size()) { + return null; + } + return fileVersion.get(number); + } + + public void setFileUuid(int number, Long formFileUuid) { + if (fileUuid == null) { + fileUuid = new ArrayList(); + } + while (number >= fileUuid.size()) { + fileUuid.add(null); + } + if (new Long(0).equals(formFileUuid)) { + fileUuid.set(number, null); + } else { + fileUuid.set(number, formFileUuid); + } + } + + public Long getFileUuid(int number) { + if (fileUuid == null || number >= fileUuid.size()) { + return null; + } + return fileUuid.get(number); + } + + public Integer getItemCount() { + return title == null ? 0 : title.size(); + } + + public boolean removeItem(int number) { + if (title == null || number >= title.size()) { + return false; + } + title.remove(number); + url.remove(number); + type.remove(number); + file.remove(number); + fileName.remove(number); + fileUuid.remove(number); + fileVersion.remove(number); + return true; + } + + public List getTypeList() { + return type; + } + + public List getFileNameList() { + return fileName; + } + + /** + * Special method that is used to fool the browser. If there was no file provided, there was an argument type + * mismatch excpetion since browser tried to fill an empty string to file field. Now in pedagogicalPlanner.js in + * lams_central it is detected and the field name is changed to fileDummy, which sets the file to NULLM + * here in Java form file. + * + * @param number + * where to set the empty file + * @param emptyString + * never used; the file is set to NULL anyway + */ + public void setFileDummy(int number, String emptyString) { + setFile(number, null); + } + + public String getInstructions() { + return instructions; + } + + public void setInstructions(String instructions) { + this.instructions = instructions; + } + + public String getContentFolderID() { + return contentFolderID; + } + + public void setContentFolderID(String contentFolderID) { + this.contentFolderID = contentFolderID; + } +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/ReflectionForm.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/ReflectionForm.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/form/ReflectionForm.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,69 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $$Id$$ */ +package org.lamsfoundation.lams.tool.commonCartridge.web.form; + +import org.apache.log4j.Logger; +import org.apache.struts.validator.ValidatorForm; + +/** + * + * Reflection Form. + * + * @struts.form name="reflectionForm" + * + */ +public class ReflectionForm extends ValidatorForm { + private static final long serialVersionUID = -9054365604649146735L; + private static Logger logger = Logger.getLogger(ReflectionForm.class.getName()); + + private Integer userID; + private String sessionMapID; + private String entryText; + + public String getEntryText() { + return entryText; + } + + public void setEntryText(String entryText) { + this.entryText = entryText; + } + + public Integer getUserID() { + return userID; + } + + public void setUserID(Integer userUid) { + this.userID = userUid; + } + + public String getSessionMapID() { + return sessionMapID; + } + + public void setSessionMapID(String sessionMapID) { + this.sessionMapID = sessionMapID; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/CompleteItemServlet.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/CompleteItemServlet.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/CompleteItemServlet.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,137 @@ +/** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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.commonCartridge.web.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeItem; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeServiceProxy; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeItemComparator; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeToolContentHandler; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; + +/** + * + * + * @author mseaton + */ +@SuppressWarnings("serial") +public class CompleteItemServlet extends HttpServlet { + private static Logger log = Logger.getLogger(CompleteItemServlet.class); + + private CommonCartridgeToolContentHandler handler; + private ICommonCartridgeService service; + + @Override + public void init() throws ServletException { + service = CommonCartridgeServiceProxy.getCommonCartridgeService(getServletContext()); + super.init(); + } + + /** + * The doGet method of the servlet.
    + * + * + * @param request + * the request send by the client to the server + * @param response + * the response send by the server to the client + * @throws ServletException + * if an error occurred + * @throws IOException + * if an error occurred + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String sessionMapID = request.getParameter(CommonCartridgeConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + Long commonCartridgeItemUid = new Long(request.getParameter(CommonCartridgeConstants.PARAM_RESOURCE_ITEM_UID)); + + HttpSession ss = SessionManager.getSession(); + + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + + Long sessionId = (Long) sessionMap.get(CommonCartridgeConstants.ATTR_TOOL_SESSION_ID); + service.setItemComplete(commonCartridgeItemUid, new Long(user.getUserID().intValue()), sessionId); + + // set commonCartridge item complete tag + SortedSet commonCartridgeItemList = getCommonCartridgeItemList(sessionMap); + for (CommonCartridgeItem item : commonCartridgeItemList) { + if (item.getUid().equals(commonCartridgeItemUid)) { + item.setComplete(true); + break; + } + } + + CommonCartridgeUser rUser = service.getUserByIDAndSession(new Long(user.getUserID()), sessionId); + + response.setContentType("text/javascript"); + PrintWriter out = response.getWriter(); + + if (!rUser.isSessionFinished()) { + out.println("window.parent.opener.checkNew(false);"); + out.println("window.parent.opener=null;"); + out.println("window.parent.close();"); + } else { + out.println("window.parent.opener.checkNew(true);"); + out.println("window.parent.opener=null;"); + out.println("window.parent.close();"); + } + + out.println(); + out.flush(); + out.close(); + } + + /** + * List save current commonCartridge items. + * + * @param request + * @return + */ + private SortedSet getCommonCartridgeItemList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST); + if (list == null) { + list = new TreeSet(new CommonCartridgeItemComparator()); + sessionMap.put(CommonCartridgeConstants.ATTR_RESOURCE_ITEM_LIST, list); + } + return list; + } + +} Index: lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/ExportServlet.java =================================================================== diff -u --- lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/ExportServlet.java (revision 0) +++ lams_tool_imscc/src/java/org/lamsfoundation/lams/tool/commonCartridge/web/servlet/ExportServlet.java (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,285 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $$Id$$ */ + +package org.lamsfoundation.lams.tool.commonCartridge.web.servlet; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants; +import org.lamsfoundation.lams.tool.commonCartridge.dto.ReflectDTO; +import org.lamsfoundation.lams.tool.commonCartridge.dto.Summary; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridge; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeSession; +import org.lamsfoundation.lams.tool.commonCartridge.model.CommonCartridgeUser; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeApplicationException; +import org.lamsfoundation.lams.tool.commonCartridge.service.CommonCartridgeServiceProxy; +import org.lamsfoundation.lams.tool.commonCartridge.service.ICommonCartridgeService; +import org.lamsfoundation.lams.tool.commonCartridge.util.CommonCartridgeToolContentHandler; +import org.lamsfoundation.lams.tool.commonCartridge.util.ReflectDTOComparator; +import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.web.servlet.AbstractExportPortfolioServlet; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Export portfolio servlet to export all shared commonCartridge into offline HTML package. + * + * @author Andrey Balan + */ +public class ExportServlet extends AbstractExportPortfolioServlet { + private static final long serialVersionUID = -4529093489007108143L; + + private static Logger logger = Logger.getLogger(ExportServlet.class); + + private final String FILENAME = "shared_commonCartridge_main.html"; + + private CommonCartridgeToolContentHandler handler; + + private ICommonCartridgeService service; + + @Override + public void init() throws ServletException { + service = CommonCartridgeServiceProxy.getCommonCartridgeService(getServletContext()); + super.init(); + } + + public String doExport(HttpServletRequest request, HttpServletResponse response, String directoryName, + Cookie[] cookies) { + + // initial sessionMap + SessionMap sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + + try { + if (StringUtils.equals(mode, ToolAccessMode.LEARNER.toString())) { + sessionMap.put(AttributeNames.ATTR_MODE, ToolAccessMode.LEARNER); + learner(request, response, directoryName, cookies, sessionMap); + } else if (StringUtils.equals(mode, ToolAccessMode.TEACHER.toString())) { + sessionMap.put(AttributeNames.ATTR_MODE, ToolAccessMode.TEACHER); + teacher(request, response, directoryName, cookies, sessionMap); + } + } catch (CommonCartridgeApplicationException e) { + logger.error("Cannot perform export for commonCartridge tool."); + } + + String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + + request.getContextPath(); + writeResponseToFile(basePath + "/pages/export/exportportfolio.jsp?sessionMapID=" + sessionMap.getSessionID(), + directoryName, FILENAME, cookies); + + return FILENAME; + } + + protected String doOfflineExport(HttpServletRequest request, HttpServletResponse response, String directoryName, + Cookie[] cookies) { + if (toolContentID == null && toolSessionID == null) { + logger.error("Tool content Id or and session Id are null. Unable to activity title"); + } else { + + CommonCartridge content = null; + if (toolContentID != null) { + content = service.getCommonCartridgeByContentId(toolContentID); + } else { + CommonCartridgeSession session = service.getCommonCartridgeSessionBySessionId(toolSessionID); + if (session != null) + content = session.getCommonCartridge(); + } + if (content != null) { + activityTitle = content.getTitle(); + } + } + return super.doOfflineExport(request, response, directoryName, cookies); + } + + public void learner(HttpServletRequest request, HttpServletResponse response, String directoryName, + Cookie[] cookies, HashMap sessionMap) throws CommonCartridgeApplicationException { + + if (userID == null || toolSessionID == null) { + String error = "Tool session Id or user Id is null. Unable to continue"; + logger.error(error); + throw new CommonCartridgeApplicationException(error); + } + + CommonCartridgeUser learner = service.getUserByIDAndSession(userID, toolSessionID); + + if (learner == null) { + String error = "The user with user id " + userID + " does not exist."; + logger.error(error); + throw new CommonCartridgeApplicationException(error); + } + + CommonCartridge content = service.getCommonCartridgeBySessionId(toolSessionID); + + if (content == null) { + String error = "The content for this activity has not been defined yet."; + logger.error(error); + throw new CommonCartridgeApplicationException(error); + } + + List group = service.exportBySessionId(toolSessionID, true); + saveFileToLocal(group, directoryName); + + List groupList = new ArrayList(); + if (group.size() > 0) + groupList.add(group); + + // Add flag to indicate whether to render user notebook entries + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECTION_ON, content.isReflectOnActivity()); + + // Create reflectList if reflection is enabled. + if (content.isReflectOnActivity()) { + // Create reflectList, need to follow same structure used in teacher + // see service.getReflectList(); + Map> map = new HashMap>(); + Set reflectDTOSet = new TreeSet(new ReflectDTOComparator()); + reflectDTOSet.add(getReflectionEntry(learner)); + map.put(toolSessionID, reflectDTOSet); + + // Add reflectList to sessionMap + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECT_LIST, map); + } + + sessionMap.put(CommonCartridgeConstants.ATTR_TITLE, content.getTitle()); + sessionMap.put(CommonCartridgeConstants.ATTR_INSTRUCTIONS, content.getInstructions()); + sessionMap.put(CommonCartridgeConstants.ATTR_SUMMARY_LIST, groupList); + } + + public void teacher(HttpServletRequest request, HttpServletResponse response, String directoryName, + Cookie[] cookies, HashMap sessionMap) throws CommonCartridgeApplicationException { + + // check if toolContentId exists in db or not + if (toolContentID == null) { + String error = "Tool Content Id is missing. Unable to continue"; + logger.error(error); + throw new CommonCartridgeApplicationException(error); + } + + CommonCartridge content = service.getCommonCartridgeByContentId(toolContentID); + + if (content == null) { + String error = "Data is missing from the database. Unable to Continue"; + logger.error(error); + throw new CommonCartridgeApplicationException(error); + } + List> groupList = service.exportByContentId(toolContentID); + if (groupList != null) { + for (List list : groupList) { + saveFileToLocal(list, directoryName); + } + } + + // Add flag to indicate whether to render user notebook entries + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECTION_ON, content.isReflectOnActivity()); + + // Create reflectList if reflection is enabled. + if (content.isReflectOnActivity()) { + Map> reflectList = service.getReflectList(content.getContentId(), true); + // Add reflectList to sessionMap + sessionMap.put(CommonCartridgeConstants.ATTR_REFLECT_LIST, reflectList); + } + + // put it into HTTPSession + sessionMap.put(CommonCartridgeConstants.ATTR_TITLE, content.getTitle()); + sessionMap.put(CommonCartridgeConstants.ATTR_INSTRUCTIONS, content.getInstructions()); + sessionMap.put(CommonCartridgeConstants.ATTR_SUMMARY_LIST, groupList); + } + + private void saveFileToLocal(List list, String directoryName) { + handler = getToolContentHandler(); + for (Summary summary : list) { + // TODO we have changed file-->common cartridge file + // for learning object, it just display "No offlice pakcage avaliable" information. + if (summary.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_COMMON_CARTRIDGE + || summary.getItemType() == CommonCartridgeConstants.RESOURCE_TYPE_BASIC_LTI + || summary.getItemType() == 0) { + continue; + } + + try { + int idx = 1; + String userName = summary.getUsername(); + String localDir; + while (true) { + localDir = FileUtil.getFullPath(directoryName, userName + "/" + idx); + File local = new File(localDir); + if (!local.exists()) { + local.mkdirs(); + break; + } + idx++; + } + summary.setAttachmentLocalUrl(userName + "/" + idx + "/" + summary.getFileUuid() + '.' + + FileUtil.getFileExtension(summary.getFileName())); + handler.saveFile(summary.getFileUuid(), + FileUtil.getFullPath(directoryName, summary.getAttachmentLocalUrl())); + } catch (Exception e) { + logger.error("Export forum topic attachment failed: " + e.toString()); + } + } + + } + + private CommonCartridgeToolContentHandler getToolContentHandler() { + if (handler == null) { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(this + .getServletContext()); + handler = (CommonCartridgeToolContentHandler) wac + .getBean(CommonCartridgeConstants.TOOL_CONTENT_HANDLER_NAME); + } + return handler; + } + + private ReflectDTO getReflectionEntry(CommonCartridgeUser commonCartridgeUser) { + ReflectDTO reflectDTO = new ReflectDTO(commonCartridgeUser); + NotebookEntry notebookEntry = service.getEntry(commonCartridgeUser.getSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, CommonCartridgeConstants.TOOL_SIGNATURE, commonCartridgeUser + .getUserId().intValue()); + + // check notebookEntry is not null + if (notebookEntry != null) { + reflectDTO.setReflect(notebookEntry.getEntry()); + logger.debug("Could not find notebookEntry for CommonCartridgeUser: " + commonCartridgeUser.getUid()); + } + return reflectDTO; + } +} Index: lams_tool_imscc/web/403.jsp =================================================================== diff -u --- lams_tool_imscc/web/403.jsp (revision 0) +++ lams_tool_imscc/web/403.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,6 @@ +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-core" prefix="c" %> + + + Index: lams_tool_imscc/web/404.jsp =================================================================== diff -u --- lams_tool_imscc/web/404.jsp (revision 0) +++ lams_tool_imscc/web/404.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,8 @@ +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-core" prefix="c" %> + + + + + Index: lams_tool_imscc/web/WEB-INF/.cvsignore =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/.cvsignore (revision 0) +++ lams_tool_imscc/web/WEB-INF/.cvsignore (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,4 @@ +lib +struts-config.xml +validation.xml +classes Index: lams_tool_imscc/web/WEB-INF/tags/AuthoringButton.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/AuthoringButton.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/AuthoringButton.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,93 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * AuthoringButton.tag + * Author: Dapeng Ni + * Description: Creates the save/cancel button for authoring page + */ + + %> +<%@ tag body-content="scriptless" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-fmt" prefix="fmt" %> +<%@ taglib uri="tags-html" prefix="html" %> + +<%@ attribute name="formID" required="true" rtexprvalue="true" %> +<%@ attribute name="toolSignature" required="true" rtexprvalue="true" %> +<%@ attribute name="toolContentID" required="true" rtexprvalue="true" %> +<%@ attribute name="contentFolderID" required="true" rtexprvalue="true" %> +<%@ attribute name="clearSessionActionUrl" required="true" rtexprvalue="true" %> + +<%-- Optional attribute --%> +<%@ attribute name="accessMode" required="false" rtexprvalue="true" %> +<%@ attribute name="cancelButtonLabelKey" required="false" rtexprvalue="true" %> +<%@ attribute name="saveButtonLabelKey" required="false" rtexprvalue="true" %> +<%@ attribute name="cancelConfirmMsgKey" required="false" rtexprvalue="true" %> +<%@ attribute name="defineLater" required="false" rtexprvalue="true" %> +<%@ attribute name="customiseSessionID" required="false" rtexprvalue="true" %> + +<%-- Default value for message key --%> + + + + + + + + + + + + + + + +

    + + + + + + +

    + Index: lams_tool_imscc/web/WEB-INF/tags/Date.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/Date.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/Date.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,52 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Author: Fiona Malikoff + * Description: Format a date, using the locale, based on standard parameters. + * Need to use long for the date otherwise the AU locale comes out as 1/2/06 and + * full is needed to include the timezone. + */ + + %> +<%@ tag body-content="empty" %> +<%@ attribute name="value" required="true" rtexprvalue="true" type="java.util.Date" %> +<%@ attribute name="style" required="false" rtexprvalue="true"%> +<%@ attribute name="type" required="false" rtexprvalue="true"%> + +<%@ taglib uri="tags-fmt" prefix="fmt" %> +<%@ taglib uri="tags-core" prefix="c" %> + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/DefineLater.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/DefineLater.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/DefineLater.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,58 @@ + +<% + /**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * DefineLater.tag + * Author: Fiona Malikoff + * Description: Layout for "Define Later" screens - to be used in learning. + * A suggested layout - unless the tool has special requirements, this layout should be used. + * Expects to be used inside
    + */ +%> + +<%@ tag body-content="scriptless"%> +<%@ taglib uri="tags-fmt" prefix="fmt"%> +<%@ taglib uri="tags-core" prefix="c"%> + +<%@ attribute name="defineLaterMessageKey" required="false" + rtexprvalue="true"%> +<%@ attribute name="buttonTryAgainKey" required="false" + rtexprvalue="true"%> + +<%-- Default value for I18N keys --%> + + + + + + + +

    + +

    +
    + +
    Index: lams_tool_imscc/web/WEB-INF/tags/ExportPortOutput.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/ExportPortOutput.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/ExportPortOutput.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,59 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Passon + * Author: Fiona Malikoff + * Description: Outputs the Activity details on the main page in export portfolio. Recursive tag. + * + */ + + %> +<%@ tag body-content="empty" %> +<%@ attribute name="actport" required="true" rtexprvalue="true" type="org.lamsfoundation.lams.learning.export.ActivityPortfolio" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + +
  • + + + " target="_blank"/> + + + + + + + + +
      + + + +
    +
    +
    + +
  • + Index: lams_tool_imscc/web/WEB-INF/tags/FCKEditor.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/FCKEditor.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/FCKEditor.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,77 @@ +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="fck-editor" prefix="fck"%> + +<%@ attribute name="id" required="true" rtexprvalue="true"%> +<%@ attribute name="value" required="true" rtexprvalue="true"%> +<%@ attribute name="toolbarSet" required="false" rtexprvalue="true"%> +<%@ attribute name="height" required="false" rtexprvalue="true"%> +<%@ attribute name="width" required="false" rtexprvalue="true"%> +<%@ attribute name="contentFolderID" required="false" rtexprvalue="true"%> +<%@ attribute name="displayExpanded" required="false" rtexprvalue="true"%> + + + + + + + + + + + + + + + + + +/fckeditor/ + + + + +${value} + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/Head.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/Head.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/Head.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,41 @@ +<%/**************************************************************** + * 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 + * **************************************************************** + */ + +/** + * Head.tag + * Author: Fiona Malikoff + * Description: Sets up the non-cache pragma statements and the UTF-8 + * encoding. Use in place of the normal head tag. + */ +%> + +<%@ tag body-content="scriptless"%> + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/ImgButtonWrapper.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/ImgButtonWrapper.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/ImgButtonWrapper.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,37 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * ImgButtonWrapper.tag + * Author: Mitchell Seaton + * Description: Simple wrapper that will display buttons correctly when RTL page rendering is used. + */ + + %> +<%@ tag body-content="scriptless" %> +
    +
    + +
    +
    Index: lams_tool_imscc/web/WEB-INF/tags/LearnerFlashEnabled.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/LearnerFlashEnabled.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/LearnerFlashEnabled.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,45 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Learner Flash Enabled + * Author: Fiona Malikoff + * Description: Is Flash enabled for learner? + * + */ + + %> +<%@ tag body-content="empty" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + + + + + + true + false + + + Index: lams_tool_imscc/web/WEB-INF/tags/Passon.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/Passon.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/Passon.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,86 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Passon + * Author: Mitchell Seaton + * Description: Passes on progress data to the Flash Learner to update the progress bar. + * + */ + + %> +<%@ tag body-content="empty" %> +<%@ attribute name="progress" required="true" rtexprvalue="true" type="java.lang.String" %> +<%@ attribute name="version" required="false" rtexprvalue="true" %> +<%@ attribute name="id" required="true" rtexprvalue="true" %> +<%@ attribute name="redirect" required="false" rtexprvalue="true" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/ProgressOutput.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/ProgressOutput.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/ProgressOutput.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,79 @@ +<% +/**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Progress Output + * Author: Fiona Malikoff + * Description: Outputs the Activity details on the jsp progress page. Recursive tag + * + */ + + /** Need to add current ! */ + + %> +<%@ tag body-content="empty" %> +<%@ attribute name="activity" required="true" rtexprvalue="true" type="org.lamsfoundation.lams.learning.web.bean.ActivityURL" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + +
  • + + + + + + + + + + + + + + + + + + + + + + + + ${activity.title} + + + + + +
      + + + +
    +
    +
    + +
  • + Index: lams_tool_imscc/web/WEB-INF/tags/Tab.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/Tab.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/Tab.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,85 @@ +<% + /**************************************************************** + * 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 + * **************************************************************** + */ + + /** + * Tab.tag + * Author: Mitchell Seaton + * Description: Creates a tab element. + * Wiki: + */ +%> +<%@ tag body-content="empty"%> +<%@ attribute name="id" required="true" rtexprvalue="true"%> +<%@ attribute name="value" required="false" rtexprvalue="true"%> +<%@ attribute name="key" required="false" rtexprvalue="true"%> +<%@ attribute name="inactive" required="false" rtexprvalue="true"%> +<%@ attribute name="methodCall" required="false" rtexprvalue="true"%> + +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-fmt" prefix="fmt"%> +<%@ taglib uri="tags-lams" prefix="lams"%> + +<%-- Check if bundle is set --%> + + + + + + + + + + +<%-- + Usually methodCall is selectTab, but the calling code can override methodCall if desired. + this is handy if the page needs different logic on initialisation and user switching tabs +--%> + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/TabBody.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/TabBody.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/TabBody.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,52 @@ +<%/**************************************************************** + * 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 + * **************************************************************** + */ + +/** + * TabBody.tag + * Author: Mitchell Seaton + * Description: Creates the body container for a tab element + * Wiki: + */ + + %> +<%@ tag body-content="scriptless"%> +<%@ attribute name="id" required="true" rtexprvalue="true"%> +<%@ attribute name="tabTitle" required="false" rtexprvalue="true"%> +<%@ attribute name="titleKey" required="false" rtexprvalue="true"%> +<%@ attribute name="page" required="false" rtexprvalue="true"%> +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-bean" prefix="bean"%> + + +
    + + + + + + + + + +
    + Index: lams_tool_imscc/web/WEB-INF/tags/TabName.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/TabName.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/TabName.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,60 @@ +<%/**************************************************************** + * 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 + * **************************************************************** + */ + +/** + * TabName Tag + * Author: Mitchell Seaton + * Description: Shortens name that are too long to fit inside a tab + */ + + %> +<%@ tag body-content="scriptless" %> + +<%@ attribute name="url" required="true" rtexprvalue="true"%> +<%@ attribute name="highlight" required="false" rtexprvalue="true" %> + +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-function" prefix="fn"%> + +12 + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/Tabs.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/Tabs.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/Tabs.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,69 @@ +<%/**************************************************************** + * 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 + * **************************************************************** + */ + +/** + * Tabs.tag + * Author: Mitchell Seaton + * Description: Create a tab list from a input collection or nested Tab tags. + * Wiki: + */ + + %> +<%@ tag body-content="scriptless"%> +<%@ attribute name="collection" type="java.util.Collection" required="false" rtexprvalue="true"%> +<%@ attribute name="control" required="false" rtexprvalue="true"%> +<%@ attribute name="useKey" required="false" rtexprvalue="true"%> +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-lams" prefix="lams"%> + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tags/headItems.tag =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tags/headItems.tag (revision 0) +++ lams_tool_imscc/web/WEB-INF/tags/headItems.tag (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,52 @@ +<%/**************************************************************** + * 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 + * **************************************************************** + */ + +/** + * Standard Head Items + * Author: Fiona Malikoff + * Description: Includes all the standard head items e.g. the + * lams css files, sets the content type, standard javascript files. + */ + + %> +<%@ tag body-content="empty"%> + +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-fmt" prefix="fmt"%> + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tiles-defs.xml =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tiles-defs.xml (revision 0) +++ lams_tool_imscc/web/WEB-INF/tiles-defs.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/fckeditor/FCKeditor.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/fckeditor/FCKeditor.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/fckeditor/FCKeditor.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,129 @@ + + + + The FCKeditor Tag Library offers a very convenient way to create + several FCKeditor instances with different configurations. + Additionally, you can check for user-based capabilities. + + FCKeditor Tag Library + 2.4 + FCK + http://java.fckeditor.net + + + Creates a FCKeditor instance with the given parameters. Any + parameter except instanceName which is empty or contains + whitespaces only will be ignored. + + editor + editor + net.fckeditor.tags.EditorTag + JSP + + + The unique instance name under which the editor can be + retrieved through the API. + + instanceName + true + true + java.lang.String + + + + Width of the FCKeditor instance in the browser window. + + width + true + java.lang.String + + + + Height of the FCKeditor instance in the browser window. + + height + true + java.lang.String + + + + The toolbar set which shall be displayed to the user. + + toolbarSet + true + java.lang.String + + + + The path/folder in which the editor is deployed under + the given context. The context path will be attached + automatically. (e.g. '/fckeditor') + + basePath + true + java.lang.String + + + + Passes any content to the FCKeditor document. Use the + jsp:attribute tag for large inline content. \r, \n, and + \t will be truncated. + + value + true + java.lang.String + + ]]> + + + + + Sets a config property of the editor to the supplied value. + You may provide any attribute you want for the editor. Set + at least one attribute per tag or several attributes with + one tag. This tag can only be nested within an editor tag. + For all configuration options click + here]]>. + + config + config + net.fckeditor.tags.ConfigTag + empty + true + + ]]> + + + + + Displays session-dependent and compatibility-related + information. This tag is intended for developers only. + Response messages cannot be localized, they are English + only. + + check + check + net.fckeditor.tags.CheckTag + empty + + + Provide the feature name you want to check. Valid + features are [FileUpload, FileBrowsing, + CompatibleBrowser] + + command + true + java.lang.String + + +]]> + + + Index: lams_tool_imscc/web/WEB-INF/tlds/jstl/c.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/jstl/c.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/jstl/c.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,563 @@ + + + + + JSTL 1.1 core library + JSTL core + 1.1 + c + http://java.sun.com/jsp/jstl/core + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlCoreTLV + + + + + + Catches any Throwable that occurs in its body and optionally + exposes it. + + catch + org.apache.taglibs.standard.tag.common.core.CatchTag + JSP + + +Name of the exported scoped variable for the +exception thrown from a nested action. The type of the +scoped variable is the type of the exception thrown. + + var + false + false + + + + + + Simple conditional tag that establishes a context for + mutually exclusive conditional operations, marked by + <when> and <otherwise> + + choose + org.apache.taglibs.standard.tag.common.core.ChooseTag + JSP + + + + + Simple conditional tag, which evalutes its body if the + supplied condition is true and optionally exposes a Boolean + scripting variable representing the evaluation of this condition + + if + org.apache.taglibs.standard.tag.rt.core.IfTag + JSP + + +The test condition that determines whether or +not the body content should be processed. + + test + true + true + boolean + + + +Name of the exported scoped variable for the +resulting value of the test condition. The type +of the scoped variable is Boolean. + + var + false + false + + + +Scope for var. + + scope + false + false + + + + + + Retrieves an absolute or relative URL and exposes its contents + to either the page, a String in 'var', or a Reader in 'varReader'. + + import + org.apache.taglibs.standard.tag.rt.core.ImportTag + org.apache.taglibs.standard.tei.ImportTEI + JSP + + +The URL of the commonCartridge to import. + + url + true + true + + + +Name of the exported scoped variable for the +commonCartridge's content. The type of the scoped +variable is String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +Name of the exported scoped variable for the +commonCartridge's content. The type of the scoped +variable is Reader. + + varReader + false + false + + + +Name of the context when accessing a relative +URL commonCartridge that belongs to a foreign +context. + + context + false + true + + + +Character encoding of the content at the input +commonCartridge. + + charEncoding + false + true + + + + + + The basic iteration tag, accepting many different + collection types and supporting subsetting and other + functionality + + forEach + org.apache.taglibs.standard.tag.rt.core.ForEachTag + org.apache.taglibs.standard.tei.ForEachTEI + JSP + + +Collection of items to iterate over. + + items + false + true + java.lang.Object + + + +If items specified: +Iteration begins at the item located at the +specified index. First item of the collection has +index 0. +If items not specified: +Iteration begins with index set at the value +specified. + + begin + false + true + int + + + +If items specified: +Iteration ends at the item located at the +specified index (inclusive). +If items not specified: +Iteration ends when index reaches the value +specified. + + end + false + true + int + + + +Iteration will only process every step items of +the collection, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. Its type depends +on the object of the underlying collection. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of type +javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Iterates over tokens, separated by the supplied delimeters + + forTokens + org.apache.taglibs.standard.tag.rt.core.ForTokensTag + JSP + + +String of tokens to iterate over. + + items + true + true + java.lang.String + + + +The set of delimiters (the characters that +separate the tokens in the string). + + delims + true + true + java.lang.String + + + +Iteration begins at the token located at the +specified index. First token has index 0. + + begin + false + true + int + + + +Iteration ends at the token located at the +specified index (inclusive). + + end + false + true + int + + + +Iteration will only process every step tokens +of the string, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of +type +javax.servlet.jsp.jstl.core.LoopTag +Status. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Like <%= ... >, but for expressions. + + out + org.apache.taglibs.standard.tag.rt.core.OutTag + JSP + + +Expression to be evaluated. + + value + true + true + + + +Default value if the resulting value is null. + + default + false + true + + + +Determines whether characters <,>,&,'," in the +resulting string should be converted to their +corresponding character entity codes. Default value is +true. + + escapeXml + false + true + + + + + + + Subtag of <choose> that follows <when> tags + and runs only if all of the prior conditions evaluated to + 'false' + + otherwise + org.apache.taglibs.standard.tag.common.core.OtherwiseTag + JSP + + + + + Adds a parameter to a containing 'import' tag's URL. + + param + org.apache.taglibs.standard.tag.rt.core.ParamTag + JSP + + +Name of the query string parameter. + + name + true + true + + + +Value of the parameter. + + value + false + true + + + + + + Redirects to a new URL. + + redirect + org.apache.taglibs.standard.tag.rt.core.RedirectTag + JSP + + +The URL of the commonCartridge to redirect to. + + url + false + true + + + +Name of the context when redirecting to a relative URL +commonCartridge that belongs to a foreign context. + + context + false + true + + + + + + Removes a scoped variable (from a particular scope, if specified). + + remove + org.apache.taglibs.standard.tag.common.core.RemoveTag + empty + + +Name of the scoped variable to be removed. + + var + true + false + + + +Scope for var. + + scope + false + false + + + + + + Sets the result of an expression evaluation in a 'scope' + + set + org.apache.taglibs.standard.tag.rt.core.SetTag + JSP + + +Name of the exported scoped variable to hold the value +specified in the action. The type of the scoped variable is +whatever type the value expression evaluates to. + + var + false + false + + + +Expression to be evaluated. + + value + false + true + + + +Target object whose property will be set. Must evaluate to +a JavaBeans object with setter property property, or to a +java.util.Map object. + + target + false + true + + + +Name of the property to be set in the target object. + + property + false + true + + + +Scope for var. + + scope + false + false + + + + + + Creates a URL with optional query parameters. + + url + org.apache.taglibs.standard.tag.rt.core.UrlTag + JSP + + +Name of the exported scoped variable for the +processed url. The type of the scoped variable is +String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +URL to be processed. + + value + false + true + + + +Name of the context when specifying a relative URL +commonCartridge that belongs to a foreign context. + + context + false + true + + + + + + Subtag of <choose> that includes its body if its + condition evalutes to 'true' + + when + org.apache.taglibs.standard.tag.rt.core.WhenTag + JSP + + +The test condition that determines whether or not the +body content should be processed. + + test + true + true + boolean + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/jstl/fmt.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/jstl/fmt.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/jstl/fmt.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,671 @@ + + + + + JSTL 1.1 i18n-capable formatting library + JSTL fmt + 1.1 + fmt + http://java.sun.com/jsp/jstl/fmt + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlFmtTLV + + + + + + Sets the request character encoding + + requestEncoding + org.apache.taglibs.standard.tag.rt.fmt.RequestEncodingTag + empty + + +Name of character encoding to be applied when +decoding request parameters. + + value + false + true + + + + + + Stores the given locale in the locale configuration variable + + setLocale + org.apache.taglibs.standard.tag.rt.fmt.SetLocaleTag + empty + + +A String value is interpreted as the +printable representation of a locale, which +must contain a two-letter (lower-case) +language code (as defined by ISO-639), +and may contain a two-letter (upper-case) +country code (as defined by ISO-3166). +Language and country codes must be +separated by hyphen (-) or underscore +(_). + + value + true + true + + + +Vendor- or browser-specific variant. +See the java.util.Locale javadocs for +more information on variants. + + variant + false + true + + + +Scope of the locale configuration variable. + + scope + false + false + + + + + + Specifies the time zone for any time formatting or parsing actions + nested in its body + + timeZone + org.apache.taglibs.standard.tag.rt.fmt.TimeZoneTag + JSP + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See +java.util.TimeZone for more information on +supported time zone formats. + + value + true + true + + + + + + Stores the given time zone in the time zone configuration variable + + setTimeZone + org.apache.taglibs.standard.tag.rt.fmt.SetTimeZoneTag + empty + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See java.util.TimeZone for +more information on supported time zone +formats. + + value + true + true + + + +Name of the exported scoped variable which +stores the time zone of type +java.util.TimeZone. + + var + false + false + + + +Scope of var or the time zone configuration +variable. + + scope + false + false + + + + + + Loads a commonCartridge bundle to be used by its tag body + + bundle + org.apache.taglibs.standard.tag.rt.fmt.BundleTag + JSP + + +CommonCartridge bundle base name. This is the bundle's +fully-qualified commonCartridge name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Prefix to be prepended to the value of the message +key of any nested <fmt:message> action. + + prefix + false + true + + + + + + Loads a commonCartridge bundle and stores it in the named scoped variable or + the bundle configuration variable + + setBundle + org.apache.taglibs.standard.tag.rt.fmt.SetBundleTag + empty + + +CommonCartridge bundle base name. This is the bundle's +fully-qualified commonCartridge name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Name of the exported scoped variable which stores +the i18n localization context of type +javax.servlet.jsp.jstl.fmt.LocalizationC +ontext. + + var + false + false + + + +Scope of var or the localization context +configuration variable. + + scope + false + false + + + + + + Maps key to localized message and performs parametric replacement + + message + org.apache.taglibs.standard.tag.rt.fmt.MessageTag + JSP + + +Message key to be looked up. + + key + false + true + + + +Localization context in whose commonCartridge +bundle the message key is looked up. + + bundle + false + true + + + +Name of the exported scoped variable +which stores the localized message. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Supplies an argument for parametric replacement to a containing + <message> tag + + param + org.apache.taglibs.standard.tag.rt.fmt.ParamTag + JSP + + +Argument used for parametric replacement. + + value + false + true + + + + + + Formats a numeric value as a number, currency, or percentage + + formatNumber + org.apache.taglibs.standard.tag.rt.fmt.FormatNumberTag + JSP + + +Numeric value to be formatted. + + value + false + true + + + +Specifies whether the value is to be +formatted as number, currency, or +percentage. + + type + false + true + + + +Custom formatting pattern. + + pattern + false + true + + + +ISO 4217 currency code. Applied only +when formatting currencies (i.e. if type is +equal to "currency"); ignored otherwise. + + currencyCode + false + true + + + +Currency symbol. Applied only when +formatting currencies (i.e. if type is equal +to "currency"); ignored otherwise. + + currencySymbol + false + true + + + +Specifies whether the formatted output +will contain any grouping separators. + + groupingUsed + false + true + + + +Maximum number of digits in the integer +portion of the formatted output. + + maxIntegerDigits + false + true + + + +Minimum number of digits in the integer +portion of the formatted output. + + minIntegerDigits + false + true + + + +Maximum number of digits in the +fractional portion of the formatted output. + + maxFractionDigits + false + true + + + +Minimum number of digits in the +fractional portion of the formatted output. + + minFractionDigits + false + true + + + +Name of the exported scoped variable +which stores the formatted result as a +String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a number, currency, or percentage + + parseNumber + org.apache.taglibs.standard.tag.rt.fmt.ParseNumberTag + JSP + + +String to be parsed. + + value + false + true + + + +Specifies whether the string in the value +attribute should be parsed as a number, +currency, or percentage. + + type + false + true + + + +Custom formatting pattern that determines +how the string in the value attribute is to be +parsed. + + pattern + false + true + + + +Locale whose default formatting pattern (for +numbers, currencies, or percentages, +respectively) is to be used during the parse +operation, or to which the pattern specified +via the pattern attribute (if present) is +applied. + + parseLocale + false + true + + + +Specifies whether just the integer portion of +the given value should be parsed. + + integerOnly + false + true + + + +Name of the exported scoped variable which +stores the parsed result (of type +java.lang.Number). + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Formats a date and/or time using the supplied styles and pattern + + formatDate + org.apache.taglibs.standard.tag.rt.fmt.FormatDateTag + empty + + +Date and/or time to be formatted. + + value + true + true + + + +Specifies whether the time, the date, or both +the time and date components of the given +date are to be formatted. + + type + false + true + + + +Predefined formatting style for dates. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a date or both a date and +time (i.e. if type is missing or is equal to +"date" or "both"); ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting style for times. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a time or both a date and +time (i.e. if type is equal to "time" or "both"); +ignored otherwise. + + timeStyle + false + true + + + +Custom formatting style for dates and times. + + pattern + false + true + + + +Time zone in which to represent the formatted +time. + + timeZone + false + true + + + +Name of the exported scoped variable which +stores the formatted result as a String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a date and/or time + + parseDate + org.apache.taglibs.standard.tag.rt.fmt.ParseDateTag + JSP + + +Date string to be parsed. + + value + false + true + + + +Specifies whether the date string in the +value attribute is supposed to contain a +time, a date, or both. + + type + false + true + + + +Predefined formatting style for days +which determines how the date +component of the date string is to be +parsed. Applied only when formatting a +date or both a date and time (i.e. if type +is missing or is equal to "date" or "both"); +ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting styles for times +which determines how the time +component in the date string is to be +parsed. Applied only when formatting a +time or both a date and time (i.e. if type +is equal to "time" or "both"); ignored +otherwise. + + timeStyle + false + true + + + +Custom formatting pattern which +determines how the date string is to be +parsed. + + pattern + false + true + + + +Time zone in which to interpret any time +information in the date string. + + timeZone + false + true + + + +Locale whose predefined formatting styles +for dates and times are to be used during +the parse operation, or to which the +pattern specified via the pattern +attribute (if present) is applied. + + parseLocale + false + true + + + +Name of the exported scoped variable in +which the parsing result (of type +java.util.Date) is stored. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/jstl/fn.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/jstl/fn.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/jstl/fn.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,207 @@ + + + + + JSTL 1.1 functions library + JSTL functions + 1.1 + fn + http://java.sun.com/jsp/jstl/functions + + + + Tests if an input string contains the specified substring. + + contains + org.apache.taglibs.standard.functions.Functions + boolean contains(java.lang.String, java.lang.String) + + <c:if test="${fn:contains(name, searchString)}"> + + + + + + Tests if an input string contains the specified substring in a case insensitive way. + + containsIgnoreCase + org.apache.taglibs.standard.functions.Functions + boolean containsIgnoreCase(java.lang.String, java.lang.String) + + <c:if test="${fn:containsIgnoreCase(name, searchString)}"> + + + + + + Tests if an input string ends with the specified suffix. + + endsWith + org.apache.taglibs.standard.functions.Functions + boolean endsWith(java.lang.String, java.lang.String) + + <c:if test="${fn:endsWith(filename, ".txt")}"> + + + + + + Escapes characters that could be interpreted as XML markup. + + escapeXml + org.apache.taglibs.standard.functions.Functions + java.lang.String escapeXml(java.lang.String) + + ${fn:escapeXml(param:info)} + + + + + + Returns the index withing a string of the first occurrence of a specified substring. + + indexOf + org.apache.taglibs.standard.functions.Functions + int indexOf(java.lang.String, java.lang.String) + + ${fn:indexOf(name, "-")} + + + + + + Joins all elements of an array into a string. + + join + org.apache.taglibs.standard.functions.Functions + java.lang.String join(java.lang.String[], java.lang.String) + + ${fn:join(array, ";")} + + + + + + Returns the number of items in a collection, or the number of characters in a string. + + length + org.apache.taglibs.standard.functions.Functions + int length(java.lang.Object) + + You have ${fn:length(shoppingCart.products)} in your shopping cart. + + + + + + Returns a string resulting from replacing in an input string all occurrences + of a "before" string into an "after" substring. + + replace + org.apache.taglibs.standard.functions.Functions + java.lang.String replace(java.lang.String, java.lang.String, java.lang.String) + + ${fn:replace(text, "-", "•")} + + + + + + Splits a string into an array of substrings. + + split + org.apache.taglibs.standard.functions.Functions + java.lang.String[] split(java.lang.String, java.lang.String) + + ${fn:split(customerNames, ";")} + + + + + + Tests if an input string starts with the specified prefix. + + startsWith + org.apache.taglibs.standard.functions.Functions + boolean startsWith(java.lang.String, java.lang.String) + + <c:if test="${fn:startsWith(product.id, "100-")}"> + + + + + + Returns a subset of a string. + + substring + org.apache.taglibs.standard.functions.Functions + java.lang.String substring(java.lang.String, int, int) + + P.O. Box: ${fn:substring(zip, 6, -1)} + + + + + + Returns a subset of a string following a specific substring. + + substringAfter + org.apache.taglibs.standard.functions.Functions + java.lang.String substringAfter(java.lang.String, java.lang.String) + + P.O. Box: ${fn:substringAfter(zip, "-")} + + + + + + Returns a subset of a string before a specific substring. + + substringBefore + org.apache.taglibs.standard.functions.Functions + java.lang.String substringBefore(java.lang.String, java.lang.String) + + Zip (without P.O. Box): ${fn:substringBefore(zip, "-")} + + + + + + Converts all of the characters of a string to lower case. + + toLowerCase + org.apache.taglibs.standard.functions.Functions + java.lang.String toLowerCase(java.lang.String) + + Product name: ${fn.toLowerCase(product.name)} + + + + + + Converts all of the characters of a string to upper case. + + toUpperCase + org.apache.taglibs.standard.functions.Functions + java.lang.String toUpperCase(java.lang.String) + + Product name: ${fn.UpperCase(product.name)} + + + + + + Removes white spaces from both ends of a string. + + trim + org.apache.taglibs.standard.functions.Functions + java.lang.String trim(java.lang.String) + + Name: ${fn.trim(name)} + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/jstl/x.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/jstl/x.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/jstl/x.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,448 @@ + + + + + JSTL 1.1 XML library + JSTL XML + 1.1 + x + http://java.sun.com/jsp/jstl/xml + + + + Provides validation features for JSTL XML tags. + + + org.apache.taglibs.standard.tlv.JstlXmlTLV + + + + + + Simple conditional tag that establishes a context for + mutually exclusive conditional operations, marked by + <when> and <otherwise> + + choose + org.apache.taglibs.standard.tag.common.core.ChooseTag + JSP + + + + + Like <%= ... >, but for XPath expressions. + + out + org.apache.taglibs.standard.tag.rt.xml.ExprTag + empty + + +XPath expression to be evaluated. + + select + true + false + + + +Determines whether characters <,>,&,'," in the +resulting string should be converted to their +corresponding character entity codes. Default +value is true. + + escapeXml + false + true + + + + + + XML conditional tag, which evalutes its body if the + supplied XPath expression evalutes to 'true' as a boolean + + if + org.apache.taglibs.standard.tag.common.xml.IfTag + JSP + + +The test condition that tells whether or not the +body content should be processed. + + select + true + false + + + +Name of the exported scoped variable for the +resulting value of the test condition. The type +of the scoped variable is Boolean. + + var + false + false + + + +Scope for var. + + scope + false + false + + + + + + XML iteration tag. + + forEach + org.apache.taglibs.standard.tag.common.xml.ForEachTag + JSP + + +Name of the exported scoped variable for the +current item of the iteration. This scoped variable +has nested visibility. Its type depends on the +result of the XPath expression in the select +attribute. + + var + false + false + + + +XPath expression to be evaluated. + + select + true + false + + + +Iteration begins at the item located at the +specified index. First item of the collection has +index 0. + + begin + false + true + int + + + +Iteration ends at the item located at the specified +index (inclusive). + + end + false + true + int + + + +Iteration will only process every step items of +the collection, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of type +javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested visibility. + + varStatus + false + false + + + + + + Subtag of <choose> that follows <when> tags + and runs only if all of the prior conditions evaluated to + 'false' + + otherwise + org.apache.taglibs.standard.tag.common.core.OtherwiseTag + JSP + + + + + Adds a parameter to a containing 'transform' tag's Transformer + + param + org.apache.taglibs.standard.tag.rt.xml.ParamTag + JSP + + +Name of the transformation parameter. + + name + true + true + + + +Value of the parameter. + + value + false + true + + + + + + Parses XML content from 'source' attribute or 'body' + + parse + org.apache.taglibs.standard.tag.rt.xml.ParseTag + org.apache.taglibs.standard.tei.XmlParseTEI + JSP + + +Name of the exported scoped variable for +the parsed XML document. The type of the +scoped variable is implementation +dependent. + + var + false + false + + + +Name of the exported scoped variable for +the parsed XML document. The type of the +scoped variable is +org.w3c.dom.Document. + + varDom + false + false + + + +Scope for var. + + scope + false + false + + + +Scope for varDom. + + scopeDom + false + false + + + +Deprecated. Use attribute 'doc' instead. + + xml + false + true + + + +Source XML document to be parsed. + + doc + false + true + + + +The system identifier (URI) for parsing the +XML document. + + systemId + false + true + + + +Filter to be applied to the source +document. + + filter + false + true + + + + + + Saves the result of an XPath expression evaluation in a 'scope' + + set + org.apache.taglibs.standard.tag.common.xml.SetTag + empty + + +Name of the exported scoped variable to hold +the value specified in the action. The type of the +scoped variable is whatever type the select +expression evaluates to. + + var + true + false + + + +XPath expression to be evaluated. + + select + false + false + + + +Scope for var. + + scope + false + false + + + + + + Conducts a transformation given a source XML document + and an XSLT stylesheet + + transform + org.apache.taglibs.standard.tag.rt.xml.TransformTag + org.apache.taglibs.standard.tei.XmlTransformTEI + JSP + + +Name of the exported +scoped variable for the +transformed XML +document. The type of the +scoped variable is +org.w3c.dom.Document. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +Result +Object that captures or +processes the transformation +result. + + result + false + true + + + +Deprecated. Use attribute +'doc' instead. + + xml + false + true + + + +Source XML document to be +transformed. (If exported by +<x:set>, it must correspond +to a well-formed XML +document, not a partial +document.) + + doc + false + true + + + +Deprecated. Use attribute +'docSystemId' instead. + + xmlSystemId + false + true + + + +The system identifier (URI) +for parsing the XML +document. + + docSystemId + false + true + + + +javax.xml.transform.Source +Transformation stylesheet as +a String, Reader, or +Source object. + + xslt + false + true + + + +The system identifier (URI) +for parsing the XSLT +stylesheet. + + xsltSystemId + false + true + + + + + + Subtag of <choose> that includes its body if its + expression evalutes to 'true' + + when + org.apache.taglibs.standard.tag.common.xml.WhenTag + JSP + + +The test condition that tells whether or +not the body content should be +processed + + select + true + false + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/lams/lams.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/lams/lams.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/lams/lams.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,513 @@ + + + + + 1.0 + lams + + LAMSTags + + + + + Output the basic URL for the current webapp. e.g. http://server/lams/tool/nb11/ + Base URL for the current web app + + + WebAppURL + org.lamsfoundation.lams.web.tag.WebAppURLTag + empty + + + + + Output a random number for the learner and passon flash movies to communicate directly. + generate unique ID + + + generateID + org.lamsfoundation.lams.web.tag.GenerateIDTag + empty + + + Output a random number for the learner and passon flash movies to communicate directly. + id + false + + true + + + + + + + Get the configuration value for the specified key + Configuration value + + + Configuration + org.lamsfoundation.lams.web.tag.ConfigurationTag + empty + + + Get the configuration value for the specified key + key + false + + true + + + + + + + Output the Server URL as defined in the lams.xml configuration file. + LAMS URL + + + LAMSURL + org.lamsfoundation.lams.web.tag.LAMSURLTag + empty + + + + + Render html tag with direction and language + Render html tag with direction and language + + + html + org.lamsfoundation.lams.web.tag.HtmlTag + JSP + + + Render html tag with direction and language + xhtml + false + + true + + + + + + + Converts text from \n or \r\n to <BR> before rendering + Converts text from \n or \r\n to <BR> before rendering + + + out + org.lamsfoundation.lams.web.tag.MultiLinesOutputTag + empty + + + Converts text from \n or \r\n to <BR> before rendering + value + true + + true + + + + Converts text from \n or \r\n to <BR> before rendering + escapeHtml + false + + true + + + + + + + Help tag + Help tag + + + help + org.lamsfoundation.lams.web.tag.HelpTag + empty + + + Help tag + module + false + + true + + + + Help tag + toolSignature + false + + true + + + + Help tag + page + false + + true + + + + Help tag + style + false + + true + + + + + + + Converts role name into form usable as message commonCartridge key + Converts role name into form usable as message commonCartridge key + + + role + org.lamsfoundation.lams.web.tag.RoleTag + empty + + + Converts role name into form usable as message commonCartridge key + role + true + + true + + + + + + + Output stylesheet based on the user preferences. + User's chosen stylesheet + + + css + org.lamsfoundation.lams.web.tag.CssTag + empty + + + Output stylesheet based on the user preferences. + localLinkPath + false + + true + + + + Output stylesheet based on the user preferences. + style + false + + true + + + + + + + Output details from the shared session UserDTO object + user details + + + user + org.lamsfoundation.lams.web.tag.UserTag + empty + + + Output details from the shared session UserDTO object + property + true + + true + + + + + + + STRUTS-textarea + org.lamsfoundation.lams.web.tag.MultiLinesTextareaTag + empty + + accesskey + false + true + + + alt + false + true + + + altKey + false + true + + + bundle + false + true + + + cols + false + true + + + disabled + false + true + + + errorKey + false + true + + + errorStyle + false + true + + + errorStyleClass + false + true + + + errorStyleId + false + true + + + index + false + true + + + indexed + false + true + + + name + false + true + + + onblur + false + true + + + onchange + false + true + + + onclick + false + true + + + ondblclick + false + true + + + onfocus + false + true + + + onkeydown + false + true + + + onkeypress + false + true + + + onkeyup + false + true + + + onmousedown + false + true + + + onmousemove + false + true + + + onmouseout + false + true + + + onmouseover + false + true + + + onmouseup + false + true + + + property + true + true + + + readonly + false + true + + + rows + false + true + + + style + false + true + + + styleClass + false + true + + + styleId + false + true + + + tabindex + false + true + + + title + false + true + + + titleKey + false + true + + + value + false + true + + + + Tab + /WEB-INF/tags/Tab.tag + + + Tabs + /WEB-INF/tags/Tabs.tag + + + TabBody + /WEB-INF/tags/TabBody.tag + + + TabName + /WEB-INF/tags/TabName.tag + + + FCKEditor + /WEB-INF/tags/FCKEditor.tag + + + AuthoringButton + /WEB-INF/tags/AuthoringButton.tag + + + headItems + /WEB-INF/tags/headItems.tag + + + Passon + /WEB-INF/tags/Passon.tag + + + ExportPortOutput + /WEB-INF/tags/ExportPortOutput.tag + + + Date + /WEB-INF/tags/Date.tag + + + DefineLater + /WEB-INF/tags/DefineLater.tag + + + ImgButtonWrapper + /WEB-INF/tags/ImgButtonWrapper.tag + + + textarea + org.lamsfoundation.lams.web.tag.LAMSMultiLinesTextareaTag + JSP + true + + Render text exactly same as original input, which even won't escape the input HTML tag. + + + + + name + true + true + + + + + id + false + true + + + + + onchange + false + true + + + + head + /WEB-INF/tags/Head.tag + + + ProgressOutput + /WEB-INF/tags/ProgressOutput.tag + + + LearnerFlashEnabled + /WEB-INF/tags/LearnerFlashEnabled.tag + + + Index: lams_tool_imscc/web/WEB-INF/tlds/struts/struts-bean.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/struts/struts-bean.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/struts/struts-bean.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,382 @@ + + + + + + + + + + +1.2 +1.1 +bean +http://struts.apache.org/tags-bean + +cookie +org.apache.struts.taglib.bean.CookieTag +org.apache.struts.taglib.bean.CookieTei +empty + +id +true +false + + +multiple +false +true + + +name +true +true + + +value +false +true + + + +define +org.apache.struts.taglib.bean.DefineTag +org.apache.struts.taglib.bean.DefineTei +JSP + +id +true +false + + +name +false +true + + +property +false +true + + +scope +false +true + + +toScope +false +true + + +type +false +true + + +value +false +true + + + +header +org.apache.struts.taglib.bean.HeaderTag +org.apache.struts.taglib.bean.HeaderTei +empty + +id +true +false + + +multiple +false +true + + +name +true +true + + +value +false +true + + + +include +org.apache.struts.taglib.bean.IncludeTag +org.apache.struts.taglib.bean.IncludeTei +empty + +anchor +false +true + + +forward +false +true + + +href +false +true + + +id +true +false + + +name +false +true + + +page +false +true + + +transaction +false +true + + + +message +org.apache.struts.taglib.bean.MessageTag +empty + +arg0 +false +true + + +arg1 +false +true + + +arg2 +false +true + + +arg3 +false +true + + +arg4 +false +true + + +bundle +false +true + + +key +false +true + + +locale +false +true + + +name +false +true + + +property +false +true + + +scope +false +true + + + +page +org.apache.struts.taglib.bean.PageTag +org.apache.struts.taglib.bean.PageTei +empty + +id +true +false + + +property +true +true + + + +parameter +org.apache.struts.taglib.bean.ParameterTag +org.apache.struts.taglib.bean.ParameterTei +empty + +id +true +false + + +multiple +false +true + + +name +true +true + + +value +false +true + + + +resource +org.apache.struts.taglib.bean.ResourceTag +org.apache.struts.taglib.bean.ResourceTei +empty + +id +true +false + + +input +false +true + + +name +true +true + + + +size +org.apache.struts.taglib.bean.SizeTag +org.apache.struts.taglib.bean.SizeTei +empty + +collection +false +true + + +id +true +false + + +name +false +true + + +property +false +true + + +scope +false +true + + + +struts +org.apache.struts.taglib.bean.StrutsTag +org.apache.struts.taglib.bean.StrutsTei +empty + +id +true +false + + +formBean +false +true + + +forward +false +true + + +mapping +false +true + + + +write +org.apache.struts.taglib.bean.WriteTag +empty + +bundle +false +true + + +filter +false +true + + +format +false +true + + +formatKey +false +true + + +ignore +false +true + + +locale +false +true + + +name +true +true + + +property +false +true + + +scope +false +true + + + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/struts/struts-html.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/struts/struts-html.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/struts/struts-html.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,3302 @@ + + + + + + + + + + +1.2 +1.1 +html +http://struts.apache.org/tags-html + +base +org.apache.struts.taglib.html.BaseTag +empty + +target +false +true + + +server +false +true + + + +button +org.apache.struts.taglib.html.ButtonTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +cancel +org.apache.struts.taglib.html.CancelTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +checkbox +org.apache.struts.taglib.html.CheckboxTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +errors +org.apache.struts.taglib.html.ErrorsTag +empty + +bundle +false +true + + +footer +false +true + + +header +false +true + + +locale +false +true + + +name +false +true + + +prefix +false +true + + +property +false +true + + +suffix +false +true + + + +file +org.apache.struts.taglib.html.FileTag + +accesskey +false +true + + +accept +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +size +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +form +org.apache.struts.taglib.html.FormTag +JSP + +action +true +true + + +acceptCharset +false +true + + +disabled +false +true + + +enctype +false +true + + +focus +false +true + + +focusIndex +false +true + + +method +false +true + + +onreset +false +true + + +onsubmit +false +true + + +readonly +false +true + + +scriptLanguage +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +target +false +true + + + +frame +org.apache.struts.taglib.html.FrameTag + +bundle +false +true + + +action +false +true + + +module +false +true + + +anchor +false +true + + +forward +false +true + + +frameborder +false +true + + +frameName +false +true + + +href +false +true + + +longdesc +false +true + + +marginheight +false +true + + +marginwidth +false +true + + +name +false +true + + +noresize +false +true + + +page +false +true + + +paramId +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +scrolling +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +title +false +true + + +titleKey +false +true + + +transaction +false +true + + + +hidden +org.apache.struts.taglib.html.HiddenTag +empty + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + +write +false +true + + + +html +org.apache.struts.taglib.html.HtmlTag +JSP + +lang +false +true + + +locale +false +true + + +xhtml +false +true + + + +image +org.apache.struts.taglib.html.ImageTag + +accesskey +false +true + + +align +false +true + + +alt +false +true + + +altKey +false +true + + +border +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +locale +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +page +false +true + + +pageKey +false +true + + +property +false +true + + +src +false +true + + +srcKey +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +img +org.apache.struts.taglib.html.ImgTag +empty + +align +false +true + + +alt +false +true + + +altKey +false +true + + +border +false +true + + +bundle +false +true + + +contextRelative +false +true + + +height +false +true + + +hspace +false +true + + +imageName +false +true + + +ismap +false +true + + +locale +false +true + + +lowsrc +false +true + + +name +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +paramId +false +true + + +page +false +true + + +pageKey +false +true + + +action +false +true + + +module +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +src +false +true + + +srcKey +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +title +false +true + + +titleKey +false +true + + +useLocalEncoding +false +true + + +usemap +false +true + + +vspace +false +true + + +width +false +true + + + +javascript +org.apache.struts.taglib.html.JavascriptValidatorTag +empty + +cdata +false +true + + +dynamicJavascript +false +false + + +formName +false +true + + +method +false +true + + +page +false +true + + +scriptLanguage +false +true + + +src +false +true + + +staticJavascript +false +false + + +htmlComment +false +true + + +bundle +false +true + + + +link +org.apache.struts.taglib.html.LinkTag + +accesskey +false +true + + +action +false +true + + +module +false +true + + +anchor +false +true + + +forward +false +true + + +href +false +true + + +indexed +false +true + + +indexId +false +true + + +bundle +false +true + + +linkName +false +true + + +name +false +true + + +onblur +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +page +false +true + + +paramId +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +target +false +true + + +title +false +true + + +titleKey +false +true + + +transaction +false +true + + +useLocalEncoding +false +true + + + +messages +org.apache.struts.taglib.html.MessagesTag +org.apache.struts.taglib.html.MessagesTei +JSP + +id +true +false + + +bundle +false +true + + +locale +false +true + + +name +false +true + + +property +false +true + + +header +false +true + + +footer +false +true + + +message +false +true + + + +multibox +org.apache.struts.taglib.html.MultiboxTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +option +org.apache.struts.taglib.html.OptionTag + +bundle +false +true + + +disabled +false +true + + +key +false +true + + +locale +false +true + + +style +false +true + + +styleId +false +true + + +styleClass +false +true + + +value +true +true + + + +options +org.apache.struts.taglib.html.OptionsTag +empty + +collection +false +true + + +filter +false +true + + +labelName +false +true + + +labelProperty +false +true + + +name +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + + +optionsCollection +org.apache.struts.taglib.html.OptionsCollectionTag +empty + +filter +false +true + + +label +false +true + + +name +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + +value +false +true + + + +password +org.apache.struts.taglib.html.PasswordTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +redisplay +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +size +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +radio +org.apache.struts.taglib.html.RadioTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +property +true +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +true +true + + +idName +false +true + + + +reset +org.apache.struts.taglib.html.ResetTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +rewrite +org.apache.struts.taglib.html.RewriteTag +empty + +action +false +true + + +module +false +true + + +anchor +false +true + + +forward +false +true + + +href +false +true + + +name +false +true + + +page +false +true + + +paramId +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +transaction +false +true + + +useLocalEncoding +false +true + + + +select +org.apache.struts.taglib.html.SelectTag +JSP + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +multiple +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +size +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +submit +org.apache.struts.taglib.html.SubmitTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +text +org.apache.struts.taglib.html.TextTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +size +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +textarea +org.apache.struts.taglib.html.TextareaTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +cols +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +rows +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +xhtml +org.apache.struts.taglib.html.XhtmlTag +empty + + + Index: lams_tool_imscc/web/WEB-INF/tlds/struts/struts-logic.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/struts/struts-logic.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/struts/struts-logic.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,652 @@ + + + + + + + + + +1.2 +1.1 +logic +http://struts.apache.org/tags-logic + +empty +org.apache.struts.taglib.logic.EmptyTag +JSP + +name +false +true + + +property +false +true + + +scope +false +true + + + +equal +org.apache.struts.taglib.logic.EqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +forward +org.apache.struts.taglib.logic.ForwardTag +empty + +name +true +true + + + +greaterEqual +org.apache.struts.taglib.logic.GreaterEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +greaterThan +org.apache.struts.taglib.logic.GreaterThanTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +iterate +org.apache.struts.taglib.logic.IterateTag +org.apache.struts.taglib.logic.IterateTei +JSP + +collection +false +true + + +id +true +false + + +indexId +false +false + + +length +false +true + + +name +false +true + + +offset +false +true + + +property +false +true + + +scope +false +true + + +type +false +true + + + +lessEqual +org.apache.struts.taglib.logic.LessEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +lessThan +org.apache.struts.taglib.logic.LessThanTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +match +org.apache.struts.taglib.logic.MatchTag +JSP + +cookie +false +true + + +header +false +true + + +location +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +messagesNotPresent +org.apache.struts.taglib.logic.MessagesNotPresentTag +JSP + +name +false +true + + +property +false +true + + +message +false +true + + + +messagesPresent +org.apache.struts.taglib.logic.MessagesPresentTag +JSP + +name +false +true + + +property +false +true + + +message +false +true + + + +notEmpty +org.apache.struts.taglib.logic.NotEmptyTag +JSP + +name +false +true + + +property +false +true + + +scope +false +true + + + +notEqual +org.apache.struts.taglib.logic.NotEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +notMatch +org.apache.struts.taglib.logic.NotMatchTag +JSP + +cookie +false +true + + +header +false +true + + +location +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +notPresent +org.apache.struts.taglib.logic.NotPresentTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +role +false +true + + +scope +false +true + + +user +false +true + + + +present +org.apache.struts.taglib.logic.PresentTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +role +false +true + + +scope +false +true + + +user +false +true + + + +redirect +org.apache.struts.taglib.logic.RedirectTag + +action +false +true + + +anchor +false +true + + +forward +false +true + + +href +false +true + + +name +false +true + + +page +false +true + + +paramId +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +transaction +false +true + + +useLocalEncoding +false +true + + + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/struts/struts-nested.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/struts/struts-nested.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/struts/struts-nested.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,3171 @@ + + + + + + + + + +1.2 +1.1 +nested +http://struts.apache.org/tags-nested + +nest +org.apache.struts.taglib.nested.NestedPropertyTag +JSP + +property +false +true + + + +writeNesting +org.apache.struts.taglib.nested.NestedWriteNestingTag +org.apache.struts.taglib.nested.NestedWriteNestingTei +JSP + +property +false +true + + +id +false +true + + +filter +false +true + + + +root +org.apache.struts.taglib.nested.NestedRootTag +JSP + +name +false +true + + + +define +org.apache.struts.taglib.nested.bean.NestedDefineTag +org.apache.struts.taglib.nested.bean.NestedDefineTei +empty + +id +true +true + + +name +false +true + + +property +false +true + + +scope +false +true + + +toScope +false +true + + +type +false +true + + +value +false +true + + + +message +org.apache.struts.taglib.nested.bean.NestedMessageTag +empty + +arg0 +false +true + + +arg1 +false +true + + +arg2 +false +true + + +arg3 +false +true + + +arg4 +false +true + + +bundle +false +true + + +key +false +true + + +locale +false +true + + +name +false +true + + +property +false +true + + +scope +false +true + + + +size +org.apache.struts.taglib.nested.bean.NestedSizeTag +org.apache.struts.taglib.bean.SizeTei +empty + +collection +false +true + + +id +true +true + + +name +false +true + + +property +false +true + + +scope +false +true + + + +write +org.apache.struts.taglib.nested.bean.NestedWriteTag +empty + +bundle +false +true + + +filter +false +true + + +format +false +true + + +formatKey +false +true + + +ignore +false +true + + +locale +false +true + + +name +false +true + + +property +false +true + + +scope +false +true + + + +checkbox +org.apache.struts.taglib.nested.html.NestedCheckboxTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +errors +org.apache.struts.taglib.nested.html.NestedErrorsTag +empty + +bundle +false +true + + +footer +false +true + + +header +false +true + + +locale +false +true + + +name +false +true + + +prefix +false +true + + +property +false +true + + +suffix +false +true + + + +file +org.apache.struts.taglib.nested.html.NestedFileTag + +accesskey +false +true + + +accept +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +size +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +form +org.apache.struts.taglib.nested.html.NestedFormTag +JSP + +action +true +true + + +acceptCharset +false +true + + +disabled +false +true + + +enctype +false +true + + +focus +false +true + + +focusIndex +false +true + + +method +false +true + + +onreset +false +true + + +onsubmit +false +true + + +readonly +false +true + + +scriptLanguage +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +target +false +true + + + +hidden +org.apache.struts.taglib.nested.html.NestedHiddenTag + +alt +false +true + + +altKey +false +true + + +indexed +false +true + + +name +false +true + + +property +true +true + + +title +false +true + + +titleKey +false +true + + +styleClass +false +true + + +styleId +false +true + + +value +false +true + + +write +false +true + + + +image +org.apache.struts.taglib.nested.html.NestedImageTag + +accesskey +false +true + + +align +false +true + + +alt +false +true + + +altKey +false +true + + +border +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +locale +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +page +false +true + + +pageKey +false +true + + +property +false +true + + +src +false +true + + +srcKey +false +true + + +style +false +true + + +styleClass +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +img +org.apache.struts.taglib.nested.html.NestedImgTag +empty + +accesskey +false +true + + +align +false +true + + +alt +false +true + + +altKey +false +true + + +border +false +true + + +bundle +false +true + + +height +false +true + + +hspace +false +true + + +imageName +false +true + + +ismap +false +true + + +locale +false +true + + +lowsrc +false +true + + +name +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +paramId +false +true + + +page +false +true + + +pageKey +false +true + + +action +false +true + + +module +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +src +false +true + + +srcKey +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +title +false +true + + +titleKey +false +true + + +useLocalEncoding +false +true + + +usemap +false +true + + +vspace +false +true + + +width +false +true + + + +link +org.apache.struts.taglib.nested.html.NestedLinkTag + +accesskey +false +true + + +action +false +true + + +module +false +true + + +anchor +false +true + + +forward +false +true + + +href +false +true + + +indexed +false +true + + +indexId +false +true + + +bundle +false +true + + +linkName +false +true + + +name +false +true + + +onblur +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +page +false +true + + +paramId +false +true + + +paramName +false +true + + +paramProperty +false +true + + +paramScope +false +true + + +property +false +true + + +scope +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +target +false +true + + +title +false +true + + +titleKey +false +true + + +transaction +false +true + + +useLocalEncoding +false +true + + + +messages +org.apache.struts.taglib.nested.html.NestedMessagesTag +org.apache.struts.taglib.html.MessagesTei +JSP + +id +true +true + + +bundle +false +true + + +locale +false +true + + +name +false +true + + +property +false +true + + +header +false +true + + +footer +false +true + + +message +false +true + + + +multibox +org.apache.struts.taglib.nested.html.NestedMultiboxTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +options +org.apache.struts.taglib.nested.html.NestedOptionsTag +empty + +collection +false +true + + +filter +false +true + + +labelName +false +true + + +labelProperty +false +true + + +name +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + + +optionsCollection +org.apache.struts.taglib.nested.html.NestedOptionsCollectionTag +empty + +filter +false +true + + +label +false +true + + +name +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +value +false +true + + + +password +org.apache.struts.taglib.nested.html.NestedPasswordTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +redisplay +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +size +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +radio +org.apache.struts.taglib.nested.html.NestedRadioTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +property +true +true + + +onmousedown +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +true +true + + +idName +false +true + + + +select +org.apache.struts.taglib.nested.html.NestedSelectTag +JSP + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +multiple +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +size +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +submit +org.apache.struts.taglib.nested.html.NestedSubmitTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +indexed +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +text +org.apache.struts.taglib.nested.html.NestedTextTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +maxlength +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +size +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +textarea +org.apache.struts.taglib.nested.html.NestedTextareaTag + +accesskey +false +true + + +alt +false +true + + +altKey +false +true + + +bundle +false +true + + +cols +false +true + + +disabled +false +true + + +errorKey +false +true + + +errorStyle +false +true + + +errorStyleClass +false +true + + +errorStyleId +false +true + + +indexed +false +true + + +name +false +true + + +onblur +false +true + + +onchange +false +true + + +onclick +false +true + + +ondblclick +false +true + + +onfocus +false +true + + +onkeydown +false +true + + +onkeypress +false +true + + +onkeyup +false +true + + +onmousedown +false +true + + +onmousemove +false +true + + +onmouseout +false +true + + +onmouseover +false +true + + +onmouseup +false +true + + +property +true +true + + +readonly +false +true + + +rows +false +true + + +style +false +true + + +styleClass +false +true + + +styleId +false +true + + +tabindex +false +true + + +title +false +true + + +titleKey +false +true + + +value +false +true + + + +empty +org.apache.struts.taglib.nested.logic.NestedEmptyTag +JSP + +name +false +true + + +property +false +true + + +scope +false +true + + + +equal +org.apache.struts.taglib.nested.logic.NestedEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +greaterEqual +org.apache.struts.taglib.nested.logic.NestedGreaterEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +greaterThan +org.apache.struts.taglib.nested.logic.NestedGreaterThanTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +iterate +org.apache.struts.taglib.nested.logic.NestedIterateTag +org.apache.struts.taglib.nested.logic.NestedIterateTei +JSP + +collection +false +true + + +id +false +true + + +indexId +false +true + + +length +false +true + + +name +false +true + + +offset +false +true + + +property +false +true + + +scope +false +true + + +type +false +true + + + +lessEqual +org.apache.struts.taglib.nested.logic.NestedLessEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +lessThan +org.apache.struts.taglib.nested.logic.NestedLessThanTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +match +org.apache.struts.taglib.nested.logic.NestedMatchTag +JSP + +cookie +false +true + + +header +false +true + + +location +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +messagesNotPresent +org.apache.struts.taglib.nested.logic.NestedMessagesNotPresentTag +JSP + +name +false +true + + +property +false +true + + +message +false +true + + + +messagesPresent +org.apache.struts.taglib.nested.logic.NestedMessagesPresentTag +JSP + +name +false +true + + +property +false +true + + +message +false +true + + + +notEmpty +org.apache.struts.taglib.nested.logic.NestedNotEmptyTag +JSP + +name +false +true + + +property +false +true + + +scope +false +true + + + +notEqual +org.apache.struts.taglib.nested.logic.NestedNotEqualTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +notMatch +org.apache.struts.taglib.nested.logic.NestedNotMatchTag +JSP + +cookie +false +true + + +header +false +true + + +location +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +scope +false +true + + +value +true +true + + + +notPresent +org.apache.struts.taglib.nested.logic.NestedNotPresentTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +role +false +true + + +scope +false +true + + +user +false +true + + + +present +org.apache.struts.taglib.nested.logic.NestedPresentTag +JSP + +cookie +false +true + + +header +false +true + + +name +false +true + + +parameter +false +true + + +property +false +true + + +role +false +true + + +scope +false +true + + +user +false +true + + + + + + Index: lams_tool_imscc/web/WEB-INF/tlds/struts/struts-tiles.tld =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/tlds/struts/struts-tiles.tld (revision 0) +++ lams_tool_imscc/web/WEB-INF/tlds/struts/struts-tiles.tld (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,344 @@ + + + + + + + + + + +1.2 +1.1 +tiles +http://struts.apache.org/tags-tiles + +insert +org.apache.struts.taglib.tiles.InsertTag +JSP + +template +false +true + + +component +false +true + + +page +false +true + + +definition +false +true + + +attribute +false +false + + +name +false +true + + +beanName +false +true + + +beanProperty +false +true + + +beanScope +false +false + + +flush +false +false + + +ignore +false +true + + +role +false +true + + +controllerUrl +false +true + + +controllerClass +false +true + + + +definition +org.apache.struts.taglib.tiles.DefinitionTag +JSP + +id +true +false + + +scope +false +false + + +template +false +true + + +page +false +true + + +role +false +true + + +extends +false +true + + + +put +org.apache.struts.taglib.tiles.PutTag +JSP + +name +false +false + + +value +false +true + + +content +false +true + + +direct +false +false + + +type +false +false + + +beanName +false +true + + +beanProperty +false +true + + +beanScope +false +false + + +role +false +true + + + +putList +org.apache.struts.taglib.tiles.PutListTag +JSP + +name +true +false + + + +add +org.apache.struts.taglib.tiles.AddTag +JSP + +value +false +false + + +content +false +true + + +direct +false +false + + +type +false +false + + +beanName +false +true + + +beanProperty +false +true + + +beanScope +false +false + + +role +false +true + + + +get +org.apache.struts.taglib.tiles.GetTag +empty + +name +true +true + + +ignore +false +true + + +flush +false +false + + +role +false +true + + + +getAsString +org.apache.struts.taglib.tiles.GetAttributeTag +empty + +name +true +true + + +ignore +false +true + + +role +false +true + + + +useAttribute +org.apache.struts.taglib.tiles.UseAttributeTag +org.apache.struts.taglib.tiles.UseAttributeTei +empty + +id +false +false + + +classname +false +false + + +scope +false +false + + +name +true +true + + +ignore +false +true + + + +importAttribute +org.apache.struts.taglib.tiles.ImportAttributeTag +empty + +name +false +true + + +scope +false +false + + +ignore +false +true + + + +initComponentDefinitions +org.apache.struts.taglib.tiles.InitDefinitionsTag +empty + +file +true +false + + +classname +false +false + + + + + + Index: lams_tool_imscc/web/WEB-INF/web.xml =================================================================== diff -u --- lams_tool_imscc/web/WEB-INF/web.xml (revision 0) +++ lams_tool_imscc/web/WEB-INF/web.xml (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,368 @@ + + + + Shared CommonCartridge + + Shared CommonCartridge tool + + + javax.servlet.jsp.jstl.fmt.localizationContext + org.lamsfoundation.lams.tool.commonCartridge.ApplicationResources + + + contextConfigLocation + classpath:/org/lamsfoundation/lams/tool/commonCartridge/dbupdates/autopatchContext.xml + + + locatorFactorySelector + classpath*:/org/lamsfoundation/lams/**/beanRefContext.xml + + + parentContextKey + context.central + + + + + org.springframework.web.context.ContextLoaderListener + + + + + + org.lamsfoundation.lams.web.session.SetMaxTimeoutListener + + + + + hibernateFilter + + org.springframework.orm.hibernate3.support.OpenSessionInViewFilter + + + sessionFactoryBeanName + coreSessionFactory + + + + + SystemSessionFilter + + org.lamsfoundation.lams.web.session.SystemSessionFilter + + + + LocaleFilter + + org.lamsfoundation.lams.web.filter.LocaleFilter + + + encoding + UTF-8 + + + + + hibernateFilter + /* + + + SystemSessionFilter + /* + + + LocaleFilter + /* + + + + + + exportPortfolio + org.lamsfoundation.lams.tool.commonCartridge.web.servlet.ExportServlet + + + + completeItem + org.lamsfoundation.lams.tool.commonCartridge.web.servlet.CompleteItemServlet + + + + action + org.apache.struts.action.ActionServlet + + config + /WEB-INF/struts-config.xml + + + debug + 999 + + + detail + 1 + + + validate + true + + 2 + + + + Connector + net.fckeditor.connector.ConnectorServlet + + baseDir + /UserFiles/ + + + debug + false + + 1 + + + + + Instructions Download + Instructions Download + download + org.lamsfoundation.lams.contentrepository.client.ToolDownload + + toolContentHandlerBeanName + commonCartridgeToolContentHandler + + 3 + + + + action + *.do + + + + Connector + /editor/filemanager/browser/default/connectors/jsp/connector + + + + download + /download/* + + + + exportPortfolio + /exportPortfolio + + + + completeItem + /learning/completeItem + + + + + + + + tags-bean + /WEB-INF/tlds/struts/struts-bean.tld + + + tags-html + /WEB-INF/tlds/struts/struts-html.tld + + + tags-logic + /WEB-INF/tlds/struts/struts-logic.tld + + + tags-tiles + /WEB-INF/tlds/struts/struts-tiles.tld + + + + + + tags-fmt + /WEB-INF/tlds/jstl/fmt.tld + + + tags-core + /WEB-INF/tlds/jstl/c.tld + + + tags-function + /WEB-INF/tlds/jstl/fn.tld + + + tags-xml + /WEB-INF/tlds/jstl/x.tld + + + + + + fck-editor + /WEB-INF/tlds/fckeditor/FCKeditor.tld + + + + + + tags-lams + /WEB-INF/tlds/lams/lams.tld + + + + + + + + Secure Content + /* + + + LEARNER + TEACHER + MONITOR + AUTHOR + ADMIN + SYSADMIN + AUTHOR ADMIN + + + + + + Authoring Update + /authoring/* + + + AUTHOR + AUTHOR ADMIN + SYSADMIN + + + + + Staff Content + /monitoring.do + + + MONITOR + TEACHER + + + + + Staff Content + /definelater.do + + + MONITOR + TEACHER + + + + + + Adminstrator Content + /admin.do + + + ADMIN + + + + + LAMS System Adminstrator Content + /sysadmin.do + + + SYSADMIN + + + + + + Download Files + /download/ + + + LEARNER + AUTHOR + MONITOR + TEACHER + ADMIN + SYSADMIN + AUTHOR ADMIN + + + + + + + + Student + LEARNER + + + Student + TEACHER + + + + Can create/modify a learning design + AUTHOR + + + + Can running and monitoring a learning session + MONITOR + + + + Can add/remove users to the system, set up classes of users for sessions + ADMIN + + + + Can add/remove users to the system, set up classes of users for sessions + SYSADMIN + + + + Can create/modify a learning design and edit default tool content + AUTHOR ADMIN + + + + + FORM + LAMS + + /login.jsp + /login.jsp?failed=y + + + + + 500 + /error.jsp + + + 403 + /403.jsp + + + 404 + /404.jsp + + + Index: lams_tool_imscc/web/common/fckeditorheader.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/fckeditorheader.jsp (revision 0) +++ lams_tool_imscc/web/common/fckeditorheader.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,5 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + Index: lams_tool_imscc/web/common/footer.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/footer.jsp (revision 0) +++ lams_tool_imscc/web/common/footer.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ +
    Index: lams_tool_imscc/web/common/header.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/header.jsp (revision 0) +++ lams_tool_imscc/web/common/header.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,18 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/common/messages.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/messages.jsp (revision 0) +++ lams_tool_imscc/web/common/messages.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,8 @@ +<%-- Error Messages --%> + +

    + +
    +
    +

    +
    Index: lams_tool_imscc/web/common/tabbedheader.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/tabbedheader.jsp (revision 0) +++ lams_tool_imscc/web/common/tabbedheader.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,17 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/common/taglibs.jsp =================================================================== diff -u --- lams_tool_imscc/web/common/taglibs.jsp (revision 0) +++ lams_tool_imscc/web/common/taglibs.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,12 @@ +<%@ page language="java" errorPage="/error.jsp" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> +<%@ taglib uri="tags-tiles" prefix="tiles" %> +<%@ taglib uri="tags-bean" prefix="bean" %> +<%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="tags-logic" prefix="logic" %> +<%@ taglib uri="tags-function" prefix="fn" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-fmt" prefix="fmt" %> +<%@ taglib uri="tags-xml" prefix="x" %> +<%@ taglib uri="tags-lams" prefix="lams" %> +<%@ taglib uri="fck-editor" prefix="FCK"%> + Index: lams_tool_imscc/web/error.jsp =================================================================== diff -u --- lams_tool_imscc/web/error.jsp (revision 0) +++ lams_tool_imscc/web/error.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,69 @@ + + +<%@ page language="java" isErrorPage="true" pageEncoding="UTF-8" contentType="text/html;charset=utf-8"%> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-core" prefix="c"%> +<%@ taglib uri="tags-fmt" prefix="fmt"%> + + + + +<%-- Catch JSP Servlet Exception --%> +<% +if (exception != null) { +%> + + <%=exception.getMessage()%> + + + <%=exception.getClass().getName()%> + +<% + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + java.io.PrintStream os = new java.io.PrintStream(bos); + exception.printStackTrace(os); + String stack = new String(bos.toByteArray()); +%> + + <%=stack%> + +<% +} else if ((Exception) request.getAttribute("javax.servlet.error.exception") != null) { +%> + + + <%=((Exception) request.getAttribute("javax.servlet.error.exception")).getMessage()%> + + + <%=((Exception) request.getAttribute("javax.servlet.error.exception")).getMessage() + .getClass().getName()%> + +<% + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + java.io.PrintStream os = new java.io.PrintStream(bos); + ((Exception) request.getAttribute("javax.servlet.error.exception")).printStackTrace(os); + String stack = new String(bos.toByteArray()); +%> + + <%=stack%> + +<% +} +%> + +
    + + + +
    + + + + Index: lams_tool_imscc/web/images/icon_commonCartridge.swf =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/css/commonCartridge.css =================================================================== diff -u --- lams_tool_imscc/web/includes/css/commonCartridge.css (revision 0) +++ lams_tool_imscc/web/includes/css/commonCartridge.css (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,33 @@ +.innerforms { + border: 0px; + font-size: small; + font-style: normal; + width:100%; +} + +div.error, div.message { + background-color: #ffffcc; + border: 1px solid #000; + color: #000000; + font-family: Arial, Helvetica, sans-serif; + font-weight: normal; + margin: 10px auto; + padding: 3px; + text-align: left; + vertical-align: bottom; +} + +/* use a different color for the errors */ +div.error { + border: 2px solid red; +} + +img.validationWarning, div.errors img.icon, div.messages img.icon { + border: 0; + width: 14px; + height: 13px; + vertical-align: top; +} +div.message img.icon { + vertical-align: middle; +} Index: lams_tool_imscc/web/includes/images/.cvsignore =================================================================== diff -u --- lams_tool_imscc/web/includes/images/.cvsignore (revision 0) +++ lams_tool_imscc/web/includes/images/.cvsignore (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ +Thumbs.db Index: lams_tool_imscc/web/includes/images/cross.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/downarrow.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/downarrow_disabled.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/edit.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/indicator.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/spacer.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/tick.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/uparrow.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/images/uparrow_disabled.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/includes/javascript/commonCartridgeItem.js =================================================================== diff -u --- lams_tool_imscc/web/includes/javascript/commonCartridgeItem.js (revision 0) +++ lams_tool_imscc/web/includes/javascript/commonCartridgeItem.js (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,86 @@ + /* + This is CommonCartridge Item instrcution area. + */ + var instructionTargetDiv = "instructionArea"; + var itemAttachmentTargetDiv = "itemAttachmentArea"; + var singleInstructionHeight = 40; + + function removeInstruction(idx){ + var param = $("#instructionForm").serialize() + "&removeIdx="+idx; + removeInstructionLoading(); + $.post(removeInstructionUrl, param, function(xml) { + removeInstructionComplete(); + document.getElementById("instructionArea").innerHTML = xml; + }); + } + function removeItemAttachment(idx){ + removeItemAttachmentLoading(); + $("#" + itemAttachmentTargetDiv).load( + removeItemAttachmentUrl, + { + reqID: new Date() + } + ); + } + function addInstruction(){ + var param = $("#instructionForm").serialize(); + addInstructionLoading(); + $.post(addInstructionUrl, param, function(xml) { + addInstructionComplete(); + document.getElementById("instructionArea").innerHTML = xml; + }); + return false; + + } + function adjustInstructionsDisplayAreaHeight(adjustAmount){ + var obj = window.top.document.getElementById('reourceInputArea'); + obj.style.height=obj.contentWindow.document.body.scrollHeight+adjustAmount+'px'; + } + function upItem(itemIdx){ + if(itemIdx == 0) + return; + var currId = "instructionItemDesc" + itemIdx; + var repId = "instructionItemDesc" + (--itemIdx); + switchValue(currId,repId); + } + function downItem(itemIdx,maxSize){ + if(itemIdx == (maxSize -1)) + return; + var currId = "instructionItemDesc" + itemIdx; + var repId = "instructionItemDesc" + (++itemIdx); + switchValue(currId,repId); + } + function switchValue(currId,repId){ + var temp = document.getElementById(repId).value; + document.getElementById(repId).value = document.getElementById(currId).value; + document.getElementById(currId).value = temp; + } + function removeInstructionLoading(){ + showBusy(instructionTargetDiv); + } + function removeInstructionComplete(){ + hideBusy(instructionTargetDiv); + adjustInstructionsDisplayAreaHeight(-singleInstructionHeight); + } + function removeItemAttachmentLoading(){ + showBusy(itemAttachmentTargetDiv); + } + function removeItemAttachmentComplete(){ + hideBusy(itemAttachmentTargetDiv); + } + function addInstructionLoading(){ + showBusy(instructionTargetDiv); + } + function addInstructionComplete(){ + hideBusy(instructionTargetDiv); + adjustInstructionsDisplayAreaHeight(singleInstructionHeight); + } + + function submitCommonCartridgeItem(){ + $("#commonCartridgeItemForm").submit(); + // after submit, it direct to itemlist.jsp, + // then refresh "basic tab" commonCartridgelist and close this window. + } + function cancelCommonCartridgeItem(){ + window.top.hideMessage(); + } Index: lams_tool_imscc/web/includes/javascript/commonCartridgecommon.js =================================================================== diff -u --- lams_tool_imscc/web/includes/javascript/commonCartridgecommon.js (revision 0) +++ lams_tool_imscc/web/includes/javascript/commonCartridgecommon.js (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,10 @@ + function showBusy(targetDiv){ + if($(targetDiv+"_Busy") != null){ + document.getElementById(targetDiv+"_Busy").style.display = ''; + } + } + function hideBusy(targetDiv){ + if($(targetDiv+"_Busy") != null){ + document.getElementById(targetDiv+"_Busy").style.display = 'none'; + } + } Index: lams_tool_imscc/web/includes/javascript/tree.js =================================================================== diff -u --- lams_tool_imscc/web/includes/javascript/tree.js (revision 0) +++ lams_tool_imscc/web/includes/javascript/tree.js (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,139 @@ +// Title: Tigra Tree +// Description: See the demo at url +// URL: http://www.softcomplex.com/products/tigra_menu_tree/ +// Version: 1.1 +// Date: 11-12-2002 (mm-dd-yyyy) +// Notes: This script is free. Visit official site for further details. + +function tree (a_items, a_template) { + + this.a_tpl = a_template; + this.a_config = a_items; + this.o_root = this; + this.a_index = []; + this.o_selected = null; + this.n_depth = -1; + + var o_icone = new Image(), + o_iconl = new Image(); + o_icone.src = a_template['icon_e']; + o_iconl.src = a_template['icon_l']; + a_template['im_e'] = o_icone; + a_template['im_l'] = o_iconl; + for (var i = 0; i < 64; i++) + if (a_template['icon_' + i]) { + var o_icon = new Image(); + a_template['im_' + i] = o_icon; + o_icon.src = a_template['icon_' + i]; + } + + this.toggle = function (n_id) { var o_item = this.a_index[n_id]; o_item.open(o_item.b_opened) }; + this.select = function (n_id) { return this.a_index[n_id].select(); }; + this.mout = function (n_id) { this.a_index[n_id].upstatus(true) }; + this.mover = function (n_id) { this.a_index[n_id].upstatus() }; + + this.a_children = []; + for (var i = 0; i < a_items.length; i++) + new tree_item(this, i); + + this.n_id = trees.length; + trees[this.n_id] = this; + + for (var i = 0; i < this.a_children.length; i++) { + document.write(this.a_children[i].init()); + this.a_children[i].open(); + } +} +function tree_item (o_parent, n_order) { + + this.n_depth = o_parent.n_depth + 1; + this.a_config = o_parent.a_config[n_order + (this.n_depth ? 2 : 0)]; + if (!this.a_config) return; + + this.o_root = o_parent.o_root; + this.o_parent = o_parent; + this.n_order = n_order; + this.b_opened = !this.n_depth; + + this.n_id = this.o_root.a_index.length; + this.o_root.a_index[this.n_id] = this; + o_parent.a_children[n_order] = this; + + this.a_children = []; + for (var i = 0; i < this.a_config.length - 2; i++) + new tree_item(this, i); + + this.get_icon = item_get_icon; + this.open = item_open; + this.select = item_select; + this.init = item_init; + this.upstatus = item_upstatus; + this.is_last = function () { return this.n_order == this.o_parent.a_children.length - 1 }; +} + +function item_open (b_close) { + var o_idiv = get_element('i_div' + this.o_root.n_id + '_' + this.n_id); + if (!o_idiv) return; + + if (!o_idiv.innerHTML) { + var a_children = []; + for (var i = 0; i < this.a_children.length; i++) + a_children[i]= this.a_children[i].init(); + o_idiv.innerHTML = a_children.join(''); + } + o_idiv.style.display = (b_close ? 'none' : 'block'); + + this.b_opened = !b_close; + var o_jicon = document.images['j_img' + this.o_root.n_id + '_' + this.n_id], + o_iicon = document.images['i_img' + this.o_root.n_id + '_' + this.n_id]; + if (o_jicon) o_jicon.src = this.get_icon(true); + if (o_iicon) o_iicon.src = this.get_icon(); + this.upstatus(); +} + +function item_select (b_deselect) { + if (!b_deselect) { + var o_olditem = this.o_root.o_selected; + this.o_root.o_selected = this; + if (o_olditem) o_olditem.select(true); + } + var o_iicon = document.images['i_img' + this.o_root.n_id + '_' + this.n_id]; + if (o_iicon) o_iicon.src = this.get_icon(); + get_element('i_txt' + this.o_root.n_id + '_' + this.n_id).style.fontWeight = b_deselect ? 'normal' : 'bold'; + + this.upstatus(); + return Boolean(this.a_config[1]); +} + +function item_upstatus (b_clear) { + window.setTimeout('window.status="' + (b_clear ? '' : this.a_config[0] + (this.a_config[1] ? ' ('+ this.a_config[1] + ')' : '')) + '"', 10); +} + +function item_init () { + var a_offset = [], + o_current_item = this.o_parent; + for (var i = this.n_depth; i > 1; i--) { + a_offset[i] = ''; + o_current_item = o_current_item.o_parent; + } + //NDPNDP: if the link href='0', then display non-link fields + return '
    ' + (this.n_depth ? a_offset.join('') + (this.a_children.length + ? '' + : '') : '') + + (this.a_config[1] == 0?'': (''))+'' + this.a_config[0] + (this.a_config[1]== 0?'':'')+'
    ' + (this.a_children.length ? '' : ''); + /** + return '
    ' + (this.n_depth ? a_offset.join('') + (this.a_children.length + ? '' + : '') : '') + + '' + this.a_config[0] + '
    ' + (this.a_children.length ? '' : ''); + **/ +} + +function item_get_icon (b_junction) { + return this.o_root.a_tpl['icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0))]; +} + +var trees = []; +get_element = document.all ? + function (s_id) { return document.all[s_id] } : + function (s_id) { return document.getElementById(s_id) }; Index: lams_tool_imscc/web/includes/javascript/tree_tpl.js =================================================================== diff -u --- lams_tool_imscc/web/includes/javascript/tree_tpl.js (revision 0) +++ lams_tool_imscc/web/includes/javascript/tree_tpl.js (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,36 @@ +/* + Feel free to use your custom icons for the tree. Make sure they are all of the same size. + User icons collections are welcome, we'll publish them giving all regards. +*/ + +var TREE_TPL = { + 'target' : 'contentFrame', // name of the frame links will be opened in + // other possible values are: _blank, _parent, _search, _self and _top + + 'icon_e' : 'icons/empty.gif', // empty image + 'icon_l' : 'icons/line.gif', // vertical line + + 'icon_32' : 'icons/base.gif', // root leaf icon normal + 'icon_36' : 'icons/base.gif', // root leaf icon selected + + 'icon_48' : 'icons/base.gif', // root icon normal + 'icon_52' : 'icons/base.gif', // root icon selected + 'icon_56' : 'icons/base.gif', // root icon opened + 'icon_60' : 'icons/base.gif', // root icon selected + + 'icon_16' : 'icons/folder.gif', // node icon normal + 'icon_20' : 'icons/folderopen.gif', // node icon selected + 'icon_24' : 'icons/folderopen.gif', // node icon opened + 'icon_28' : 'icons/folderopen.gif', // node icon selected opened + + 'icon_0' : 'icons/page.gif', // leaf icon normal + 'icon_4' : 'icons/page.gif', // leaf icon selected + + 'icon_2' : 'icons/joinbottom.gif', // junction for leaf + 'icon_3' : 'icons/join.gif', // junction for last leaf + 'icon_18' : 'icons/plusbottom.gif', // junction for closed node + 'icon_19' : 'icons/plus.gif', // junctioin for last closed node + 'icon_26' : 'icons/minusbottom.gif',// junction for opened node + 'icon_27' : 'icons/minus.gif' // junctioin for last opended node +}; + Index: lams_tool_imscc/web/layout/ frame.jsp =================================================================== diff -u --- lams_tool_imscc/web/layout/ frame.jsp (revision 0) +++ lams_tool_imscc/web/layout/ frame.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,56 @@ +<%-- +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 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 +--%> +<%@ include file="/common/taglibs.jsp" %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <body class="stripes"> + This tool requires the support of frames. Your browser does not support frames. + </body> + + + Index: lams_tool_imscc/web/layout/default.jsp =================================================================== diff -u --- lams_tool_imscc/web/layout/default.jsp (revision 0) +++ lams_tool_imscc/web/layout/default.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,20 @@ +<%@ include file="/common/taglibs.jsp"%> +<%@ taglib uri="tags-tiles" prefix="tiles"%> + + + + + + + + +

    + +

    +
    + + + + +
    Index: lams_tool_imscc/web/login.jsp =================================================================== diff -u --- lams_tool_imscc/web/login.jsp (revision 0) +++ lams_tool_imscc/web/login.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,12 @@ +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> +<%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="tags-core" prefix="c" %> + + + + Index: lams_tool_imscc/web/pages/admin/config.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/admin/config.jsp (revision 0) +++ lams_tool_imscc/web/pages/admin/config.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,63 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + + <fmt:message key="admin.page.title" /> + + + + +
    + +

    + +

    + + + +

    + + <%@ include file="/common/messages.jsp"%> + + +

    + +

    + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + +
    + +

    + + + + + + \ No newline at end of file Index: lams_tool_imscc/web/pages/authoring/advance.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/advance.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/advance.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,79 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + +

    + + + + +

    + +

    + + + +

    + +

    + + + + + + + + + + + + + + +

    + +

    + + + +

    + +

    + +

    + Index: lams_tool_imscc/web/pages/authoring/authoring.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/authoring.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/authoring.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,148 @@ + + +<%@ include file="/common/taglibs.jsp"%> +<%@ page import="org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants"%> + + + + + <fmt:message key="label.author.title" /> + + <%@ include file="/common/tabbedheader.jsp"%> + <%@ include file="/common/fckeditorheader.jsp"%> + + + + + + + +
    +

    + +

    + + +
    + + + <%@ include file="/common/messages.jsp"%> + + + + + + + + + + + + + + + + + + + + + + + + + <%-- Default value + cancelButtonLabelKey="label.authoring.cancel.button" + saveButtonLabelKey="label.authoring.save.button" + cancelConfirmMsgKey="authoring.msg.cancel.save" + accessMode="author" + --%> + + + +
    + + + +
    + + + +
    Index: lams_tool_imscc/web/pages/authoring/basic.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/basic.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/basic.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,120 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + +
    +
    + +
    + +
    +
    + +
    + +
    + +
    + + <%@ include file="/pages/authoring/parts/itemlist.jsp"%> +
    + +

    + ');"> + + ');" class="space-left"> + +

    + +

    + +

    Index: lams_tool_imscc/web/pages/authoring/definelater.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/definelater.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/definelater.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,85 @@ + + +<%@ include file="/common/taglibs.jsp"%> +<%@ page import="java.util.HashSet"%> +<%@ page import="org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants"%> +<%@ page import="java.util.Set"%> +<%Set tabs = new HashSet(); + tabs.add("label.authoring.heading.basic"); + pageContext.setAttribute("tabs", tabs); + + %> + + + <fmt:message key="label.author.title" /> + + <%@ include file="/common/tabbedheader.jsp"%> + <%@ include file="/common/fckeditorheader.jsp"%> + + + + + + + +
    + + + + + + + +

    + +

    + +
    + <%@ include file="/common/messages.jsp"%> + + +
    + + + + + + + +
    + + + + +
    + +
    + +
    Index: lams_tool_imscc/web/pages/authoring/definelaterforbid.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/definelaterforbid.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/definelaterforbid.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,21 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + <fmt:message key="label.author.title" /> + + <%@ include file="/common/header.jsp"%> + + +
    +
    +

    + +

    + + +
    +
    + +
    Index: lams_tool_imscc/web/pages/authoring/instructions.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/instructions.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/instructions.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,131 @@ +<%@ include file="/common/taglibs.jsp"%> +<%@ page + import="org.lamsfoundation.lams.contentrepository.client.IToolContentHandler"%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + +
    + <%@ include file="parts/instructionfilelist.jsp"%> +
    +
    +
    + +
    + + + + + +
    + +
    +
    +
    + +
    + +
    + +
    + <%@ include file="parts/instructionfilelist.jsp"%> +
    +
    +
    + +
    + + + + + +
    + Index: lams_tool_imscc/web/pages/authoring/parts/addbasiclti.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/parts/addbasiclti.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/parts/addbasiclti.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,93 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + <%@ include file="/common/header.jsp"%> + + + + + + + <%@ include file="/common/messages.jsp"%> + + + + + + +

    + +

    + +
    + +
    + + + + <%-- Remove description in as LDEV-617 + + + + + + + + + --%> + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + + +
    + +
    + +
    + + + +
    + +
    + +
    + +
    + + + + + + + + + +
    + +
    Index: lams_tool_imscc/web/pages/authoring/parts/addcommoncartridge.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/parts/addcommoncartridge.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/parts/addcommoncartridge.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,67 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + <%@ include file="/common/header.jsp"%> + + + + + + + + + + <%@ include file="/common/messages.jsp"%> + + + + + + +

    + +

    + +
    + +
    + + + + <%-- Remove description in as LDEV-617 + + + + + + + + + --%> + +
    + +
    + +
    + <%@ include file="/pages/authoring/parts/itemattachment.jsp"%> +
    + +
    + + + + + +
    + +
    Index: lams_tool_imscc/web/pages/authoring/parts/instructionfilelist.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/parts/instructionfilelist.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/parts/instructionfilelist.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,65 @@ +<%@ include file="/common/taglibs.jsp"%> +<%@ page + import="org.lamsfoundation.lams.contentrepository.client.IToolContentHandler"%> + + + + + + + + + + + + +<%-- check whehter has target file type --%> + + + + + + +<%-- Display target file type --%> + +
      + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + + +
    • +
      +
      +
    +
    Index: lams_tool_imscc/web/pages/authoring/parts/itemattachment.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/parts/itemattachment.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/parts/itemattachment.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,27 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + +
    + + + + + +
    +
    + + + +
    Index: lams_tool_imscc/web/pages/authoring/parts/itemlist.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/parts/itemlist.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/parts/itemlist.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,128 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + +
    +

    + + +

    + + + + + + + <%-- CommonCartridge Type:1=URL,2=File,3=Website,4=Learning Object --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + : + + ${commonCartridge.title} + + + + " + onclick="editItem(${status.index},'${sessionMapID}')" /> + + + " + onclick="deleteItem(${status.index},'${sessionMapID}')" /> + + : + ${commonCartridge.title} + + + + " + onclick="editItem(${status.index},'${sessionMapID}')" /> + + + " + onclick="deleteItem(${status.index},'${sessionMapID}')" /> + + : + ${commonCartridge.title} + + + + " + onclick="editItem(${status.index},'${sessionMapID}')" /> + + " + onclick="deleteItem(${status.index},'${sessionMapID}')" /> + + : + ${commonCartridge.title} + + + + " + onclick="editItem(${status.index},'${sessionMapID}')" /> + + " + onclick="deleteItem(${status.index},'${sessionMapID}')" /> +
    +
    + +<%-- This script will works when a new resoruce item submit in order to refresh "CommonCartridge List" panel. --%> + Index: lams_tool_imscc/web/pages/authoring/pedagogicalPlannerForm.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/pedagogicalPlannerForm.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/pedagogicalPlannerForm.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,131 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + <%@ include file="/common/messages.jsp"%> + + + + + + + +

    + + + + +

    + + + + + + + +
    + + + + + + +

    + + + +

    + +
    + + +

    + : ${itemFileName} +

    + +
    +
    +
    + " + onclick="javascript:clearEntry(${itemIndex-1})" /> +
    +
    +
    + + + +
    Index: lams_tool_imscc/web/pages/authoring/start.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/authoring/start.jsp (revision 0) +++ lams_tool_imscc/web/pages/authoring/start.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,16 @@ + + +<%@ include file="/common/taglibs.jsp" %> + + + + + + + + + + Index: lams_tool_imscc/web/pages/export/exportportfolio.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/export/exportportfolio.jsp (revision 0) +++ lams_tool_imscc/web/pages/export/exportportfolio.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,191 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + <fmt:message key="export.title" /> + + + + + + + + + + + + +
    + +

    + ${title} +

    + +
    + ${instructions} +
    + + + +

    + + + + + + + ${group[0].sessionName} + + +

    + + + + + + + + + + + + + + + <%-- Bold styling is to indicate an item created by the author --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + ${item.itemTitle} + + + + + + + + + + + + + + + + + + + +
    + + <%-- Display reflection entries --%> + + + + <%-- End all answers for this question --%> +

    + +

    + + +

    + ${reflectDTO.fullName} +

    +

    + +

    +
    +
    + +
    + +
    + +
    + + + + + + +
    Index: lams_tool_imscc/web/pages/itemreview/initnav.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/itemreview/initnav.jsp (revision 0) +++ lams_tool_imscc/web/pages/itemreview/initnav.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,24 @@ +<%-- +To avoid use HttpSession (LDEV-199), try to +use request.setAttribute() transfer value. But this page is embeded into a Frame html page, directly +request can not block on frame page, so use this trick page redirect request, then server side could handle this +request using this page as target +--%> + +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + + + Index: lams_tool_imscc/web/pages/itemreview/instructionsnav.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/itemreview/instructionsnav.jsp (revision 0) +++ lams_tool_imscc/web/pages/itemreview/instructionsnav.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,114 @@ + +<%@ include file="/common/taglibs.jsp"%> + + + + + + +<%-- runAuto and reflectOn does not set when authoring preview mode then set false as default value --%> + + + + + + + + + + + + + + + + + + + + ${instructions.title} + + <%@ include file="/common/header.jsp"%> + + + + + +
    + + + + + + + + + + + + +
    + +
    Index: lams_tool_imscc/web/pages/itemreview/mainframe.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/itemreview/mainframe.jsp (revision 0) +++ lams_tool_imscc/web/pages/itemreview/mainframe.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,26 @@ +<%-- +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 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 +--%> +<%@ include file="/common/taglibs.jsp" %> + + ?mode=${mode}&itemIndex=${itemIndex}&itemUid=${itemUid}&toolSessionID=${toolSessionID}&sessionMapID=${sessionMapID}" + name=headerFrame" marginheight="0" scrolling="YES"> + + Index: lams_tool_imscc/web/pages/itemreview/openurl.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/itemreview/openurl.jsp (revision 0) +++ lams_tool_imscc/web/pages/itemreview/openurl.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,22 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + <%@ include file="/common/header.jsp"%> + + + +
    +

    + ${title} +

    +

    + +

    +
    + + Index: lams_tool_imscc/web/pages/learning/addfile.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/addfile.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/addfile.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,47 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + <%@ include file="/common/header.jsp"%> + + + + + + + +
    + +
    + + <%@ include file="/common/messages.jsp"%> + +
    + +
    + + +
    + +
    + + +
    + +
    + + + +
    + +
    + +
    + +
    Index: lams_tool_imscc/web/pages/learning/addurl.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/addurl.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/addurl.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,56 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + <%@ include file="/common/header.jsp"%> + + + + + + + +
    + +
    + <%@ include file="/common/messages.jsp"%> + +
    + +
    + + + +
    + +
    + + + + + + + + + +
    + +
    + + + +
    + +
    +
    + +
    Index: lams_tool_imscc/web/pages/learning/definelater.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/definelater.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/definelater.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,21 @@ + + +<%@include file="/common/taglibs.jsp"%> + + + + <%@ include file="/common/header.jsp"%> + + + + +
    +

    + +

    + +
    + + +
    Index: lams_tool_imscc/web/pages/learning/finish.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/finish.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/finish.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,16 @@ + + +<%@ include file="/common/taglibs.jsp"%> +<%-- This page just for : redir finish page to parent rather that part of the frame --%> + + + + + + + Index: lams_tool_imscc/web/pages/learning/learning.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/learning.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/learning.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,160 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + <fmt:message key="label.learning.title" /> + + <%@ include file="/common/header.jsp"%> + + + + + + + + + + + + + + + +
    +

    + ${commonCartridge.title} +

    + +

    + ${commonCartridge.instructions} +

    + + +
    + + + + + + + + +
    +
    + + <%@ include file="/common/messages.jsp"%> + + + + + + + + + + + + + + + + + + +
    + + + +
    + ${item.title} + + + + + + + - + + +
    + ${commonCartridge.miniViewNumberStr} +
    + + +
    +

    + ${sessionMap.reflectInstructions} +

    + + + +

    + +

    +
    + +

    + +

    +
    +
    + + + + + + +
    +
    + + +
    + + + + + + + + + + + + +
    +
    + +
    + + + + + + +
    Index: lams_tool_imscc/web/pages/learning/notebook.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/notebook.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/notebook.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,57 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + <fmt:message key="label.learning.title" /> + + <%@ include file="/common/header.jsp"%> + + + + + + + + + + + + +
    +

    + ${sessionMap.title} +

    + + <%@ include file="/common/messages.jsp"%> + +

    + +

    + + + +
    + + + +
    +
    +
    + + + + + +
    Index: lams_tool_imscc/web/pages/learning/runoffline.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/runoffline.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/runoffline.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,85 @@ + + +<%@include file="/common/taglibs.jsp"%> + + + + <%@ include file="/common/header.jsp"%> + + + + + +
    +

    + ${sessionMap.title} +

    + +

    + +

    + + +
    +

    + ${sessionMap.reflectInstructions} +

    + + + +

    + + +

    +
    + +

    + +

    +
    +
    + + + + +
    +
    + +
    + + + + + + + + + + + + +
    +
    + + + + +
    Index: lams_tool_imscc/web/pages/learning/start.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/start.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/start.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,22 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + + Index: lams_tool_imscc/web/pages/learning/success.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learning/success.jsp (revision 0) +++ lams_tool_imscc/web/pages/learning/success.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,25 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + + + <%@ include file="/common/header.jsp"%> + + + +
    + + Add URL success, click here to return. + + + Add File success, click here to return. + +
    + +
    Index: lams_tool_imscc/web/pages/learningobj/defaultcontent.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learningobj/defaultcontent.jsp (revision 0) +++ lams_tool_imscc/web/pages/learningobj/defaultcontent.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,31 @@ +<%-- +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 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 +--%> +<%@ include file="/common/taglibs.jsp" %> + + + +
    + + +
    + Please click on a link on the left to start. +
    +
    Index: lams_tool_imscc/web/pages/learningobj/icons/.cvsignore =================================================================== diff -u --- lams_tool_imscc/web/pages/learningobj/icons/.cvsignore (revision 0) +++ lams_tool_imscc/web/pages/learningobj/icons/.cvsignore (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1 @@ +Thumbs.db Index: lams_tool_imscc/web/pages/learningobj/icons/base.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/empty.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/folder.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/folderopen.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/join.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/joinbottom.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/line.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/minus.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/minusbottom.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/page.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/plus.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/icons/plusbottom.gif =================================================================== diff -u Binary files differ Index: lams_tool_imscc/web/pages/learningobj/mainframe.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learningobj/mainframe.jsp (revision 0) +++ lams_tool_imscc/web/pages/learningobj/mainframe.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,30 @@ +<%-- +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 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 +--%> + +<%@ include file="/common/taglibs.jsp" %> + + + + + + + Index: lams_tool_imscc/web/pages/learningobj/navigatortree.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/learningobj/navigatortree.jsp (revision 0) +++ lams_tool_imscc/web/pages/learningobj/navigatortree.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,101 @@ +<%-- +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 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 +--%> + + + +<%@ include file="/common/taglibs.jsp"%> + + + + <%@ include file="/common/header.jsp"%> + + + + + + + + + + + + + + + + + +

    + The content package details are missing. +

    +
    + +

    + +

    + +

    + +
    +
    + +
    Index: lams_tool_imscc/web/pages/learningobj/xmltree.xsl =================================================================== diff -u --- lams_tool_imscc/web/pages/learningobj/xmltree.xsl (revision 0) +++ lams_tool_imscc/web/pages/learningobj/xmltree.xsl (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + +var TREE_ITEMS = [ + +]; + + + + + + + ['','', + + ], + + + ['',0, + + ], + + + + + \ No newline at end of file Index: lams_tool_imscc/web/pages/monitoring/editactivity.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/editactivity.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/editactivity.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,43 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + +

    + +

    +
    + + + + + + + + + + + + + + + +
    + + : + + +
    + + : + + +
    + + + + + + + +
    Index: lams_tool_imscc/web/pages/monitoring/instructions.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/instructions.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/instructions.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,96 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + +
    +
    + +
    + + + + + +   + + + + + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    + + + + + +   + + + + + +
    Index: lams_tool_imscc/web/pages/monitoring/monitoring.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/monitoring.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/monitoring.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,57 @@ + + +<%@ include file="/common/taglibs.jsp"%> +<%@ page import="org.lamsfoundation.lams.tool.commonCartridge.CommonCartridgeConstants"%> + + + + <%@ include file="/common/tabbedheader.jsp" %> + + + +
    +

    + +

    + +
    + + + + + + +
    + + +
    + +
    Index: lams_tool_imscc/web/pages/monitoring/notebook.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/notebook.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/notebook.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,48 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + <fmt:message key="label.learning.title" /> + <%@ include file="/common/header.jsp"%> + + + +
    +

    + +

    + ${userDTO.fullName}

    + + + + + + + +
    + +
    + + + + + + + + +
    + + + + +
    + +
    +
    + + + +
    Index: lams_tool_imscc/web/pages/monitoring/statistic.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/statistic.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/statistic.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,83 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + + + +
    + +
    +
    + + + + <%-- display group name on first row--%> + + + + + + + + + + + + + + + + + + + + + + + + +
    + ${item.sessionName} + + +
    + + + + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + ${item.itemTitle} + + + + + + + ${item.viewNumber} + + + 0 + + +
    Index: lams_tool_imscc/web/pages/monitoring/summary.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/summary.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/summary.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,234 @@ +<%@ include file="/common/taglibs.jsp"%> + + + + +

    + + + + + +

    +
    + + + + + + + +
    + +
    +
    + + + + + + <%-- display group name on first row--%> + + + + + + + + + + + <%-- End group title display --%> + + + + + + + + + + + + + + + + <%-- Reflection list --%> + + + + + + + + + + + + + + + + + + + + + + + + +
    + ${item.sessionName} + + + + + +
    + + + + + + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + ${item.itemTitle} + + + + + + + ${item.viewNumber} + + + 0 + + + + + + + + + + + +
    +

    +
    + + + + + +
    + ${user.fullName} + + ${user.loginName} + + + + + + + +
    Index: lams_tool_imscc/web/pages/monitoring/userlist.jsp =================================================================== diff -u --- lams_tool_imscc/web/pages/monitoring/userlist.jsp (revision 0) +++ lams_tool_imscc/web/pages/monitoring/userlist.jsp (revision 7f68f72a3d80b8e24ba596d34ccea104ca285d05) @@ -0,0 +1,54 @@ + + + +<%@ include file="/common/taglibs.jsp"%> + + + <%@ include file="/common/header.jsp" %> + + + + +
    + +

    + +

    + + + + + + + + + + + + + + + + + +
    + + + + + +
    + ${user.loginName} + + + + ${user.firstName},${user.lastName} +
    + Close +
    +
    + +
    + +