Revision: fe241a0e96e9 Branch: default Author: cmyers@xxxxxxxxxxxxxxxxx Date: Fri Sep 27 15:46:24 2013 UTC Log: Archiver with beginnings of epub support. http://code.google.com/p/brailleblaster/source/detail?r=fe241a0e96e9 Added: /src/main/org/brailleblaster/archiver/Archiver.java /src/main/org/brailleblaster/archiver/ArchiverFactory.java /src/main/org/brailleblaster/archiver/EPubArchiver.java /src/main/org/brailleblaster/archiver/NimasArchiver.java Modified: /src/main/org/brailleblaster/imagedescriber/ImageDescriberDialog.java /src/main/org/brailleblaster/util/Zipper.java /src/main/org/brailleblaster/wordprocessor/DocumentManager.java ======================================= --- /dev/null+++ /src/main/org/brailleblaster/archiver/Archiver.java Fri Sep 27 15:46:24 2013 UTC
@@ -0,0 +1,60 @@ +/* BrailleBlaster Braille Transcription Application + * + * Copyright (C) 2010, 2012 + * ViewPlus Technologies, Inc. www.viewplus.com + * and + * Abilitiessoft, Inc. www.abilitiessoft.com + * All rights reserved + * + * This file may contain code borrowed from files produced by various + * Java development teams. These are gratefully acknoledged. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the Apache 2.0 License, as given at + * http://www.apache.org/licenses/ + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE + * See the Apache 2.0 License for more details. + * + * You should have received a copy of the Apache 2.0 License along with + * this program; see the file LICENSE. + * If not, see + * http://www.apache.org/licenses/ + * + * Maintained by John J. Boyer john.boyer@xxxxxxxxxxxxxxxxx + */ + +package org.brailleblaster.archiver; + +import org.brailleblaster.wordprocessor.DocumentManager; + +////////////////////////////////////////////////////////////////////////////////// +// Archiver gives methods for opening/handling particular document types. +// Some of these types have special needs, and therefore, specific +// implementations. This class is ABSTRACT, and is to be used as a +// base for other archivers. +abstract public class Archiver { + + String originalDocPath; + String unzippedDocPath; + String workingDocPath; ++ //////////////////////////////////////////////////////////////////////////////////
+ // Constructor. Stores path to document to prepare. + Archiver(String docToPrepare) + { + // Store paths. + originalDocPath = docToPrepare; + workingDocPath = originalDocPath; + + }+ //////////////////////////////////////////////////////////////////////////////////
+ // + public abstract String open();+ //////////////////////////////////////////////////////////////////////////////////
+ // + public abstract void save(DocumentManager dm, String path); + +} // class Archiver ======================================= --- /dev/null+++ /src/main/org/brailleblaster/archiver/ArchiverFactory.java Fri Sep 27 15:46:24 2013 UTC
@@ -0,0 +1,96 @@ +/* BrailleBlaster Braille Transcription Application + * + * Copyright (C) 2010, 2012 + * ViewPlus Technologies, Inc. www.viewplus.com + * and + * Abilitiessoft, Inc. www.abilitiessoft.com + * All rights reserved + * + * This file may contain code borrowed from files produced by various + * Java development teams. These are gratefully acknoledged. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the Apache 2.0 License, as given at + * http://www.apache.org/licenses/ + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE + * See the Apache 2.0 License for more details. + * + * You should have received a copy of the Apache 2.0 License along with + * this program; see the file LICENSE. + * If not, see + * http://www.apache.org/licenses/ + * + * Maintained by John J. Boyer john.boyer@xxxxxxxxxxxxxxxxx + */ + +package org.brailleblaster.archiver; + +import org.brailleblaster.BBIni; +import org.brailleblaster.util.Zipper; + +////////////////////////////////////////////////////////////////////////////////// +// Archiver Factory determines file type of document, and gives appropriate +// object for opening/handling. +public class ArchiverFactory { ++ //////////////////////////////////////////////////////////////////////////////////
+ // Constructor. + void ArchiverFactory() { } ++ ////////////////////////////////////////////////////////////////////////////////// + // Pass a filepath to a document, and getArchive() will determine the file type,
+ // and return the appropriate Archive. + public static Archiver getArchive(String filePath) + { + // If the archive is contained within a zip file, go ahead and unzip it. + if( filePath.endsWith(".zip") ) + { + // Create zipper utility. + Zipper zipr = new Zipper();+ zipr.Unzip( filePath, filePath.substring(0, filePath.lastIndexOf(BBIni.getFileSep())) );
+ filePath = zipr.GetXmlPath(); + + } // UNZIP + + // Is this EPub? + if( isEPUB(filePath) ) + return new EPubArchiver(filePath); + // Is this Nimas? + if( isNIMAS(filePath) ) + return new NimasArchiver(filePath); + + // Could not determine file type. + return null; + + } // getArchive() ++ //////////////////////////////////////////////////////////////////////////////////
+ // Is this an ePub document? + static boolean isEPUB(String pathToDoc) + { + // Does it end with .epub? + if(pathToDoc.endsWith(".epub")) + return true; + + // This isn't an EPUB document. + return false; + + } // isEPUB() ++ //////////////////////////////////////////////////////////////////////////////////
+ // Is this a Nimas document? + static boolean isNIMAS(String pathToDoc) + { + // TODO: Add proper code to determine this doc type. + if(pathToDoc.endsWith(".xml")) + return true; + + // This isn't a Nimas document. + return false; + + } // isNIMAS() + +} // class ArchiverFactory ======================================= --- /dev/null+++ /src/main/org/brailleblaster/archiver/EPubArchiver.java Fri Sep 27 15:46:24 2013 UTC
@@ -0,0 +1,297 @@ +/* BrailleBlaster Braille Transcription Application + * + * Copyright (C) 2010, 2012 + * ViewPlus Technologies, Inc. www.viewplus.com + * and + * Abilitiessoft, Inc. www.abilitiessoft.com + * All rights reserved + * + * This file may contain code borrowed from files produced by various + * Java development teams. These are gratefully acknoledged. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the Apache 2.0 License, as given at + * http://www.apache.org/licenses/ + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE + * See the Apache 2.0 License for more details. + * + * You should have received a copy of the Apache 2.0 License along with + * this program; see the file LICENSE. + * If not, see + * http://www.apache.org/licenses/ + * + * Maintained by John J. Boyer john.boyer@xxxxxxxxxxxxxxxxx + */ + +package org.brailleblaster.archiver; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.brailleblaster.BBIni; +import org.brailleblaster.util.Zipper; +import org.brailleblaster.wordprocessor.DocumentManager; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSOutput; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.SAXException; + +////////////////////////////////////////////////////////////////////////////////// +// Prepares an EPub document for opening. +public class EPubArchiver extends Archiver { + + // Path to .opf file. + String opfPath; + // Manifest and spine elements. + NodeList manifestElements; + NodeList spineElements; + + EPubArchiver(String docToPrepare) { + super(docToPrepare); + } + + ++ //////////////////////////////////////////////////////////////////////////////////
+ // + @Override + public String open() { + + // First things first, we have to unzip the EPub doc. + + ///////// + // Unzip. + + // Create unzipper. + Zipper zpr = new Zipper(); + + // Unzip.+ zpr.Unzip( originalDocPath, originalDocPath.substring(0, originalDocPath.lastIndexOf(".")) + BBIni.getFileSep() );
+ + // Unzip. + ///////// + + // Get ready to look for the opf file. + opfPath = null; + + // Get paths to all unzipped files. + ArrayList<String> unzippedPaths = zpr.getUnzippedFilePaths(); + + // Find the .opf file. + for(int curFile = 0; curFile < unzippedPaths.size(); curFile++) + { + // Does this file have an .opf extension? + if(unzippedPaths.get(curFile).endsWith(".opf") == true) + { + // Found it! + opfPath = unzippedPaths.get(curFile); + + // Found it, take a break. + break; + + } // If ends with opf + + } // for(int curFile... + + // If we couldn't find the opf file, no point in continuing. + if(opfPath == null) + return null; + + // Parse opf. Find all pages of our document. + try { + // Build factory, and parse the opf. + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + builder = factory.newDocumentBuilder(); + Document opfDoc = builder.parse(opfPath); + + // The main document we'll be appending to. + Document mainDoc = null; + + // Body element of main doc. + NodeList mainBodyElement = null; + // Html element of main doc. + NodeList mainHtmlElement = null; + + // Grab the spine elements and manifest elements. + manifestElements = opfDoc.getElementsByTagName("item"); + spineElements = opfDoc.getElementsByTagName("itemref"); + + // Filepath to current document. + String curDocFilePath = null; ++ // Loop through the spine and find the items in the manifest that we need.
+ for(int curSP = 0; curSP < spineElements.getLength(); curSP++) + { + // Get the attributes for this spine element. + NamedNodeMap spineAtts = spineElements.item(curSP).getAttributes(); + + // Get the ID of the item we need from the manifest. + String fileID = spineAtts.getNamedItem("idref").getNodeValue(); + + // Get the file path from the manifest.+ curDocFilePath = originalDocPath.substring(0, originalDocPath.lastIndexOf(".")) + BBIni.getFileSep(); + curDocFilePath += "EPUB" + BBIni.getFileSep() + findHrefById(fileID).replace("/", BBIni.getFileSep());
+ + // If this is the first file, we'll use it as a base to add to. + if(curSP == 0) + { + // Get main/first document. + mainDoc = builder.parse(curDocFilePath); + + // Get body element. + mainBodyElement = mainDoc.getElementsByTagName("body"); + // Get html element. + mainHtmlElement = mainDoc.getElementsByTagName("html"); ++ // We have the base document, skip to a document that we'll be adding to
+ // this one. + continue; + + } // if(curSP == 0) + + // Parse this new document. + Document nextDoc = builder.parse(curDocFilePath); + + // Get new document's body. + NodeList newBodyElm = nextDoc.getElementsByTagName("body"); + + ////////////// + // Namespaces. + + // Next document's html element. + NodeList newHtmlElm = nextDoc.getElementsByTagName("html"); + + // Get attributes for this html element. + NamedNodeMap newHtmlAtts = newHtmlElm.item(0).getAttributes(); + + // Loop through this new document's attributes. If it has one that + // the main document doesn't have, add it.+ for(int curNewAtt = 0; curNewAtt < newHtmlAtts.getLength(); curNewAtt++)
+ { + // Grab potentially new attribute. + String newAtt = newHtmlAtts.item(curNewAtt).toString(); + + // Grab main doc's attributes. + NamedNodeMap mainHtmlAtts = mainHtmlElement.item(0).getAttributes(); + + // Loop through our main document's attributes. Is this + // new one in there somewhere? If so, don't add it. + boolean skipThis = false;+ for(int curMainAtt = 0; curMainAtt < mainHtmlAtts.getLength(); curMainAtt++) { + if(mainHtmlAtts.item(curMainAtt).toString().compareTo(newAtt) == 0) {
+ skipThis = true; + break; + } // if(mainHtmlAtts... + } // for(int curMainAtt... + + // If we make it here, then we couldn't find the new attribute + // in the main doc. Add it. + if(skipThis == false){ + Node atty = mainDoc.importNode(newHtmlAtts.item(curNewAtt), true); + mainHtmlElement.item(0).getAttributes().setNamedItem(atty); + } + + } // for(int curNewAtt... + + // Namespaces. + ////////////// + + // Get children of body element. + NodeList bodyChilds = newBodyElm.item(0).getChildNodes(); + + // Loop through all of the children and add them to the main document. + for(int curChild = 0; curChild < bodyChilds.getLength(); curChild++) + { + // Add child to main doc. + Node newNode = mainDoc.importNode(bodyChilds.item(curChild), true); + mainBodyElement.item(0).appendChild( newNode ); + + } // for(int curChild = 0... + + +// +// / \_/ \ +// >>>---| -----> +// \ / +// V +// + } // for(int curSP... + + // Save file concatenation. + + // Output filename.+ String outFileName = curDocFilePath.substring( 0, curDocFilePath.lastIndexOf(BBIni.getFileSep()) ) + BBIni.getFileSep() + "temp.xml";
+ + // Get DOM Implementation. + DOMImplementationLS domImplementationLS =+ (DOMImplementationLS) mainDoc.getImplementation().getFeature("LS","3.0");
+ + // Prepare output stream. + LSOutput lsOutput = domImplementationLS.createLSOutput(); + FileOutputStream outputStream = new FileOutputStream( outFileName ); + lsOutput.setByteStream( (OutputStream) outputStream ); + + // Create the serializer, serialize/output xml, then close the stream. + LSSerializer lsSerializer = domImplementationLS.createLSSerializer(); + lsSerializer.write( mainDoc, lsOutput ); + outputStream.close(); + + // Return path to new document. + return outFileName; + + } // try/catch+ catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); }
+ + // An error occurred; we don't have a file path to return. + return null; + + } // open() + + ///////////////////////////////////////////////////////////////////////// + // Finds the manifest element using the given id, + // and returns the href attribute value. + String findHrefById(String id) + { + // Loop through the manifest items and find the file with this ID. + for(int curMan = 0; curMan < manifestElements.getLength(); curMan++) + { + // Get the attributes for this manifest item. + NamedNodeMap manAtts = manifestElements.item(curMan).getAttributes(); ++ // If this manifest item has the id we're looking for, time to open a file.
+ if( manAtts.getNamedItem("id").getNodeValue().compareTo(id) == 0 ) + {+ // Get value of href; this is our local file path to the file. Return it.
+ return manAtts.getNamedItem("href").getNodeValue(); + + } // if manifestItem ID == fileID... + + } // for(int curMan... + + // Couldn't find it. + return null; + + } // findHrefById() + + @Override + public void save(DocumentManager dm, String path) { + + + + } // save() + +} // class EPubArchiver ======================================= --- /dev/null+++ /src/main/org/brailleblaster/archiver/NimasArchiver.java Fri Sep 27 15:46:24 2013 UTC
@@ -0,0 +1,60 @@ +/* BrailleBlaster Braille Transcription Application + * + * Copyright (C) 2010, 2012 + * ViewPlus Technologies, Inc. www.viewplus.com + * and + * Abilitiessoft, Inc. www.abilitiessoft.com + * All rights reserved + * + * This file may contain code borrowed from files produced by various + * Java development teams. These are gratefully acknoledged. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the Apache 2.0 License, as given at + * http://www.apache.org/licenses/ + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE + * See the Apache 2.0 License for more details. + * + * You should have received a copy of the Apache 2.0 License along with + * this program; see the file LICENSE. + * If not, see + * http://www.apache.org/licenses/ + * + * Maintained by John J. Boyer john.boyer@xxxxxxxxxxxxxxxxx + */ + +package org.brailleblaster.archiver; + +import org.brailleblaster.wordprocessor.DocumentManager; + +////////////////////////////////////////////////////////////////////////////////// +// Prepares Nimas Archive for opening. +public class NimasArchiver extends Archiver { + + NimasArchiver(String docToPrepare) { + super(docToPrepare); + } + + + @Override + public String open() { + + // We are able to handle this document without modifying it. Just + // give back the path to the working document. + return originalDocPath; + + } // open() + + + @Override + public void save(DocumentManager dm, String path) { + + // Save the document. Pretty easy, since it's just one file. + dm.saveAs(); + + } // save() + +} // class NimasArchiver =======================================--- /src/main/org/brailleblaster/imagedescriber/ImageDescriberDialog.java Thu Sep 12 17:37:15 2013 UTC +++ /src/main/org/brailleblaster/imagedescriber/ImageDescriberDialog.java Fri Sep 27 15:46:24 2013 UTC
@@ -180,6 +180,17 @@ // Start the image describer. imgDesc = new ImageDescriber(curDocMan); + // Image helper class. Image helper functions, and such. + imgHelper = new ImageHelper(); + + // Create shell, get display, etc. + display = parent.getDisplay(); + imgDescShell = new Shell(parent, SWT.DIALOG_TRIM); + imgDescShell.setText(lh.localValue("Image Describer")); + + // Resize window. + setUIDimensions(); + imgDescShell.setSize(dialogWidth, dialogHeight);// If there were no <img> elements found, there is no point in continuing.
if(imgDesc.getNumImgElements() == 0) { @@ -190,18 +201,6 @@ // Don't bother with the rest of image describer, there are no images. return; } - - // Image helper class. Image helper functions, and such. - imgHelper = new ImageHelper(); - - // Create shell, get display, etc. - display = parent.getDisplay(); - imgDescShell = new Shell(parent, SWT.DIALOG_TRIM); - imgDescShell.setText(lh.localValue("Image Describer")); - - // Resize window. - setUIDimensions(); - imgDescShell.setSize(dialogWidth, dialogHeight); // Create all of the buttons, edit boxes, etc. createUIelements(); =======================================--- /src/main/org/brailleblaster/util/Zipper.java Thu May 23 14:16:20 2013 UTC +++ /src/main/org/brailleblaster/util/Zipper.java Fri Sep 27 15:46:24 2013 UTC
@@ -37,6 +37,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.LinkedList; import java.util.zip.ZipEntry; @@ -54,6 +55,9 @@ // Path we've unzipped to. String unzippedPath; + + // Full paths to extracted files. + ArrayList<String> unzippedFilePaths; ////////////////////////////////////////////////////// // Extracts files from .zip archive. @@ -62,11 +66,12 @@ // extractPath is the folder/directory to extract to. // // Returns a path to the unzipped xml file. - public String Unzip(final String zipFilePath, final String extractPath) + public String Unzip(final String zipFilePath, final String extractToHere) { try { // Clear out previous zip path if it exists. + unzippedFilePaths = new ArrayList<String>(); xmlUnzippedPath = ""; if(zipEntries != null) zipEntries.clear(); @@ -74,7 +79,7 @@ zipEntries = new LinkedList<String>(); // Store where we're sticking the files. - unzippedPath = extractPath; + unzippedPath = extractToHere; // Grab the zip entries. ZipFile zipF = new ZipFile( zipFilePath ); @@ -93,14 +98,14 @@ zipEntries.add( entry.getName() ); // If this is the xml file, hold onto its path. - if( entry.getName().toLowerCase().endsWith(".xml") ) {- xmlUnzippedPath = extractPath + entry.getName().replace("/", BBIni.getFileSep()); + if( entry.getName().toLowerCase().endsWith(".xml") || entry.getName().toLowerCase().endsWith(".epub")) { + xmlUnzippedPath = extractToHere + entry.getName().replace("/", BBIni.getFileSep());
entry.getName(); } // Get path + filename that we'll be saving out to.- String unzipPath = extractPath + entry.getName().replace("/", BBIni.getFileSep());
-+ String unzipPath = extractToHere + entry.getName().replace("/", BBIni.getFileSep());
+ unzippedFilePaths.add(unzipPath); // Create any subdirectories that this file may need. CreateDirsFromPath( unzipPath ); @@ -306,4 +311,14 @@ return fileList; } // GetFileList() -} ++ //////////////////////////////////////////////////////////////////////////////////
+ // Returns list of files that were unzipped. + public ArrayList<String> getUnzippedFilePaths() + { + // Return the list of files that were unzipped, with full paths. + return unzippedFilePaths; + + } // getUnzippedFilePaths() + +} // Zipper =======================================--- /src/main/org/brailleblaster/wordprocessor/DocumentManager.java Tue Sep 17 14:47:36 2013 UTC +++ /src/main/org/brailleblaster/wordprocessor/DocumentManager.java Fri Sep 27 15:46:24 2013 UTC
@@ -46,6 +46,8 @@ import nu.xom.Text; import org.brailleblaster.BBIni; +import org.brailleblaster.archiver.Archiver; +import org.brailleblaster.archiver.ArchiverFactory; import org.brailleblaster.document.BBDocument; import org.brailleblaster.document.BBSemanticsTable; import org.brailleblaster.document.BBSemanticsTable.Styles; @@ -214,8 +216,8 @@ public void fileOpenDialog() { String tempName;- String[] filterNames = new String[] { "XML", "XML ZIP", "XHTML", "HTML","HTM","TEXT", "BRF", "UTDML working document", }; - String[] filterExtensions = new String[] { "*.xml", "*.zip", "*.xhtml","*.html", "*.htm", "*.txt", "*.brf", "*.utd", }; + String[] filterNames = new String[] { "XML", "XML ZIP", "XHTML", "HTML","HTM", "EPUB", "TEXT", "BRF", "UTDML working document", }; + String[] filterExtensions = new String[] { "*.xml", "*.zip", "*.xhtml","*.html", "*.htm", "*.epub", "*.txt", "*.brf", "*.utd", }; BBFileDialog dialog = new BBFileDialog(wp.getShell(), SWT.OPEN, filterNames, filterExtensions);
tempName = dialog.open(); @@ -223,6 +225,8 @@ // Don't do any of this if the user failed to choose a file. if(tempName != null) { + // + // Open it.if(workingFilePath != null || text.hasChanged || braille.hasChanged || documentName != null){
wp.addDocumentManager(tempName); @@ -236,13 +240,22 @@ } // if(tempName != null) } - public void openDocument(String fileName){ + public void openDocument(String fileName){ + + // Create archiver and massage document if necessary. + Archiver arch = ArchiverFactory.getArchive(fileName); + String archFileName = arch.open(); + + // File unsupported by Archiver. Let Braille Blaster handle it. + if(archFileName != null) + fileName = archFileName; + // Update file we're about to work on. workingFilePath = fileName; - + //////////////////////// // Zip and Recent Files. - + /* // If the file opened was an xml zip file, unzip it. if(fileName.endsWith(".zip")) { // Create unzipper. @@ -259,7 +272,7 @@ // There is no zip file to deal with. zippedPath = ""; } - + */ //////////////// // Recent Files.