001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/trunk/component/src/java/org/sakaiproject/tool/assessment/services/qti/QTIService.java $
003: * $Id: QTIService.java 9273 2006-05-10 22:34:28Z daisyf@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2007 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.assessment.contentpackaging;
021:
022: import java.io.IOException;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Set;
026:
027: import javax.xml.parsers.ParserConfigurationException;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.dom4j.Document;
032: import org.dom4j.DocumentException;
033: import org.dom4j.DocumentHelper;
034: import org.dom4j.Element;
035: import org.dom4j.Namespace;
036: import org.dom4j.QName;
037: import org.dom4j.io.DOMWriter;
038: import org.sakaiproject.component.cover.ServerConfigurationService;
039: import org.sakaiproject.content.cover.ContentHostingService;
040: import org.sakaiproject.exception.IdUnusedException;
041: import org.sakaiproject.exception.PermissionException;
042: import org.sakaiproject.exception.ServerOverloadException;
043: import org.sakaiproject.exception.TypeException;
044: import org.sakaiproject.tool.assessment.data.dao.assessment.Answer;
045: import org.sakaiproject.tool.assessment.data.dao.assessment.AnswerFeedback;
046: import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentAttachment;
047: import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentData;
048: import org.sakaiproject.tool.assessment.data.dao.assessment.ItemAttachment;
049: import org.sakaiproject.tool.assessment.data.dao.assessment.ItemData;
050: import org.sakaiproject.tool.assessment.data.dao.assessment.ItemFeedback;
051: import org.sakaiproject.tool.assessment.data.dao.assessment.ItemText;
052: import org.sakaiproject.tool.assessment.data.dao.assessment.SectionAttachment;
053: import org.sakaiproject.tool.assessment.data.dao.assessment.SectionData;
054: import org.sakaiproject.tool.assessment.facade.AssessmentFacade;
055: import org.sakaiproject.tool.assessment.facade.SectionFacade;
056: import org.sakaiproject.tool.assessment.qti.util.XmlUtil;
057: import org.sakaiproject.tool.assessment.services.assessment.AssessmentService;
058: import org.sakaiproject.user.api.User;
059: import org.sakaiproject.user.cover.UserDirectoryService;
060: import org.xml.sax.SAXException;
061:
062: /**
063: * <p>
064: * Copyright: Copyright (c) 2007 Sakai
065: * </p>
066: *
067: * @version $Id: ManifestGenerator 9273 2006-05-10 22:34:28Z daisyf@stanford.edu $
068: */
069:
070: public class ManifestGenerator {
071: private static Log log = LogFactory.getLog(ManifestGenerator.class);
072:
073: private String assessmentId;
074:
075: private HashMap contentMap = new HashMap();
076:
077: public ManifestGenerator(String assessmentId) {
078: this .assessmentId = assessmentId;
079: }
080:
081: public String getManifest() {
082: org.w3c.dom.Document document = null;
083: try {
084: Document doc = readXMLDocument();
085: document = new DOMWriter().write(doc);
086: } catch (ParserConfigurationException e) {
087: log.error(e.getMessage());
088: e.printStackTrace();
089: } catch (SAXException e) {
090: log.error(e.getMessage());
091: e.printStackTrace();
092: } catch (IOException e) {
093: log.error(e.getMessage());
094: e.printStackTrace();
095: } catch (DocumentException e) {
096: log.error(e.getMessage());
097: e.printStackTrace();
098: }
099: String xmlString = XmlUtil.getDOMString(document);
100: String newXmlString = xmlString;
101: if (xmlString.startsWith("<?xml version")) {
102: newXmlString = xmlString.replaceFirst("version=\"1.0\"",
103: "version=\"1.0\" encoding=\"UTF-8\"");
104: }
105: log.debug(newXmlString);
106: return newXmlString;
107: }
108:
109: public HashMap getContentMap() {
110: return contentMap;
111: }
112:
113: private Document readXMLDocument()
114: throws ParserConfigurationException, SAXException,
115: IOException {
116:
117: Document document = DocumentHelper.createDocument();
118: Element root = document.addElement("root");
119: root.addAttribute("identifier", "Manifest1");
120: // Set up the necessary namespaces
121: root.setQName(new QName("manifest", new Namespace(null,
122: "http://www.imsglobal.org/xsd/imscp_v1p1")));
123: root.add(new Namespace("imsmd",
124: "http://www.imsglobal.org/xsd/imsmd_v1p2"));
125: root.add(new Namespace("xsi",
126: "http://www.w3.org/2001/XMLSchema-instance"));
127:
128: root
129: .addAttribute(
130: "xsi:schemaLocation",
131: "http://www.imsglobal.org/xsd/imscp_v1p1 "
132: + "http://www.imsglobal.org/xsd/imscp_v1p1.xsd "
133: + "http://www.imsglobal.org/xsd/imsmd_v1p2 "
134: + "http://www.imsglobal.org/xsd/imsmd_v1p2.xsd ");
135:
136: root.addElement("organizations");
137:
138: Element resourcesElement = DocumentHelper
139: .createElement("resources");
140: root.add(resourcesElement);
141:
142: Element resourceElement = DocumentHelper
143: .createElement("resource");
144: resourceElement.addAttribute("identifier", "Resource1");
145: resourcesElement.add(resourceElement);
146:
147: getAttachments();
148: getFCKAttachments();
149: Iterator iter = contentMap.keySet().iterator();
150: Element fileElement = null;
151: String filename = null;
152: while (iter.hasNext()) {
153: filename = ((String) iter.next()).replaceAll(" ", "");
154: fileElement = resourceElement.addElement("file");
155: fileElement.addAttribute("href", filename);
156: }
157: return document;
158: }
159:
160: private void getAttachments() {
161: try {
162: AssessmentService assessmentService = new AssessmentService();
163: AssessmentFacade assessment = assessmentService
164: .getAssessment(assessmentId);
165:
166: // Assessment attachment
167: AssessmentData assessmentData = (AssessmentData) assessment
168: .getData();
169: Set assessmentAttachmentSet = assessmentData
170: .getAssessmentAttachmentSet();
171: Iterator assessmentAttachmentIter = assessmentAttachmentSet
172: .iterator();
173: byte[] content = null;
174: String resourceId = null; // resoureId is also the filename (whole
175: // path) in the zip file
176: while (assessmentAttachmentIter.hasNext()) {
177: AssessmentAttachment assessmentAttachment = (AssessmentAttachment) assessmentAttachmentIter
178: .next();
179: resourceId = assessmentAttachment.getResourceId();
180: content = ContentHostingService.getResource(resourceId)
181: .getContent();
182: contentMap.put(resourceId.replace(" ", ""), content);
183: }
184:
185: // Section attachment
186: Set sectionSet = assessment.getSectionSet();
187: Iterator sectionIter = sectionSet.iterator();
188: SectionData sectionData = null;
189: Set sectionAttachmentSet = null;
190: Iterator sectionAttachmentIter = null;
191: SectionAttachment sectionAttachment = null;
192: Set itemSet = null;
193: ItemData itemData = null;
194: Set itemAttachmentSet = null;
195: Iterator itemAttachmentIter = null;
196: ItemAttachment itemAttachment = null;
197: while (sectionIter.hasNext()) {
198: sectionData = (SectionData) ((SectionFacade) sectionIter
199: .next()).getData();
200: sectionAttachmentSet = sectionData
201: .getSectionAttachmentSet();
202: sectionAttachmentIter = sectionAttachmentSet.iterator();
203: while (sectionAttachmentIter.hasNext()) {
204: sectionAttachment = (SectionAttachment) sectionAttachmentIter
205: .next();
206: resourceId = sectionAttachment.getResourceId();
207: content = ContentHostingService.getResource(
208: resourceId).getContent();
209: contentMap
210: .put(resourceId.replace(" ", ""), content);
211: }
212:
213: itemSet = sectionData.getItemSet();
214: Iterator itemIter = itemSet.iterator();
215: while (itemIter.hasNext()) {
216: itemData = (ItemData) itemIter.next();
217: itemAttachmentSet = itemData.getItemAttachmentSet();
218: itemAttachmentIter = itemAttachmentSet.iterator();
219: while (itemAttachmentIter.hasNext()) {
220: itemAttachment = (ItemAttachment) itemAttachmentIter
221: .next();
222: resourceId = itemAttachment.getResourceId();
223: content = ContentHostingService.getResource(
224: resourceId).getContent();
225: contentMap.put(resourceId.replace(" ", ""),
226: content);
227: }
228: }
229: }
230:
231: } catch (PermissionException e) {
232: log.error(e.getMessage());
233: e.printStackTrace();
234: } catch (IdUnusedException e) {
235: log.error(e.getMessage());
236: e.printStackTrace();
237: } catch (TypeException e) {
238: log.error(e.getMessage());
239: e.printStackTrace();
240: } catch (ServerOverloadException e) {
241: log.error(e.getMessage());
242: e.printStackTrace();
243: }
244: }
245:
246: private void getFCKAttachments() {
247: AssessmentService assessmentService = new AssessmentService();
248: AssessmentFacade assessment = assessmentService
249: .getAssessment(assessmentId);
250:
251: // Assessment FCK attachment
252: AssessmentData assessmentData = (AssessmentData) assessment
253: .getData();
254: processDescription(assessmentData.getDescription());
255: processDescription(assessmentData.getAssessmentAccessControl()
256: .getSubmissionMessage());
257:
258: // Section FCK attachment
259: Set sectionSet = assessment.getSectionSet();
260: Iterator sectionIter = sectionSet.iterator();
261: SectionData sectionData = null;
262: Set itemSet = null;
263: ItemData itemData = null;
264:
265: while (sectionIter.hasNext()) {
266: sectionData = (SectionData) ((SectionFacade) sectionIter
267: .next()).getData();
268: processDescription(sectionData.getDescription());
269:
270: itemSet = sectionData.getItemSet();
271: Iterator itemIter = itemSet.iterator();
272: while (itemIter.hasNext()) {
273: itemData = (ItemData) itemIter.next();
274: // Question Text
275: Set itemTextSet = itemData.getItemTextSet();
276: ItemText itemText = null;
277: Iterator itemTextIter = itemTextSet.iterator();
278: while (itemTextIter.hasNext()) {
279: itemText = (ItemText) itemTextIter.next();
280: processDescription(itemText.getText());
281:
282: // Answer
283: Set answerSet = itemText.getAnswerSet();
284: Answer answer = null;
285: Iterator answerIter = answerSet.iterator();
286: while (answerIter.hasNext()) {
287: answer = (Answer) answerIter.next();
288: processDescription(answer.getText());
289:
290: // Answer Feedback
291: Set answerFeedbackSet = answer
292: .getAnswerFeedbackSet();
293: AnswerFeedback answerFeedback = null;
294: Iterator answerFeedbackIter = answerFeedbackSet
295: .iterator();
296: while (answerFeedbackIter.hasNext()) {
297: answerFeedback = (AnswerFeedback) answerFeedbackIter
298: .next();
299: processDescription(answerFeedback.getText());
300: }
301: }
302: }
303:
304: // Feedback
305: Set itemFeedbackSet = itemData.getItemFeedbackSet();
306: ItemFeedback itemFeedback = null;
307: Iterator itemFeedbackIter = itemFeedbackSet.iterator();
308: while (itemFeedbackIter.hasNext()) {
309: itemFeedback = (ItemFeedback) itemFeedbackIter
310: .next();
311: processDescription(itemFeedback.getText());
312: }
313: }
314: }
315: }
316:
317: private void processDescription(String description) {
318: String prependString = ServerConfigurationService
319: .getAccessUrl()
320: + ContentHostingService.REFERENCE_ROOT;
321:
322: // Hardcode here for now because I cannot find the API to get them
323: // Also, it is hardcoded in BaseContentService.java
324: String siteCollection = "/group/";
325: String userCollection = "/user/";
326: String attachment = "/attachment/";
327: User user = UserDirectoryService.getCurrentUser();
328: String userId = user.getId();
329: String eid = user.getEid();
330:
331: try {
332: if (description != null
333: && description.indexOf("<img ") > -1) {
334: byte[] content = null;
335: int srcStartIndex = 0;
336: int srcEndIndex = 0;
337: String src = null;
338: String resourceId = null;
339: String eidResourceId = null;
340:
341: String[] splittedString = description.split("<img ");
342: for (int i = 0; i < splittedString.length; i++) {
343: log.debug("splittedString[" + i + "] = "
344: + splittedString[i]);
345: if (splittedString[i].indexOf(prependString) > -1) {
346: srcStartIndex = splittedString[i]
347: .indexOf("src=\"");
348: srcEndIndex = splittedString[i].indexOf("\"",
349: srcStartIndex + 5);
350: src = splittedString[i].substring(
351: srcStartIndex + 5, srcEndIndex);
352:
353: if (src.indexOf(siteCollection) > -1) {
354: resourceId = src.replace(prependString, "");
355: content = ContentHostingService
356: .getResource(resourceId)
357: .getContent();
358: if (content != null) {
359: contentMap.put(resourceId.replace(" ",
360: ""), content);
361: }
362: } else if (src.indexOf(userCollection) > -1) {
363: eidResourceId = src.replace(prependString,
364: "");
365: resourceId = eidResourceId.replace(eid,
366: userId);
367: content = ContentHostingService
368: .getResource(resourceId)
369: .getContent();
370: if (content != null) {
371: contentMap.put(eidResourceId.replace(
372: " ", ""), content);
373: }
374: } else if (src.indexOf(attachment) > -1) {
375: resourceId = src.replace(prependString, "");
376: content = ContentHostingService
377: .getResource(resourceId)
378: .getContent();
379: if (content != null) {
380: contentMap.put(resourceId.replace(" ",
381: ""), content);
382: }
383: } else {
384: log.error("Neither group nor user");
385: }
386: }
387: }
388: }
389: } catch (PermissionException e) {
390: log.error(e.getMessage());
391: e.printStackTrace();
392: } catch (IdUnusedException e) {
393: log.error(e.getMessage());
394: e.printStackTrace();
395: } catch (TypeException e) {
396: log.error(e.getMessage());
397: e.printStackTrace();
398: } catch (ServerOverloadException e) {
399: log.error(e.getMessage());
400: e.printStackTrace();
401: }
402: }
403: }
|