package org.greenstone.gsdl3.gs3build.metadata; import java.io.PrintWriter; import java.util.List; import java.util.ArrayList; import java.net.URL; import java.net.URLConnection; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.greenstone.gsdl3.gs3build.util.HTTPTools; import org.greenstone.gsdl3.gs3build.util.XMLTools; import org.greenstone.gsdl3.gs3build.database.*; import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection; /** * An individual METS component file for a document. Many features of METS are not * currently fully supported/used here, but member variables exist for all of the * standard members. */ public class METSFile { METSFileID id; METSFilePos location; String MIMEType; int sequenceNo; long size; METSDate created; long checkSum; List adminRefs; List describeRefs; METSFileGroup group; /** * Create a new METSFile object, with the given properties. The remaining * fields are filled in with default values. * * @param String the id of the file * @param METSFilePos the location of the file * @param String the MIME type of the file */ public METSFile(METSFileID id, METSFilePos location, String mimeType) { this.id = id; // required this.location = location; // the location this.MIMEType = mimeType; // the MIME type; this.sequenceNo = -1; // -1 indicates unset this.size = -1; // -1 indicates unset this.checkSum = -1; // -1 indicates unset this.created = null; this.adminRefs = new ArrayList(); this.describeRefs = new ArrayList(); this.group = null; } /** * Set the parent group * * @param METSFileGroup the new holding file group */ public void setGroup(METSFileGroup group) { this.group = group; } /** * Get the parent group of this file * * @return METSFileGroup the holding file group */ public METSFileGroup getGroup() { return this.group; } /** * Get the identifier of this file * * @return METSFileID the file identifier */ public METSFileID getID() { return this.id; } /** * Set the identifier of this file * * @param METSFileID the file identifier */ public void setID(METSFileID id) { this.id = id; } /** * @return String the MIME (content) type of the file */ public String getMIMEType() { return this.MIMEType; } /** * @return URL the location of the file. This will often be in * "file://" form. */ public URL getLocation() { return this.location.getLocation(); } /** * Take a url and make a METSFile object out of it - works out * details such as the Mime type, identifiers and other necessary * information to call the constructor for METSFile * * @param URL the url of the object - this may be a * reference to a file on the local filestore * * @return METSFile the METS file object for the corresponding * document component. */ public static METSFile makeMETSFile(URL url, String mimeType) { METSFile reply = new METSFile(new METSFileID(), new METSFilePos(url), mimeType); return reply; } public static METSFile makeMETSFile(URL url) { String mimeType; if (url.toString().startsWith("file://")) { // TODO: Work out the MIME type mimeType = URLConnection.getFileNameMap().getContentTypeFor(url.toString().substring(7)); if (mimeType == null) { mimeType = "text/plain"; } } else { // TODO: look up the MIME type through the pertinent connection mimeType = HTTPTools.getMIMEType(url); } // TODO: make the identifier... return makeMETSFile(url, mimeType); } /** * Write the METS file in an XML to a text-output sink * * @param PrintWriter the destination of the output */ public void write(PrintWriter writer) { String tag = XMLTools.getOpenTag("mets", "file"); tag = XMLTools.addAttribute(tag, "MIMETYPE", this.MIMEType); tag = XMLTools.addAttribute(tag, "ID", this.id.toString()); writer.println(tag); tag = XMLTools.getOpenTag("mets", "FLocat"); tag = XMLTools.addAttribute(tag, "LOCTYPE", this.location.getType()); tag = XMLTools.addAttribute(tag, "xlink:href", this.location.getLocation().toString()); tag = XMLTools.addAttribute(tag, "ID", this.id.toString()); tag = XMLTools.makeSingleton(tag); writer.println(tag); writer.println(XMLTools.getCloseTag("mets", "file")); } public void writeSQL(GS3SQLConnection connection) { // check if this node is in the GS3SQLInsert insert = new GS3SQLInsert("files"); insert.addValue("FileLocType", this.location.getType()); insert.addValue("FileLocation", this.location.getLocation().toString()); insert.addValue("MIMEType", this.MIMEType); insert.addValue("ID", this.id.toString()); connection.execute(insert.toString()); } /** * Parse an XML Element as a METS File */ public static METSFile parseXML(Element element, METSFileGroup parentGroup) { METSFile file = null; NodeList children = element.getChildNodes(); for (int c = 0; c < children.getLength(); c ++) { if (children.item(c).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) { continue; } Element childElement = (Element) children.item(c); if (childElement.getNodeName().equals("mets:FLocat")) { METSFilePos filePos; // get most of the information from the child FLocat node String locationType = childElement.getAttribute("LOCTYPE"); String href = childElement.getAttribute("xlink:href"); String id = childElement.getAttribute("ID"); // some more data from the parent node String mimeType = element.getAttribute("MIMETYPE"); try { filePos = new METSFilePos(href, locationType); } catch (java.net.MalformedURLException ex) { // TODO: raise error continue; } file = new METSFile(new METSFileID(id), filePos, mimeType); } else if (childElement.getNodeName().equals("mets:FContent")) { } else { // TODO: raise an error! } } return file; } /** * Overridden toString for convenience - returns the location of the file. * * @return String the location of the file as a string */ public String toString() { return this.location.toString(); } }