package org.sakaiproject.lessonbuildertool.cc; /*********** * This code is based on a reference implementation done for the IMS Consortium. * The copyright notice for that implementation is included below. * All modifications are covered by the following copyright notice. * * Copyright (c) 2011 Rutgers, the State University of New Jersey * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /********************************************************************************** * $URL: http://ims-dev.googlecode.com/svn/trunk/cc/IMS_CCParser_v1p0/src/main/java/org/imsglobal/cc/PrintHandler.java $ * $Id: PrintHandler.java 227 2011-01-08 18:26:55Z drchuck $ ********************************************************************************** * * Copyright (c) 2010 IMS Global Learning Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * **********************************************************************************/ import org.jdom.Element; import org.jdom.Namespace; import org.jdom.output.XMLOutputter; import org.jdom.filter.ElementFilter; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.util.HashMap; import java.util.Properties; import java.util.Iterator; import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.PrintWriter; import java.io.FileOutputStream; import java.io.CharArrayWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.net.URLEncoder; import org.sakaiproject.util.Validator; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.content.cover.ContentHostingService; import org.sakaiproject.content.cover.ContentTypeImageService; import org.sakaiproject.lessonbuildertool.SimplePage; import org.sakaiproject.lessonbuildertool.SimplePageItem; import org.sakaiproject.lessonbuildertool.tool.beans.SimplePageBean; import org.sakaiproject.lessonbuildertool.service.GroupPermissionsService; import org.sakaiproject.lessonbuildertool.model.SimplePageToolDao; import org.sakaiproject.content.api.ContentCollectionEdit; import org.sakaiproject.content.api.ContentCollection; import org.sakaiproject.content.api.ContentResourceEdit; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.ResourcePropertiesEdit; import org.sakaiproject.exception.IdUsedException; import org.sakaiproject.event.api.NotificationService; import org.sakaiproject.lessonbuildertool.cc.QtiImport; import org.sakaiproject.lessonbuildertool.service.LessonEntity; import org.sakaiproject.lessonbuildertool.service.QuizEntity; import org.sakaiproject.lessonbuildertool.service.ForumInterface; import org.sakaiproject.lessonbuildertool.service.BltiInterface; import org.sakaiproject.lessonbuildertool.service.AssignmentInterface; import org.sakaiproject.component.cover.ComponentManager; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.sakaiproject.tool.assessment.services.qti.QTIService; import org.sakaiproject.tool.assessment.qti.constants.QTIVersion; /* PJN NOTE: * This class is an example of what an implementer might want to do as regards overloading DefaultHandler. * In this case, messages are written to the screen. If a method in default handler is not overridden, then it does * nothing. */ public class PrintHandler extends DefaultHandler implements AssessmentHandler, DiscussionHandler, AuthorizationHandler, MetadataHandler, LearningApplicationResourceHandler, QuestionBankHandler, WebContentHandler, WebLinkHandler{ private static final String HREF="href"; private static final String TYPE="type"; private static final String FILE="file"; private static final String XML=".xml"; private static final String URL="url"; private static final String TITLE="title"; private static final String TEXT="text"; private static final String TEXTTYPE="texttype"; private static final String TEXTHTML="text/html"; private static final String DESCRIPTION="description"; private static final String GENERAL="general"; private static final String STRING="string"; private static final String ATTACHMENT="attachment"; private static final String ATTACHMENTS="attachments"; private static final String INTENDEDUSE="intendeduse"; private static final String CC_ITEM_TITLE="title"; private static final String CC_WEBCONTENT="webcontent"; private static final String CC_WEBLINK0="imswl_xmlv1p0"; private static final String CC_WEBLINK1="imswl_xmlv1p1"; private static final String CC_WEBLINK2="imswl_xmlv1p2"; private static final String CC_TOPIC0="imsdt_xmlv1p0"; private static final String CC_TOPIC1="imsdt_xmlv1p1"; private static final String CC_TOPIC2="imsdt_xmlv1p2"; private static final String CC_ASSESSMENT0="imsqti_xmlv1p2/imscc_xmlv1p0/assessment"; private static final String CC_ASSESSMENT1="imsqti_xmlv1p2/imscc_xmlv1p1/assessment"; private static final String CC_ASSESSMENT2="imsqti_xmlv1p2/imscc_xmlv1p2/assessment"; private static final String CC_QUESTION_BANK0="imsqti_xmlv1p2/imscc_xmlv1p0/question-bank"; private static final String CC_QUESTION_BANK1="imsqti_xmlv1p2/imscc_xmlv1p1/question-bank"; private static final String CC_QUESTION_BANK2="imsqti_xmlv1p2/imscc_xmlv1p2/question-bank"; private static final String CC_BLTI0="imsbasiclti_xmlv1p0"; private static final String CC_BLTI1="imsbasiclti_xmlv1p1"; private static final boolean all = false; private static final int MAX_ATTEMPTS = 100; private List<SimplePage> pages = new ArrayList<SimplePage>(); // list parallel to pages containing sequence of last item on the page private List<Integer> sequences= new ArrayList<Integer>(); CartridgeLoader utils = null; SimplePageToolDao simplePageToolDao = null; private String title = null; private String description = null; private String baseName = null; private String baseUrl = null; private String siteId = null; private LessonEntity quiztool = null; private LessonEntity topictool = null; private LessonEntity bltitool = null; private LessonEntity assigntool = null; private Set<String>roles = null; boolean usesRole = false; boolean usesPatternMatch = false; boolean usesCurriculum = false; boolean importtop = false; Integer assignmentNumber = 1; // this is the CC file name for all files added private Set<String> filesAdded = new HashSet<String>(); // this is the CC file name (of the XML file) -> Sakaiid for non-file items private Map<String,String> itemsAdded = new HashMap<String,String>(); public PrintHandler(SimplePageBean bean, CartridgeLoader utils, SimplePageToolDao dao, LessonEntity q, LessonEntity l, LessonEntity b, LessonEntity a, boolean itop) { super(); this.utils = utils; this.simplePageBean = bean; this.simplePageToolDao = dao; this.siteId = bean.getCurrentSiteId(); this.quiztool = q; this.topictool = l; this.bltitool = b; this.assigntool = a; this.importtop = itop; } public void setAssessmentDetails(String the_ident, String the_title) { if (all) System.err.println("assessment ident: "+the_ident +" title: "+the_title); } public void endCCFolder() { if (all) System.err.println("cc folder ends"); int top = pages.size()-1; sequences.remove(top); pages.remove(top); } public void endCCItem() { if (all) System.err.println("cc item ends"); } public void startCCFolder(Element folder) { String title = this.title; if (folder != null) title = folder.getChildText(TITLE, ns.cc_ns()); // add top level pages to left margin SimplePage page = null; if (pages.size() == 0) { page = simplePageBean.addPage(title, false); // add new top level page if (description != null && !description.trim().equals("")) { SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), 1, SimplePageItem.TEXT, "", ""); item.setHtml(Validator.escapeHtml(description)); simplePageBean.saveItem(item); sequences.add(2); } else sequences.add(1); } else { page = simplePageToolDao.makePage("0", siteId, title, 0L, 0L); simplePageBean.saveItem(page); SimplePage parent = pages.get(pages.size()-1); int seq = simplePageBean.getItemsOnPage(parent.getPageId()).size() + 1; SimplePageItem item = simplePageToolDao.makeItem(parent.getPageId(), seq, SimplePageItem.PAGE, Long.toString(page.getPageId()), title); simplePageBean.saveItem(item); sequences.add(1); } pages.add(page); } public void startCCItem(String the_id, String the_title) { if (all) { System.err.println("cc item "+the_id+" begins"); System.err.println("title: "+the_title); } } private ContentCollection makeBaseFolder(String name) { if (siteId == null) { simplePageBean.setErrKey("simplepage.nosite", ""); return null; } if (importtop) { try { ContentCollection top = ContentHostingService.getCollection(ContentHostingService.getSiteCollection(siteId)); return top; } catch (Exception e) { simplePageBean.setErrKey("simplepage.create.resource.failed",name + " " +e); return null; } } if (name == null) name = "Common Cartridge"; if (name.trim().length() == 0) name = "Common Cartridge"; // we must reject certain characters that we cannot even escape and get into Tomcat via a URL StringBuffer newname = new StringBuffer(ContentHostingService.getSiteCollection(siteId)); int length = name.length(); for (int i = 0; i < length; i++) { if (Validator.INVALID_CHARS_IN_RESOURCE_ID.indexOf(name.charAt(i)) != -1) newname.append("_"); else newname.append(name.charAt(i)); } length = newname.length(); if (length > (ContentHostingService.MAXIMUM_RESOURCE_ID_LENGTH - 5)) length = ContentHostingService.MAXIMUM_RESOURCE_ID_LENGTH - 5; // for trailing / and possible count newname.setLength(length); name = newname.toString() + "1"; ContentCollectionEdit collection = null; int tries = 1; int olength = name.length(); for (; tries <= MAX_ATTEMPTS; tries++) { try { collection = ContentHostingService.addCollection(name + "/"); // append / here because we may hack on the name String display = name; int main = name.lastIndexOf("/"); if (main >= 0) display = display.substring(main+1); collection.getPropertiesEdit().addProperty(ResourceProperties.PROP_DISPLAY_NAME, display); ContentHostingService.commitCollection(collection); break; // got it } catch (IdUsedException e) { name = name.substring(0, olength) + "-" + tries; } catch (Exception e) { simplePageBean.setErrKey("simplepage.create.resource.failed",name + " " +e); return null; } } if (collection == null) { simplePageBean.setErrKey("simplepage.resource100", name); return null; } return collection; } private String getFileName(Element resource) { Element file = resource.getChild(FILE, ns.cc_ns()); if (file != null) return file.getAttributeValue(HREF); else return null; } public String getGroupForRole(String role) { // if group already exists, this will return the existing one try { return GroupPermissionsService.makeGroup(siteId, role); } catch (Exception e) { System.err.println("Unable to create group " + role); return null; } } public void setCCItemXml(Element the_xml, Element resource, AbstractParser parser, CartridgeLoader loader, boolean nopage) { if (all) System.err.println("\nadd item to page " + pages.get(pages.size()-1).getTitle() + " xml: "+the_xml + " title " + (the_xml==null?"Question Pool" : the_xml.getChildText(CC_ITEM_TITLE, ns.cc_ns())) + " type " + resource.getAttributeValue(TYPE) + " href " + resource.getAttributeValue(HREF)); String type = resource.getAttributeValue(TYPE); boolean isBank = type.equals(CC_QUESTION_BANK0) || type.equals(CC_QUESTION_BANK1) || type.equals(CC_QUESTION_BANK2); boolean hide = false; List<String>roles = new ArrayList<String>(); Iterator mdroles = resource.getDescendants(new ElementFilter("intendedEndUserRole", ns.lom_ns())); if (mdroles != null) { while (mdroles.hasNext()) { Element role = (Element)mdroles.next(); if (!"Learner".equals(role.getChildText("value", ns.lom_ns()))) { usesRole = true; } if ("Mentor".equals(role.getChildText("value", ns.lom_ns()))) { roles.add(getGroupForRole("Mentor")); } if ("Instructor".equals(role.getChildText("value", ns.lom_ns()))) { roles.add(getGroupForRole("Instructor")); } } } if (nopage) hide = true; // for question banks we don't need a current page, as we don't put banks on a page if (pages.size() == 0 && !isBank && !nopage) startCCFolder(null); int top = pages.size()-1; SimplePage page = (isBank || nopage) ? null : pages.get(top); Integer seq = (isBank || nopage) ? 0 : sequences.get(top); String title = null; if (the_xml == null) title = "Question Pool"; else title = the_xml.getChildText(CC_ITEM_TITLE, ns.cc_ns()); try { if (type.equals(CC_WEBCONTENT) && !hide) { // note: when this code is called the actual sakai resource hasn't been created yet String sakaiId = baseName + resource.getAttributeValue(HREF); String extension = Validator.getFileExtension(sakaiId); String mime = ContentTypeImageService.getContentType(extension); String intendedUse = resource.getAttributeValue(INTENDEDUSE); SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.RESOURCE, sakaiId, title); item.setHtml(mime); item.setSameWindow(true); if (intendedUse != null) { intendedUse = intendedUse.toLowerCase(); if (intendedUse.equals("lessonplan")) item.setDescription(simplePageBean.getMessageLocator().getMessage("simplepage.import_cc_lessonplan")); else if (intendedUse.equals("syllabus")) item.setDescription(simplePageBean.getMessageLocator().getMessage("simplepage.import_cc_syllabus")); else if (assigntool != null && intendedUse.equals("assignment")) { String fileName = getFileName(resource); if (itemsAdded.get(fileName) == null) { // itemsAdded.put(fileName, SimplePageItem.DUMMY); // don't add the same test more than once AssignmentInterface a = (AssignmentInterface) assigntool; // file hasn't been written yet to contenthosting. A2 requires it to be there addFile(resource.getAttributeValue(HREF)); String assignmentId = a.importObject(title, sakaiId, mime); // sakaiid for assignment if (assignmentId!= null) { item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.ASSIGNMENT, assignmentId, title); sakaiId = assignmentId; } } } } simplePageBean.saveItem(item); if (roles.size() > 0) { // has to be written already or we can't set groups // file hasn't been written yet to contenthosting. setitemgroups requires it to be there addFile(resource.getAttributeValue(HREF)); simplePageBean.setItemGroups(item, roles.toArray(new String[0])); } sequences.set(top, seq+1); } else if (type.equals(CC_WEBCONTENT)) { // i.e. hidden. if it's an assignment have to load it String intendedUse = resource.getAttributeValue(INTENDEDUSE); if (assigntool != null && intendedUse != null && intendedUse.equals("assignment")) { String fileName = getFileName(resource); if (itemsAdded.get(fileName) == null) { itemsAdded.put(fileName, SimplePageItem.DUMMY); // don't add the same test more than once String sakaiId = baseName + resource.getAttributeValue(HREF); String extension = Validator.getFileExtension(sakaiId); String mime = ContentTypeImageService.getContentType(extension); AssignmentInterface a = (AssignmentInterface) assigntool; // file hasn't been written yet to contenthosting. A2 requires it to be there addFile(resource.getAttributeValue(HREF)); // in this case there's no item to take a title from String atitle = simplePageBean.getMessageLocator().getMessage("simplepage.importcc-assigntitle").replace("{}", (assignmentNumber++).toString()); String assignmentId = a.importObject(atitle, sakaiId, mime); // sakaiid for assignment } } } else if (type.equals(CC_WEBLINK0) || type.equals(CC_WEBLINK1) || type.equals(CC_WEBLINK2)){ String filename = getFileName(resource); Element linkXml = parser.getXML(loader, filename); Namespace linkNs = ns.link_ns(); Element urlElement = linkXml.getChild(URL, linkNs); String url = urlElement.getAttributeValue(HREF); // the name must end in XML, so we can just turn it into URL filename = filename.substring(0, filename.length()-3) + "url"; String sakaiId = baseName + filename; if (! filesAdded.contains(filename)) { // we store the URL as a text/url resource ContentResourceEdit edit = ContentHostingService.addResource(sakaiId); edit.setContentType("text/url"); edit.setResourceType("org.sakaiproject.content.types.urlResource"); edit.setContent(url.getBytes("UTF-8")); edit.getPropertiesEdit().addProperty(ResourceProperties.PROP_DISPLAY_NAME, Validator.escapeResourceName(filename)); ContentHostingService.commitResource(edit, NotificationService.NOTI_NONE); filesAdded.add(filename); } if (!hide) { // now create the Sakai item SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.RESOURCE, sakaiId, title); item.setHtml(simplePageBean.getTypeOfUrl(url)); // checks the web site to see what it actually is item.setSameWindow(true); simplePageBean.saveItem(item); if (roles.size() > 0) simplePageBean.setItemGroups(item, roles.toArray(new String[0])); sequences.set(top, seq+1); } } else if (topictool != null && ( type.equals(CC_TOPIC0) || type.equals(CC_TOPIC1) || type.equals(CC_TOPIC2))){ String filename = getFileName(resource); Element topicXml = parser.getXML(loader, filename); Namespace topicNs = ns.topic_ns(); String topicTitle = topicXml.getChildText(TITLE, topicNs); if (topicTitle == null) topicTitle = simplePageBean.getMessageLocator().getMessage("simplepage.cc-defaulttopic"); String text = topicXml.getChildText(TEXT, topicNs); boolean texthtml = false; if (text != null) { Element textNode = topicXml.getChild(TEXT, topicNs); String textformat = textNode.getAttributeValue(TEXTTYPE); if (TEXTHTML.equalsIgnoreCase(textformat)) texthtml = true; } String base = baseUrl + filename; int slash = base.lastIndexOf("/"); if (slash >= 0) base = base.substring(0, slash+1); // include trailing slash if (texthtml) { text = text.replaceAll("\\$IMS-CC-FILEBASE\\$", base); } // I'm going to assume that URLs in the CC files are legal, but if // I add to them I nneed to URLencode what I add Element attachmentlist = topicXml.getChild(ATTACHMENTS, topicNs); List<Element>attachments = new ArrayList<Element>(); if (attachmentlist != null) attachments = attachmentlist.getChildren(); List<String>attachmentHrefs = new ArrayList<String>(); for (Element a: attachments) attachmentHrefs.add(a.getAttributeValue(HREF)); ForumInterface f = (ForumInterface)topictool; if (nopage) title = simplePageBean.getMessageLocator().getMessage("simplepage.cc-defaultforum"); // System.out.println("about to call forum import base " + base); // title is for the cartridge. That will be used as the forum // if already added, don't do it again String sakaiId = itemsAdded.get(filename); if (sakaiId == null) { if ( f != null ) sakaiId = f.importObject(title, topicTitle, text, texthtml, base, siteId, attachmentHrefs, hide); if (sakaiId != null) itemsAdded.put(filename, sakaiId); } if (!hide) { // System.out.println("about to add formum item"); SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.FORUM, sakaiId, title); simplePageBean.saveItem(item); if (roles.size() > 0) simplePageBean.setItemGroups(item, roles.toArray(new String[0])); sequences.set(top, seq+1); // System.out.println("finished with forum item"); } } else if (quiztool != null && ( type.equals(CC_ASSESSMENT0) || type.equals(CC_ASSESSMENT1) || type.equals (CC_ASSESSMENT2) || type.equals(CC_QUESTION_BANK0) || type.equals(CC_QUESTION_BANK1) || type.equals(CC_QUESTION_BANK2))) { String fileName = getFileName(resource); String sakaiId = null; if (itemsAdded.get(fileName) == null) { itemsAdded.put(fileName, SimplePageItem.DUMMY); // don't add the same test more than once InputStream instream = utils.getFile(fileName); // ByteArrayOutputStream baos = new ByteArrayOutputStream(); //PrintWriter outwriter = new PrintWriter(baos); File qtitemp = File.createTempFile("ccqti", "txt"); PrintWriter outwriter = new PrintWriter(qtitemp); // I'm going to assume that URLs in the CC files are legal, but if // I add to them I nneed to URLencode what I add String base = baseUrl + fileName; int slash = base.lastIndexOf("/"); if (slash >= 0) base = base.substring(0, slash+1); // include trailing slash QtiImport imp = new QtiImport(); try { boolean thisUsesPattern = imp.mainproc(instream, outwriter, isBank, base, siteId, simplePageBean); if (thisUsesPattern) usesPatternMatch = true; if (imp.getUsesCurriculum()) usesCurriculum = true; } catch (Exception e) { e.printStackTrace(); } outwriter.close(); InputStream inputStream = new FileInputStream(qtitemp); try { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setNamespaceAware(true); builderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); builderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(inputStream); QuizEntity q = (QuizEntity)quiztool; sakaiId = q.importObject(document, isBank, siteId, hide); if (sakaiId == null) sakaiId = SimplePageItem.DUMMY; } catch (Exception e) { System.out.println("CC import error creating or parsing QTI file " + fileName + " " + e); simplePageBean.setErrKey("simplepage.create.object.failed", e.toString()); } inputStream.close(); qtitemp.delete(); } // question banks don't appear on the page if (!isBank && !hide) { SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.ASSESSMENT, (sakaiId == null ? SimplePageItem.DUMMY : sakaiId), title); simplePageBean.saveItem(item); if (roles.size() > 0) simplePageBean.setItemGroups(item, roles.toArray(new String[0])); sequences.set(top, seq+1); } } else if (type.equals(CC_QUESTION_BANK0) || type.equals(CC_QUESTION_BANK1)) ; // handled elsewhere // current code seems to assume that BLTI tool is part of the page so skip if no page else if (!nopage && (type.equals(CC_BLTI0) || type.equals(CC_BLTI1))) { String filename = getFileName(resource); Element ltiXml = parser.getXML(loader, filename); XMLOutputter outputter = new XMLOutputter(); String strXml = outputter.outputString(ltiXml); Namespace bltiNs = ns.blti_ns(); String bltiTitle = ltiXml.getChildText(TITLE, bltiNs); Element customElement = ltiXml.getChild("custom", bltiNs); List<Element>customs = new ArrayList<Element>(); if (customElement != null) customs = customElement.getChildren(); StringBuffer sb = new StringBuffer(); String custom = null; for (Element a: customs) { String key = a.getAttributeValue("name"); String value = a.getText(); if ( key == null ) continue; key = key.trim(); if ( value == null ) continue; sb.append(key.trim()); sb.append("="); sb.append(value.trim()); sb.append("\n"); } if ( sb.length() > 0 ) custom = sb.toString(); String launchUrl = ltiXml.getChildText("secure_launch_url", bltiNs); if ( launchUrl == null ) launchUrl = ltiXml.getChildText("launch_url", bltiNs); String sakaiId = null; if ( bltitool != null ) { sakaiId = ((BltiInterface) bltitool).doImportTool(launchUrl, bltiTitle, strXml, custom); } if (!hide) { if ( sakaiId != null) { // System.out.println("Adding LTI content item "+sakaiId); SimplePageItem item = simplePageToolDao.makeItem(page.getPageId(), seq, SimplePageItem.BLTI, sakaiId, title); item.setHeight(""); // default depends upon format, so it's supplied at runtime simplePageBean.saveItem(item); if (roles.size() > 0) simplePageBean.setItemGroups(item, roles.toArray(new String[0])); sequences.set(top, seq+1); } else { System.out.println("LTI Import Failed.."); } } } else if (type.equals(CC_WEBCONTENT) && hide) { // handled elsewhere } else System.err.println("implemented type: " + resource.getAttributeValue(TYPE)); } catch (Exception e) { e.printStackTrace(); System.err.println(">>>Exception " + e); } } public void addAttachment(String attachment_path) { if (all) System.err.println("adding an attachment: "+attachment_path); } public void endDiscussion() { if (all) System.err.println("end discussion"); } public void startManifest() { if (all) System.err.println("start manifest"); } public void checkCurriculum(Element the_xml) { Element md = the_xml.getChild("curriculumStandardsMetadataSet",ns.csmd_ns()); if (md != null) { if (md.getChild("curriculumStandardsMetadata",ns.csmd_ns()) != null) { usesCurriculum = true; } } } public void setManifestXml(Element the_xml) { if (all) System.err.println("manifest xml: "+the_xml); } public void endManifest() { if (all) System.err.println("end manifest"); if (usesRole) simplePageBean.setErrKey("simplepage.cc-uses-role", null); // the pattern match is restricted enough that we can actually do it // if (usesPatternMatch) // simplePageBean.setErrKey("simplepage.import_cc_usespattern", null); if (usesCurriculum) simplePageBean.setErrKey("simplepage.cc-uses-curriculum", null); } public void startDiscussion(String topic_name, String text_type, String text, boolean isProtected) { if (all){ System.err.println("start a discussion: "+topic_name); System.err.println("text type: "+text_type); System.err.println("text: "+text); System.err.println("protected: "+isProtected); } } public void endWebLink() { if (all) System.err.println("end weblink"); } public void startWebLink(String the_title, String the_url, String the_target, String the_window_features, boolean isProtected) { if (all) { System.err.println("start weblink: "+the_title); System.err.println("link to: "+the_url); System.err.println("target window: "+the_target); System.err.println("window features: "+the_window_features); System.err.println("protected: "+isProtected); } } public void setWebLinkXml(Element the_link) { if (all) System.err.println("weblink xml: "+the_link); } public void addFile(String the_file_id) { if (filesAdded.contains(the_file_id)) return; InputStream infile = null; for (int tries = 1; tries < 3; tries++) { try { infile = utils.getFile(the_file_id); String name = the_file_id; int slash = the_file_id.lastIndexOf("/"); if (slash >=0 ) name = name.substring(slash+1); String extension = Validator.getFileExtension(name); String type = ContentTypeImageService.getContentType(extension); ContentResourceEdit edit = ContentHostingService.addResource(baseName + the_file_id); edit.setContentType(type); edit.setContent(infile); edit.getPropertiesEdit().addProperty(ResourceProperties.PROP_DISPLAY_NAME, name); // if roles specified for this resource and student not in it, hide it if (roles != null && !roles.contains("Learner")) edit.setAvailability(true, null, null); ContentHostingService.commitResource(edit, NotificationService.NOTI_NONE); filesAdded.add(the_file_id); } catch (IdUsedException e) { // remove existing if we are importing whole site. // otherwise this is an error (and should be impossible, as this is a new directory) if (importtop && tries == 1) { try { ContentHostingService.removeResource(baseName + the_file_id); continue; } catch (Exception e1) { } } simplePageBean.setErrKey("simplepage.create.resource.failed", e + ": " + the_file_id); System.out.println("CC loader: unable to get file " + the_file_id + " error: " + e); } catch (Exception e) { simplePageBean.setErrKey("simplepage.create.resource.failed", e + ": " + the_file_id); System.out.println("CC loader: unable to get file " + the_file_id + " error: " + e); } break; // if we get to the end, no need to retry; really a goto would be clearer } } public void endWebContent() { if (all) System.err.println("ending webcontent"); } public void startWebContent(String entry_point, boolean isProtected) { if (all) { System.err.println("start web content"); System.err.println("protected: "+isProtected); if (entry_point!=null) { System.err.println("entry point is: "+entry_point); } } } public void endLearningApplicationResource() { if (all) System.err.println("end learning application resource"); } public void startLearningApplicationResource(String entry_point, boolean isProtected) { if (all) { System.err.println("start learning application resource"); System.err.println("protected: "+isProtected); if (entry_point!=null) { System.err.println("entry point is: "+entry_point); } } } public void endAssessment() { if (all) System.err.println("end assessment"); } public void setAssessmentXml(Element xml) { if (all) System.err.println("assessment xml: "+xml); } public void startAssessment(String the_file_name, boolean isProtected) { if (all) { System.err.println("start assessment contained in: "+the_file_name); System.err.println("protected: "+isProtected); } } public void endQuestionBank() { if (all) System.err.println("end question bank"); } public void setQuestionBankXml(Element the_xml) { if (all) System.err.println("question bank xml: "+the_xml); } public void startQuestionBank(String the_file_name, boolean isProtected) { if (all) { System.err.println("start question bank in: "+the_file_name); System.err.println("protected: "+isProtected); } } public void setAuthorizationServiceXml(Element the_node) { if (all) System.err.println(the_node); } public void setAuthorizationService(String cartridgeId, String webservice_url) { if (all) System.err.println("adding auth service for "+cartridgeId+" @ "+webservice_url); } public void endAuthorization() { if (all) System.err.println("end of authorizations"); } public void startAuthorization(boolean isCartridgeScope, boolean isResourceScope, boolean isImportScope) { if (all) { System.err.println("start of authorizations"); System.err.println("protect all: "+isCartridgeScope); System.err.println("protect resources: "+isResourceScope); System.err.println("protect import: "+isImportScope); } } public void endManifestMetadata() { if (all) System.err.println("end of manifest metadata"); } public void startManifestMetadata(String schema, String schema_version) { if (all) { System.err.println("start manifest metadata"); System.err.println("schema: "+schema); System.err.println("schema_version: "+schema_version); } } public void setPresentationXml(Element the_xml) { if (all) System.err.println("QTI presentation xml: "+the_xml); } public void setQTICommentXml(Element the_xml) { if (all) System.err.println("QTI comment xml: "+the_xml); } public void setSection(String ident, String title) { if (all) { System.err.println("set section ident: "+ident); System.err.println("set section title: "+title); } } public void setSectionXml(Element the_xml) { if (all) System.err.println("set Section Xml: "+the_xml); } public void endQTIMetadata() { if (all) System.err.println("end of QTI metadata"); } public void setManifestMetadataXml(Element the_md) { if (all) System.err.println("manifest md xml: "+the_md); // NOTE: need to handle languages if (the_md != null) { Element general = the_md.getChild(GENERAL, ns.lomimscc_ns()); if (general != null) { Element tnode = general.getChild(TITLE, ns.lomimscc_ns()); if (tnode != null) { title = tnode.getChildTextTrim(STRING, ns.lomimscc_ns()); } Element tdescription=general.getChild(DESCRIPTION, ns.lomimscc_ns()); if (tdescription != null) { description = tdescription.getChildTextTrim(STRING, ns.lomimscc_ns()); } } } if (title == null || title.equals("")) title = "Cartridge"; if ("".equals(description)) description = null; ContentCollection baseCollection = makeBaseFolder(title); baseName = baseCollection.getId(); baseUrl = baseCollection.getUrl(); // kill the hostname part. We want to use relative URLs int relPart = baseUrl.indexOf("/access/"); if (relPart >= 0) baseUrl = baseUrl.substring(relPart); } public void setResourceMetadataXml(Element the_md) { Iterator mdroles = the_md.getDescendants(new ElementFilter("intendedEndUserRole", ns.lom_ns())); while (mdroles.hasNext()) { Element role = (Element)mdroles.next(); if (roles == null) roles = new HashSet<String>(); roles.add(role.getChildText("value", ns.lom_ns())); } if (all) System.err.println("resource md xml: "+the_md); } public void addQTIMetadataField(String label, String entry) { if (all) { System.err.println("QTI md label: "+label); System.err.println("QTI md entry: "+entry); } } public void setQTIComment(String the_comment) { if (all) System.err.println("QTI comment: "+the_comment); } public void endDependency() { if (all) System.err.println("end dependency"); } public void startDependency(String source, String target) { if (all) System.err.println("start dependency- resource : "+source+" is dependent upon: "+target); } public void startResource(String id, boolean isProtected) { roles = null; if (all) System.err.println("start resource: "+id+ " protected: "+isProtected); } public void setResourceXml(Element the_xml) { if (all) System.err.println("resource xml: "+the_xml); } public void endResource() { if (all) System.err.println("end resource"); } public void addAssessmentItem(QTIItem the_item) { if (all) System.err.println("add QTI assessment item: "+the_item.toString()); } public void addQTIMetadataXml(Element the_md) { if (all) System.err.println("add QTI metadata xml: "+the_md); } public void startQTIMetadata() { if (all) System.err.println("start QTI metadata"); } public void setDiscussionXml(Element the_element) { if (all) System.err.println("set discussion xml: "+the_element); } public void addQuestionBankItem(QTIItem the_item) { if (all) System.err.println("add QTI QB item: "+the_item.toString()); } public void setQuestionBankDetails(String the_ident) { if (all) System.err.println("set qti qb details: "+the_ident); } }