001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/trunk/component/src/java/org/sakaiproject/tool/assessment/business/entity/RecordingData.java $
003: * $Id: RecordingData.java 9273 2006-05-10 22:34:28Z daisyf@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 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.business.entity;
021:
022: import java.io.ByteArrayOutputStream;
023: import java.io.File;
024: import java.io.Serializable;
025: import java.util.StringTokenizer;
026: import javax.xml.parsers.DocumentBuilder;
027: import javax.xml.parsers.DocumentBuilderFactory;
028: import javax.xml.parsers.ParserConfigurationException;
029: import javax.xml.transform.Result;
030: import javax.xml.transform.Source;
031: import javax.xml.transform.Transformer;
032: import javax.xml.transform.TransformerException;
033: import javax.xml.transform.TransformerFactory;
034: import javax.xml.transform.dom.DOMSource;
035: import javax.xml.transform.stream.StreamResult;
036:
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039: import org.w3c.dom.Document;
040: import org.w3c.dom.Element;
041:
042: /**
043: * <p>
044: * Copyright: Copyright (c) 2003
045: * </p>
046: *
047: * <p>
048: * Organization: Stanford University
049: * </p>
050: *
051: * <p>
052: * This class implements common methods for describing data needed to
053: * record/save and retrieve audio recordings.
054: * </p>
055: *
056: * <p>
057: * Usage : <code><br>
058: * <br>
059: * RecordingData rd = new RecordingData("Rachel Gollub", "rgollub", "Intro to
060: * Wolverines and Aardvarks 221B", "10", "25"); log.debug("rgollub
061: * file:" + rd.getFileName() + "." + rd.getFileExtension());
062: * log.debug("limit =" + rd.getLimit());
063: * log.debug("seconds=" + rd.getSeconds()); </code>
064: * </p>
065: *
066: * @author Ed Smiley
067: * @version $Id: RecordingData.java 9273 2006-05-10 22:34:28Z daisyf@stanford.edu $
068: */
069: public class RecordingData implements Serializable {
070: /**
071: *
072: */
073: private static final long serialVersionUID = 4398684269227144959L;
074:
075: private static Log log = LogFactory.getLog(RecordingData.class);
076:
077: //properties
078: private String agentName;
079: private String agentId;
080: private String courseAssignmentContext;
081: private String fileExtension;
082: private String fileName;
083: private String limit;
084: private String dir;
085: private String seconds;
086: private String appName;
087: private String imageURL;
088:
089: /**
090: * Initialize with required data. All other values are assigned a default.
091: * All values can be overridden with the mutators.
092: *
093: * @param agent_name The name of the person uploading the file
094: * @param agent_id The id code of the person uploading the file
095: * @param course_assignment_context The name of the course, assignment, part,
096: * quetion etc.
097: * @param lim limit on number of tries (0=unlimited, default if null)
098: * @param sec limit on time in seconds (30 default if null)
099: *
100: * <p>
101: * Usage : <code><br>
102: * <br>
103: * RecordingData rd = new RecordingData("Rachel Gollub", "rgollub", "Intro to
104: * Wolverines and Aardvarks 221B", "10", "25"); log.debug("rgollub
105: * file:" + rd.getFileName() + "." + rd.getFileExtension());
106: * log.debug("limit =" + rd.getLimit());
107: * log.debug("seconds=" + rd.getSeconds()); </code>
108: * </p>
109: */
110: public RecordingData(String agent_name, String agent_id,
111: String course_assignment_context, String lim, String sec) {
112: agentName = "" + agent_name;
113: agentId = "" + agent_id;
114: courseAssignmentContext = "" + course_assignment_context;
115: // quotation marks can interfere with dynamic JavaScript for WYSIWYG
116: courseAssignmentContext = cleanOutQuotes(courseAssignmentContext);
117: limit = lim;
118: seconds = sec;
119: initDefaults();
120: }
121:
122: /**
123: * Usage: for parameters that might show up quoted in dynamic Javascript
124: * @param s raw string
125: * @return string with no quotes
126: */
127: private String cleanOutQuotes(String s) {
128: StringTokenizer st = new StringTokenizer(s, "\"'");
129: String cleanS = "";
130: while (st.hasMoreTokens()) {
131: cleanS += st.nextToken();
132: }
133:
134: return cleanS;
135: }
136:
137: /**
138: * Private helper for constructor, sets defaults.
139: */
140: private void initDefaults() {
141: fileExtension = "au";
142: fileName = FileNamer.make(agentName, agentId,
143: courseAssignmentContext);
144: if (limit == null) {
145: limit = "0";
146: }
147:
148: if (seconds == null) {
149: seconds = "30";
150: }
151:
152: // just to be good, we make this OS independent so you can run on Windoze
153: // also you can change via setDir()
154:
155: // @todo: determine what is the best default target directory to use
156: // for file system uploads
157: if (File.separator.equals("/")) {
158: dir = "/tmp";
159: } else {
160: dir = "c:\\tmp";
161: }
162:
163: appName = "Audio Recording";
164:
165: //
166: // we will probably want to migrate these images to the
167: // main image directory, the current directory is an artifact of
168: // Stanford/Indiana code merge
169: imageURL = "/samigo/jsp/aam/images/";
170: }
171:
172: /**
173: * Accessor for agent (creator) name.
174: *
175: * @return agent (creator) name.
176: */
177: public String getAgentName() {
178: return agentName;
179: }
180:
181: /**
182: * Accessor for agent (creator) id.
183: *
184: * @return agent (creator) id.
185: */
186: public String getAgentId() {
187: return agentId;
188: }
189:
190: /**
191: * Accessor for free form text describing creation context.
192: * See Usage notes.
193: *
194: * @return free form text describing creation context.
195: */
196: public String getCourseAssignmentContext() {
197: return courseAssignmentContext;
198: }
199:
200: /**
201: * Accessor for standard audio filename extension.
202: *
203: * @return standard audio file extension.
204: */
205: public String getFileExtension() {
206: return fileExtension;
207: }
208:
209: /**
210: * Accessor for standard audio filename.
211: *
212: * @return standard audio file name.
213: */
214: public String getFileName() {
215: return fileName;
216: }
217:
218: /**
219: * Accessor for retry limit.
220: * If the number of retries are unlimited, this is 0.
221: *
222: * @return retry limit
223: */
224: public String getLimit() {
225: return limit;
226: }
227:
228: /**
229: * Get target file system directory for audio uploads.
230: *
231: * @return file system directory for audio uploads.
232: */
233: public String getDir() {
234: return dir;
235: }
236:
237: /**
238: * Accessor for maximum number of seconds for recording.
239: *
240: * @return maximum number of seconds for recording.
241: */
242: public String getSeconds() {
243: return seconds;
244: }
245:
246: /**
247: * Accessor for the user-facing application name for recording applet.
248: *
249: * @return user-facing application name for recording applet.
250: */
251: public String getAppName() {
252: return appName;
253: }
254:
255: /**
256: * Accessor for the image URL for recording widget images.
257: *
258: * @return image URL for recording widget images.
259: */
260: public String getImageURL() {
261: return imageURL;
262: }
263:
264: /**
265: * Mutator for recording agent.
266: *
267: * @param s recording agent
268: */
269: public void setAgentName(String s) {
270: agentName = s;
271: }
272:
273: /**
274: * Mutator for recording agent id.
275: *
276: * @param s recording agent id.
277: */
278: public void setAgentId(String s) {
279: agentId = s;
280: }
281:
282: /**
283: * Mutator for recording context string.
284: * See: Usage
285: *
286: * @param s recording context string.
287: */
288: public void setCourseAssignmentContext(String s) {
289: courseAssignmentContext = s;
290: }
291:
292: /**
293: * Mutator for file extension.
294: *
295: * @param s audio recording file extension.
296: */
297: public void setFileExtension(String s) {
298: fileExtension = s;
299: }
300:
301: /**
302: * Mutator for file name.
303: *
304: * @param s audio recording file name.
305: */
306: public void setFileName(String s) {
307: fileName = s;
308: }
309:
310: /**
311: * Mutator for retry limit.
312: *
313: * @param s audio recording retry limit.
314: */
315: public void setLimit(String s) {
316: limit = s;
317: }
318:
319: /**
320: * DOCUMENTATION PENDING
321: *
322: * @param s DOCUMENTATION PENDING
323: */
324: public void setDir(String s) {
325: dir = s;
326: }
327:
328: /**
329: * Mutator for seconds limit.
330: *
331: * @param s audio recording seconds limit.
332: */
333: public void setSeconds(String s) {
334: seconds = s;
335: }
336:
337: /**
338: * Mutator for the user-facing application name for recording applet.
339: *
340: * @param s user-facing application name for recording applet.
341: */
342: public void setAppName(String s) {
343: appName = s;
344: }
345:
346: /**
347: * Mutator for widget images directory.
348: *
349: * @param s widget images directory.
350: */
351: public void setImageURL(String s) {
352: imageURL = s;
353: }
354:
355: /**
356: * This takes a RecordingData object and puts it in XML.
357: * @return the XML as an org.w3c.dom.Document
358: */
359: public Document getXMLDataModel() {
360: Document document = null;
361: DocumentBuilderFactory builderFactory = DocumentBuilderFactory
362: .newInstance();
363: builderFactory.setNamespaceAware(true);
364: try {
365: DocumentBuilder documentBuilder = builderFactory
366: .newDocumentBuilder();
367: document = documentBuilder.newDocument();
368: } catch (ParserConfigurationException e) {
369: log.error(e.getMessage(), e);
370: }
371:
372: if (document == null) {
373: log.error("document is null");
374: return null;
375: }
376: //add audio setup data to XML document
377: //root
378: Element recordingData = document.createElement("RecordingData");
379:
380: //sub elements
381: Element agentName = document.createElement("AgentName");
382: Element agentId = document.createElement("AgentId");
383: Element courseAssignmentContext = document
384: .createElement("CourseAssignmentContext");
385: Element fileExtension = document.createElement("FileExtension");
386: Element fileName = document.createElement("FileName");
387: Element limit = document.createElement("Limit");
388: Element dir = document.createElement("Dir");
389: Element seconds = document.createElement("Seconds");
390: Element appName = document.createElement("AppName");
391: Element imageURL = document.createElement("ImageURL");
392:
393: agentName.appendChild(document.createTextNode(this
394: .getAgentName()));
395: agentId.appendChild(document.createTextNode(this .getAgentId()));
396: courseAssignmentContext.appendChild(document
397: .createTextNode(this .getCourseAssignmentContext()));
398: fileExtension.appendChild(document.createTextNode(this
399: .getFileExtension()));
400: fileName.appendChild(document
401: .createTextNode(this .getFileName()));
402: limit.appendChild(document.createTextNode(this .getLimit()));
403: dir.appendChild(document.createTextNode(this .getDir()));
404: seconds.appendChild(document.createTextNode(this .getSeconds()));
405: appName.appendChild(document.createTextNode(this .getAppName()));
406: imageURL.appendChild(document
407: .createTextNode(this .getImageURL()));
408:
409: recordingData.appendChild(agentName);
410: recordingData.appendChild(agentId);
411: recordingData.appendChild(courseAssignmentContext);
412: recordingData.appendChild(fileExtension);
413: recordingData.appendChild(fileName);
414: recordingData.appendChild(limit);
415: recordingData.appendChild(dir);
416: recordingData.appendChild(seconds);
417: recordingData.appendChild(appName);
418: recordingData.appendChild(imageURL);
419:
420: document.appendChild(recordingData);
421:
422: // return the recording data available in XML
423: return document;
424: }
425:
426: /**
427: * unit test for use with jUnit etc. this only tests the file name
428: * computation, the other methods are pretty trivial
429: *
430: * @param none
431: * @return none
432: */
433: public static void unitTest() {
434: RecordingData rd = new RecordingData("Ed Smiley", "esmiley",
435: "Intro to Wombats 101", "10", "30");
436: log.debug("esmiley file:" + rd.getFileName() + "."
437: + rd.getFileExtension());
438: log.debug("limit =" + rd.getLimit());
439: log.debug("seconds=" + rd.getSeconds());
440:
441: rd = new RecordingData("Rachel Gollub", "rgollub",
442: "Rachel's Intro to Wolverines and Aardvarks 221B",
443: "10", "25");
444: log.debug("rgollub file:" + rd.getFileName() + "."
445: + rd.getFileExtension());
446: log.debug("limit =" + rd.getLimit());
447: log.debug("seconds=" + rd.getSeconds());
448:
449: rd = new RecordingData("Rachel Gollub", "rgollub",
450: "Intro to Wolverines and Aardvarks 221B", "10", "25");
451: log.debug("rgollub file:" + rd.getFileName() + "."
452: + rd.getFileExtension());
453: log.debug("limit =" + rd.getLimit());
454: log.debug("seconds=" + rd.getSeconds());
455:
456: ByteArrayOutputStream out = new ByteArrayOutputStream();
457: Source xmlSource = new DOMSource(rd.getXMLDataModel());
458: Result outputTarget = new StreamResult(out);
459: Transformer tf;
460: try {
461: tf = TransformerFactory.newInstance().newTransformer();
462: tf.transform(xmlSource, outputTarget);
463: } catch (TransformerException e) {
464: log.debug("cannot serialize" + e);
465: }
466:
467: rd = new RecordingData(null, null, null, null, null);
468: log.debug("NULL file: " + rd.getFileName() + "."
469: + rd.getFileExtension());
470: log.debug("limit =" + rd.getLimit());
471: log.debug("seconds=" + rd.getSeconds());
472:
473: rd = new RecordingData(null, null, null, null, null);
474: log.debug("NULL file: " + rd.getFileName() + "."
475: + rd.getFileExtension());
476: log.debug("limit =" + rd.getLimit());
477: log.debug("seconds=" + rd.getSeconds());
478: }
479:
480: /**
481: * hook for unit test
482: *
483: * @param args not used
484: */
485: public static void main(String[] args) {
486: unitTest();
487: }
488: }
|