Index: lams_bb_integration/.classpath =================================================================== diff -u -r8ea6dac2e1f9e39a41030dd5907592bc2aa04d17 -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/.classpath (.../.classpath) (revision 8ea6dac2e1f9e39a41030dd5907592bc2aa04d17) +++ lams_bb_integration/.classpath (.../.classpath) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -1,21 +1,16 @@ - - - - - - + Index: lams_bb_integration/WEB-INF/bb-manifest.xml =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/WEB-INF/bb-manifest.xml (.../bb-manifest.xml) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/WEB-INF/bb-manifest.xml (.../bb-manifest.xml) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -5,7 +5,7 @@ - + @@ -27,6 +27,7 @@ + @@ -40,16 +41,16 @@ - + - - - - - + + + + + - + Index: lams_bb_integration/WEB-INF/web.xml =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/WEB-INF/web.xml (.../web.xml) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/WEB-INF/web.xml (.../web.xml) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -13,6 +13,10 @@ LamsActionRequestServlet org.lamsfoundation.ld.integration.blackboard.LamsActionRequestServlet + + GradebookServlet + org.lamsfoundation.ld.integration.blackboard.GradebookServlet + LamsActionRequestServlet @@ -22,6 +26,9 @@ UserDataServlet /UserData + + GradebookServlet + /Gradebook + - Index: lams_bb_integration/build.xml =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/build.xml (.../build.xml) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/build.xml (.../build.xml) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -2,7 +2,7 @@ - + Index: lams_bb_integration/lib/bb-cms-admin.jar =================================================================== diff -u -ra225f60e82f4197c7a2bf6dbb7200709d1e852d7 -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 Binary files differ Index: lams_bb_integration/lib/bb-platform.jar =================================================================== diff -u -ra225f60e82f4197c7a2bf6dbb7200709d1e852d7 -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 Binary files differ Index: lams_bb_integration/lib/bb-taglibs.jar =================================================================== diff -u -ra225f60e82f4197c7a2bf6dbb7200709d1e852d7 -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 Binary files differ Index: lams_bb_integration/lib/commons-io-1.4.jar =================================================================== diff -u Binary files differ Index: lams_bb_integration/readme.txt =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/readme.txt (.../readme.txt) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/readme.txt (.../readme.txt) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -4,10 +4,7 @@ By Luke Foxton LAMS Foundation Copyright (C) 2007 (http://lamsfoundation.org) -Updated for the Blackboard 9.1 SP6 Building block by -Richard Stals (www.stals.com.au) -Edith Cowan University -2011 +Updated for the Blackboard 9.1 SP6 Building block by Richard Stals (www.stals.com.au) Edith Cowan University 2011 Contents ================================================================================ @@ -17,6 +14,9 @@ 2. Installing the module in Blackboard 3. Configuring the module in Blackboard 4. Configuring the LAMS Server for Blackboard Integration +5. Creating BB course +6. Creating LAMS lesson +7. Accessing Gradebook marks 1. Requirements @@ -25,15 +25,16 @@ - Blackboard Learning System 9.1 1.2 Minimum requirement to build the module from source - - Java 2 Platform, Standard Edition, v 1.5 + - Java 2 Platform, Standard Edition, v 1.6 - Ant 1.6 + 2. Installing the module in Blackboard ================================================================================ 1. Download lams2-bb-plugin-1.x.war 2. Log into Blackboard as Administrator 3. Click on - System Admin->Building Blocks->Install Building Block + System Admin->Building Blocks->Installed Tools->Upload Building Block 4. Click on Browse and select lams2-bb-plugin-1.x.war 5. Submit 6. Select "Available" in the Availability drop-down menu and click ok @@ -43,7 +44,7 @@ 3. Configuring the module in Blackboard ================================================================================ 1. Once the LAMS2 integration Block is installed, Goto - System Admin->Building Blocks + System Admin->Building Blocks->Installed Tools 2. Click the "Properties" button in the LAMS Module row 3. Fill in the LAMS server url, this is the url that points to the login page for LAMS. The same as the server URL set during LAMS installation @@ -74,16 +75,27 @@ (See step 7 of "Configuring the module in Blackboard") 8. You can optionally put a timeout URL and choose an organisation to add the integrated server to. - - - - - - - - - - - +5. Creating BB course +================================================================================ + 1. Click on My Institution->Launch the Course Creation Wizard and follow all required steps. + 2. To browse available courses head to Courses and there is a "Course List" + + +6. Creating LAMS lesson +================================================================================ + 1. Create BB Course as described above + 2. Go to Courses->${YOUR_COURSE_NAME}->Information->Tools->Lams2. + If you don't have Lams2 in the list then something went wrong on installation of lams2-bb-plugin-1.x.war + 3. Enter all necessary information and press submit. + + +7. Accessing Gradebook marks +================================================================================ + 1. Created LAMS lesson. + Once you created LAMS lesson it automatically adds grade to gradebook using the next algorithm: if LAMS lesson contains MCQ or Assessment + it creates scorable grade, otherwise - complete/incomplete grade. + 2. Go to Courses->${YOUR_COURSE_NAME}->Grade Center->Full Grade Center. + And you'll see there the grade with lesson's name. That is the column which will hold all the grades for that lesson. + * One note though: only learners receive grades (thus Administrators don't get one) Index: lams_bb_integration/src/org/lamsfoundation/ld/integration/Constants.java =================================================================== diff -u -r8ea6dac2e1f9e39a41030dd5907592bc2aa04d17 -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/src/org/lamsfoundation/ld/integration/Constants.java (.../Constants.java) (revision 8ea6dac2e1f9e39a41030dd5907592bc2aa04d17) +++ lams_bb_integration/src/org/lamsfoundation/ld/integration/Constants.java (.../Constants.java) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -23,36 +23,38 @@ package org.lamsfoundation.ld.integration; /** - * Constants used for blackboard integration - * - * @author Luke Foxton + * Constants used for blackboard integration + * + * @author Luke Foxton */ public class Constants { - + public static final String PARAM_USER_ID = "uid"; public static final String PARAM_SERVER_ID = "sid"; public static final String PARAM_TIMESTAMP = "ts"; public static final String PARAM_HASH = "hash"; - //public static final String PARAM_URL = "url"; + // public static final String PARAM_URL = "url"; public static final String PARAM_METHOD = "method"; - public static final String PARAM_LEARNING_SESSION_ID = "lsid"; + public static final String PARAM_LESSON_ID = "lsId"; public static final String PARAM_LEARNING_DESIGN_ID = "ldid"; public static final String PARAM_COURSE_ID = "course_id"; - public static final String SERVLET_LOGIN_REQUEST = "/lams/LoginRequest"; public static final String SERVLET_ACTION_REQUEST = "/LamsActionRequest"; - + public static final String URLDECODER_CODING = "US-ASCII"; - + public static final String METHOD_AUTHOR = "author"; public static final String METHOD_MONITOR = "monitor"; public static final String METHOD_LEARNER = "learner"; - // XML format constnats - public static final String ELEM_FOLDER = "Folder"; - public static final String ELEM_LEARNING_DESIGN = "LearningDesign"; - public static final String ATTR_NAME = "name"; - public static final String ATTR_RESOURCE_ID = "resourceId"; - + public static final String GRADEBOOK_LINEITEM_TYPE = "LAMS grades"; + public static final int GRADEBOOK_POINTS_POSSIBLE = 100; + + // XML format constnats + public static final String ELEM_FOLDER = "Folder"; + public static final String ELEM_LEARNING_DESIGN = "LearningDesign"; + public static final String ATTR_NAME = "name"; + public static final String ATTR_RESOURCE_ID = "resourceId"; + } Index: lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java =================================================================== diff -u --- lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java (revision 0) +++ lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,402 @@ +/** + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + */ +package org.lamsfoundation.ld.integration.blackboard; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.codec.binary.Hex; +import org.apache.log4j.Logger; +import org.lamsfoundation.ld.integration.Constants; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import blackboard.data.course.Course; +import blackboard.data.course.CourseMembership; +import blackboard.data.gradebook.Lineitem; +import blackboard.data.gradebook.Score; +import blackboard.data.gradebook.impl.Outcome; +import blackboard.data.gradebook.impl.OutcomeDefinition.CalculationType; +import blackboard.data.gradebook.impl.OutcomeDefinitionCategory; +import blackboard.data.gradebook.impl.OutcomeDefinitionScale; +import blackboard.data.user.User; +import blackboard.persist.BbPersistenceManager; +import blackboard.persist.KeyNotFoundException; +import blackboard.persist.PersistenceException; +import blackboard.persist.PkId; +import blackboard.persist.course.CourseDbLoader; +import blackboard.persist.course.CourseMembershipDbLoader; +import blackboard.persist.gradebook.LineitemDbLoader; +import blackboard.persist.gradebook.LineitemDbPersister; +import blackboard.persist.gradebook.ScoreDbLoader; +import blackboard.persist.gradebook.ScoreDbPersister; +import blackboard.persist.user.UserDbLoader; +import blackboard.platform.BbServiceManager; +import blackboard.platform.context.Context; +import blackboard.platform.context.ContextManager; +import blackboard.portal.data.ExtraInfo; +import blackboard.portal.data.PortalExtraInfo; +import blackboard.portal.servlet.PortalUtil; + +/** + * Deals with Blackboard Grade Center. + */ +public class GradebookServlet extends HttpServlet { + + private static final long serialVersionUID = -3587062723412672084L; + static Logger logger = Logger.getLogger(GradebookServlet.class); + + /** + * Receives call from Lams ab lesson completion. After that get the latest marks for this user in this lesson and stores it in DB.
+ */ + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + ContextManager ctxMgr = null; + String errorMsg = "error"; + + try { + // get Blackboard context + ctxMgr = (ContextManager) BbServiceManager.lookupService(ContextManager.class); + Context ctx = ctxMgr.setContext(request); + + // get Parameter values + String userName = request.getParameter(Constants.PARAM_USER_ID); + String timeStamp = request.getParameter(Constants.PARAM_TIMESTAMP); + String hash = request.getParameter(Constants.PARAM_HASH); + String lessonIdStr = request.getParameter(Constants.PARAM_LESSON_ID); + + // check paramaeters + if (userName == null || timeStamp == null || hash == null) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "missing expected parameters"); + return; + } + + String secretKey = LamsPluginUtil.getSecretKey(); + String serverId = LamsPluginUtil.getServerId(); + + if (!sha1( + timeStamp.toLowerCase() + userName.toLowerCase() + serverId.toLowerCase() + + secretKey.toLowerCase()).equals(hash)) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "authentication failed"); + } + + // get the persistence manager + BbPersistenceManager bbPm = BbServiceManager.getPersistenceService().getDbPersistenceManager(); + + // get user list, but no role info since there are no course info + UserDbLoader userLoader = (UserDbLoader) bbPm.getLoader(UserDbLoader.TYPE); + User user = userLoader.loadByUserName(userName); + + if (user == null) { + throw new ServletException("user not found"); + } + + String serverAddr = LamsSecurityUtil.getServerAddress(); + + Document document = null; + String serviceURL = serverAddr + "/services/xml/LessonManager?" + + LamsSecurityUtil.generateAuthenticateParameters(ctx) + "&courseId=" + + "&method=toolOutputsUser&lsId=" + lessonIdStr + "&outputsUser=" + + URLEncoder.encode(userName, "UTF8"); + + URL url = new URL(serviceURL); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + logger.error("Unable to open connection to: " + serviceURL); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + errorMsg = "HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " + + httpConn.getResponseMessage(); + logger.error(errorMsg); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, errorMsg); + return; + } + + // InputStream is = url.openConnection().getInputStream(); + InputStream is = conn.getInputStream(); + + // parse xml response + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + document = db.parse(is); + + + NodeList activities = document.getDocumentElement().getFirstChild().getChildNodes(); + + int maxResult = 0; + int userResult = 0; + for (int i = 0; i < activities.getLength(); i++) { + Node activity = activities.item(i); + + for (int j = 0; j < activity.getChildNodes().getLength(); j++) { + + Node toolOutput = activity.getChildNodes().item(j); + String toolOutputName = toolOutput.getAttributes().getNamedItem("name").getNodeValue(); + // The only numeric outputs we get from LAMS are for the MCQ and Assessment activities + // learner.total.score = Assessment + // learner.mark = MCQ + if ("learner.mark".equals(toolOutputName) || "learner.total.score".equals(toolOutputName)) { + String userResultStr = toolOutput.getAttributes().getNamedItem("output").getNodeValue(); + String maxResultStr = toolOutput.getAttributes().getNamedItem("marksPossible").getNodeValue(); + + userResult += Integer.parseInt(userResultStr); + maxResult += Integer.parseInt(maxResultStr); + } + } + + } + + + + + + + + // Get the content ID for this item +// Container bbContainer = bbPm.getContainer(); + //Id lessonId = new PkId( bbContainer, CourseDocument.DATA_TYPE, lessonIdStr ); +// Id.generateId(new DataType(Lineitem.class),lid) + + + //Id userId = new PkId( bbContainer, CourseDocument.DATA_TYPE, userName ); +// CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); +// ContentDbLoader courseDocumentLoader = (ContentDbLoader) bbPm.getLoader( ContentDbLoader.TYPE ); +// List userCourses = cLoader.loadByUserId(user.getId()); +// response.getWriter().print("!!!!!!!"+userCourses.size()); +// System.out.println("!!!!!!!"+userCourses.size()); +// Content lesson = null; +// for (Course userCourse: userCourses) { +// //userCourse.getClassification().gDefaultViewContent().gCartridge().get +// +// // Load the Course Document (Lams Lesson) +// List lessons = courseDocumentLoader.loadMapView(user.getId(), userCourse.getId(), null); +// response.getWriter().print("Xxx"+lessons.size()); +// System.out.println("Xxx"+lessons.size()); +// for (Content lessonIter: lessons) { +// if (lessonIter.getLinkRef() != null && lessonIter.getLinkRef().equals(lessonIdStr)) { +// lesson = lessonIter; +// break; +// } +// +// } +// } +// +// if (lesson == null) { +// throw new ServletException("lesson not found"); +// } + + + CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); + LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); + + List userCourses = cLoader.loadByUserId(ctx.getUserId()); + + // search for appropriate lineitem + Lineitem lineitem = null; + for (Course userCourse : userCourses) { + List lineitems = lineitemLoader.loadByCourseId(userCourse.getId()); + + for (Lineitem lineitemIter : lineitems) { + if (lineitemIter.getAssessmentId() != null && lineitemIter.getAssessmentId().equals(lessonIdStr)) { + lineitem = lineitemIter; + break; + } + } + + } + + if (lineitem == null) { + throw new ServletException("lineitem not found"); + } + + // store new score + CourseMembershipDbLoader memLoader = (CourseMembershipDbLoader) bbPm + .getLoader(CourseMembershipDbLoader.TYPE); + ScoreDbLoader scoreLoader = (ScoreDbLoader) bbPm.getLoader(ScoreDbLoader.TYPE); + ScoreDbPersister scorePersister = (ScoreDbPersister) bbPm.getPersister(ScoreDbPersister.TYPE); + CourseMembership cms = memLoader.loadByCourseAndUserId(lineitem.getCourseId(), ctx.getUserId()); + Score current_score = null; + try { + current_score = scoreLoader.loadByCourseMembershipIdAndLineitemId(cms.getId(), lineitem.getId()); + } catch (KeyNotFoundException c) { + current_score = new Score(); + current_score.setLineitemId(lineitem.getId()); + current_score.setCourseMembershipId(cms.getId()); + } + + //set score grade. if Lams supplies one (and lineitem will have score type) we set score; otherwise (and lineitme of type Complete/Incomplete) we set 0 + int gradebookMark = 0; + if (maxResult > 0) { + gradebookMark = (userResult / maxResult) * Constants.GRADEBOOK_POINTS_POSSIBLE; + } + current_score.setGrade("" + gradebookMark); + current_score.validate(); + scorePersister.persist(current_score); + + + } catch (MalformedURLException e) { + errorMsg = "Unable to get LAMS learning designs, bad URL: " + ", please check lams.properties"; + logger.error(errorMsg, e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (IllegalStateException e) { + errorMsg = "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator"; + logger.error(errorMsg, e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (ConnectException e) { + errorMsg = "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator"; + logger.error(errorMsg, e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (UnsupportedEncodingException e) { + logger.error(e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (IOException e) { + logger.error(e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (ParserConfigurationException e) { + logger.error(e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (SAXException e) { + logger.error(e); + e.printStackTrace(); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, errorMsg); + } catch (Exception e) { + e.printStackTrace(); + logger.error("Problem with gradebook servlet: " + e.getMessage(), e); + logger.error(e.getStackTrace().toString()); + throw new ServletException(e); + } finally { + // make sure context is released + if (ctxMgr != null) + ctxMgr.releaseContext(); + } + + response.setContentType("text/html"); + PrintWriter out = response.getWriter(); + out.write("OK"); + + + +// blackboard.data.content.CourseDocument l = null; +// +// +// String externalLessonId = request.getParameter("content_id"); +// String courseId = request.getParameter("course_id"); +// +// +// try { +// PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsStorage"); +// ExtraInfo ei = pei.getExtraInfo(); +// ei.setValue(l.getId().toString(), less); +// ei.setValue("value2", request.getParameter("value2")); +// PortalUtil.savePortalExtraInfo(pei); +// } catch (PersistenceException e) { +// e.printStackTrace(); +// } +// +// blackboard.data.content.CourseDocument ss; +// PkId pkId = (PkId) ss.getId(); +// String s = "_" + pkId.getPk1() + "_" + pkId.getPk2(); +// +// try { +// PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, " LamsStorage "); +// ExtraInfo ei = pei.getExtraInfo(); +// String value1 = ei.getValue("value1"); +// String value2 = ei.getValue("value2"); +// } catch (PersistenceException e) { +// e.printStackTrace(); +// } +// Lineitem lineitem = null; +// LineitemDbPersister linePersister= (LineitemDbPersister) bbPm.getPersister( LineitemDbPersister.TYPE ); +// linePersister.deleteById(lineitem.getId().g); + + +// may be store lessonIdInternal --> lessonIdExternal in course object +// and then you'll be able to find lineitem + + + +// CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); +// LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); +// +// List userCourses = cLoader.loadByUserId(ctx.getUserId()); +// +// //search for appropriate lineitem +// Lineitem lineitem = null; +// for (Course userCourse : userCourses) { +// userCourse.s +// +// List lineitems = lineitemLoader.loadByCourseId(userCourse.getId()); +// +// for (Lineitem lineitemIter : lineitems) { +// if (lineitemIter.getAssessmentId() != null +// && lineitemIter.getAssessmentId().equals(lessonIdStr)) { +// lineitem = lineitemIter; +// break; +// } +// } +// +// } +// +// if (lineitem == null) { +// throw new ServletException("lineitem not found"); +// } + } + + private String sha1(String str) { + try { + MessageDigest md = MessageDigest.getInstance("SHA1"); + return new String(Hex.encodeHex(md.digest(str.getBytes()))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + +} Index: lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java (.../LamsSecurityUtil.java) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java (.../LamsSecurityUtil.java) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -22,11 +22,10 @@ */ package org.lamsfoundation.ld.integration.blackboard; -import java.lang.IllegalStateException; -import java.net.ConnectException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -35,476 +34,572 @@ import java.rmi.RemoteException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import blackboard.platform.context.Context; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.codec.binary.Hex; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; import org.lamsfoundation.ld.integration.Constants; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import org.apache.log4j.Logger; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; +import blackboard.platform.context.Context; /** - * This class creates URLs, servlet calls and webservice calls - * for communication with LAMS - * - * @author Luke Foxton + * This class creates URLs, servlet calls and webservice calls for communication with LAMS + * + * @author Luke Foxton */ public class LamsSecurityUtil { - + static Logger logger = Logger.getLogger(LamsSecurityUtil.class); - - + /** * Generates login requests to LAMS for author, monitor and learner * - * @param ctx the blackboard contect, contains session data - * @param method the mehtod to request of LAMS "author", "monitor", "learner" + * @param ctx + * the blackboard contect, contains session data + * @param method + * the mehtod to request of LAMS "author", "monitor", "learner" * @return a url pointing to the LAMS lesson, monitor, author session * @throws Exception */ - public static String generateRequestURL(Context ctx, String method) throws Exception - { - String serverAddr = getServerAddress(); - String serverId = getServerID(); - String reqSrc = getReqSrc(); - - // If lams.properties could not be read, throw exception - if(serverAddr == null || serverId == null || reqSrc==null){ - throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); - } - - String timestamp = new Long(System.currentTimeMillis()).toString(); - String username = ctx.getUser().getUserName(); - String hash = generateAuthenticationHash(timestamp, username, method, serverId); - String courseId = ctx.getCourse().getCourseId(); - - String locale = ctx.getUser().getLocale(); - String country = getCountry(locale); - String lang = getLanguage(locale); + public static String generateRequestURL(Context ctx, String method) throws Exception { +// Course c = CourseDbLoader.Default.getInstance().loadByCourseId("aa"); +// Id cID = c.getId(); +// +// OutcomeDefinition def = new OutcomeDefinition(); +// Id sID = OutcomeDefinitionScaleDbLoader.Default.getInstance().loadByCourseIdAndTitle(cID, OutcomeDefinitionScale.COMPLETE_INCOMPLETE).getId(); +// def.setScaleId(sID); +// //def.setScorable(false); +// OutcomeDefinitionDbPersister.Default.getInstance().persist(def); + + String serverAddr = getServerAddress(); + String serverId = getServerID(); + String reqSrc = getReqSrc(); - String url; - try { - url = serverAddr + "/LoginRequest?" - + "&uid=" + URLEncoder.encode(username, "UTF8") - + "&method=" + method - + "&ts=" + timestamp - + "&sid=" + serverId - + "&hash=" + hash - + "&courseid=" + URLEncoder.encode(courseId, "UTF8") - + "&country=" + country - + "&lang=" + lang - + "&requestSrc=" + URLEncoder.encode(reqSrc, "UTF8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(); - } - - logger.info("LAMS Req: " + url); - //System.out.println(url); + // If lams.properties could not be read, throw exception + if (serverAddr == null || serverId == null || reqSrc == null) { + throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); + } - return url; + String timestamp = new Long(System.currentTimeMillis()).toString(); + String username = ctx.getUser().getUserName(); + String hash = generateAuthenticationHash(timestamp, username, method, serverId); + String courseId = ctx.getCourse().getCourseId(); + + String locale = ctx.getUser().getLocale(); + String country = getCountry(locale); + String lang = getLanguage(locale); + + String url; + try { + url = serverAddr + "/LoginRequest?" + "&uid=" + URLEncoder.encode(username, "UTF8") + "&method=" + method + + "&ts=" + timestamp + "&sid=" + serverId + "&hash=" + hash + "&courseid=" + + URLEncoder.encode(courseId, "UTF8") + "&country=" + country + "&lang=" + lang + "&requestSrc=" + + URLEncoder.encode(reqSrc, "UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(); } + + logger.info("LAMS Req: " + url); + // System.out.println(url); + + return url; + } /** + * Generates default + */ + public static String generateAuthenticateParameters(Context ctx) throws Exception { + String serverAddr = getServerAddress(); + String serverId = getServerID(); + String reqSrc = getReqSrc(); + + // If lams.properties could not be read, throw exception + if (serverAddr == null || serverId == null || reqSrc == null) { + throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); + } + + String timestamp = new Long(System.currentTimeMillis()).toString(); + String username = ctx.getUser().getUserName(); + String hash = generateAuthenticationHash(timestamp, username, serverId); + + String authenticateParameters = "&serverId=" + serverId + "&datetime=" + timestamp + "&hashValue=" + hash + + "&username=" + URLEncoder.encode(username, "UTF8"); + + return authenticateParameters; + } + + /** + * Generates url request to LAMS for LearningDesignImage. + * + * @param ctx + * the blackboard contect, contains session data + * @return a url pointing to the LAMS lesson, monitor, author session + * @throws Exception + */ + public static String generateRequestLearningDesignImage(Context ctx, boolean isSvgImage) throws Exception { + String serverAddr = getServerAddress(); + int svgFormat = (isSvgImage) ? 1 : 2; + + //$request = "$CFG->lamslesson_serverurl/services/LearningDesignSVG?serverId=" . $CFG->lamslesson_serverid . "&datetime=" . $datetime_encoded . "&hashValue=" . + //$hashvalue . "&username=" . $username . "&courseId=" . $courseid . "&courseName=" . urlencode($coursename) . "&mode=2&country=" . $country . "&lang=" . $lang . + //"&ldId=" . $ldid . "&svgFormat=" . $format; + String url = serverAddr + "/services/LearningDesignSVG?" + generateAuthenticateParameters(ctx) + "&svgFormat=" + svgFormat; + + logger.info("LAMS Req: " + url); + + return url; + } + + /** + * Checks whether lesson has scorable outputs (i.e. MCQ or Assessment activity). + * + * @param ctx + * the blackboard contect, contains session data + * @return a url pointing to the LAMS lesson, monitor, author session + * @throws Exception + */ + public static boolean hasLessonScoreOutputs(Context ctx) throws Exception { + String ldId = ctx.getRequestParameter("sequence_id").trim(); + String learningDesignSvgUrl = generateRequestLearningDesignImage(ctx, true) + "&ldId=" + ldId; + + URL url = new URL(learningDesignSvgUrl); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + logger.error("Unable to open connection to: " + learningDesignSvgUrl); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + String errorMsg = "HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " + + httpConn.getResponseMessage(); + logger.error(errorMsg); + throw new RuntimeException(errorMsg); + } + + // InputStream is = url.openConnection().getInputStream(); + InputStream is = conn.getInputStream(); + + // parse xml response + String learningDesignSvg = IOUtils.toString(is, "UTF-8"); + boolean hasLessonScoreOutputs = (learningDesignSvg.indexOf("icon_mcq.png") != -1) || (learningDesignSvg.indexOf("icon_assessment.png") != -1); + + return hasLessonScoreOutputs; + } + + /** * Gets a list of learning designs for the current user from LAMS * - * @param ctx the blackboard contect, contains session data - * @param mode the mode to call upon learning designes + * @param ctx + * the blackboard contect, contains session data + * @param mode + * the mode to call upon learning designes * @return a string containing the LAMS workspace tree in tigra format * @throws Exception */ - public static String getLearningDesigns(Context ctx, Integer mode) throws Exception - { - String serverAddr = getServerAddress(); - String serverId = getServerID(); - String serverKey = getServerKey(); - - // If lams.properties could not be read, throw exception - if(serverAddr == null || serverId == null || serverKey==null){ - throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); - } - - String timestamp = new Long(System.currentTimeMillis()).toString(); - String username = ctx.getUser().getUserName(); - String hash = generateAuthenticationHash(timestamp, username, serverId); - String courseId = ctx.getCourse().getCourseId(); + public static String getLearningDesigns(Context ctx, Integer mode) throws Exception { + String serverAddr = getServerAddress(); + String serverId = getServerID(); + String serverKey = getServerKey(); - String locale = ctx.getUser().getLocale(); - String country = getCountry(locale); - String lang = getLanguage(locale); + // If lams.properties could not be read, throw exception + if (serverAddr == null || serverId == null || serverKey == null) { + throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); + } - // TODO: Make locale settings work - String learningDesigns = "[]"; // empty javascript array - try { - String serviceURL = serverAddr + "/services/xml/LearningDesignRepository?" - + "datetime=" + timestamp - + "&username=" + URLEncoder.encode(username, "utf8") - + "&serverId=" + URLEncoder.encode(serverId, "utf8") - + "&hashValue=" + hash - + "&courseId=" + URLEncoder.encode(courseId, "UTF8") - + "&country=" + country - + "&lang=" + lang - + "&mode=" + mode; - - URL url = new URL(serviceURL); - URLConnection conn = url.openConnection(); - if (!(conn instanceof HttpURLConnection)) { - logger.error("Unable to open connection to: " + serviceURL); - } - - HttpURLConnection httpConn = (HttpURLConnection)conn; - - - if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { - logger.error("HTTP Response Code: " + httpConn.getResponseCode() - + ", HTTP Response Message: " + httpConn.getResponseMessage()); - return "error"; - } - - - //InputStream is = url.openConnection().getInputStream(); - InputStream is = conn.getInputStream(); - - - // parse xml response - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(is); - - learningDesigns = "[" + convertToTigraFormat(document.getDocumentElement()) + "]"; - - // replace sequence id with javascript method - String pattern = "'(\\d+)'"; - String replacement = "'javascript:selectSequence($1)'"; - learningDesigns = learningDesigns.replaceAll(pattern, replacement); - - // TODO better error handling - } catch (MalformedURLException e) { - logger.error("Unable to get LAMS learning designs, bad URL: '" - + serverAddr - + "', please check lams.properties", e); - e.printStackTrace(); - return "error"; - }catch (IllegalStateException e){ - logger.error("LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return "error"; - }catch (ConnectException e){ - logger.error("LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return "error"; - } catch (UnsupportedEncodingException e) { - logger.error(e); - e.printStackTrace(); - return "error"; - } catch (IOException e) { - logger.error(e); - e.printStackTrace(); - return "error"; - } catch (ParserConfigurationException e) { - logger.error(e); - e.printStackTrace(); - return "error"; - } catch (SAXException e) { - logger.error(e); - e.printStackTrace(); - return "error"; - } - return learningDesigns; + String timestamp = new Long(System.currentTimeMillis()).toString(); + String username = ctx.getUser().getUserName(); + String hash = generateAuthenticationHash(timestamp, username, serverId); + String courseId = ctx.getCourse().getCourseId(); + + String locale = ctx.getUser().getLocale(); + String country = getCountry(locale); + String lang = getLanguage(locale); + + // TODO: Make locale settings work + String learningDesigns = "[]"; // empty javascript array + try { + String serviceURL = serverAddr + "/services/xml/LearningDesignRepository?" + "datetime=" + timestamp + + "&username=" + URLEncoder.encode(username, "utf8") + "&serverId=" + + URLEncoder.encode(serverId, "utf8") + "&hashValue=" + hash + "&courseId=" + + URLEncoder.encode(courseId, "UTF8") + "&country=" + country + "&lang=" + lang + "&mode=" + mode; + + URL url = new URL(serviceURL); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + logger.error("Unable to open connection to: " + serviceURL); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + logger.error("HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " + + httpConn.getResponseMessage()); + return "error"; + } + + // InputStream is = url.openConnection().getInputStream(); + InputStream is = conn.getInputStream(); + + // parse xml response + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(is); + + learningDesigns = "[" + convertToTigraFormat(document.getDocumentElement()) + "]"; + + // replace sequence id with javascript method + //String pattern = "'(\\d+)'"; + //String replacement = "'javascript:selectSequence($1)'"; + //learningDesigns = learningDesigns.replaceAll(pattern, replacement); + + // TODO better error handling + } catch (MalformedURLException e) { + logger.error("Unable to get LAMS learning designs, bad URL: '" + serverAddr + + "', please check lams.properties", e); + e.printStackTrace(); + return "error"; + } catch (IllegalStateException e) { + logger.error( + "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", + e); + e.printStackTrace(); + return "error"; + } catch (ConnectException e) { + logger.error( + "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", + e); + e.printStackTrace(); + return "error"; + } catch (UnsupportedEncodingException e) { + logger.error(e); + e.printStackTrace(); + return "error"; + } catch (IOException e) { + logger.error(e); + e.printStackTrace(); + return "error"; + } catch (ParserConfigurationException e) { + logger.error(e); + e.printStackTrace(); + return "error"; + } catch (SAXException e) { + logger.error(e); + e.printStackTrace(); + return "error"; + } + return learningDesigns; } - + /** * Starts lessons in lams through a LAMS webservice * - * @param ctx the blackboard contect, contains session data - * @param ldId the learning design id for which you wish to start a lesson - * @param title the title of the lesson - * @param desc the description of the lesson + * @param ctx + * the blackboard contect, contains session data + * @param ldId + * the learning design id for which you wish to start a lesson + * @param title + * the title of the lesson + * @param desc + * the description of the lesson + * * @return the learning session id */ - public static Long startLesson(Context ctx, long ldId, String title, String desc) - { - Long error = new Long(-1); - String serverId = getServerID(); - String serverAddr = getServerAddress(); - String serverKey = getServerKey(); - String courseId = ctx.getCourse().getCourseId(); - String username = ctx.getUser().getUserName(); - String locale = ctx.getUser().getLocale(); - String country = getCountry(locale); - String lang = getLanguage(locale); - - if (serverId == null || serverAddr == null || serverKey == null ) { - logger.error("Unable to retrieve learning designs from LAMS, one or more lams configuration properties is null"); - return null; - } - - try { - - String timestamp = new Long(System.currentTimeMillis()).toString(); - String hash = generateAuthenticationHash(timestamp, username, serverId); - - // (serverId, datetime, hashValue, username, ldId, courseId, title, desc, country, lang) + public static Long startLesson(Context ctx, long ldId, String title, String desc, boolean isPreview) { + Long error = new Long(-1); + String serverId = getServerID(); + String serverAddr = getServerAddress(); + String serverKey = getServerKey(); + String courseId = ctx.getCourse().getCourseId(); + String username = ctx.getUser().getUserName(); + String locale = ctx.getUser().getLocale(); + String country = getCountry(locale); + String lang = getLanguage(locale); + String method = (isPreview) ? "preview" : "start"; - String serviceURL = serverAddr + "/services/xml/LessonManager?" - + "&serverId=" + URLEncoder.encode(serverId, "utf8") - + "&datetime=" + timestamp - + "&username=" + URLEncoder.encode(username, "utf8") - + "&hashValue=" + hash - + "&courseId=" + URLEncoder.encode(courseId, "utf8") - + "&ldId=" + new Long(ldId).toString() - + "&country=" + country - + "&lang=" + lang - + "&method=" + "start" - + "&title=" + URLEncoder.encode(title, "utf8").trim() - + "&desc=" + URLEncoder.encode(desc, "utf8").trim(); - - - logger.info("LAMS START LESSON Req: " + serviceURL); - //System.out.println("START LESSON: " + serviceURL); - - URL url = new URL(serviceURL); - URLConnection conn = url.openConnection(); - if (!(conn instanceof HttpURLConnection)) { - logger.error("Unable to open connection to: " + serviceURL); - } - - HttpURLConnection httpConn = (HttpURLConnection)conn; - - if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { - logger.error("HTTP Response Code: " + httpConn.getResponseCode() - + ", HTTP Response Message: " + httpConn.getResponseMessage()); - return error; - } - - //InputStream is = url.openConnection().getInputStream(); - InputStream is = conn.getInputStream(); - - - // parse xml response - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(is); - - // get the lesson id from the response - - /* - * The getTextContext is not a java 1.4 method, so Blackboard 7.1 comes up with errors - * using getNodeValue() instead - */ - //return Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes().getNamedItem("lessonId").getTextContent()); - return Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes().getNamedItem("lessonId").getNodeValue()); - } catch (MalformedURLException e) { - logger.error("Unable to start LAMS lesson, bad URL: '" - + serverAddr - + "', please check lams.properties", e); - e.printStackTrace(); - return error; - }catch (IllegalStateException e){ - logger.error("LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return error; - } catch (RemoteException e) { - logger.error("Unable to start LAMS lesson, RMI Remote Exception",e); - e.printStackTrace(); - return error; - } catch (UnsupportedEncodingException e) - { - logger.error("Unable to start LAMS lesson, Unsupported Encoding Exception",e); - e.printStackTrace(); - return error; - } - catch (ConnectException e) - { - logger.error("LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return error; - } - catch (Exception e) { - logger.error("Unable to start LAMS lesson. Please contact your system administrator.",e); - e.printStackTrace(); - return error; - } - + if (serverId == null || serverAddr == null || serverKey == null) { + logger.error("Unable to retrieve learning designs from LAMS, one or more lams configuration properties is null"); + return null; } - - + + try { + + String timestamp = new Long(System.currentTimeMillis()).toString(); + String hash = generateAuthenticationHash(timestamp, username, serverId); + + // (serverId, datetime, hashValue, username, ldId, courseId, title, desc, country, lang) + + String serviceURL = serverAddr + "/services/xml/LessonManager?" + "&serverId=" + + URLEncoder.encode(serverId, "utf8") + "&datetime=" + timestamp + "&username=" + + URLEncoder.encode(username, "utf8") + "&hashValue=" + hash + "&courseId=" + + URLEncoder.encode(courseId, "utf8") + "&ldId=" + new Long(ldId).toString() + "&country=" + + country + "&lang=" + lang + "&method=" + method + "&title=" + + URLEncoder.encode(title, "utf8").trim() + "&desc=" + URLEncoder.encode(desc, "utf8").trim(); + + logger.info("LAMS START LESSON Req: " + serviceURL); + // System.out.println("START LESSON: " + serviceURL); + + URL url = new URL(serviceURL); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + logger.error("Unable to open connection to: " + serviceURL); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + logger.error("HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " + + httpConn.getResponseMessage()); + return error; + } + + // InputStream is = url.openConnection().getInputStream(); + InputStream is = conn.getInputStream(); + + // parse xml response + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(is); + + // get the lesson id from the response + + /* + * The getTextContext is not a java 1.4 method, so Blackboard 7.1 comes up with errors using getNodeValue() + * instead + */ + // return + // Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes().getNamedItem("lessonId").getTextContent()); + return Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes() + .getNamedItem("lessonId").getNodeValue()); + } catch (MalformedURLException e) { + logger.error("Unable to start LAMS lesson, bad URL: '" + serverAddr + "', please check lams.properties", e); + e.printStackTrace(); + return error; + } catch (IllegalStateException e) { + logger.error( + "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", + e); + e.printStackTrace(); + return error; + } catch (RemoteException e) { + logger.error("Unable to start LAMS lesson, RMI Remote Exception", e); + e.printStackTrace(); + return error; + } catch (UnsupportedEncodingException e) { + logger.error("Unable to start LAMS lesson, Unsupported Encoding Exception", e); + e.printStackTrace(); + return error; + } catch (ConnectException e) { + logger.error( + "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", + e); + e.printStackTrace(); + return error; + } catch (Exception e) { + logger.error("Unable to start LAMS lesson. Please contact your system administrator.", e); + e.printStackTrace(); + return error; + } + + } + /** * @return gets server address from the lams.properties file */ - public static String getServerAddress() - { - return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_URL); + public static String getServerAddress() { + return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_URL); } - + /** * @return gets server id from the lams.properties file */ - public static String getServerID() - { - return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_SERVER_ID); + public static String getServerID() { + return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_SERVER_ID); } - + /** * @return gets server key from the lams.properties file */ - public static String getServerKey() - { - return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_SECRET_KEY); + public static String getServerKey() { + return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_LAMS_SECRET_KEY); } - + /** * @return gets request source from the lams.properties file */ - public static String getReqSrc() - { - return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_REQ_SRC); + public static String getReqSrc() { + return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_REQ_SRC); } - - + + +// +// if (empty($array['#']['LearningDesign']) && empty($array['#']['Folder'])) { +// $output .= ",expanded:0,children:[{type:'HTML',html:'-" . get_string('empty', 'lamslesson') . "-', id:0}]}"; +// return $output; +// } else { +// $output .= ",children:["; +// } +// +// if (!empty($array['#']['LearningDesign'])) { +// $lds = $array['#']['LearningDesign']; +// for($i=0; $i-empty-', id:0}]}"); return sb.toString(); + } else { + sb.append(",children:["); + + + sb.append(convertToTigraFormat(children.item(0))); + for (int i = 1; i < children.getLength(); i++) { + sb.append(',').append(convertToTigraFormat(children.item(i))); + } + + sb.append("]}"); + } + + } else if (node.getNodeName().equals(Constants.ELEM_LEARNING_DESIGN)) { + + +// $ld_name = preg_replace("/'/", "$1\'", $xml_node['@']['name']); +// $output .= "{type:'Text',label:'" . $ld_name . "',id:'" . $xml_node['@']['resourceId'] . "'}"; + + StringBuilder attrName = new StringBuilder(node.getAttributes().getNamedItem(Constants.ATTR_NAME) + .getNodeValue().replace("'", "\\'")); + StringBuilder attrResId = new StringBuilder(node.getAttributes().getNamedItem(Constants.ATTR_RESOURCE_ID) + .getNodeValue().replace("'", "\\'")); + + sb.append("{type:'Text',label:'"); + sb.append(attrName); + sb.append("',id:'"); + sb.append(attrResId); + sb.append("'}"); } + return sb.toString(); + } - //generate authentication hash code to validate parameters + // generate authentication hash code to validate parameters public static String generateAuthenticationHash(String datetime, String login, String method, String serverId) { - String secretkey = LamsPluginUtil.getSecretKey(); - - String plaintext = datetime.toLowerCase().trim() + - login.toLowerCase().trim() + - method.toLowerCase().trim() + - serverId.toLowerCase().trim() + - secretkey.toLowerCase().trim(); - - String hash = sha1(plaintext); - return hash; + String secretkey = LamsPluginUtil.getSecretKey(); + + String plaintext = datetime.toLowerCase().trim() + login.toLowerCase().trim() + method.toLowerCase().trim() + + serverId.toLowerCase().trim() + secretkey.toLowerCase().trim(); + + String hash = sha1(plaintext); + return hash; } - - - //generate authentication hash code to validate parameters + // generate authentication hash code to validate parameters + public static String generateAuthenticationHash(String datetime, String login, String serverId) { - String secretkey = getServerKey(); - - String plaintext = datetime.toLowerCase().trim() + - login.toLowerCase().trim() + - serverId.toLowerCase().trim() + - secretkey.toLowerCase().trim(); - - String hash = sha1(plaintext); - - return hash; + String secretkey = getServerKey(); + + String plaintext = datetime.toLowerCase().trim() + login.toLowerCase().trim() + serverId.toLowerCase().trim() + + secretkey.toLowerCase().trim(); + + String hash = sha1(plaintext); + + return hash; } - - //generate authentication hash code to validate parameters - public static String generateAuthenticationHash(String datetime, String serverId) - throws NoSuchAlgorithmException { - String secretkey = LamsPluginUtil.getSecretKey(); - - String plaintext = datetime.toLowerCase().trim() + - serverId.toLowerCase().trim() + - secretkey.toLowerCase().trim() ; - - return sha1(plaintext); + + // generate authentication hash code to validate parameters + public static String generateAuthenticationHash(String datetime, String serverId) throws NoSuchAlgorithmException { + String secretkey = LamsPluginUtil.getSecretKey(); + + String plaintext = datetime.toLowerCase().trim() + serverId.toLowerCase().trim() + + secretkey.toLowerCase().trim(); + + return sha1(plaintext); } - - + /** - * The parameters are: - * uid - the username on the external system - * method - either author, monitor or learner - * ts - timestamp - * sid - serverID - * str is [ts + uid + method + serverID + serverKey] (Note: all lower case) + * The parameters are: uid - the username on the external system method - either author, monitor or learner ts - + * timestamp sid - serverID str is [ts + uid + method + serverID + serverKey] (Note: all lower case) * - * @param str The string to be hashed + * @param str + * The string to be hashed * @return The hased string */ - private static String sha1(String str){ - try{ - MessageDigest md = MessageDigest.getInstance("SHA1"); - return new String(Hex.encodeHex(md.digest(str.getBytes()))); - } catch(NoSuchAlgorithmException e){ - throw new RuntimeException(e); - } + private static String sha1(String str) { + try { + MessageDigest md = MessageDigest.getInstance("SHA1"); + return new String(Hex.encodeHex(md.digest(str.getBytes()))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); } - - /** - * - * @param localeStr the full balckboard locale string - * @return the language - */ - public static String getLanguage(String localeStr) - { - if (localeStr==null) - return "xx"; - String[] split = localeStr.split("_"); - return split[0]; - } - - /** - * - * @param localeStr the full balckboard locale string - * @return the country - */ - public static String getCountry(String localeStr) - { - if (localeStr==null) - return "XX"; - String[] split = localeStr.split("_"); - return split[1]; - } - - - + } + + /** + * + * @param localeStr + * the full balckboard locale string + * @return the language + */ + public static String getLanguage(String localeStr) { + if (localeStr == null) + return "xx"; + String[] split = localeStr.split("_"); + return split[0]; + } + + /** + * + * @param localeStr + * the full balckboard locale string + * @return the country + */ + public static String getCountry(String localeStr) { + if (localeStr == null) + return "XX"; + String[] split = localeStr.split("_"); + return split[1]; + } + } Index: lams_bb_integration/web/images/folders/lm.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/lmh.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/ln.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/loading.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/lp.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/lph.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/tm.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/tmh.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/tn.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/tp.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/tph.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/folders/vline.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/check0.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/check1.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/check2.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/loading.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/treeview-loading.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/images/sam/treeview-sprite.gif =================================================================== diff -u Binary files differ Index: lams_bb_integration/web/lib/tree/treeview-min.js =================================================================== diff -u --- lams_bb_integration/web/lib/tree/treeview-min.js (revision 0) +++ lams_bb_integration/web/lib/tree/treeview-min.js (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,12 @@ +/* +Copyright (c) 2011, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.9.0 +*/ +(function(){var d=YAHOO.util.Dom,b=YAHOO.util.Event,f=YAHOO.lang,e=YAHOO.widget;YAHOO.widget.TreeView=function(h,g){if(h){this.init(h);}if(g){this.buildTreeFromObject(g);}else{if(f.trim(this._el.innerHTML)){this.buildTreeFromMarkup(h);}}};var c=e.TreeView;c.prototype={id:null,_el:null,_nodes:null,locked:false,_expandAnim:null,_collapseAnim:null,_animCount:0,maxAnim:2,_hasDblClickSubscriber:false,_dblClickTimer:null,currentFocus:null,singleNodeHighlight:false,_currentlyHighlighted:null,setExpandAnim:function(g){this._expandAnim=(e.TVAnim.isValid(g))?g:null;},setCollapseAnim:function(g){this._collapseAnim=(e.TVAnim.isValid(g))?g:null;},animateExpand:function(i,j){if(this._expandAnim&&this._animCount0||(d&&this.isDynamic()&&!this.dynamicLoadComplete));}},toggle:function(){if(!this.tree.locked&&(this.hasChildren(true)||this.isDynamic())){if(this.expanded){this.collapse();}else{this.expand();}}},getHtml:function(){this.childrenRendered=false;return['
',this.getNodeHtml(),this.getChildrenHtml(),"
"].join("");},getChildrenHtml:function(){var d=[];d[d.length]='
";return d.join("");},renderChildren:function(){var d=this;if(this.isDynamic()&&!this.dynamicLoadComplete){this.isLoading=true;this.tree.locked=true;if(this.dataLoader){setTimeout(function(){d.dataLoader(d,function(){d.loadComplete();});},10);}else{if(this.tree.root.dataLoader){setTimeout(function(){d.tree.root.dataLoader(d,function(){d.loadComplete(); +});},10);}else{return"Error: data loader not found or not specified.";}}return"";}else{return this.completeRender();}},completeRender:function(){var e=[];for(var d=0;d=this.depth||e<0){return null;}var d=this.parent;while(d.depth>e){d=d.parent;}return d;},getDepthStyle:function(d){return(this.getAncestor(d).nextSibling)?"ygtvdepthcell":"ygtvblankdepthcell";},getNodeHtml:function(){var e=[];e[e.length]='
';}if(this.hasIcon){e[e.length]='';}e[e.length]='
 
";return e.join("");},getContentHtml:function(){return"";},refresh:function(){this.getChildrenEl().innerHTML=this.completeRender();if(this.hasIcon){var d=this.getToggleEl();if(d){d.className=d.className.replace(/\bygtv[lt][nmp]h*\b/gi,this.getStyle());}}},toString:function(){return this._type+" ("+this.index+")";},_focusHighlightedItems:[],_focusedItem:null,_canHaveFocus:function(){return this.getEl().getElementsByTagName("a").length>0;},_removeFocus:function(){if(this._focusedItem){a.removeListener(this._focusedItem,"blur");this._focusedItem=null;}var d;while((d=this._focusHighlightedItems.shift())){b.removeClass(d,YAHOO.widget.TreeView.FOCUS_CLASS_NAME);}},focus:function(){var f=false,d=this;if(this.tree.currentFocus){this.tree.currentFocus._removeFocus();}var e=function(g){if(g.parent){e(g.parent);g.parent.expand();}};e(this);b.getElementsBy(function(g){return(/ygtv(([tl][pmn]h?)|(content))/).test(g.className);},"td",d.getEl().firstChild,function(h){b.addClass(h,YAHOO.widget.TreeView.FOCUS_CLASS_NAME);if(!f){var g=h.getElementsByTagName("a");if(g.length){g=g[0];g.focus();d._focusedItem=g;a.on(g,"blur",function(){d.tree.fireEvent("focusChanged",{oldNode:d.tree.currentFocus,newNode:null});d.tree.currentFocus=null;d._removeFocus();});f=true;}}d._focusHighlightedItems.push(h);});if(f){this.tree.fireEvent("focusChanged",{oldNode:this.tree.currentFocus,newNode:this});this.tree.currentFocus=this;}else{this.tree.fireEvent("focusChanged",{oldNode:d.tree.currentFocus,newNode:null});this.tree.currentFocus=null;this._removeFocus();}return f;},getNodeCount:function(){for(var d=0,e=0;d":"";return d.join("");},getNodeDefinition:function(){var d=YAHOO.widget.TextNode.superclass.getNodeDefinition.call(this);if(d===false){return false;}d.label=this.label;if(this.labelStyle!="ygtvlabel"){d.style=this.labelStyle;}if(this.title){d.title=this.title;}if(this.href){d.href=this.href;}if(this.target!="_self"){d.target=this.target;}return d;},toString:function(){return YAHOO.widget.TextNode.superclass.toString.call(this)+": "+this.label;},onLabelClick:function(){return false;},refresh:function(){YAHOO.widget.TextNode.superclass.refresh.call(this);var d=this.getLabelEl();d.innerHTML=this.label;if(d.tagName.toUpperCase()=="A"){d.href=this.href;d.target=this.target;}}});})();YAHOO.widget.MenuNode=function(c,b,a){YAHOO.widget.MenuNode.superclass.constructor.call(this,c,b,a);this.multiExpand=false;};YAHOO.extend(YAHOO.widget.MenuNode,YAHOO.widget.TextNode,{_type:"MenuNode"});(function(){var b=YAHOO.util.Dom,c=YAHOO.lang,a=YAHOO.util.Event;var d=function(h,g,f,e){if(h){this.init(h,g,f);this.initContent(h,e);}};YAHOO.widget.HTMLNode=d;YAHOO.extend(d,YAHOO.widget.Node,{contentStyle:"ygtvhtml",html:null,_type:"HTMLNode",initContent:function(f,e){this.setHtml(f);this.contentElId="ygtvcontentel"+this.index;if(!c.isUndefined(e)){this.hasIcon=e;}},setHtml:function(f){this.html=(c.isObject(f)&&"html" in f)?f.html:f;var e=this.getContentEl();if(e){if(f.nodeType&&f.nodeType==1&&f.tagName){e.innerHTML="";}else{e.innerHTML=this.html;}}},getContentHtml:function(){if(typeof this.html==="string"){return this.html;}else{d._deferredNodes.push(this);if(!d._timer){d._timer=window.setTimeout(function(){var e;while((e=d._deferredNodes.pop())){e.getContentEl().appendChild(e.html);}d._timer=null;},0);}return"";}},getNodeDefinition:function(){var e=d.superclass.getNodeDefinition.call(this);if(e===false){return false;}e.html=this.html;return e;}});d._deferredNodes=[];d._timer=null;})();(function(){var b=YAHOO.util.Dom,c=YAHOO.lang,a=YAHOO.util.Event,d=YAHOO.widget.Calendar;YAHOO.widget.DateNode=function(g,f,e){YAHOO.widget.DateNode.superclass.constructor.call(this,g,f,e);};YAHOO.extend(YAHOO.widget.DateNode,YAHOO.widget.TextNode,{_type:"DateNode",calendarConfig:null,fillEditorContainer:function(g){var h,f=g.inputContainer;if(c.isUndefined(d)){b.replaceClass(g.editorPanel,"ygtv-edit-DateNode","ygtv-edit-TextNode");YAHOO.widget.DateNode.superclass.fillEditorContainer.call(this,g);return;}if(g.nodeType!=this._type){g.nodeType=this._type;g.saveOnEnter=false;g.node.destroyEditorContents(g);g.inputObject=h=new d(f.appendChild(document.createElement("div")));if(this.calendarConfig){h.cfg.applyConfig(this.calendarConfig,true);h.cfg.fireQueue();}h.selectEvent.subscribe(function(){this.tree._closeEditor(true);},this,true);}else{h=g.inputObject;}g.oldValue=this.label;h.cfg.setProperty("selected",this.label,false);var i=h.cfg.getProperty("DATE_FIELD_DELIMITER");var e=this.label.split(i);h.cfg.setProperty("pagedate",e[h.cfg.getProperty("MDY_MONTH_POSITION")-1]+i+e[h.cfg.getProperty("MDY_YEAR_POSITION")-1]);h.cfg.fireQueue();h.render();h.oDomContainer.focus();},getEditorValue:function(f){if(c.isUndefined(d)){return f.inputElement.value;}else{var h=f.inputObject,g=h.getSelectedDates()[0],e=[];e[h.cfg.getProperty("MDY_DAY_POSITION")-1]=g.getDate();e[h.cfg.getProperty("MDY_MONTH_POSITION")-1]=g.getMonth()+1;e[h.cfg.getProperty("MDY_YEAR_POSITION")-1]=g.getFullYear();return e.join(h.cfg.getProperty("DATE_FIELD_DELIMITER"));}},displayEditedValue:function(g,e){var f=e.node;f.label=g;f.getLabelEl().innerHTML=g;},getNodeDefinition:function(){var e=YAHOO.widget.DateNode.superclass.getNodeDefinition.call(this);if(e===false){return false;}if(this.calendarConfig){e.calendarConfig=this.calendarConfig;}return e;}});})();(function(){var e=YAHOO.util.Dom,f=YAHOO.lang,b=YAHOO.util.Event,d=YAHOO.widget.TreeView,c=d.prototype;d.editorData={active:false,whoHasIt:null,nodeType:null,editorPanel:null,inputContainer:null,buttonsContainer:null,node:null,saveOnEnter:true,oldValue:undefined}; +c.validator=null;c._initEditor=function(){this.createEvent("editorSaveEvent",this);this.createEvent("editorCancelEvent",this);};c._nodeEditing=function(m){if(m.fillEditorContainer&&m.editable){var i,k,l,j,h=d.editorData;h.active=true;h.whoHasIt=this;if(!h.nodeType){h.editorPanel=i=this.getEl().appendChild(document.createElement("div"));e.addClass(i,"ygtv-label-editor");i.tabIndex=0;l=h.buttonsContainer=i.appendChild(document.createElement("div"));e.addClass(l,"ygtv-button-container");j=l.appendChild(document.createElement("button"));e.addClass(j,"ygtvok");j.innerHTML=" ";j=l.appendChild(document.createElement("button"));e.addClass(j,"ygtvcancel");j.innerHTML=" ";b.on(l,"click",function(q){var r=b.getTarget(q),o=d.editorData,p=o.node,n=o.whoHasIt;if(e.hasClass(r,"ygtvok")){b.stopEvent(q);n._closeEditor(true);}if(e.hasClass(r,"ygtvcancel")){b.stopEvent(q);n._closeEditor(false);}});h.inputContainer=i.appendChild(document.createElement("div"));e.addClass(h.inputContainer,"ygtv-input");b.on(i,"keydown",function(q){var p=d.editorData,n=YAHOO.util.KeyListener.KEY,o=p.whoHasIt;switch(q.keyCode){case n.ENTER:b.stopEvent(q);if(p.saveOnEnter){o._closeEditor(true);}break;case n.ESCAPE:b.stopEvent(q);o._closeEditor(false);break;}});}else{i=h.editorPanel;}h.node=m;if(h.nodeType){e.removeClass(i,"ygtv-edit-"+h.nodeType);}e.addClass(i," ygtv-edit-"+m._type);e.setStyle(i,"display","block");e.setXY(i,e.getXY(m.getContentEl()));i.focus();m.fillEditorContainer(h);return true;}};c.onEventEditNode=function(h){if(h instanceof YAHOO.widget.Node){h.editNode();}else{if(h.node instanceof YAHOO.widget.Node){h.node.editNode();}}return false;};c._closeEditor=function(j){var h=d.editorData,i=h.node,k=true;if(!i||!h.active){return;}if(j){k=h.node.saveEditorValue(h)!==false;}else{this.fireEvent("editorCancelEvent",i);}if(k){e.setStyle(h.editorPanel,"display","none");h.active=false;i.focus();}};c._destroyEditor=function(){var h=d.editorData;if(h&&h.nodeType&&(!h.active||h.whoHasIt===this)){b.removeListener(h.editorPanel,"keydown");b.removeListener(h.buttonContainer,"click");h.node.destroyEditorContents(h);document.body.removeChild(h.editorPanel);h.nodeType=h.editorPanel=h.inputContainer=h.buttonsContainer=h.whoHasIt=h.node=null;h.active=false;}};var g=YAHOO.widget.Node.prototype;g.editable=false;g.editNode=function(){this.tree._nodeEditing(this);};g.fillEditorContainer=null;g.destroyEditorContents=function(h){b.purgeElement(h.inputContainer,true);h.inputContainer.innerHTML="";};g.saveEditorValue=function(h){var j=h.node,k,i=j.tree.validator;k=this.getEditorValue(h);if(f.isFunction(i)){k=i(k,h.oldValue,j);if(f.isUndefined(k)){return false;}}if(this.tree.fireEvent("editorSaveEvent",{newValue:k,oldValue:h.oldValue,node:j})!==false){this.displayEditedValue(k,h);}};g.getEditorValue=function(h){};g.displayEditedValue=function(i,h){};var a=YAHOO.widget.TextNode.prototype;a.fillEditorContainer=function(i){var h;if(i.nodeType!=this._type){i.nodeType=this._type;i.saveOnEnter=true;i.node.destroyEditorContents(i);i.inputElement=h=i.inputContainer.appendChild(document.createElement("input"));}else{h=i.inputElement;}i.oldValue=this.label;h.value=this.label;h.focus();h.select();};a.getEditorValue=function(h){return h.inputElement.value;};a.displayEditedValue=function(j,h){var i=h.node;i.label=j;i.getLabelEl().innerHTML=j;};a.destroyEditorContents=function(h){h.inputContainer.innerHTML="";};})();YAHOO.widget.TVAnim=function(){return{FADE_IN:"TVFadeIn",FADE_OUT:"TVFadeOut",getAnim:function(b,a,c){if(YAHOO.widget[b]){return new YAHOO.widget[b](a,c);}else{return null;}},isValid:function(a){return(YAHOO.widget[a]);}};}();YAHOO.widget.TVFadeIn=function(a,b){this.el=a;this.callback=b;};YAHOO.widget.TVFadeIn.prototype={animate:function(){var e=this;var d=this.el.style;d.opacity=0.1;d.filter="alpha(opacity=10)";d.display="";var c=0.4;var b=new YAHOO.util.Anim(this.el,{opacity:{from:0.1,to:1,unit:""}},c);b.onComplete.subscribe(function(){e.onComplete();});b.animate();},onComplete:function(){this.callback();},toString:function(){return"TVFadeIn";}};YAHOO.widget.TVFadeOut=function(a,b){this.el=a;this.callback=b;};YAHOO.widget.TVFadeOut.prototype={animate:function(){var d=this;var c=0.4;var b=new YAHOO.util.Anim(this.el,{opacity:{from:1,to:0.1,unit:""}},c);b.onComplete.subscribe(function(){d.onComplete();});b.animate();},onComplete:function(){var a=this.el.style;a.display="none";a.opacity=1;a.filter="alpha(opacity=100)";this.callback();},toString:function(){return"TVFadeOut";}};YAHOO.register("treeview",YAHOO.widget.TreeView,{version:"2.9.0",build:"2800"}); \ No newline at end of file Index: lams_bb_integration/web/lib/tree/yahoo-dom-event.js =================================================================== diff -u --- lams_bb_integration/web/lib/tree/yahoo-dom-event.js (revision 0) +++ lams_bb_integration/web/lib/tree/yahoo-dom-event.js (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,14 @@ +/* +Copyright (c) 2011, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.9.0 +*/ +if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var b=arguments,g=null,e,c,f;for(e=0;e":">",'"':""","'":"'","/":"/","`":"`"},d=["toString","valueOf"],e={isArray:function(j){return a.toString.apply(j)===c;},isBoolean:function(j){return typeof j==="boolean";},isFunction:function(j){return(typeof j==="function")||a.toString.apply(j)===h;},isNull:function(j){return j===null;},isNumber:function(j){return typeof j==="number"&&isFinite(j);},isObject:function(j){return(j&&(typeof j==="object"||f.isFunction(j)))||false;},isString:function(j){return typeof j==="string";},isUndefined:function(j){return typeof j==="undefined";},_IEEnumFix:(YAHOO.env.ua.ie)?function(l,k){var j,n,m;for(j=0;j"'\/`]/g,function(k){return g[k];});},extend:function(m,n,l){if(!n||!m){throw new Error("extend failed, please check that "+"all dependencies are included.");}var k=function(){},j;k.prototype=n.prototype;m.prototype=new k();m.prototype.constructor=m;m.superclass=n.prototype;if(n.prototype.constructor==a.constructor){n.prototype.constructor=n;}if(l){for(j in l){if(f.hasOwnProperty(l,j)){m.prototype[j]=l[j];}}f._IEEnumFix(m.prototype,l);}},augmentObject:function(n,m){if(!m||!n){throw new Error("Absorb failed, verify dependencies.");}var j=arguments,l,o,k=j[2];if(k&&k!==true){for(l=2;l0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}if(r.length>1){r.pop();}r.push("]");}else{r.push("{");for(l in j){if(f.hasOwnProperty(j,l)){r.push(l+m);if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}}if(r.length>1){r.pop();}r.push("}");}return r.join("");},substitute:function(x,y,E,l){var D,C,B,G,t,u,F=[],p,z=x.length,A="dump",r=" ",q="{",m="}",n,w;for(;;){D=x.lastIndexOf(q,z);if(D<0){break;}C=x.indexOf(m,D);if(D+1>C){break;}p=x.substring(D+1,C);G=p;u=null;B=G.indexOf(r);if(B>-1){u=G.substring(B+1);G=G.substring(0,B);}t=y[G];if(E){t=E(G,t,u);}if(f.isObject(t)){if(f.isArray(t)){t=f.dump(t,parseInt(u,10));}else{u=u||"";n=u.indexOf(A);if(n>-1){u=u.substring(4);}w=t.toString();if(w===i||n>-1){t=f.dump(t,parseInt(u,10));}else{t=w;}}}else{if(!f.isString(t)&&!f.isNumber(t)){t="~-"+F.length+"-~";F[F.length]=p;}}x=x.substring(0,D)+t+x.substring(C+1);if(l===false){z=D-1;}}for(D=F.length-1;D>=0;D=D-1){x=x.replace(new RegExp("~-"+D+"-~"),"{"+F[D]+"}","g");}return x;},trim:function(j){try{return j.replace(/^\s+|\s+$/g,"");}catch(k){return j; +}},merge:function(){var n={},k=arguments,j=k.length,m;for(m=0;m-1;}}else{}return G;},addClass:function(W,G){return e.Dom.batch(W,e.Dom._addClass,G);},_addClass:function(X,W){var G=false,Y;if(X&&W){Y=e.Dom._getAttribute(X,f)||i;if(!e.Dom._hasClass(X,W)){e.Dom.setAttribute(X,f,a(Y+b+W));G=true;}}else{}return G;},removeClass:function(W,G){return e.Dom.batch(W,e.Dom._removeClass,G);},_removeClass:function(Y,X){var W=false,aa,Z,G;if(Y&&X){aa=e.Dom._getAttribute(Y,f)||i;e.Dom.setAttribute(Y,f,aa.replace(e.Dom._getClassRegex(X),i));Z=e.Dom._getAttribute(Y,f);if(aa!==Z){e.Dom.setAttribute(Y,f,a(Z));W=true;if(e.Dom._getAttribute(Y,f)===""){G=(Y.hasAttribute&&Y.hasAttribute(E))?E:f;Y.removeAttribute(G);}}}else{}return W;},replaceClass:function(X,W,G){return e.Dom.batch(X,e.Dom._replaceClass,{from:W,to:G});},_replaceClass:function(Y,X){var W,ab,aa,G=false,Z;if(Y&&X){ab=X.from;aa=X.to;if(!aa){G=false;}else{if(!ab){G=e.Dom._addClass(Y,X.to);}else{if(ab!==aa){Z=e.Dom._getAttribute(Y,f)||i;W=(b+Z.replace(e.Dom._getClassRegex(ab),b+aa).replace(/\s+/g,b)).split(e.Dom._getClassRegex(aa));W.splice(1,0,b+aa);e.Dom.setAttribute(Y,f,a(W.join(i)));G=true;}}}}else{}return G;},generateId:function(G,X){X=X||"yui-gen";var W=function(Y){if(Y&&Y.id){return Y.id;}var Z=X+YAHOO.env._id_counter++; +if(Y){if(Y[C]&&Y[C].getElementById(Z)){return e.Dom.generateId(Y,Z+X);}Y.id=Z;}return Z;};return e.Dom.batch(G,W,e.Dom,true)||W.apply(e.Dom,arguments);},isAncestor:function(W,X){W=e.Dom.get(W);X=e.Dom.get(X);var G=false;if((W&&X)&&(W[K]&&X[K])){if(W.contains&&W!==X){G=W.contains(X);}else{if(W.compareDocumentPosition){G=!!(W.compareDocumentPosition(X)&16);}}}else{}return G;},inDocument:function(G,W){return e.Dom._inDoc(e.Dom.get(G),W);},_inDoc:function(W,X){var G=false;if(W&&W[c]){X=X||W[C];G=e.Dom.isAncestor(X[U],W);}else{}return G;},getElementsBy:function(W,af,ab,ad,X,ac,ae){af=af||"*";ab=(ab)?e.Dom.get(ab):null||j;var aa=(ae)?null:[],G;if(ab){G=ab.getElementsByTagName(af);for(var Y=0,Z=G.length;Y=8){e.Dom.DOT_ATTRIBUTES.type=true;}})();YAHOO.util.Region=function(d,e,a,c){this.top=d;this.y=d;this[1]=d;this.right=e;this.bottom=a;this.left=c;this.x=c;this[0]=c;this.width=this.right-this.left;this.height=this.bottom-this.top;};YAHOO.util.Region.prototype.contains=function(a){return(a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(f){var d=Math.max(this.top,f.top),e=Math.min(this.right,f.right),a=Math.min(this.bottom,f.bottom),c=Math.max(this.left,f.left); +if(a>=d&&e>=c){return new YAHOO.util.Region(d,e,a,c);}else{return null;}};YAHOO.util.Region.prototype.union=function(f){var d=Math.min(this.top,f.top),e=Math.max(this.right,f.right),a=Math.max(this.bottom,f.bottom),c=Math.min(this.left,f.left);return new YAHOO.util.Region(d,e,a,c);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+", height: "+this.height+", width: "+this.width+"}");};YAHOO.util.Region.getRegion=function(e){var g=YAHOO.util.Dom.getXY(e),d=g[1],f=g[0]+e.offsetWidth,a=g[1]+e.offsetHeight,c=g[0];return new YAHOO.util.Region(d,f,a,c);};YAHOO.util.Point=function(a,b){if(YAHOO.lang.isArray(a)){b=a[1];a=a[0];}YAHOO.util.Point.superclass.constructor.call(this,b,a,b,a);};YAHOO.extend(YAHOO.util.Point,YAHOO.util.Region);(function(){var b=YAHOO.util,a="clientTop",f="clientLeft",j="parentNode",k="right",w="hasLayout",i="px",u="opacity",l="auto",d="borderLeftWidth",g="borderTopWidth",p="borderRightWidth",v="borderBottomWidth",s="visible",q="transparent",n="height",e="width",h="style",t="currentStyle",r=/^width|height$/,o=/^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i,m={get:function(x,z){var y="",A=x[t][z];if(z===u){y=b.Dom.getStyle(x,u);}else{if(!A||(A.indexOf&&A.indexOf(i)>-1)){y=A;}else{if(b.Dom.IE_COMPUTED[z]){y=b.Dom.IE_COMPUTED[z](x,z);}else{if(o.test(A)){y=b.Dom.IE.ComputedStyle.getPixel(x,z);}else{y=A;}}}}return y;},getOffset:function(z,E){var B=z[t][E],x=E.charAt(0).toUpperCase()+E.substr(1),C="offset"+x,y="pixel"+x,A="",D;if(B==l){D=z[C];if(D===undefined){A=0;}A=D;if(r.test(E)){z[h][E]=D;if(z[C]>D){A=D-(z[C]-D);}z[h][E]=l;}}else{if(!z[h][y]&&!z[h][E]){z[h][E]=B;}A=z[h][y];}return A+i;},getBorderWidth:function(x,z){var y=null;if(!x[t][w]){x[h].zoom=1;}switch(z){case g:y=x[a];break;case v:y=x.offsetHeight-x.clientHeight-x[a];break;case d:y=x[f];break;case p:y=x.offsetWidth-x.clientWidth-x[f];break;}return y+i;},getPixel:function(y,x){var A=null,B=y[t][k],z=y[t][x];y[h][k]=z;A=y[h].pixelRight;y[h][k]=B;return A+i;},getMargin:function(y,x){var z;if(y[t][x]==l){z=0+i;}else{z=b.Dom.IE.ComputedStyle.getPixel(y,x);}return z;},getVisibility:function(y,x){var z;while((z=y[t])&&z[x]=="inherit"){y=y[j];}return(z)?z[x]:s;},getColor:function(y,x){return b.Dom.Color.toRGB(y[t][x])||q;},getBorderColor:function(y,x){var z=y[t],A=z[x]||z.color;return b.Dom.Color.toRGB(b.Dom.Color.toHex(A));}},c={};c.top=c.right=c.bottom=c.left=c[e]=c[n]=m.getOffset;c.color=m.getColor;c[g]=c[p]=c[v]=c[d]=m.getBorderWidth;c.marginTop=c.marginRight=c.marginBottom=c.marginLeft=m.getMargin;c.visibility=m.getVisibility;c.borderColor=c.borderTopColor=c.borderRightColor=c.borderBottomColor=c.borderLeftColor=m.getBorderColor;b.Dom.IE_COMPUTED=c;b.Dom.IE_ComputedStyle=m;})();(function(){var c="toString",a=parseInt,b=RegExp,d=YAHOO.util;d.Dom.Color={KEYWORDS:{black:"000",silver:"c0c0c0",gray:"808080",white:"fff",maroon:"800000",red:"f00",purple:"800080",fuchsia:"f0f",green:"008000",lime:"0f0",olive:"808000",yellow:"ff0",navy:"000080",blue:"00f",teal:"008080",aqua:"0ff"},re_RGB:/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,re_hex:/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,re_hex3:/([0-9A-F])/gi,toRGB:function(e){if(!d.Dom.Color.re_RGB.test(e)){e=d.Dom.Color.toHex(e);}if(d.Dom.Color.re_hex.exec(e)){e="rgb("+[a(b.$1,16),a(b.$2,16),a(b.$3,16)].join(", ")+")";}return e;},toHex:function(f){f=d.Dom.Color.KEYWORDS[f]||f;if(d.Dom.Color.re_RGB.exec(f)){f=[Number(b.$1).toString(16),Number(b.$2).toString(16),Number(b.$3).toString(16)];for(var e=0;e0){i=c[0];}try{b=g.fn.call(f,i,g.obj);}catch(h){this.lastError=h;if(a){throw h;}}}else{try{b=g.fn.call(f,this.type,c,g.obj);}catch(d){this.lastError=d;if(a){throw d;}}}return b;},unsubscribeAll:function(){var a=this.subscribers.length,b;for(b=a-1;b>-1;b--){this._delete(b);}this.subscribers=[];return a;},_delete:function(a){var b=this.subscribers[a];if(b){delete b.fn;delete b.obj;}this.subscribers.splice(a,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"context: "+this.scope;}};YAHOO.util.Subscriber=function(a,b,c){this.fn=a;this.obj=YAHOO.lang.isUndefined(b)?null:b;this.overrideContext=c;};YAHOO.util.Subscriber.prototype.getScope=function(a){if(this.overrideContext){if(this.overrideContext===true){return this.obj;}else{return this.overrideContext;}}return a;};YAHOO.util.Subscriber.prototype.contains=function(a,b){if(b){return(this.fn==a&&this.obj==b);}else{return(this.fn==a);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", overrideContext: "+(this.overrideContext||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var g=false,h=[],j=[],a=0,e=[],b=0,c={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9},d=YAHOO.env.ua.ie,f="focusin",i="focusout";return{POLL_RETRYS:500,POLL_INTERVAL:40,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,CAPTURE:7,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:d,_interval:null,_dri:null,_specialTypes:{focusin:(d?"focusin":"focus"),focusout:(d?"focusout":"blur")},DOMReady:false,throwErrors:false,startInterval:function(){if(!this._interval){this._interval=YAHOO.lang.later(this.POLL_INTERVAL,this,this._tryPreloadAttach,null,true);}},onAvailable:function(q,m,o,p,n){var k=(YAHOO.lang.isString(q))?[q]:q;for(var l=0;l-1;m--){s=(this.removeListener(l[m],k,r)&&s);}return s;}}if(!r||!r.call){return this.purgeElement(l,false,k);}if("unload"==k){for(m=j.length-1;m>-1;m--){u=j[m];if(u&&u[0]==l&&u[1]==k&&u[2]==r){j.splice(m,1);return true;}}return false;}var n=null;var o=arguments[3];if("undefined"===typeof o){o=this._getCacheIndex(h,l,k,r);}if(o>=0){n=h[o];}if(!l||!n){return false;}var t=n[this.CAPTURE]===true?true:false;try{this._simpleRemove(l,k,n[this.WFN],t);}catch(q){this.lastError=q;return false;}delete h[o][this.WFN];delete h[o][this.FN];h.splice(o,1);return true;},getTarget:function(m,l){var k=m.target||m.srcElement;return this.resolveTextNode(k);},resolveTextNode:function(l){try{if(l&&3==l.nodeType){return l.parentNode;}}catch(k){return null;}return l;},getPageX:function(l){var k=l.pageX;if(!k&&0!==k){k=l.clientX||0;if(this.isIE){k+=this._getScrollLeft();}}return k;},getPageY:function(k){var l=k.pageY;if(!l&&0!==l){l=k.clientY||0;if(this.isIE){l+=this._getScrollTop();}}return l;},getXY:function(k){return[this.getPageX(k),this.getPageY(k)];},getRelatedTarget:function(l){var k=l.relatedTarget; +if(!k){if(l.type=="mouseout"){k=l.toElement;}else{if(l.type=="mouseover"){k=l.fromElement;}}}return this.resolveTextNode(k);},getTime:function(m){if(!m.time){var l=new Date().getTime();try{m.time=l;}catch(k){this.lastError=k;return l;}}return m.time;},stopEvent:function(k){this.stopPropagation(k);this.preventDefault(k);},stopPropagation:function(k){if(k.stopPropagation){k.stopPropagation();}else{k.cancelBubble=true;}},preventDefault:function(k){if(k.preventDefault){k.preventDefault();}else{k.returnValue=false;}},getEvent:function(m,k){var l=m||window.event;if(!l){var n=this.getEvent.caller;while(n){l=n.arguments[0];if(l&&Event==l.constructor){break;}n=n.caller;}}return l;},getCharCode:function(l){var k=l.keyCode||l.charCode||0;if(YAHOO.env.ua.webkit&&(k in c)){k=c[k];}return k;},_getCacheIndex:function(n,q,r,p){for(var o=0,m=n.length;o0&&e.length>0);}var p=[];var r=function(t,u){var s=t;if(u.overrideContext){if(u.overrideContext===true){s=u.obj;}else{s=u.overrideContext;}}u.fn.call(s,u.obj);};var l,k,o,n,m=[];for(l=0,k=e.length;l-1;l--){o=e[l];if(!o||!o.id){e.splice(l,1);}}this.startInterval();}else{if(this._interval){this._interval.cancel();this._interval=null;}}this.locked=false;},purgeElement:function(p,q,s){var n=(YAHOO.lang.isString(p))?this.getEl(p):p;var r=this.getListeners(n,s),o,k;if(r){for(o=r.length-1;o>-1;o--){var m=r[o];this.removeListener(n,m.type,m.fn);}}if(q&&n&&n.childNodes){for(o=0,k=n.childNodes.length;o-1;o--){n=h[o];if(n){try{m.removeListener(n[m.EL],n[m.TYPE],n[m.FN],o);}catch(v){}}}n=null;}try{m._simpleRemove(window,"unload",m._unload);m._simpleRemove(window,"load",m._load);}catch(u){}},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var k=document.documentElement,l=document.body;if(k&&(k.scrollTop||k.scrollLeft)){return[k.scrollTop,k.scrollLeft];}else{if(l){return[l.scrollTop,l.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(m,n,l,k){m.addEventListener(n,l,(k));};}else{if(window.attachEvent){return function(m,n,l,k){m.attachEvent("on"+n,l);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(m,n,l,k){m.removeEventListener(n,l,(k));};}else{if(window.detachEvent){return function(l,m,k){l.detachEvent("on"+m,k);};}else{return function(){};}}}()};}();(function(){var a=YAHOO.util.Event;a.on=a.addListener;a.onFocus=a.addFocusListener;a.onBlur=a.addBlurListener; +/*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller/Diego Perini */ +if(a.isIE){if(self!==self.top){document.onreadystatechange=function(){if(document.readyState=="complete"){document.onreadystatechange=null;a._ready();}};}else{YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var b=document.createElement("p");a._dri=setInterval(function(){try{b.doScroll("left");clearInterval(a._dri);a._dri=null;a._ready();b=null;}catch(c){}},a.POLL_INTERVAL);}}else{if(a.webkit&&a.webkit<525){a._dri=setInterval(function(){var c=document.readyState;if("loaded"==c||"complete"==c){clearInterval(a._dri);a._dri=null;a._ready();}},a.POLL_INTERVAL);}else{a._simpleAdd(document,"DOMContentLoaded",a._ready);}}a._simpleAdd(window,"load",a._load);a._simpleAdd(window,"unload",a._unload);a._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(a,c,f,e){this.__yui_events=this.__yui_events||{};var d=this.__yui_events[a];if(d){d.subscribe(c,f,e);}else{this.__yui_subscribers=this.__yui_subscribers||{};var b=this.__yui_subscribers;if(!b[a]){b[a]=[];}b[a].push({fn:c,obj:f,overrideContext:e});}},unsubscribe:function(c,e,g){this.__yui_events=this.__yui_events||{};var a=this.__yui_events;if(c){var f=a[c];if(f){return f.unsubscribe(e,g);}}else{var b=true;for(var d in a){if(YAHOO.lang.hasOwnProperty(a,d)){b=b&&a[d].unsubscribe(e,g); +}}return b;}return false;},unsubscribeAll:function(a){return this.unsubscribe(a);},createEvent:function(b,g){this.__yui_events=this.__yui_events||{};var e=g||{},d=this.__yui_events,f;if(d[b]){}else{f=new YAHOO.util.CustomEvent(b,e.scope||this,e.silent,YAHOO.util.CustomEvent.FLAT,e.fireOnce);d[b]=f;if(e.onSubscribeCallback){f.subscribeEvent.subscribe(e.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var a=this.__yui_subscribers[b];if(a){for(var c=0;c <%@ page import="blackboard.platform.plugin.PlugInUtil"%> <%@ page import="blackboard.platform.plugin.PlugInException"%> @@ -21,8 +20,11 @@ <%@ taglib uri="/bbNG" prefix="bbNG"%> - - + + + + + <% // SECURITY! // Authorise current user for Course Control Panel (automatic redirect) @@ -38,11 +40,12 @@ // Get the list of Learning Designs String learningDesigns = LamsSecurityUtil.getLearningDesigns(ctx, 2); - // Error checking - if (learningDesigns.equals("error")) { - response.sendRedirect("lamsServerDown.jsp"); - return; - } + // Error checking + if (learningDesigns.equals("error")) { + response.sendRedirect("lamsServerDown.jsp"); + return; + } + String lamsServerUrl = LamsSecurityUtil.getServerAddress(); %> <%-- Breadcrumbs --%> @@ -55,38 +58,108 @@ - <%-- Action Control Bar --%> - - <%-- Open the LAMS Author Window --%> - <%-- Refresh the list of LAMS sequences --%> - <%-- Go to Next Step --%> - - <%-- Form to Collect ID of Selected LAMS Sequence --%> -
+ "> "> - <%-- Display LAMS Sequence tree (Using tigra) --%> - + + + + + + + + + + + + + + + + <%-- Preview and Author Buttons --%> +
+ + + + + + + +
+ +
+
+
+ Display image design? +
+ + <%-- Display LAMS Sequence tree (Using tigra) --%> + +
+ + + + Yes + No + + + Yes + No + + + + + + + + +
- Index: lams_bb_integration/web/modules/css/folders.css =================================================================== diff -u --- lams_bb_integration/web/modules/css/folders.css (revision 0) +++ lams_bb_integration/web/modules/css/folders.css (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,64 @@ +/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ + +/* first or middle sibling, no children */ +.ygtvtn { background: url(../../images/folders/tn.gif) 0 0 no-repeat; width:17px; height:22px; } + +/* first or middle sibling, collapsable */ +.ygtvtm { background: url(../../images/folders/tm.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* first or middle sibling, collapsable, hover */ +.ygtvtmh { background: url(../../images/folders/tmh.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* first or middle sibling, expandable */ +.ygtvtp { background: url(../../images/folders/tp.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* first or middle sibling, expandable, hover */ +.ygtvtph { background: url(../../images/folders/tph.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* last sibling, no children */ +.ygtvln { background: url(../../images/folders/ln.gif) 0 0 no-repeat; width:17px; height:22px; } + +/* Last sibling, collapsable */ +.ygtvlm { background: url(../../images/folders/lm.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* Last sibling, collapsable, hover */ +.ygtvlmh { background: url(../../images/folders/lmh.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* Last sibling, expandable */ +.ygtvlp { background: url(../../images/folders/lp.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* Last sibling, expandable, hover */ +.ygtvlph { background: url(../../images/folders/lph.gif) 0 0 no-repeat; width:34px; height:22px; cursor:pointer } + +/* Loading icon */ +.ygtvloading { background: url(../../images/folders/loading.gif) 0 0 no-repeat; width:16px; height:22px; } + +/* the style for the empty cells that are used for rendering the depth + * of the node */ +.ygtvdepthcell { background: url(../../images/folders/vline.gif) 0 0 no-repeat; width:17px; height:22px; } + +.ygtvblankdepthcell { width:17px; height:22px; } + +/* the style of the div around each node */ +.ygtvitem { } + +.ygtvitem table{ + margin-bottom:0; +} +.ygtvitem td { + border:none;padding:0; +} + + + +/* the style of the div around each node's collection of children */ +.ygtvchildren { } +* html .ygtvchildren { height:1%; } + +/* the style of the text label in ygTextNode */ +.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { + margin-left:2px; + text-decoration: none; +} + + Index: lams_bb_integration/web/modules/css/treeview.css =================================================================== diff -u --- lams_bb_integration/web/modules/css/treeview.css (revision 0) +++ lams_bb_integration/web/modules/css/treeview.css (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,7 @@ +/* +Copyright (c) 2011, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.9.0 +*/ +table.ygtvtable{margin-bottom:0;border:0;border-collapse:collapse}td.ygtvcell{border:0;padding:0}a.ygtvspacer{text-decoration:none;outline-style:none;display:block}.ygtvtn{width:18px;height:22px;background:url(../../images/sam/treeview-sprite.gif) 0 -5600px no-repeat;cursor:pointer}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -4000px no-repeat}.ygtvtmh,.ygtvtmhh{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -4800px no-repeat}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -6400px no-repeat}.ygtvtph,.ygtvtphh{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -7200px no-repeat}.ygtvln{width:18px;height:22px;background:url(../../images/sam/treeview-sprite.gif) 0 -1600px no-repeat;cursor:pointer}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 0 no-repeat}.ygtvlmh,.ygtvlmhh{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -800px no-repeat}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -2400px no-repeat}.ygtvlph,.ygtvlphh{width:18px;height:22px;cursor:pointer;background:url(../../images/sam/treeview-sprite.gif) 0 -3200px no-repeat;cursor:pointer}.ygtvloading{width:18px;height:22px;background:url(../../images/sam/treeview-loading.gif) 0 0 no-repeat}.ygtvdepthcell{width:18px;height:22px;background:url(../../images/sam/treeview-sprite.gif) 0 -8000px no-repeat}.ygtvblankdepthcell{width:18px;height:22px}* html .ygtvchildren{height:2%}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;cursor:pointer}.ygtvcontent{cursor:default}.ygtvspacer{height:22px;width:18px}.ygtvfocus{background-color:#c0e0e0;border:0}.ygtvfocus .ygtvlabel,.ygtvfocus .ygtvlabel:link,.ygtvfocus .ygtvlabel:visited,.ygtvfocus .ygtvlabel:hover{background-color:#c0e0e0}.ygtvfocus a{outline-style:none}.ygtvok{width:18px;height:22px;background:url(../../images/sam/treeview-sprite.gif) 0 -8800px no-repeat}.ygtvok:hover{background:url(../../images/sam/treeview-sprite.gif) 0 -8844px no-repeat}.ygtvcancel{width:18px;height:22px;background:url(../../images/sam/treeview-sprite.gif) 0 -8822px no-repeat}.ygtvcancel:hover{background:url(../../images/sam/treeview-sprite.gif) 0 -8866px no-repeat}.ygtv-label-editor{background-color:#f2f2f2;border:1px solid silver;position:absolute;display:none;overflow:hidden;margin:auto;z-index:9000}.ygtv-edit-TextNode{width:190px}.ygtv-edit-TextNode .ygtvcancel,.ygtv-edit-TextNode .ygtvok{border:0}.ygtv-edit-TextNode .ygtv-button-container{float:right}.ygtv-edit-TextNode .ygtv-input input{width:140px}.ygtv-edit-DateNode .ygtvcancel{border:0}.ygtv-edit-DateNode .ygtvok{display:none}.ygtv-edit-DateNode .ygtv-button-container{text-align:right;margin:auto}.ygtv-highlight .ygtv-highlight1,.ygtv-highlight .ygtv-highlight1 .ygtvlabel{background-color:#47BC23;color:white}.ygtv-highlight .ygtv-highlight2,.ygtv-highlight .ygtv-highlight2 .ygtvlabel{background-color:silver}.ygtv-highlight .ygtv-highlight0 .ygtvfocus .ygtvlabel,.ygtv-highlight .ygtv-highlight1 .ygtvfocus .ygtvlabel,.ygtv-highlight .ygtv-highlight2 .ygtvfocus .ygtvlabel{background-color:#c0e0e0}.ygtv-highlight .ygtvcontent{padding-right:1em}.ygtv-checkbox .ygtv-highlight0 .ygtvcontent{padding-left:1em;background:url(../../images/sam/check0.gif) no-repeat}.ygtv-checkbox .ygtv-highlight0 .ygtvfocus.ygtvcontent,.ygtv-checkbox .ygtv-highlight1 .ygtvfocus.ygtvcontent,.ygtv-checkbox .ygtv-highlight2 .ygtvfocus.ygtvcontent{background-color:#c0e0e0}.ygtv-checkbox .ygtv-highlight1 .ygtvcontent{padding-left:1em;background:url(../../images/sam/check1.gif) no-repeat}.ygtv-checkbox .ygtv-highlight2 .ygtvcontent{padding-left:1em;background:url(../../images/sam/check2.gif) no-repeat} Index: lams_bb_integration/web/modules/delete.jsp =================================================================== diff -u --- lams_bb_integration/web/modules/delete.jsp (revision 0) +++ lams_bb_integration/web/modules/delete.jsp (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -0,0 +1,89 @@ +<%-- + Original Version: 2007 LAMS Foundation + Updated for Blackboard 9.1 SP6 (including new bbNG tag library) 2011 + Richard Stals (www.stals.com.au) + Edith Cowan University, Western Australia +--%> +<%-- + Handle LAMS Lesson Access + Students - access lesson only + Staff - additionally access the Lesson Monitor +--%> +<%@ page import="java.util.*"%> +<%@ page import="java.util.Date"%> +<%@ page import="java.text.SimpleDateFormat"%> +<%@ page import="blackboard.data.*"%> +<%@ page import="blackboard.persist.*"%> +<%@ page import="blackboard.data.course.*"%> +<%@ page import="blackboard.data.user.*"%> +<%@ page import="blackboard.persist.course.*"%> +<%@ page import="blackboard.data.content.*"%> +<%@ page import="blackboard.persist.content.*"%> +<%@ page import="blackboard.persist.navigation.CourseTocDbLoader"%> +<%@ page import="blackboard.db.*"%> +<%@ page import="blackboard.base.*"%> +<%@ page import="blackboard.platform.*"%> +<%@ page import="blackboard.platform.plugin.*"%> +<%@ page import="org.lamsfoundation.ld.integration.blackboard.LamsSecurityUtil"%> +<%@ page import="blackboard.portal.data.*" %> +<%@ page import="blackboard.portal.servlet.PortalUtil" %> +<%@ page import="blackboard.persist.PersistenceException" %> +<%@ page import="blackboard.persist.gradebook.*" %> +<%@ page import="blackboard.data.gradebook.*" %> +<%@ page errorPage="/error.jsp"%> +<%@ taglib uri="/bbNG" prefix="bbNG"%> + + +<% + // SECURITY! + // Authorise current user for Course Access (automatic redirect) + try { + if (!PlugInUtil.authorizeForCourse(request, response)) + return; + } catch (PlugInException e) { + throw new RuntimeException(e); + } + + String internalLessonId = request.getParameter("content_id"); + String courseIdStr = request.getParameter("course_id"); + BbPersistenceManager bbPm = BbServiceManager.getPersistenceService().getDbPersistenceManager(); + Id courseId = bbPm.generateId(Course.DATA_TYPE, courseIdStr); + + //get stored internalContentId -> externalContentId. + PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsStorage"); + ExtraInfo ei = pei.getExtraInfo(); + String externalLessonId = ei.getValue(internalLessonId); + + if (externalLessonId == null || "".equals(externalLessonId)) { + throw new ServletException("externalLessonId not found in PortalExtraInfo LamsStorage"); + } + + CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); + LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); + + //search for appropriate lineitem + Lineitem lineitem = null; + List lineitems = lineitemLoader.loadByCourseId(courseId); + + for (Lineitem lineitemIter : lineitems) { + if (lineitemIter.getAssessmentId() != null && lineitemIter.getAssessmentId().equals(externalLessonId)) { + lineitem = lineitemIter; + break; + } + } + + if (lineitem == null) { + throw new ServletException("lineitem not found"); + } + + LineitemDbPersister linePersister = (LineitemDbPersister) bbPm.getPersister(LineitemDbPersister.TYPE); + linePersister.deleteById(lineitem.getId()); +%> + + <%-- Page Header --%> + + + + + + \ No newline at end of file Fisheye: Tag 3b9ddc508e73ba1d53a30bf7e6a45d400da05096 refers to a dead (removed) revision in file `lams_bb_integration/web/modules/gradeit.jsp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 3b9ddc508e73ba1d53a30bf7e6a45d400da05096 refers to a dead (removed) revision in file `lams_bb_integration/web/modules/index.jsp'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_bb_integration/web/modules/learnermonitor.jsp =================================================================== diff -u -re90547eeb5330fd68c424212233b1689f25c71ce -r3b9ddc508e73ba1d53a30bf7e6a45d400da05096 --- lams_bb_integration/web/modules/learnermonitor.jsp (.../learnermonitor.jsp) (revision e90547eeb5330fd68c424212233b1689f25c71ce) +++ lams_bb_integration/web/modules/learnermonitor.jsp (.../learnermonitor.jsp) (revision 3b9ddc508e73ba1d53a30bf7e6a45d400da05096) @@ -20,6 +20,8 @@ <%@ page import="blackboard.data.content.*"%> <%@ page import="blackboard.persist.content.*"%> <%@ page import="blackboard.persist.navigation.CourseTocDbLoader"%> +<%@ page import="blackboard.persist.gradebook.*"%> +<%@ page import="blackboard.data.gradebook.*"%> <%@ page import="blackboard.db.*"%> <%@ page import="blackboard.base.*"%> <%@ page import="blackboard.platform.*"%> @@ -83,6 +85,29 @@ if (!isActive) { PlugInUtil.sendAccessDeniedRedirect(request, response); } + + String strIsDisplayDesignImage = request.getParameter("isDisplayDesignImage"); + boolean isDisplayDesignImage = strIsDisplayDesignImage.equals("true")?true:false; + + String learningDesignImageUrl = ""; + if (isDisplayDesignImage) { + String strLearningDesignId = request.getParameter("ldid").trim(); + long learningDesignId = Long.parseLong(strLearningDesignId); + + learningDesignImageUrl = LamsSecurityUtil.generateRequestLearningDesignImage(ctx, false) + "&ldId=" + learningDesignId; + } + + //check whether user has score for this lesson + String strLineitemId = request.getParameter("lineitemid").trim(); + Id lineitemId = bbPm.generateId(Lineitem.LINEITEM_DATA_TYPE, strLineitemId); + ScoreDbLoader scoreLoader = (ScoreDbLoader) bbPm.getLoader(ScoreDbLoader.TYPE); + Score current_score = null; + try { + current_score = scoreLoader.loadByCourseMembershipIdAndLineitemId(courseMembership.getId(), lineitemId); + } catch (KeyNotFoundException c) { + //no score availalbe + } + boolean isScoreAvailable = (current_score != null); %> <%-- Breadcrumbs --%> @@ -103,6 +128,26 @@ <% } %> <%-- Cancel (Go Back) --%> + +

+ <%=request.getParameter("title")%> +

+

+ <%=request.getParameter("description")%> +

+ + <% if(isDisplayDesignImage) { %> +
+ +
+ <% } %> + + <% if(isScoreAvailable) { %> +
+ You have completed this lesson. +
+ <% } %> +