package org.emile.cirilo.business; import java.awt.Color; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.BufferedReader; import java.io.FileWriter; import java.io.OutputStreamWriter; import java.io.InputStreamReader; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.net.URLConnection; import java.text.MessageFormat; import java.util.*; import org.apache.log4j.Logger; import org.emile.cirilo.business.MDMapper; import org.emile.cirilo.Common; import org.emile.cirilo.ServiceNames; import org.emile.cirilo.User; import org.emile.cirilo.ecm.repository.Repository; import org.emile.cirilo.utils.eXist; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import org.jdom.xpath.XPath; import org.xmldb.api.DatabaseManager; import org.xmldb.api.base.Resource; import org.xmldb.api.modules.XMLResource; import org.emile.cirilo.utils.ImageTools; import org.emile.cirilo.business.IIIFFactory; import org.json.JSONObject; import org.json.XML; import voodoosoft.jroots.core.CPropertyService; import voodoosoft.jroots.core.CServiceProvider; import voodoosoft.jroots.dialog.CDefaultGuiAdapter; public class STORY { private static Logger log = Logger.getLogger(STORY.class); private Document story; private File file; private String collection; private Format format; private XMLOutputter outputter; private FileWriter logger; private String PID; private String URI; private String raw; private User user; private SAXBuilder builder; private boolean onlyValidate; private boolean mode; private CPropertyService props; public STORY(FileWriter logger, boolean validate, boolean mode) { try { props = (CPropertyService) CServiceProvider.getService(ServiceNames.PROPERTIES); user = (User) CServiceProvider.getService(ServiceNames.CURRENT_USER); URI = user.getExistUrl(); format = Format.getRawFormat(); format.setEncoding("UTF-8"); outputter = new XMLOutputter(format); this.logger = logger; this.onlyValidate = validate; this.mode = mode; this.raw = null; this.builder = new SAXBuilder(); } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } } public void setUser (String u) {} public boolean set (String file, boolean eXist) { String stream = null; int n; try { this.PID = ""; if (!eXist) { this.file = new File (file); this.collection=""; if (this.file.exists()) { char[] buff = new char[1024]; StringWriter sw = new StringWriter(); FileInputStream is = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); try { while ((n = br.read(buff)) != -1) { sw.write(buff, 0, n); } stream = sw.toString(); } catch (Exception io) { sw.close(); br.close(); } } } else { eXist eX = new eXist(file); org.xmldb.api.base.Collection collection = DatabaseManager.getCollection( URI + eX.getCollection(), user.getExistUser(), user.getExistPasswd() ); XMLResource res = (XMLResource) collection.getResource(eX.getStream()); stream = (String) res.getContent(); collection.close(); this.collection = file; } } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } try { this.raw = stream; if (stream.contains("\"storymap\":")) { JSONObject json = new JSONObject(stream); stream = XML.toString(json); } this.story = builder.build( new StringReader( stream )); return true; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } } public boolean set (String stream) { try { SAXBuilder builder = new SAXBuilder(); if (stream.contains("\"storymap\":")) { JSONObject json = new JSONObject(stream); stream = XML.toString(json); } this.collection=""; this.story = builder.build(new StringReader(stream)); this.PID = ""; return true; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } } public boolean get (String pid) { try { SAXBuilder builder = new SAXBuilder(); this.story = builder.build(new StringReader(new String(Repository.getDatastream(pid, "STORY","")))); this.PID = pid; return true; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } } public String toString() { return this.outputter.outputString(this.story); } public String getName() { try { return !this.collection.isEmpty() ? this.collection : this.file.getCanonicalPath(); } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return ""; } } public String getPID() { try { XPath xpath = XPath.newInstance("/storymap/pid"); Element idno = (Element) xpath.selectSingleNode( this.story ); if (idno != null) { String s = idno.getTextNormalize(); this.PID = s.startsWith(Common.INFO_FEDORA) ? s.substring(Common.INFO_FEDORA.length()) : s; } } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } return this.PID; } public void setPID(String pid) { try { XPath xpath = XPath.newInstance("/storymap/pid"); Element idno = (Element) xpath.selectSingleNode( this.story ); if (idno == null) { Element root = this.story.getRootElement(); if (!pid.startsWith("o:")) pid= "o:"+pid; Element child = new Element ("pid"); child.setText(pid); root.addContent(0,child); } else { if (this.mode) { idno.setText(pid); } } this.PID = pid; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } } public boolean isValid() { try { return true; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } } public boolean write(boolean mode) { try { if (!onlyValidate) { if (mode) { if (this.raw.contains("\"storymap\":")) { JSONObject obj = XML.toJSONObject(outputter.outputString(this.story)); this.raw = obj.toString(4); } else { this.raw = outputter.outputString(this.story); } } if (this.collection.isEmpty()) { if (mode) { FileOutputStream fos = new FileOutputStream( this.file.toString() ); BufferedWriter out = new BufferedWriter(new OutputStreamWriter( fos, "UTF-8" ) ); out.write(new String(this.raw.getBytes("UTF-8"),"UTF-8")); out.close(); } } else { if (mode) { eXist eX = new eXist (this.collection); org.xmldb.api.base.Collection coll = DatabaseManager.getCollection( URI + eX.getCollection(), user.getExistUser(), user.getExistPasswd() ); XMLResource res = (XMLResource) coll.getResource(eX.getStream()); res.setContent(new String(this.raw.getBytes("UTF-8"),"UTF-8")); coll.storeResource(res); coll.close(); } } } return true; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return false; } } public void ingestImages() { try { ResourceBundle resb =(ResourceBundle) CServiceProvider.getService(ServiceNames.RESOURCES); List images = getChildren("//*[contains(.'file:///')]"); if (images != null && images.size() > 0) { int i = 1; IIIFFactory i3f = (IIIFFactory) CServiceProvider.getService(ServiceNames.I3F_SERVICE); i3f.delete(this.PID); for (Iterator iter = images.iterator(); iter.hasNext();) { try { Element el = (Element) iter.next(); String url = el.getText(); if (!url.startsWith(Common.INFO_FEDORA) && !url.startsWith("http://")) { String id = el.getAttributeValue("id", Common.xmlns_xml); id = id == null ? "IMAGE."+new Integer(i).toString() : id; String mimetype = el.getAttributeValue("mimeType"); File f = null; if (this.collection.isEmpty()) { url = url.startsWith("file:///") ? url.substring(8) : url; f = new File (url); if (!f.exists()) { f = new File (file.getParent()+System.getProperty( "file.separator" )+url); } } else { url = url.startsWith("exist:///") ? url.substring(9) : url; eXist eX = new eXist(this.collection); eXist eP = new eXist(url); String suffix = ""; if (!eP.getCollection().isEmpty()) { suffix = "/"+eP.getCollection(); url = eP.getStream(); } org.xmldb.api.base.Collection coll = DatabaseManager.getCollection( URI + eX.getCollection()+suffix, user.getExistUser(), user.getExistPasswd() ); Resource res = (Resource) coll.getResource(url); if (res != null) { f= File.createTempFile("temp", ".tmp"); byte[] data = (byte[]) res.getContent(); FileOutputStream fos = new FileOutputStream(f); fos.write(data); fos.flush(); fos.close(); } coll.close(); } if (f != null && f.exists()){ if (!onlyValidate) { if (mimetype == null) { if ( url.indexOf(".tif") > -1 ) mimetype ="image/tiff"; else mimetype ="image/jpeg"; } if (Common.exist(this.PID)) { if (!Repository.exists(this.PID, id)) { Repository.addDatastream(this.PID, id, "Facsimile", "M", mimetype, f); } else { Repository.modifyDatastream(this.PID, id, mimetype, "M", f); } if ( i == 1 ) { File thumb = File.createTempFile( "temp", ".tmp" ); ImageTools.createThumbnail( f, thumb, 100, 80, Color.lightGray ); Repository.modifyDatastream(this.PID, "THUMBNAIL", "image/jpeg", "M", thumb); thumb.delete(); } i++; } } else { MessageFormat msgFmt = new MessageFormat(resb.getString("objectnotfound")); Object[] args0 = {this.PID}; Common.log(logger, msgFmt.format(args0)+"\n"); return; } try { if (!this.collection.isEmpty()) f.delete(); } catch (Exception q) {} continue; } else { MessageFormat msgFmt = new MessageFormat(resb.getString("imagenotfound")); Object[] args0 = {url, this.PID}; Common.log(logger, msgFmt.format(args0)+"\n"); } } } catch (Exception eq) { Common.log(logger, eq); return; } } } } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } } public void createMapping(String pid, CDefaultGuiAdapter moGA) { try { if (!onlyValidate) { byte[] url = Repository.getDatastream(pid != null ? pid : this.PID, "DC_MAPPING" , ""); SAXBuilder builder = new SAXBuilder(); URLConnection con = new URL (new String(url)).openConnection(); con.setUseCaches(false); org.jdom.Document mapping = builder.build( con.getInputStream()); MDMapper m = new MDMapper(this.PID,outputter.outputString(mapping)); builder = new SAXBuilder(); org.jdom.Document dc = builder.build( new StringReader (m.transform(this.story) ) ); if (moGA != null) { Element root = dc.getRootElement(); for (int i = 1; i < org.emile.cirilo.Common.DCMI.length; i++) { String s = (String) moGA.getText("jtf"+ org.emile.cirilo.Common.DCMI[i]); if (s.length() > 0) { StringTokenizer st = new StringTokenizer(s, "~"); if (st.hasMoreTokens()) { while (st.hasMoreTokens()) { String p = Common.itrim(st.nextToken()); Element e = new Element( org.emile.cirilo.Common.DCMI[i].toLowerCase(), org.emile.cirilo.Common.xmlns_dc); e.addContent(p); root.addContent(e); } } } } } dc = Common.validate(dc); Repository.modifyDatastreamByValue(this.PID, "DC", "text/xml", outputter.outputString(dc)); } } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } finally { } } public List getChildren(String path) { try { XPath xpath = XPath.newInstance(path); xpath.addNamespace( Common.xmlns_lido ); List nodes = (List) xpath.selectNodes( this.story ); return nodes; } catch (Exception e) { log.error(e.getLocalizedMessage(),e); return null; } } public void validate(String pid, CDefaultGuiAdapter moGA) { try { if(this.PID != null && this.PID.startsWith("cirilo:")) return; ingestImages(); createMapping(pid, moGA); write(true); } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } } public void refresh() { try { } catch (Exception e) { log.error(e.getLocalizedMessage(),e); } } }