diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java deleted file mode 100644 index 129213c5f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java +++ /dev/null @@ -1,64 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.IOException; - -import com.hp.hpl.jena.rdf.model.Resource; - -/** - * Adjust any individual that has a thumbnail with no main image. - */ -public class AllThumbsAdjuster extends FsuScanner { - private ImageDirectoryWithBackup imageDirectoryWithBackup; - - public AllThumbsAdjuster(FSUController controller) { - super(controller); - this.imageDirectoryWithBackup = controller - .getImageDirectoryWithBackup(); - } - - /** - * For every individual with thumbnails but no main images, create a main - * image from the first thumbnail. - */ - public void adjust() { - updateLog.section("Creating main images for thumbnails " - + "that have none."); - - for (Resource resource : ModelWrapper.listResourcesWithProperty(model, - thumbProperty)) { - if (ResourceWrapper.getProperty(resource, imageProperty) == null) { - createMainImageFromThumbnail(resource); - } - } - } - - /** - * This individual has a thumbnail but no main image. Create one. - * - */ - private void createMainImageFromThumbnail(Resource resource) { - String thumbFilename = getValues(resource, thumbProperty).get(0); - String mainFilename = addFilenamePrefix("_main_image_", thumbFilename); - updateLog.log(resource, "creating a main file at '" + mainFilename - + "' to match the thumbnail at '" + thumbFilename + "'"); - - try { - File thumbFile = imageDirectoryWithBackup - .getExistingFile(thumbFilename); - File mainFile = imageDirectoryWithBackup.getNewfile(mainFilename); - mainFile = checkNameConflicts(mainFile); - FileUtil.copyFile(thumbFile, mainFile); - ResourceWrapper.addProperty(resource, imageProperty, mainFilename); - } catch (IOException e) { - updateLog.error(resource, "failed to create main file '" - + mainFilename + "'", e); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java deleted file mode 100644 index f81a1c0e3..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java +++ /dev/null @@ -1,71 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; - -/** - * Removes any image properties (main or thumbnail) that point to files that - * don't actually exist. - */ -public class DeadEndPropertyRemover extends FsuScanner { - private ImageDirectoryWithBackup imageDirectoryWithBackup; - - public DeadEndPropertyRemover(FSUController controller) { - super(controller); - this.imageDirectoryWithBackup = controller - .getImageDirectoryWithBackup(); - } - - /** - * Remove dead end properties for both main images and thumbnails. - */ - public void remove() { - updateLog.section("Removing image properties whose " - + "referenced files do not exist."); - - removeDeadEndProperties(imageProperty, "main image"); - removeDeadEndProperties(thumbProperty, "thumbnail"); - } - - /** - * Check all of the individuals that possess this property. - */ - private void removeDeadEndProperties(Property prop, String label) { - for (Resource resource : ModelWrapper.listResourcesWithProperty(model, - prop)) { - removeDeadEndPropertiesFromResource(resource, prop, label); - } - } - - /** - * Check these statments on this resource. If any of them does not point to - * an existing file, remove the statement. - */ - private void removeDeadEndPropertiesFromResource(Resource resource, - Property prop, String label) { - for (Statement stmt : getStatements(resource, prop)) { - RDFNode node = stmt.getObject(); - if (node.isLiteral()) { - String filename = ((Literal) node).getString(); - File file = imageDirectoryWithBackup.getExistingFile(filename); - if (!file.exists()) { - updateLog.warn( - resource, - "removing link to " + label + " '" + filename - + "': file does not exist at '" - + file.getAbsolutePath() + "'."); - - ModelWrapper.removeStatement(model, stmt); - } - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java deleted file mode 100644 index bc45ad247..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java +++ /dev/null @@ -1,38 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; - -import com.hp.hpl.jena.rdf.model.Model; - -import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; - -/** - * An object that can initialize one of the {@link FsuScanner}s. - */ -public interface FSUController { - - /** The Jena model. */ - Model getModel(); - - /** The update log. */ - FSULog getUpdateLog(); - - /** The place to find or to create image files. */ - ImageDirectoryWithBackup getImageDirectoryWithBackup(); - - /** A helper with access to the DAO layer and the file storage system. */ - UploadedFileHelper getUploadedFileHelper(); - - /** The file storage system. */ - FileStorage getFileStorage(); - - /** Where to store the files that were translated. */ - File getTranslatedDirectory(); - - /** Where to store the files that weren't in use anyway. */ - File getUnreferencedDirectory(); - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java deleted file mode 100644 index 33a0e9915..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java +++ /dev/null @@ -1,181 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.text.SimpleDateFormat; -import java.util.Date; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; - -/** - * Writes the log file for the {@link FileStorageUpdater}. Be sure to call - * {@link #close()} when finished. - */ -public class FSULog { - private final SimpleDateFormat timeStamper = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss"); - - private final File logFile; - private final PrintWriter writer; - private boolean open; - - FSULog(File logDirectory, String prefix) throws IOException { - this.logFile = generateTimestampedFilename(logDirectory, prefix); - this.writer = new PrintWriter(this.logFile); - open = true; - } - - /** - * Create a filename for the log file that contains a timestamp, so if we - * run the process more than once, we will see multiple files. - */ - private File generateTimestampedFilename(File upgradeDirectory, - String prefix) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-sss"); - String filename = prefix + "." + sdf.format(new Date()) + ".txt"; - return new File(upgradeDirectory, filename); - } - - /** - * Where are we writing the output? - */ - String getFilename() { - return this.logFile.getAbsolutePath(); - } - - /** - * Write this message. - */ - void log(String message) { - writer.println(timeStamper.format(new Date()) + " INFO " + message); - } - - /** - * Write this message about this resource. - */ - void log(Resource resource, String message) { - log(showResource(resource) + message); - } - - /** - * Write this warning message. - */ - public void warn(String message) { - writer.println(timeStamper.format(new Date()) + " WARN " + message); - } - - /** - * Write this warning message about this resource. - */ - public void warn(Resource resource, String message) { - warn(showResource(resource) + message); - } - - /** - * Write this error message. - */ - void error(String message) { - writer.println(timeStamper.format(new Date()) + " ERROR " + message); - } - - /** - * Write this exception as an error message.. - */ - void error(Exception e) { - error(e.toString()); - e.printStackTrace(writer); - } - - /** - * Write an error message with this exception. - */ - public void error(String message, Exception e) { - error(message); - e.printStackTrace(writer); - } - - /** - * Write an error message about this resource and with this exception. - */ - public void error(Resource resource, String message) { - error(showResource(resource) + message); - } - - /** - * Write an error message about this resource and with this exception. - */ - public void error(Resource resource, String message, Exception e) { - error(showResource(resource) + message, e); - } - - /** - * Write a section heading. - */ - public void section(String message) { - log(">>>>>>>>>> "); - log(">>>>>>>>>> " + message); - log(">>>>>>>>>> "); - } - - /** - * Close the writer, if not already closed. - */ - public void close() { - if (open) { - writer.close(); - open = false; - } - } - - /** - * Format the resource label and URI for output in a message. - */ - private String showResource(Resource resource) { - return "On resource '" + getLabel(resource) + "' (" + getUri(resource) - + "), "; - } - - /** - * Find the URI for this resource, if there is one. - */ - private String getUri(Resource resource) { - if (resource != null) { - String uri = resource.getURI(); - if (uri != null) { - return uri; - } - } - return "no URI"; - } - - /** - * Find the label for this resource, if there is one. - */ - private String getLabel(Resource resource) { - if (resource != null) { - Model model = resource.getModel(); - if (model != null) { - Property prop = model.createProperty(VitroVocabulary.LABEL); - Statement stmt = resource.getProperty(prop); - if (stmt != null) { - RDFNode node = stmt.getObject(); - if (node.isLiteral()) { - return ((Literal) node).getString(); - } - } - } - } - return "no label"; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java deleted file mode 100644 index 1329e2f65..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java +++ /dev/null @@ -1,352 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; - -/** - * Check all of the FileByteStream objects. If there are any that don't have - * alias URLs, fix them. - */ -public class FileStorageAliasAdder { - private static final Log log = LogFactory - .getLog(FileStorageAliasAdder.class); - - private static final String FILE_PATH = "/file/"; - - /** - * Query: get all bytestream resources that do not have alias URLs. - */ - private static final String QUERY_BYTESTREAMS_WITHOUT_ALIASES = "" - + "PREFIX rdf: \n" - + "PREFIX public: \n" - + "SELECT ?bs\n" + "WHERE {\n" - + " ?bs rdf:type public:FileByteStream\n" - + " OPTIONAL { ?bs public:directDownloadUrl ?alias }\n" - + " FILTER ( !BOUND(?alias) )\n" + "}\n"; - - /** - * Query: get the filenames for all bytestream resources that do not have - * alias URLs. - */ - private static final String QUERY_FILENAMES_FOR_BYTESTREAMS = "" - + "PREFIX rdf: \n" - + "PREFIX public: \n" - + "SELECT ?bs ?fn\n" + "WHERE {\n" - + " ?bs rdf:type public:FileByteStream . \n" - + " ?f public:downloadLocation ?bs . \n" - + " ?f public:filename ?fn . \n" - + " OPTIONAL { ?bs public:directDownloadUrl ?alias . }\n" - + " FILTER ( !BOUND(?alias) )\n" + "}\n"; - - private final Model model; - private final File upgradeDirectory; - private final String vivoDefaultNamespace; - - private FSULog updateLog; - - private Set bytestreamUrisWithoutAliases; - private Map bytestreamUrisAndFilenames; - - public FileStorageAliasAdder(Model model, File uploadDirectory, - String vivoDefaultNamespace) { - this.model = model; - this.upgradeDirectory = new File(uploadDirectory, "upgrade"); - this.vivoDefaultNamespace = vivoDefaultNamespace; - } - - /** - * Go through all of the FileByteStream objects in the model, creating Alias - * URLs for any objects that don't have them. - * - * If there is nothing to do, don't even create a log file, just exit. - * - * If there is something to do, go through the whole process. - * - * At the end, there should be nothing to do. - */ - public void update() { - // If there is nothing to do, we're done: don't even create a log file. - if (!isThereAnythingToDo()) { - log.debug("Found no FileByteStreams without alias URLs."); - return; - } - - setup(); - - try { - findAndAddMissingAliasUrls(); - - if (isThereAnythingToDo()) { - throw new IllegalStateException("FileStorageAliasAdder " - + "was unsuccessful -- model still contains " - + "FileByteStreams without alias URLs."); - } - - updateLog.section("Finished adding alias URLs to FileByteStreams."); - } finally { - updateLog.close(); - } - - log.info("Finished adding alias URLs to FileByteStreams."); - } - - /** - * Query the model. If there are any FileByteStream objects with no Alias - * URL, we have work to do. - */ - private boolean isThereAnythingToDo() { - String queryString = QUERY_BYTESTREAMS_WITHOUT_ALIASES; - log.debug("query: " + queryString); - - QueryExecution qexec = null; - try { - qexec = createQueryExecutor(queryString); - ResultSet results = qexec.execSelect(); - - boolean foundSome = results.hasNext(); - log.debug("any work to do? " + foundSome); - - return foundSome; - } catch (Exception e) { - log.error(e, e); - return false; - } finally { - if (qexec != null) { - qexec.close(); - } - } - } - - /** - * Create the upgrade directory. Create the log file. If we fail, drop dead. - */ - private void setup() { - try { - this.upgradeDirectory.mkdirs(); - updateLog = new FSULog(this.upgradeDirectory, - "FileStorageAliasAdder-log"); - log.info("Updating pre-1.1 file references. Log file is " - + updateLog.getFilename()); - } catch (IOException e) { - if (updateLog != null) { - updateLog.close(); - } - throw new IllegalStateException("can't create log file: '" - + updateLog.getFilename() + "'", e); - } - } - - /** - * Add an alias URL to any FileByteStream object that doesn't have one. - */ - private void findAndAddMissingAliasUrls() { - findBytestreamsWithoutAliasUrls(); - findFilenamesForBytestreams(); - addAliasUrlsToModel(); - } - - /** - * Find every bytestream that doesn't have an alias URL. - */ - private void findBytestreamsWithoutAliasUrls() { - BytestreamUriUnpacker unpacker = new BytestreamUriUnpacker(); - - runQuery(QUERY_BYTESTREAMS_WITHOUT_ALIASES, unpacker); - this.bytestreamUrisWithoutAliases = unpacker.getUris(); - - log.debug("Found " + unpacker.getUris().size() - + " bytestreams without alias URLs"); - } - - /** - * Find the filename for every bytestream that doesn't have an alias URL. - */ - private void findFilenamesForBytestreams() { - FilenameUnpacker unpacker = new FilenameUnpacker(); - - runQuery(QUERY_FILENAMES_FOR_BYTESTREAMS, unpacker); - this.bytestreamUrisAndFilenames = unpacker.getFilenameMap(); - - log.debug("Found " + unpacker.getFilenameMap().size() - + " bytestreams with filenames but no alias URLs"); - } - - /** Add an alias URL to each resource in the list. */ - private void addAliasUrlsToModel() { - if (this.bytestreamUrisWithoutAliases.isEmpty()) { - updateLog.warn("Found no bytestreams without aliases. " - + "Why am I here?"); - return; - } - - Property aliasProperty = model - .createProperty(VitroVocabulary.FS_ALIAS_URL); - - for (String bytestreamUri : this.bytestreamUrisWithoutAliases) { - String aliasUrl = figureAliasUrl(bytestreamUri); - Resource resource = model.getResource(bytestreamUri); - - ModelWrapper.add(model, resource, aliasProperty, aliasUrl); - updateLog.log(resource, "added alias URL: '" + aliasUrl + "'"); - } - } - - /** - * Convert the bytestream URI and the filename into an alias URL. - * - * If they aren't in our default namespace, or they don't have a filename, - * then their URI is the best we can do for an alias URL. - */ - private String figureAliasUrl(String bytestreamUri) { - if (!bytestreamUri.startsWith(vivoDefaultNamespace)) { - updateLog.warn("bytestream uri does not start " - + "with the default namespace: '" + bytestreamUri + "'"); - return bytestreamUri; - } - - String filename = this.bytestreamUrisAndFilenames.get(bytestreamUri); - if (filename == null) { - updateLog.warn("bytestream has no surrogate or no filename: '" - + bytestreamUri + "'"); - return "filename_not_found"; - } - - try { - String remainder = bytestreamUri.substring(vivoDefaultNamespace - .length()); - String encodedFilename = URLEncoder.encode(filename, "UTF-8"); - String separator = remainder.endsWith("/") ? "" : "/"; - - return FILE_PATH + remainder + separator + encodedFilename; - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); // No UTF-8? Can't happen. - } - } - - private void runQuery(String queryString, QueryResultUnpacker unpacker) { - log.debug("query: " + queryString); - - QueryExecution qexec = null; - try { - qexec = createQueryExecutor(queryString); - - Iterator results = qexec.execSelect(); - while (results.hasNext()) { - QuerySolution result = results.next(); - if (log.isDebugEnabled()) { - log.debug("Query result variables: " - + listVariables(result)); - } - unpacker.unpack(result); - } - } catch (Exception e) { - log.error(e, e); - } finally { - if (qexec != null) { - qexec.close(); - } - } - } - - private QueryExecution createQueryExecutor(String queryString) { - Query query = QueryFactory.create(queryString); - return QueryExecutionFactory.create(query, model); - } - - /** For debug logging. */ - private List listVariables(QuerySolution result) { - List list = new ArrayList(); - for (Iterator names = result.varNames(); names.hasNext();) { - String name = names.next(); - RDFNode value = result.get(name); - list.add(name + "=" + value); - } - return list; - } - - // ---------------------------------------------------------------------- - // Helper classes - // ---------------------------------------------------------------------- - - private interface QueryResultUnpacker { - public abstract void unpack(QuerySolution result); - } - - private class BytestreamUriUnpacker implements QueryResultUnpacker { - private final Set uris = new HashSet(); - - @Override - public void unpack(QuerySolution result) { - Resource bytestream = result.getResource("bs"); - if (bytestream == null) { - updateLog.error("Query result contains no " - + "bytestream resource: " + result); - return; - } - - uris.add(bytestream.getURI()); - } - - public Set getUris() { - return uris; - } - } - - private class FilenameUnpacker implements QueryResultUnpacker { - private final Map filenameMap = new HashMap(); - - @Override - public void unpack(QuerySolution result) { - Resource bytestream = result.getResource("bs"); - if (bytestream == null) { - updateLog.error("Query result contains no " - + "bytestream resource: " + result); - return; - } - String bytestreamUri = bytestream.getURI(); - - Literal filenameLiteral = result.getLiteral("fn"); - if (filenameLiteral == null) { - updateLog.error("Query result for '" + bytestreamUri - + "' contains no filename."); - return; - } - String filename = filenameLiteral.getString(); - - filenameMap.put(bytestreamUri, filename); - } - - public Map getFilenameMap() { - return filenameMap; - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java deleted file mode 100644 index b31ae17e4..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java +++ /dev/null @@ -1,268 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.IOException; -import java.util.Collection; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.rdf.model.Model; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; - -/** - *

- * Clean up any files that are stored in the old directory structure and - * referenced by old-style image properties. - *

- *

- * Besides converting the files to the new framework, this process will produce - * these artifacts: - *

    - *
  • A log file in the uploaded files directory, with a timestamped name, such - * as upgrade/upgradeLog2010-06-20T14-55-00.txt, for example. If - * for any reason, the upgrade process must run again, the log will not be - * overwritten.
  • - *
  • A directory of "deleted" files - these were extra thumbnail files or - * extra main image files -- see the details below.
  • - *
  • A directory of "unreferenced" files - these were in the image directory, - * but not connected to any entity.
  • - *
- *

- *

- * We consider some special cases: - *

    - *
  • An individual may refer to an image file that does not actually exist. If - * so, that reference will be deleted.
  • - *
  • There may be more than one reference to the same image file. If so, all - * but the first such reference will be deleted.
  • - *
  • - * In the old style, it was possible to have a main image without a thumbnail. - * If we find that, we will generate a scaled down copy of the main image, store - * that as a thumbnail image file, and then proceed.
  • - *
  • - * In the old style, it was possible to have a thumbnail without a main image. - * If we find that, we will make a copy of the thumbnail image file, declare - * that copy to be the main image, and then proceed.
  • - *
  • - * We may find individuals with more than one main image, or more than one - * thumbnail. If so, we will discard all but the first one (move them to the - * "deleted" directory).
  • - *
- *

- *

- * Aside from these special cases, we will: - *

    - *
  • Translate the main image. - *
      - *
    • Store the image in the new file system.
    • - *
    • Delete the image from the old images directory.
    • - *
    • Create a ByteStream individual for the main image.
    • - *
    • Create a Surrogate individual for the main image.
    • - *
    • Tie these together and attach to the entity that owns the image.
    • - *
    - *
  • - *
  • Translate the thumbnail. - *
      - *
    • Store the thumbnail in the new file system.
    • - *
    • Create a ByteStream individual for the thumbnail.
    • - *
    • Create a Surrogate individual for the thumbnail.
    • - *
    • Tie these together and attach to the Surrogate for the main image.
    • - *
    - *
  • - *
- *

- *

- * After processing all of these cases, there may be some images remaining in - * the "images" directory. These will be moved to the "unreferenced" directory, - * while preserving any internal tree structure. - *

- */ -public class FileStorageUpdater implements FSUController { - private static final Log log = LogFactory.getLog(FileStorageUpdater.class); - - /** How wide should a generated thumbnail image be (in pixels)? */ - public static final int THUMBNAIL_WIDTH = 200; - - /** How high should a generated thumbnail image be (in pixels)? */ - public static final int THUMBNAIL_HEIGHT = 200; - - /** How is the main image referenced in the old scheme? */ - public static final String IMAGEFILE = VitroVocabulary.vitroURI - + "imageFile"; - - /** How is the thumbnail referenced in the old scheme? */ - public static final String IMAGETHUMB = VitroVocabulary.vitroURI - + "imageThumb"; - - private final Model model; - - private final FileStorage fileStorage; - private final UploadedFileHelper uploadedFileHelper; - private final ImageDirectoryWithBackup imageDirectoryWithBackup; - private final File upgradeDirectory; - - private FSULog updateLog; - - public FileStorageUpdater(WebappDaoFactory wadf, Model model, - FileStorage fileStorage, File uploadDirectory, - File webappImageDirectory, ServletContext ctx) { - this.model = model; - this.fileStorage = fileStorage; - this.uploadedFileHelper = new UploadedFileHelper(fileStorage, wadf, ctx); - this.upgradeDirectory = new File(uploadDirectory, "upgrade"); - - this.imageDirectoryWithBackup = new ImageDirectoryWithBackup(new File( - uploadDirectory, "images"), webappImageDirectory); - } - - /** - *

- * Go through all of the individuals who have image files or thumbnail - * files, adjusting them to the new way. - *

- *

- * If there is nothing to do, don't even create a log file, just exit. - *

- *

- * If there is something to do, go through the whole process. - *

- *

- * At the end, there should be nothing to do. If that's true, clean out the - * old images directory. - *

- */ - public void update() { - // If there is nothing to do, we're done: don't even create a log file. - if (!isThereAnythingToDo()) { - log.debug("Found no pre-1.1 file references."); - return; - } - - // Create the upgrade directory and the log file. - setup(); - - try { - // Remove any image properties that don't point to literals. - new NonLiteralPropertyRemover(this).remove(); - - // Remove any image properties that point to files that don't exist. - new DeadEndPropertyRemover(this).remove(); - - // No resource may have multiple main images or multiple thumbnails. - new MultiplePropertyRemover(this).remove(); - - // Create a main image for any thumbnail that doesn't have one. - new AllThumbsAdjuster(this).adjust(); - - // Create a thumbnail for any main image that doesn't have one. - new NoThumbsAdjuster(this).adjust(); - - // Copy all images into the new file storage system, translating - // into the new schema. Get a list of all the images we translated. - ImageSchemaTranslater translater = new ImageSchemaTranslater(this); - Collection translatedFiles = translater.translate(); - - if (isThereAnythingToDo()) { - throw new IllegalStateException( - "FileStorageUpdate was unsuccessful -- " - + "model still contains pre-1.1 file references."); - } - - // Clean out the old image directory, separating into files which - // were translated, and files for which we found no reference. - new ImageDirectoryCleaner(this).clean(translatedFiles); - - updateLog.section("File Storage update is complete."); - } finally { - updateLog.close(); - } - - log.info("Finished updating pre-1.1 file references."); - } - - /** - * Query the model. If there are any resources with old-style image - * properties, we have work to do. - */ - private boolean isThereAnythingToDo() { - if (!ModelWrapper.listResourcesWithProperty(model, - model.createProperty(IMAGEFILE)).isEmpty()) { - return true; - } - - if (!ModelWrapper.listResourcesWithProperty(model, - model.createProperty(IMAGETHUMB)).isEmpty()) { - return true; - } - - return false; - } - - /** - * Create the upgrade directory. Create the log file. If we fail, drop dead. - */ - private void setup() { - try { - this.upgradeDirectory.mkdirs(); - updateLog = new FSULog(this.upgradeDirectory, - "FileStorageUpdater-log"); - log.info("Updating pre-1.1 file references. Log file is " - + updateLog.getFilename()); - } catch (IOException e) { - if (updateLog != null) { - updateLog.close(); - } - throw new IllegalStateException("can't create log file: '" - + updateLog.getFilename() + "'", e); - } - } - - // ---------------------------------------------------------------------- - // Methods to set up the individual scanners. - // ---------------------------------------------------------------------- - - @Override - public Model getModel() { - return this.model; - } - - @Override - public FSULog getUpdateLog() { - return this.updateLog; - } - - @Override - public UploadedFileHelper getUploadedFileHelper() { - return this.uploadedFileHelper; - } - - @Override - public FileStorage getFileStorage() { - return this.fileStorage; - } - - @Override - public ImageDirectoryWithBackup getImageDirectoryWithBackup() { - return this.imageDirectoryWithBackup; - } - - @Override - public File getTranslatedDirectory() { - return new File(this.upgradeDirectory, "translatedImages"); - } - - @Override - public File getUnreferencedDirectory() { - return new File(this.upgradeDirectory, "unreferencedImages"); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java deleted file mode 100644 index 95b40eba1..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java +++ /dev/null @@ -1,107 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A collection of static routines for moving, copying and deleting files. - */ -public class FileUtil { - /** - * Copy a file from one location to another, and remove it from the original - * location. - */ - public static void moveFile(File from, File to) throws IOException { - copyFile(from, to); - deleteFile(from); - } - - /** - * Copy a file from one location to another. - */ - public static void copyFile(File from, File to) throws IOException { - if (!from.exists()) { - throw new FileNotFoundException("File '" + from.getAbsolutePath() - + "' does not exist."); - } - - InputStream in = null; - try { - in = new FileInputStream(from); - writeFile(in, to); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Create a file with the contents of this data stream. - * - * @param stream - * the data stream. You must close it afterward. - */ - public static void writeFile(InputStream stream, File to) - throws IOException { - if (to.exists()) { - throw new IOException("File '" + to.getAbsolutePath() - + "' already exists."); - } - - File parent = to.getParentFile(); - if (!parent.exists()) { - parent.mkdirs(); - if (!parent.exists()) { - throw new IOException("Can't create parent directory for '" - + to.getAbsolutePath() + "'"); - } - } - - OutputStream out = null; - try { - out = new FileOutputStream(to); - byte[] buffer = new byte[8192]; - int howMany; - while (-1 != (howMany = stream.read(buffer))) { - out.write(buffer, 0, howMany); - } - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Delete this file, and make sure that it's gone. - */ - public static void deleteFile(File file) throws IOException { - file.delete(); - if (file.exists()) { - throw new IOException("Failed to delete file '" - + file.getAbsolutePath() + "'"); - } - } - - /** No need to instantiate it -- all methods are static. */ - private FileUtil() { - // Nothing to instantiate. - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java deleted file mode 100644 index e0549d66e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java +++ /dev/null @@ -1,126 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.shared.Lock; - -/** - * Base class for the tools that scan the model. Holds some useful fields and - * some utility methods. - */ -public abstract class FsuScanner { - protected final Model model; - protected final FSULog updateLog; - - protected final Property imageProperty; - protected final Property thumbProperty; - - public FsuScanner(FSUController controller) { - this.model = controller.getModel(); - this.updateLog = controller.getUpdateLog(); - - this.imageProperty = model.createProperty(FileStorageUpdater.IMAGEFILE); - this.thumbProperty = model - .createProperty(FileStorageUpdater.IMAGETHUMB); - } - - /** - * Read all of the specified properties on a resource, and return a - * {@link List} of the {@link String} values. - */ - protected List getValues(Resource resource, Property property) { - List list = new ArrayList(); - StmtIterator stmts = resource.listProperties(property); - try { - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - RDFNode object = stmt.getObject(); - if (object.isLiteral()) { - list.add(((Literal) object).getString()); - } else { - updateLog.error(resource, - "property value was not a literal: " - + "property is '" + property.getURI() - + "', value is '" + object + "'"); - } - } - } finally { - stmts.close(); - } - return list; - } - - /** - * Read all of the specified properties on a resource, and return a - * {@link List} of the {@link Statement}s. - */ - protected List getStatements(Resource resource, Property property) { - List list = new ArrayList(); - - resource.getModel().enterCriticalSection(Lock.READ); - StmtIterator stmts = resource.listProperties(property); - try { - while (stmts.hasNext()) { - list.add(stmts.next()); - } - } finally { - stmts.close(); - resource.getModel().leaveCriticalSection(); - } - return list; - } - - /** - * Find the filename within a path so we can add this prefix to it, while - * retaining the path. - */ - protected String addFilenamePrefix(String prefix, String path) { - int slashHere = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')); - if (slashHere == -1) { - return prefix + path; - } else { - String dirs = path.substring(0, slashHere + 1); - String filename = path.substring(slashHere + 1); - return dirs + prefix + filename; - } - } - - /** - * We are about to create a file - if a file of this name already exists, - * increment the name until we have no collision. - * - * @return the original file, or the file with the incremented name. - */ - protected File checkNameConflicts(final File file) { - if (!file.exists()) { - // No conflict. - return file; - } - - File parent = file.getParentFile(); - String filename = file.getName(); - for (int i = 0; i < 100; i++) { - File newFile = new File(parent, i + filename); - if (!newFile.exists()) { - updateLog.log("File '" + file + "' already exists, using '" - + newFile + "' to avoid conflict."); - return newFile; - } - } - - updateLog.error("File '" + file - + "' already exists. Unable to avoid conflict."); - return file; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java deleted file mode 100644 index 06084ec08..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java +++ /dev/null @@ -1,134 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.IOException; -import java.util.Collection; - -/** - * Clean out the old image directory. Copy the files into the upgrade directory, - * separating into the ones that we translated, and the ones that weren't - * referenced. - */ -public class ImageDirectoryCleaner extends FsuScanner { - private final ImageDirectoryWithBackup imageDirectoryWithBackup; - protected final File translatedDirectory; - protected final File unreferencedDirectory; - - public ImageDirectoryCleaner(FSUController controller) { - super(controller); - this.imageDirectoryWithBackup = controller - .getImageDirectoryWithBackup(); - - this.translatedDirectory = controller.getTranslatedDirectory(); - this.unreferencedDirectory = controller.getUnreferencedDirectory(); - } - - /** - * Remove all of the files from the old image directory. - */ - public void clean(Collection translatedFiles) { - updateLog.section("Cleaning the old image directory of " - + "files that were translated."); - removeTranslatedFiles(translatedFiles); - - updateLog.section("Cleaning the old image directory of " - + "files that were not referenced."); - removeRemainingFiles(imageDirectoryWithBackup - .getPrimaryImageDirectory()); - } - - /** - * Move all of the files that we translated into the new system. - */ - private void removeTranslatedFiles(Collection translatedFiles) { - for (String path : translatedFiles) { - File oldFile = new File( - imageDirectoryWithBackup.getPrimaryImageDirectory(), path); - if (oldFile.exists()) { - updateLog.log("moving image file '" + path - + "' to the 'translated' directory."); - File deletedFile = new File(translatedDirectory, path); - try { - FileUtil.moveFile(oldFile, deletedFile); - } catch (IOException e) { - updateLog.error("Failed to move translated file '" - + oldFile.getAbsolutePath() + "'"); - } - } else { - updateLog.log("Not moving image file '" + path - + "' to the 'translated' directory -- " - + "found it in the backup directory."); - } - } - } - - /** - * Go through the images directory, and discard any that remain. They must - * not have been referenced by any existing individuals. - */ - private void removeRemainingFiles(File directory) { - updateLog.log("Cleaning image directory '" + directory + "'"); - try { - File targetDirectory = makeCorrespondingDirectory(directory); - File[] children = directory.listFiles(); - if (children != null) { - for (File child : children) { - if (child.isDirectory()) { - removeRemainingFiles(child); - } else { - moveUnreferencedFile(targetDirectory, child); - } - } - } - } catch (IOException e) { - updateLog.error( - "Failed to clean images directory '" - + directory.getAbsolutePath() + "'", e); - } - } - - /** - * Move this file from its current location to its new home in the - * "unreferenced" directory. Log it. - */ - private void moveUnreferencedFile(File targetDirectory, File file) { - updateLog.log("Moving image file '" + file.getPath() - + "' to the 'unreferenced' directory"); - try { - File newFile = new File(targetDirectory, file.getName()); - FileUtil.moveFile(file, newFile); - } catch (IOException e) { - updateLog.error( - "Can't move unreferenced file '" + file.getAbsolutePath() - + "'", e); - } - } - - /** - * Figure out the path from the "images" directory to this one, and create a - * corresponding directory in the "unreferenced" area. - */ - private File makeCorrespondingDirectory(File directory) throws IOException { - String imagesPath = imageDirectoryWithBackup.getPrimaryImageDirectory() - .getAbsolutePath(); - String thisPath = directory.getAbsolutePath(); - - if (!thisPath.startsWith(imagesPath)) { - throw new IOException("Can't make a corresponding directory for '" - + thisPath + "'"); - } - - String suffix = thisPath.substring(imagesPath.length()); - - File corresponding = new File(unreferencedDirectory, suffix); - corresponding.mkdirs(); - if (!corresponding.exists()) { - throw new IOException("Failed to create corresponding directory '" - + corresponding.getAbsolutePath() + "'"); - } - - return corresponding; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java deleted file mode 100644 index 4ddb5c49f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java +++ /dev/null @@ -1,77 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A way to look for files in TOMCAT_WEBAPP/vivo/images, if they are not found - * in upload.directory/images. - */ -public class ImageDirectoryWithBackup { - private static final Log log = LogFactory - .getLog(ImageDirectoryWithBackup.class); - - /** The primary image directory, where we do most of the manipulation. */ - private final File uploadImageDirectory; - - /** - * If we are looking for a file and don't find it in the primary directory, - * look for it here. - */ - private final File webappImageDirectory; - - /** - * Be careful! webappImageDirectory may be null. - */ - public ImageDirectoryWithBackup(File uploadImageDirectory, - File webappImageDirectory) { - this.uploadImageDirectory = uploadImageDirectory; - this.webappImageDirectory = webappImageDirectory; - } - - /** - * When looking to read a file, start by looking in the - * {@link #uploadImageDirectory}. - * - * If the file isn't found there, look in the {@link #webappImageDirectory} - * as a fallback. - * - * If not there either, return the pointer to the nonexistent file in the - * {@link #uploadImageDirectory}. - */ - File getExistingFile(String relativePath) { - File file1 = new File(uploadImageDirectory, relativePath); - if (file1.exists()) { - log.trace("Found file: " + file1.getAbsolutePath()); - return file1; - } - if (webappImageDirectory != null) { - File file2 = new File(webappImageDirectory, relativePath); - if (file2.exists()) { - log.trace("Found file: " + file2.getAbsolutePath()); - return file2; - } - } - log.trace("Didn't find file: " + file1.getAbsolutePath()); - return file1; - } - - /** - * New files will always be created in the primary directory. - */ - File getNewfile(String relativePath) { - return new File(uploadImageDirectory, relativePath); - } - - /** - * You can get a direct reference to the primary image directory, but it - * should only be used for directory-base operations, like final cleanup. - */ - public File getPrimaryImageDirectory() { - return uploadImageDirectory; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java deleted file mode 100644 index 39409487b..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java +++ /dev/null @@ -1,170 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.commons.io.FilenameUtils; - -import com.hp.hpl.jena.rdf.model.ResIterator; -import com.hp.hpl.jena.rdf.model.Resource; - -import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; -import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; - -/** - * Make copies of the main image and thumbnail in the new file storage system, - * and in the model. Remove the old properties, but don't remove the old files - * yet, in case someone else is referring to them also. - */ -public class ImageSchemaTranslater extends FsuScanner { - private final ImageDirectoryWithBackup imageDirectoryWithBackup; - protected final FileStorage fileStorage; - protected final UploadedFileHelper uploadedFileHelper; - - public ImageSchemaTranslater(FSUController controller) { - super(controller); - this.imageDirectoryWithBackup = controller - .getImageDirectoryWithBackup(); - this.fileStorage = controller.getFileStorage(); - this.uploadedFileHelper = controller.getUploadedFileHelper(); - } - - /** - * By the time we get here, any individual with a main image also has a - * thumbnail, and vice versa, and exactly one of each. For each one, - * translate the main image and the thumbnail into the new system. - */ - public Collection translate() { - updateLog.section("Copying images into the new file storage, " - + "and adding them to the new model."); - - SortedSet translated = new TreeSet(); - ResIterator haveImage = model.listResourcesWithProperty(imageProperty); - try { - while (haveImage.hasNext()) { - Resource resource = haveImage.next(); - translateImages(resource, translated); - } - } finally { - haveImage.close(); - } - return translated; - } - - /** - * This individual should have exactly one main image and exactly one - * thumbnail. - *
    - *
  • Translate the first main image into the new system.
  • - *
  • Translate the first thumbnail into the new system.
  • - *
  • Remove all old-style main image properties.
  • - *
  • Remove all old-style thumbnail properties.
  • - *
- */ - private void translateImages(Resource resource, - Collection translated) { - List mainImages = getValues(resource, imageProperty); - if (mainImages.size() != 1) { - updateLog.error(resource, "has " + mainImages.size() - + " main images: " + mainImages); - return; - } - - List thumbnails = getValues(resource, thumbProperty); - if (thumbnails.size() != 1) { - updateLog.error(resource, "has " + thumbnails.size() - + " thumbnails: " + thumbnails); - return; - } - - FileInfo main = translateFile(resource, mainImages.get(0), "main image"); - FileInfo thumb = translateFile(resource, thumbnails.get(0), "thumbnail"); - if ((main == null) || (thumb == null)) { - return; - } - uploadedFileHelper.setImagesOnEntity(resource.getURI(), main, thumb); - - translated.add(mainImages.get(0)); - ResourceWrapper.removeAll(resource, imageProperty); - - translated.add(thumbnails.get(0)); - ResourceWrapper.removeAll(resource, thumbProperty); - - } - - /** - * Translate an image file into the new system - *
    - *
  • Attempt to infer MIME type.
  • - *
  • Copy into the File system.
  • - *
  • Create the File and Bytestream individuals in the model.
  • - *
- */ - private FileInfo translateFile(Resource resource, String path, String label) { - File oldFile = imageDirectoryWithBackup.getExistingFile(path); - String filename = getSimpleFilename(path); - String mimeType = guessMimeType(resource, filename); - - InputStream inputStream = null; - try { - inputStream = new FileInputStream(oldFile); - // Create the file individuals in the model - FileInfo fileInfo = uploadedFileHelper.createFile(filename, - mimeType, inputStream); - updateLog.log(resource, "translating " + label + " '" + path - + "' into the file storage as '" + fileInfo.getUri() + "'"); - return fileInfo; - } catch (IOException e) { - updateLog.error(resource, "Can't create the " + label + " file. ", - e); - return null; - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Remove any path parts, and just get the filename and extension. - */ - private String getSimpleFilename(String path) { - return FilenameUtils.getName(path); - } - - /** - * Guess what the MIME type might be. - */ - private String guessMimeType(Resource resource, String filename) { - if (filename.endsWith(".gif") || filename.endsWith(".GIF")) { - return "image/gif"; - } else if (filename.endsWith(".png") || filename.endsWith(".PNG")) { - return "image/png"; - } else if (filename.endsWith(".jpg") || filename.endsWith(".JPG")) { - return "image/jpeg"; - } else if (filename.endsWith(".jpeg") || filename.endsWith(".JPEG")) { - return "image/jpeg"; - } else if (filename.endsWith(".jpe") || filename.endsWith(".JPE")) { - return "image/jpeg"; - } else { - updateLog.warn(resource, - "can't recognize the MIME type of this image file: '" - + filename + "'"); - return "image"; - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java deleted file mode 100644 index d6aa95956..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java +++ /dev/null @@ -1,54 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.ResIterator; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.shared.Lock; - -/** - * Utility methods that operate against the Model with proper locks. - */ -public class ModelWrapper { - - public static Collection listResourcesWithProperty(Model model, - Property property) { - List list = new ArrayList(); - ResIterator iterator = model.listResourcesWithProperty(property); - try { - while (iterator.hasNext()) { - Resource resource = iterator.next(); - list.add(resource); - } - } finally { - iterator.close(); - } - return list; - } - - public static void removeStatement(Model model, Statement stmt) { - model.enterCriticalSection(Lock.WRITE); - try { - model.remove(stmt); - } finally { - model.leaveCriticalSection(); - } - } - - public static void add(Model model, Resource subject, Property predicate, - String value) { - model.enterCriticalSection(Lock.WRITE); - try { - model.add(subject, predicate, value); - } finally { - model.leaveCriticalSection(); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java deleted file mode 100644 index 4148943fa..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java +++ /dev/null @@ -1,65 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.util.List; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; - -/** - * If a resource has more than one image or more than one thumbnail, this - * discards the extras. - */ -public class MultiplePropertyRemover extends FsuScanner { - - public MultiplePropertyRemover(FSUController controller) { - super(controller); - } - - /** - * By now, we have removed any non-literals or dead ends, so keep the first - * one and discard any extras. - */ - public void remove() { - updateLog.section("Checking for resources with more " - + "than one main image, or more than one thumbnail."); - - removeExtraProperties(imageProperty, "main image"); - removeExtraProperties(thumbProperty, "thumbnail"); - } - - /** - * Check each resource that has this property. - */ - public void removeExtraProperties(Property prop, String label) { - for (Resource resource : ModelWrapper.listResourcesWithProperty(model, - prop)) { - removeExtraProperties(resource, prop, label); - } - } - - /** - * If this resource has more than one of this property, delete the extras. - */ - private void removeExtraProperties(Resource resource, Property prop, - String label) { - List stmts = getStatements(resource, prop); - for (int i = 1; i < stmts.size(); i++) { - Statement stmt = stmts.get(i); - RDFNode node = stmt.getObject(); - if (node.isLiteral()) { - String value = ((Literal) node).getString(); - updateLog.warn(resource, "removing extra " + label - + " property: '" + value + "'"); - } else { - updateLog.warn(resource, "removing extra " + label - + " property: '" + node + "'"); - } - ModelWrapper.removeStatement(model, stmt); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java deleted file mode 100644 index 7166aece1..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java +++ /dev/null @@ -1,173 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT; -import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.media.jai.JAI; -import javax.media.jai.RenderedOp; - -import com.hp.hpl.jena.rdf.model.Resource; -import com.sun.media.jai.codec.MemoryCacheSeekableStream; - -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.CropRectangle; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadThumbnailer; - -/** - * Adjust any individual that has a main image but no thumbnail. - */ -public class NoThumbsAdjuster extends FsuScanner { - private ImageDirectoryWithBackup imageDirectoryWithBackup; - - public NoThumbsAdjuster(FSUController controller) { - super(controller); - this.imageDirectoryWithBackup = controller - .getImageDirectoryWithBackup(); - } - - /** - * For every individual with main images but no thumbnails, create a - * thumbnail from the first main image. - */ - public void adjust() { - updateLog.section("Creating thumbnails to match main images."); - - for (Resource resource : ModelWrapper.listResourcesWithProperty(model, - imageProperty)) { - if (resource.getProperty(thumbProperty) == null) { - createThumbnailFromMainImage(resource); - } - } - } - - /** - * This individual has a main image but no thumbnail. Create one. - *
    - *
  • Figure a name for the thumbnail image.
  • - *
  • Make a scaled copy of the main image into the thumbnail.
  • - *
  • Set that file as a thumbnail (old-style) on the individual.
  • - *
- */ - private void createThumbnailFromMainImage(Resource resource) { - String mainFilename = getValues(resource, imageProperty).get(0); - String thumbFilename = addFilenamePrefix("_thumbnail_", mainFilename); - updateLog.log(resource, "creating a thumbnail at '" + thumbFilename - + "' from the main image at '" + mainFilename + "'"); - - File mainFile = imageDirectoryWithBackup.getExistingFile(mainFilename); - File thumbFile = imageDirectoryWithBackup.getNewfile(thumbFilename); - thumbFile = checkNameConflicts(thumbFile); - - try { - CropRectangle crop = getImageSize(mainFile); - if (imageIsSmallEnoughAlready(crop)) { - copyMainImageToThumbnail(mainFile, thumbFile); - } else { - cropScaleAndStore(crop, mainFile, thumbFile); - } - - ResourceWrapper.addProperty(resource, thumbProperty, thumbFilename); - } catch (IOException e) { - updateLog.error(resource, "failed to create thumbnail file '" - + thumbFilename + "'", e); - } - } - - private CropRectangle getImageSize(File file) throws IOException { - InputStream imageSource = null; - try { - imageSource = new FileInputStream(file); - MemoryCacheSeekableStream stream = new MemoryCacheSeekableStream( - imageSource); - RenderedOp image = JAI.create("stream", stream); - return new CropRectangle(0, 0, image.getHeight(), image.getWidth()); - } finally { - if (imageSource != null) { - try { - imageSource.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - private boolean imageIsSmallEnoughAlready(CropRectangle crop) { - return (crop.height <= THUMBNAIL_HEIGHT) - && (crop.width <= THUMBNAIL_WIDTH); - } - - private void copyMainImageToThumbnail(File mainFile, File thumbFile) - throws IOException { - InputStream imageSource = null; - try { - imageSource = new FileInputStream(mainFile); - storeImage(imageSource, thumbFile); - } finally { - if (imageSource != null) { - try { - imageSource.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - private void cropScaleAndStore(CropRectangle crop, File mainFile, - File thumbFile) throws IOException { - InputStream mainImageStream = null; - InputStream imageSource = null; - try { - mainImageStream = new FileInputStream(mainFile); - ImageUploadThumbnailer iut = new ImageUploadThumbnailer( - THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH); - imageSource = iut.cropAndScale(mainImageStream, crop); - storeImage(imageSource, thumbFile); - } finally { - if (mainImageStream != null) { - try { - mainImageStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - if (imageSource != null) { - try { - imageSource.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - private void storeImage(InputStream source, File file) throws IOException { - OutputStream sink = null; - try { - sink = new FileOutputStream(file); - - byte[] buffer = new byte[8192]; - int howMany; - while (-1 != (howMany = source.read(buffer))) { - sink.write(buffer, 0, howMany); - } - } finally { - if (sink != null) { - try { - sink.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java deleted file mode 100644 index 6b78468e8..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java +++ /dev/null @@ -1,71 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.util.ArrayList; -import java.util.List; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.shared.Lock; - -/** - * All image properties should have literal values. Burn any that don't. - */ -public class NonLiteralPropertyRemover extends FsuScanner { - - public NonLiteralPropertyRemover(FSUController controller) { - super(controller); - } - - /** - * Remove any image properties whose objects are not {@link Literal}s. - */ - public void remove() { - updateLog.section("Checking for image properties whose objects " - + "are not literals."); - - removeNonLiterals(imageProperty, "image file"); - removeNonLiterals(thumbProperty, "thumbnail"); - } - - /** - * Check all resources for bogus values on this property. - */ - private void removeNonLiterals(Property prop, String label) { - for (Resource resource : ModelWrapper.listResourcesWithProperty(model, - prop)) { - removeNonLiterals(resource, prop, label); - } - } - - /** - * Check this resource for bogus values onthis property. - */ - private void removeNonLiterals(Resource resource, Property prop, - String label) { - List bogusValues = new ArrayList(); - for (Statement stmt : ResourceWrapper.listProperties(resource, prop)) { - RDFNode object = stmt.getObject(); - if (!object.isLiteral()) { - bogusValues.add(object); - } - } - - for (RDFNode bogusValue : bogusValues) { - updateLog.warn(resource, "discarding " + label - + " property with non-literal as object: '" + bogusValue - + "'"); - model.enterCriticalSection(Lock.WRITE); - try { - model.createStatement(resource, prop, bogusValue).remove(); - } finally { - model.leaveCriticalSection(); - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java deleted file mode 100644 index 4253d4d18..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java +++ /dev/null @@ -1,63 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage.updater; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.shared.Lock; - -/** - * Utility methods that get the appropriate model locks before manipluating - * resources. - */ -public class ResourceWrapper { - - public static Statement getProperty(Resource resource, Property property) { - resource.getModel().enterCriticalSection(Lock.READ); - try { - return resource.getProperty(property); - } finally { - resource.getModel().leaveCriticalSection(); - } - } - - public static void addProperty(Resource resource, Property property, - String value) { - resource.getModel().enterCriticalSection(Lock.WRITE); - try { - resource.addProperty(property, value); - } finally { - resource.getModel().leaveCriticalSection(); - } - } - - public static void removeAll(Resource resource, Property property) { - resource.getModel().enterCriticalSection(Lock.WRITE); - try { - resource.removeAll(property); - } finally { - resource.getModel().leaveCriticalSection(); - } - } - - public static Collection listProperties(Resource resource, - Property prop) { - List list = new ArrayList(); - StmtIterator stmts = resource.listProperties(prop); - try { - while (stmts.hasNext()) { - list.add(stmts.next()); - } - return list; - } finally { - stmts.close(); - } - } - -}