Index: lams_tool_larsrc/.classpath =================================================================== diff -u -r588fe01186ff8c7c5b215e15f5ac4763137e0284 -r71012b6f2ac523d8faaef475332dbad1338c448d --- lams_tool_larsrc/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) +++ lams_tool_larsrc/.classpath (.../.classpath) (revision 71012b6f2ac523d8faaef475332dbad1338c448d) @@ -5,7 +5,7 @@ - + @@ -26,6 +26,5 @@ - Index: lams_tool_larsrc/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r5e63656a12c02f7476564e278b43ff4ce86ac930 -r71012b6f2ac523d8faaef475332dbad1338c448d --- lams_tool_larsrc/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 5e63656a12c02f7476564e278b43ff4ce86ac930) +++ lams_tool_larsrc/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 71012b6f2ac523d8faaef475332dbad1338c448d) @@ -63,8 +63,6 @@ error.msg.upload.file.not.found =Could not find upload file {0}. error.msg.zip.file.exception =Could not handle zip file when uploading file. error.msg.file.not.found =File not found exception occurs when uploading file. -error.msg.ims.package =Invalid IMS CP format. -error.msg.ims.application =ImscpApplicationException occurs when uploading resource item file. error.msg.website.no.initial.file =Website zip can not find out initial file (index.htm/html or default.htm/html). error.msg.io.exception =IOException occurs when uploading file. error.msg.invaid.param.upload =InvalidParameterException occured while trying to upload File. Fisheye: Tag 71012b6f2ac523d8faaef475332dbad1338c448d refers to a dead (removed) revision in file `lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ims/OrganizationXMLDef.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ims/SimpleContentPackageConverter.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r71012b6f2ac523d8faaef475332dbad1338c448d --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ims/SimpleContentPackageConverter.java (.../SimpleContentPackageConverter.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/ims/SimpleContentPackageConverter.java (.../SimpleContentPackageConverter.java) (revision 71012b6f2ac523d8faaef475332dbad1338c448d) @@ -24,469 +24,250 @@ package org.lamsfoundation.lams.tool.rsrc.ims; import java.io.File; -import java.io.FileNotFoundException; +import java.io.FileInputStream; import java.io.IOException; -import java.util.Iterator; -import java.util.List; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.Namespace; +import org.lamsfoundation.lams.util.FileUtil; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; -import uk.ac.reload.jdom.XMLDocument; -import uk.ac.reload.jdom.XMLPath; -import uk.ac.reload.jdom.XMLUtils; -import uk.ac.reload.moonunit.contentpackaging.CP_Core; - /** - * SimpleContentPackageConverter contains the code required for - * parsing the IMS Content Package and converting the info into our - * own structures. + * SimpleContentPackageConverter contains the code required for parsing the IMS Content Package and converting the info + * into our own structures. * - * Note: this class has instance data, so do not use it as a singleton. - * - * @author Fiona Malikoff + * @author Fiona Malikoff, Marcin Cieslak */ -public class SimpleContentPackageConverter implements IContentPackageConverter { +public class SimpleContentPackageConverter { + private static Logger log = Logger.getLogger(SimpleContentPackageConverter.class); - private Logger log = Logger.getLogger(SimpleContentPackageConverter.class); - - // manifestDoc and cpCore are set up in the constructor. They are then used - // to generate the rest of the values - private XMLDocument manifestDoc = null; - private CP_Core cpCore = null; + private static DocumentBuilder docBuilder = null; + private static final XPathFactory xPathFactory = XPathFactory.newInstance(); + private final XPath xPath = SimpleContentPackageConverter.xPathFactory.newXPath(); - private String schema=null; - private String title=null; - private String description=null; - private String defaultItem=null; - private String organzationXML=null; - - // cachedResourceList is used to avoid building up the list - // every time an item is parsed - otherwise there is a lot - // of processing done by the reload code time and time again. - private Element[] cachedResourceList = null; + private Document manifestDoc = null; - /** Set up a package converter, using the supplied directory as the package. - * The package should be parsed automatically and the values readied for calls - * to getSchema(), getTitle(), etc. - * - * @param directoryName: directory containing an expanded IMS content package. - * @throws IMSManifestException if there is an error in parsing the manifest file - * due to an error in the file or an unexpected value. - * @throws ImscpApplicationException if there is any other error - */ - public SimpleContentPackageConverter(String directoryName) - throws IMSManifestException, ImscpApplicationException { + private String schema = null; + private String title = null; + private String description = null; + private String defaultItem = null; + private String organzationXML = null; - this.manifestDoc = getDocument(directoryName); - this.cpCore = new CP_Core(manifestDoc); + static { + try { + // a single doc builder is enough + SimpleContentPackageConverter.docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + SimpleContentPackageConverter.log.error("Error while initialising XML document builder", e); + } + } - // initialise the property file required for the reload code. Needed to make - // the metadata call work. If we remove the metadata call, then this constructor - // may be removed. - System.setProperty("editor.properties.file", "uk.ac.reload.editor.properties.rb"); + public SimpleContentPackageConverter(String directoryName) throws IOException { + // first parse the manifest XML file + this.manifestDoc = getDocument(directoryName); - parsePackage(); - } - - /** Parse IMS content package expanded out - * into the supplied directory. Note: the manifest file is expected to be in the - * root of the supplied directory. - * - * @throws ImscpApplicationException - * @throws IMSManifestException - */ - private void parsePackage( ) throws IMSManifestException, ImscpApplicationException { - - String schemaText = getText(manifestDoc, "//metadata/schema"); - String schemaVersion = getText(manifestDoc, "//metadata/schemaversion"); - this.schema = ( schemaText != null ? schemaText : "unknown" ) - + " " + ( schemaVersion != null ? schemaVersion : "unknown") ; - - Document orgs = buildOrganisationList(); - if ( orgs == null ) { - String error = "Unable to convert organizations from manifest file to our own structure. Reason unknown - buildOrganisationList returned null"; - log.error(error); - throw new ImscpApplicationException(error); - } - - try { - this.organzationXML = XMLUtils.write2XMLString(orgs); - } catch ( IOException ioe ) { - String error = "Exception thrown converting organization structure (as document) to an XML string."+ioe.getMessage(); - log.error(error,ioe); - throw new ImscpApplicationException(error,ioe); - } + // get the necessary data from the XML document using XPath + String schemaText = getText("/manifest/metadata/schema/text()", manifestDoc); + String schemaVersion = getText("/manifest/metadata/schemaversion/text()", manifestDoc); + this.schema = (schemaText == null ? "unknown" : schemaText) + " " + + (schemaVersion == null ? "unknown" : schemaVersion); - XMLPath xmlPath = new XMLPath("//metadata/*:lom/*:general/*:title/*:langstring"); - this.title = getMetaValue(xmlPath); - if ( this.title == null ) { - // try the old root name - untested - xmlPath = new XMLPath("//metadata/*:record/*:general/*:title/*:langstring"); - this.title = getMetaValue(xmlPath); - } - - xmlPath = new XMLPath("//metadata/*:lom/*:general/*:description/*:langstring"); - this.description = getMetaValue(xmlPath); - if ( this.description == null ) { - // try the old root name - untested - xmlPath = new XMLPath("//metadata/*:record/*:general/*:description/*:langstring"); - this.description = getMetaValue(xmlPath); - } - + Document orgs = null; + try { + orgs = buildOrganisationList(); + } catch (XPathExpressionException e) { + throw new IOException("Error while building organisations list", e); } + if (orgs == null) { + throw new IOException("Unable to convert organisations from manifest file to our own structure"); + } + this.organzationXML = FileUtil.writeXMLtoString(orgs); + this.title = getText("/manifest/metadata/lom/general/title/langstring/text()", manifestDoc); + this.description = getText("/manifest/metadata/lom/general/description/langstring/text()", manifestDoc); + } - /** - * Finds a value at the given xmlPath. If only one element, uses that value. - * If more than one element, tries to find an English value. - * @param xmlPath - * @return Value of the element found at xmlPath. - */ - private String getMetaValue(XMLPath xmlPath) { - Element[] elList = manifestDoc.getElements(xmlPath); - String value = null; - if ( elList != null ) { - if ( elList.length == 0 ) { - value="Unknown"; - } else if ( elList.length == 1 ) { - value=elList[0].getTextTrim(); - } else { - value = null; - // TODO check if it is really testing for english - for ( int i=0; value == null && i < elList.length; i++ ) { - // grab the first English one - Element el = elList[i]; - String attrValue = el.getAttributeValue("lang", Namespace.XML_NAMESPACE ); - if ( attrValue != null && attrValue.startsWith("en") ) { - value = el.getTextTrim(); - } - } - if ( value == null ) { - // can't seem to find an English one, just pick the first - value=elList[0].getTextTrim(); - } - } - } - return value; + /* Get the text for first element matching XPath */ + private String getText(String xPathString, Object context) throws IOException { + try { + return xPath.evaluate(xPathString, context); + } catch (XPathExpressionException e) { + throw new IOException("Error when parsing XPath expression: " + xPathString, e); } + } - /* Get the text for this element - expect only 1 */ - private String getText(XMLDocument document, String xmlPathString ) { - XMLPath xmlPath = new XMLPath(xmlPathString); - Element el = document.getElement(xmlPath); - return el != null ? el.getTextTrim() : null; + private Document getDocument(String directoryName) throws IOException { + File docFile = new File(directoryName, "imsmanifest.xml"); + Document doc; + try { + doc = SimpleContentPackageConverter.docBuilder.parse(new FileInputStream(docFile)); + } catch (SAXException | IOException e) { + throw new IOException("Error while parsing IMS manifest", e); } - - private String debug(XMLDocument document, String param, String xmlPathString ) { - XMLPath xmlPath = new XMLPath(xmlPathString); - Element[]elList = document.getElements(xmlPath); - if ( elList != null ) { - log.error(param+" xp: length "+elList.length+" el "+elList); - if ( elList.length >= 1 ) { - log.error("text is "+elList[0].getTextTrim()); - return elList[0].getTextTrim(); - } - } else { - log.error(param+" xp: el is null"); - } - return null; - } + return doc; + } - /** - * @param directoryName - * @return - * @throws JDOMException - * @throws IOException - */ - private XMLDocument getDocument(String directoryName) throws IMSManifestException { - try { - XMLDocument doc = new XMLDocument(); - doc.loadDocument(new File(directoryName, "imsmanifest.xml")); - return doc; - } catch (JDOMException je) { - String error = "Parsing error occured while loading imsmanifest.xml file. Contents of file may be invalid. "+je.getMessage(); - log.error(error, je); - throw new IMSManifestException(error, je); - } catch (FileNotFoundException e) { - String error = "Unable to find imsmanifest file in the package."+e.getMessage(); - log.error(error, e); - throw new IMSManifestException(error, e); - } catch (IOException ioe) { - String error = "IOException occured while loading imsmanifest file. "+ioe.getMessage(); - log.error(error, ioe); - throw new IMSManifestException(error, ioe); - } + /** + * Build an XML document which is a list of organisations/resources. + */ + private Document buildOrganisationList() throws XPathExpressionException, IOException { + Element orgsElem = (Element) xPath.evaluate("/manifest/organizations", manifestDoc, XPathConstants.NODE); + + // default org is for finding default item, but all orgs get processed + String defaultOrgIdentifier = orgsElem.getAttribute("default"); + if (StringUtils.isBlank(defaultOrgIdentifier)) { + defaultOrgIdentifier = getText("organization/@identifier", orgsElem); } + if (SimpleContentPackageConverter.log.isDebugEnabled()) { + SimpleContentPackageConverter.log.debug("Default organisation identifier is: " + defaultOrgIdentifier); + } - /** Built an XML document which is a list of organisations/resources. - */ - private Document buildOrganisationList( ) throws IMSManifestException { - - Namespace nm = cpCore.getRootManifestElement().getNamespace(); - - Element rootElement = cpCore.getRootManifestElement(); - Element orgsElement = rootElement.getChild(CP_Core.ORGANIZATIONS, nm); - - // set up a list of all the resources - - // now get all the organizations and set up the new XML document, combining - // the organization and the resources. - Element defaultOrg = cpCore.getDefaultOrganization(orgsElement); - String defaultOrgIdentifier = null; - if ( defaultOrg != null ) - defaultOrgIdentifier = defaultOrg.getAttributeValue("identifier"); + Document newDoc = SimpleContentPackageConverter.docBuilder.newDocument(); + Element newRootElement = newDoc.createElement("organizations"); + setAttribute(newRootElement, "version", "imscp1"); + newDoc.appendChild(newRootElement); - log.debug("cpCore default org id: "+defaultOrgIdentifier); + NodeList orgs = (NodeList) xPath.evaluate("organization", orgsElem, XPathConstants.NODESET); + for (int childIndex = 0; childIndex < orgs.getLength(); childIndex++) { + Element organizationElement = processItem(newDoc, (Element) orgs.item(childIndex), defaultOrgIdentifier, + null); + if (organizationElement != null) { + newRootElement.appendChild(organizationElement); + } + } - Element newRootElement = new Element("organizations"); - setAttribute(newRootElement, "version", "imscp1"); - Document doc = new Document(newRootElement); - - Element[] orgs = cpCore.getOrganizationsAllowed(orgsElement); - Element initOrganizationElement =null; - for ( int i=0; i - + <%@ include file="/common/taglibs.jsp"%> <%@ include file="/common/header.jsp"%> - - - - - - - - - - - + + + + + + + - - The content package details are missing. - + The content package details are missing. - - - + \ No newline at end of file
- The content package details are missing. -
The content package details are missing.