diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java index 8d8f3bcf9..1b315ec95 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/IndividualImpl.java @@ -5,7 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.beans; import org.json.JSONException; import org.json.JSONObject; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import java.lang.reflect.Method; import java.sql.Timestamp; @@ -49,8 +49,7 @@ public class IndividualImpl extends BaseResourceBean implements Individual, Comp protected String anchor = null; protected String blurb = null; protected String mainImageUri = NOT_INITIALIZED; - protected String imageUrl; - protected String thumbUrl; + protected ImageInfo imageInfo = null; protected int statusId = 0; protected String status = null; protected List linksList = null; @@ -281,8 +280,7 @@ public class IndividualImpl extends BaseResourceBean implements Individual, Comp @Override public void setMainImageUri(String mainImageUri) { this.mainImageUri = mainImageUri; - this.imageUrl = null; - this.thumbUrl = null; + this.imageInfo = null; } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java index 587d1b90e..ad64e1146 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java @@ -41,10 +41,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQuery; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryWrapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; @@ -102,7 +99,7 @@ public class EntityController extends VitroHttpServlet { } // If this is an uploaded file, redirect to its "alias URL". - String aliasUrl = getAliasUrlForBytestreamIndividual(indiv); + String aliasUrl = getAliasUrlForBytestreamIndividual(req, indiv); if (aliasUrl != null) { res.sendRedirect(req.getContextPath() + aliasUrl); return; @@ -491,39 +488,16 @@ public class EntityController extends VitroHttpServlet { * If this entity represents a File Bytestream, get its alias URL so we can * properly serve the file contents. */ - private String getAliasUrlForBytestreamIndividual(Individual entity) + private String getAliasUrlForBytestreamIndividual(HttpServletRequest req, Individual entity) throws IOException { - if (!FileModelHelper.isFileBytestream(entity)) { - log.debug("Entity at '" + entity.getURI() - + "' is not recognized as a FileByteStream."); - return null; - } - - FileStorage fs = (FileStorage) getServletContext().getAttribute( - FileStorageSetup.ATTRIBUTE_NAME); - if (fs == null) { - log.error("Servlet context does not contain file storage at '" - + FileStorageSetup.ATTRIBUTE_NAME + "'"); - return null; - } - - String filename = fs.getFilename(entity.getURI()); - if (filename == null) { - log.error("Entity at '" + entity.getURI() - + "' is recognized as a FileByteStream, " - + "but the file system does not recognize it."); - return null; - } - - String url = FileServingHelper.getBytestreamAliasUrl(entity.getURI(), - filename); - if (url.equals(entity.getURI())) { - log.error("Entity at '" + entity.getURI() - + "' is recognized as a FileByteStream, " - + "but can't be translated to an alias URL."); + FileInfo fileInfo = FileInfo.instanceFromBytestreamUri(new VitroRequest( + req).getWebappDaoFactory(), entity.getURI()); + if (fileInfo == null) { + log.trace("Entity '" + entity.getURI() + "' is not a bytestream."); return null; } + String url = fileInfo.getBytestreamAliasUrl(); log.debug("Alias URL for '" + entity.getURI() + "' is '" + url + "'"); return url; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java index 381ab6fc2..bfa0b78e8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java @@ -25,11 +25,10 @@ import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; import freemarker.template.Configuration; @@ -196,8 +195,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { // Add the values that we got, and merge to the template. body.putAll(values.getBodyMap()); - root.put("body", mergeBodyToTemplate(values.getTemplateName(), body, - config)); + root.put("body", + mergeBodyToTemplate(values.getTemplateName(), body, config)); // Continue to simulate FreeMarkerHttpServlet.doGet() root.put("title", body.get("title")); @@ -276,11 +275,12 @@ public class ImageUploadController extends FreemarkerHttpServlet { * Show the first screen in the upload process: Add or Replace. */ private ResponseValues doIntroScreen(VitroRequest vreq, Individual entity) { - String thumbUrl = getThumbnailUrl(entity); - if (thumbUrl == null) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri( + vreq.getFullWebappDaoFactory(), entity); + if (imageInfo == null) { return showAddImagePage(vreq, entity); } else { - return showReplaceImagePage(vreq, entity, thumbUrl); + return showReplaceImagePage(vreq, entity, imageInfo); } } @@ -289,8 +289,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { * image (and thumbnail), and attach the new main image. */ private ResponseValues doUploadImage(VitroRequest vreq, Individual entity) { - ImageUploadHelper helper = new ImageUploadHelper(fileStorage, vreq - .getFullWebappDaoFactory()); + ImageUploadHelper helper = new ImageUploadHelper(fileStorage, + vreq.getFullWebappDaoFactory()); try { // Did they provide a file to upload? If not, show an error. @@ -303,8 +303,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { Dimensions size = helper.getNewImageSize(fileInfo); // Go to the cropping page. - return showCropImagePage(vreq, entity, fileInfo - .getBytestreamAliasUrl(), size); + return showCropImagePage(vreq, entity, + fileInfo.getBytestreamAliasUrl(), size); } catch (UserMistakeException e) { return showErrorMessage(vreq, entity, e.getMessage()); } @@ -316,11 +316,12 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private ResponseValues showErrorMessage(VitroRequest vreq, Individual entity, String message) { - String thumbUrl = getThumbnailUrl(entity); - if (thumbUrl == null) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri( + vreq.getFullWebappDaoFactory(), entity); + if (imageInfo == null) { return showAddImagePageWithError(vreq, entity, message); } else { - return showReplaceImagePageWithError(vreq, entity, thumbUrl, + return showReplaceImagePageWithError(vreq, entity, imageInfo, message); } } @@ -331,8 +332,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private ResponseValues doCreateThumbnail(VitroRequest vreq, Individual entity) { - ImageUploadHelper helper = new ImageUploadHelper(fileStorage, vreq - .getFullWebappDaoFactory()); + ImageUploadHelper helper = new ImageUploadHelper(fileStorage, + vreq.getFullWebappDaoFactory()); try { CropRectangle crop = validateCropCoordinates(vreq); @@ -353,8 +354,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { * page. */ private ResponseValues doDeleteImage(VitroRequest vreq, Individual entity) { - ImageUploadHelper helper = new ImageUploadHelper(fileStorage, vreq - .getFullWebappDaoFactory()); + ImageUploadHelper helper = new ImageUploadHelper(fileStorage, + vreq.getFullWebappDaoFactory()); helper.removeExistingImage(entity); @@ -366,8 +367,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { * screen. */ private ResponseValues doDeleteThenEdit(VitroRequest vreq, Individual entity) { - ImageUploadHelper helper = new ImageUploadHelper(fileStorage, vreq - .getFullWebappDaoFactory()); + ImageUploadHelper helper = new ImageUploadHelper(fileStorage, + vreq.getFullWebappDaoFactory()); helper.removeExistingImage(entity); @@ -425,15 +426,6 @@ public class ImageUploadController extends FreemarkerHttpServlet { } } - /** - * Get the URL that will serve this entity's thumbnail image, or null. - */ - private String getThumbnailUrl(Individual entity) { - String thumbUri = FileModelHelper.getThumbnailBytestreamUri(entity); - String thumbFilename = FileModelHelper.getThumbnailFilename(entity); - return FileServingHelper.getBytestreamAliasUrl(thumbUri, thumbFilename); - } - /** * The individual has no image - go to the Add Image page. * @@ -444,8 +436,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { Individual entity) { String formAction = (entity == null) ? "" : formAction(entity.getURI(), ACTION_UPLOAD); - String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq, entity - .getURI()); + String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq, + entity.getURI()); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW); rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(DUMMY_THUMBNAIL_URL)); @@ -467,10 +459,11 @@ public class ImageUploadController extends FreemarkerHttpServlet { * The individual has an image - go to the Replace Image page. */ private TemplateResponseValues showReplaceImagePage(VitroRequest vreq, - Individual entity, String thumbUrl) { + Individual entity, ImageInfo imageInfo) { TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE); - rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(thumbUrl)); - rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT)); + rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail() + .getBytestreamAliasUrl())); + rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); rv.put(BODY_TITLE, "Replace image" + forName(entity)); @@ -481,9 +474,10 @@ public class ImageUploadController extends FreemarkerHttpServlet { * The individual has an image, but the user did something wrong. */ private TemplateResponseValues showReplaceImagePageWithError( - VitroRequest vreq, Individual entity, String thumbUrl, + VitroRequest vreq, Individual entity, ImageInfo imageInfo, String message) { - TemplateResponseValues rv = showReplaceImagePage(vreq, entity, thumbUrl); + TemplateResponseValues rv = showReplaceImagePage(vreq, entity, + imageInfo); rv.put(BODY_ERROR_MESSAGE, message); return rv; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java index 2e2ee5664..de632bb64 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java @@ -40,8 +40,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadControl import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.Dimensions; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.UserMistakeException; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.TempFileHolder; +import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; @@ -87,14 +87,13 @@ public class ImageUploadHelper { new NonNoisyImagingListener()); } - private final WebappDaoFactory webAppDaoFactory; - private final FileModelHelper fileModelHelper; private final FileStorage fileStorage; + private final UploadedFileHelper uploadedFileHelper; ImageUploadHelper(FileStorage fileStorage, WebappDaoFactory webAppDaoFactory) { - this.webAppDaoFactory = webAppDaoFactory; - this.fileModelHelper = new FileModelHelper(webAppDaoFactory); this.fileStorage = fileStorage; + this.uploadedFileHelper = new UploadedFileHelper(fileStorage, + webAppDaoFactory); } /** @@ -162,10 +161,8 @@ public class ImageUploadHelper { inputStream = fileItem.getInputStream(); String mimeType = getMimeType(fileItem); String filename = getSimpleFilename(fileItem); - WebappDaoFactory wadf = vreq.getWebappDaoFactory(); - - FileInfo fileInfo = FileModelHelper.createFile(fileStorage, wadf, - filename, mimeType, inputStream); + FileInfo fileInfo = uploadedFileHelper.createFile(filename, + mimeType, inputStream); TempFileHolder.attach(vreq.getSession(), ATTRIBUTE_TEMP_FILE, fileInfo); @@ -274,9 +271,9 @@ public class ImageUploadHelper { String mimeType = RECOGNIZED_FILE_TYPES.get(".jpg"); String filename = createThumbnailFilename(mainFilename); + FileInfo fileInfo = uploadedFileHelper.createFile(filename, + mimeType, thumbStream); - FileInfo fileInfo = FileModelHelper.createFile(fileStorage, - webAppDaoFactory, filename, mimeType, thumbStream); log.debug("Created thumbnail: " + fileInfo); return fileInfo; } catch (FileAlreadyExistsException e) { @@ -304,64 +301,11 @@ public class ImageUploadHelper { } /** - * If this entity already had a main image, remove the connection. If the - * image and the thumbnail are no longer used by anyone, remove them from - * the model, and from the file system. + * If this entity already had a main image, remove it. If the image and the + * thumbnail are no longer used by anyone, throw them away. */ void removeExistingImage(Individual person) { - Individual mainImage = fileModelHelper.removeMainImage(person); - if (mainImage == null) { - return; - } - - removeExistingThumbnail(person); - - if (!fileModelHelper.isFileReferenced(mainImage)) { - Individual bytes = FileModelHelper.getBytestreamForFile(mainImage); - if (bytes != null) { - try { - fileStorage.deleteFile(bytes.getURI()); - } catch (IOException e) { - throw new IllegalStateException( - "Can't delete the main image file: '" - + bytes.getURI() + "' for '" - + person.getName() + "' (" - + person.getURI() + ")", e); - } - } - fileModelHelper.removeFileFromModel(mainImage); - } - } - - /** - * If the entity already has a thumbnail, remove it. If there are no other - * references to the thumbnail, delete it from the model and from the file - * system. - */ - void removeExistingThumbnail(Individual person) { - Individual mainImage = FileModelHelper.getMainImage(person); - Individual thumbnail = FileModelHelper.getThumbnailForImage(mainImage); - if (thumbnail == null) { - return; - } - - fileModelHelper.removeThumbnail(person); - - if (!fileModelHelper.isFileReferenced(thumbnail)) { - Individual bytes = FileModelHelper.getBytestreamForFile(thumbnail); - if (bytes != null) { - try { - fileStorage.deleteFile(bytes.getURI()); - } catch (IOException e) { - throw new IllegalStateException( - "Can't delete the thumbnail file: '" - + bytes.getURI() + "' for '" - + person.getName() + "' (" - + person.getURI() + ")", e); - } - } - fileModelHelper.removeFileFromModel(thumbnail); - } + uploadedFileHelper.removeMainImage(person); } /** @@ -369,7 +313,7 @@ public class ImageUploadHelper { */ void storeImageFiles(Individual entity, FileInfo newImage, FileInfo thumbnail) { - FileModelHelper.setImagesOnEntity(webAppDaoFactory, entity, newImage, + uploadedFileHelper.setImagesOnEntity(entity.getURI(), newImage, thumbnail); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index fefd9da56..b5a7a4569 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -43,10 +43,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQuery; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryWrapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; @@ -114,7 +111,7 @@ public class IndividualController extends FreemarkerHttpServlet { } // If this is an uploaded file, redirect to its "alias URL". - String aliasUrl = getAliasUrlForBytestreamIndividual(indiv); + String aliasUrl = getAliasUrlForBytestreamIndividual(req, indiv); if (aliasUrl != null) { res.sendRedirect(req.getContextPath() + aliasUrl); return; @@ -499,43 +496,20 @@ public class IndividualController extends FreemarkerHttpServlet { return false; } - /** + /** * If this entity represents a File Bytestream, get its alias URL so we can * properly serve the file contents. */ - private String getAliasUrlForBytestreamIndividual(Individual entity) + private String getAliasUrlForBytestreamIndividual(HttpServletRequest req, Individual entity) throws IOException { - if (!FileModelHelper.isFileBytestream(entity)) { - log.debug("Entity at '" + entity.getURI() - + "' is not recognized as a FileByteStream."); - return null; - } - - FileStorage fs = (FileStorage) getServletContext().getAttribute( - FileStorageSetup.ATTRIBUTE_NAME); - if (fs == null) { - log.error("Servlet context does not contain file storage at '" - + FileStorageSetup.ATTRIBUTE_NAME + "'"); - return null; - } - - String filename = fs.getFilename(entity.getURI()); - if (filename == null) { - log.error("Entity at '" + entity.getURI() - + "' is recognized as a FileByteStream, " - + "but the file system does not recognize it."); - return null; - } - - String url = FileServingHelper.getBytestreamAliasUrl(entity.getURI(), - filename); - if (url.equals(entity.getURI())) { - log.error("Entity at '" + entity.getURI() - + "' is recognized as a FileByteStream, " - + "but can't be translated to an alias URL."); + FileInfo fileInfo = FileInfo.instanceFromBytestreamUri(new VitroRequest( + req).getWebappDaoFactory(), entity.getURI()); + if (fileInfo == null) { + log.trace("Entity '" + entity.getURI() + "' is not a bytestream."); return null; } + String url = fileInfo.getBytestreamAliasUrl(); log.debug("Alias URL for '" + entity.getURI() + "' is '" + url + "'"); return url; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java index 30cd92263..2d9eaa91f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java @@ -41,8 +41,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.utils.FlagMathUtils; public class IndividualJena extends IndividualImpl implements Individual { @@ -496,38 +495,33 @@ public class IndividualJena extends IndividualImpl implements Individual { @Override public String getImageUrl() { - if (this.imageUrl != null) { - log.debug("imageUrl was cached for " + getURI() + ": '" - + this.imageUrl + "'"); - return imageUrl; - } else { - String imageUri = FileModelHelper.getMainImageBytestreamUri(this); - String filename = FileModelHelper.getMainImageFilename(this); - imageUrl = FileServingHelper.getBytestreamAliasUrl(imageUri, - filename); - log.debug("figured imageUrl for " + getURI() + ": '" - + this.imageUrl + "'"); - return imageUrl; + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.instanceFromEntityUri(webappDaoFactory, this); + log.trace("figured imageInfo for " + getURI() + ": '" + + this.imageInfo + "'"); } + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; + log.trace("imageInfo for " + getURI() + " is empty."); + } + return this.imageInfo.getMainImage().getBytestreamAliasUrl(); } @Override public String getThumbUrl() { - if (this.thumbUrl != null) { - log.debug("thumbUrl was cached for " + getURI() + ": '" - + this.thumbUrl + "'"); - return thumbUrl; - } else { - String imageUri = FileModelHelper.getThumbnailBytestreamUri(this); - String filename = FileModelHelper.getThumbnailFilename(this); - thumbUrl = FileServingHelper.getBytestreamAliasUrl(imageUri, filename); - log.debug("figured thumbUrl for " + getURI() + ": '" - + this.thumbUrl + "'"); - return thumbUrl; + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.instanceFromEntityUri(webappDaoFactory, this); + log.trace("figured imageInfo for " + getURI() + ": '" + + this.imageInfo + "'"); } + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; + log.trace("imageInfo for " + getURI() + " is empty."); + } + return this.imageInfo.getThumbnail().getBytestreamAliasUrl(); } - public String getAnchor() { + public String getAnchor() { if (this.anchor != null) { return anchor; } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/FileModelHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/FileModelHelper.java deleted file mode 100644 index ce3d427e0..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/FileModelHelper.java +++ /dev/null @@ -1,500 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filestorage; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; -import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.InsertException; -import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException; -import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; -import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; - -/** - *

- * A collection of methods to help manipulate the model, with regard to uploaded - * files. - *

- *

- * Some of the public methods are static, since the Individual that is passed as - * a parameter holds all necessary references for the operation. Other methods - * require an instance, which is initialized with a {@link WebappDaoFactory}. - *

- *

- * TODO: This should be based around FileInfo and ImageInfo, as much as - * possible. - *

- */ -public class FileModelHelper { - private static final Log log = LogFactory.getLog(FileModelHelper.class); - - // ---------------------------------------------------------------------- - // Methods based around FileInfo - // ---------------------------------------------------------------------- - - public static FileInfo createFile(FileStorage fileStorage, - WebappDaoFactory wadf, String filename, String mimeType, - InputStream inputStream) throws FileAlreadyExistsException, - IOException { - FileModelHelper fmh = new FileModelHelper(wadf); - - // Create the file individuals in the model - Individual byteStream = fmh.createByteStreamIndividual(); - String bytestreamUri = byteStream.getURI(); - Individual file = fmh.createFileIndividual(mimeType, filename, - byteStream); - String fileUri = file.getURI(); - - // Store the file in the FileStorage system. - fileStorage.createFile(bytestreamUri, filename, inputStream); - - // Figure out the alias URL - String aliasUrl = FileServingHelper.getBytestreamAliasUrl( - bytestreamUri, filename); - - // And wrap it all up in a tidy little package. - return new FileInfo.Builder().setFilename(filename).setMimeType( - mimeType).setUri(fileUri).setBytestreamUri(bytestreamUri) - .setBytestreamAliasUrl(aliasUrl).build(); - } - - /** - * Record this image file and thumbnail on this entity. NOTE: after this - * update, the entity object is stale. - */ - public static void setImagesOnEntity(WebappDaoFactory wadf, - Individual entity, FileInfo mainInfo, FileInfo thumbInfo) { - IndividualDao individualDao = wadf.getIndividualDao(); - - // Add the thumbnail file to the main image file. - ObjectPropertyStatementDao opsd = wadf.getObjectPropertyStatementDao(); - opsd.insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl( - mainInfo.getUri(), VitroVocabulary.FS_THUMBNAIL_IMAGE, - thumbInfo.getUri())); - - // Add the main image file to the entity. - entity.setMainImageUri(mainInfo.getUri()); - individualDao.updateIndividual(entity); - - log.debug("Set images on '" + entity.getURI() + "': main=" + mainInfo - + ", thumb=" + thumbInfo); - } - - // ---------------------------------------------------------------------- - // Static methods -- the Individual holds all necessary references. - // ---------------------------------------------------------------------- - - /** - * Is this a FileByteStream individual? - */ - public static boolean isFileBytestream(Individual entity) { - for (VClass vClass : entity.getVClasses()) { - if (VitroVocabulary.FS_BYTESTREAM_CLASS.equals(vClass.getURI())) { - log.debug("Entity '" + entity.getURI() + "' is a bytestream"); - return true; - } - } - log.debug("Entity '" + entity.getURI() + "' is not a bytestream"); - return false; - } - - /** - * Locate the file surrogate for the main image of this entity. - * - * @return the surrogate, or null if there is no such image, or - * if the entity itself is null. - */ - public static Individual getMainImage(Individual entity) { - if (entity == null) { - return null; - } - - Individual mainFile = entity - .getRelatedIndividual(VitroVocabulary.IND_MAIN_IMAGE); - - if (mainFile == null) { - log.debug("Entity '" + entity.getURI() - + "' had no associated main image: mainImageURI=" - + entity.getMainImageUri()); - return null; - } else { - log.debug("Entity '" + entity.getURI() - + "' had associated main image: '" + mainFile.getURI() - + "'"); - return mainFile; - } - } - - /** - * Locate the file surrogate for the thumbnail of this file. - * - * @return the surrogate, or null if there is no thumbnail, or - * if the file itself is null. - */ - public static Individual getThumbnailForImage(Individual fileSurrogate) { - if (fileSurrogate == null) { - return null; - } - - Individual thumbFile = fileSurrogate - .getRelatedIndividual(VitroVocabulary.FS_THUMBNAIL_IMAGE); - - if (thumbFile == null) { - log.warn("Main image file '" + fileSurrogate.getURI() - + "' had no associated thumbnail."); - return null; - } else { - log.debug("Main image file '" + fileSurrogate.getURI() - + "' had associated thumbnail: '" + thumbFile.getURI() - + "'"); - return thumbFile; - } - } - - /** - * Locate the bytestream object for this file. - * - * @return the bytestream object, or null if there is no - * bytestream, or if the file itself is null. - */ - public static Individual getBytestreamForFile(Individual fileSurrogate) { - if (fileSurrogate == null) { - return null; - } - - Individual byteStream = fileSurrogate - .getRelatedIndividual(VitroVocabulary.FS_DOWNLOAD_LOCATION); - - if (byteStream == null) { - log.error("File surrogate '" + fileSurrogate.getURI() - + "' had no associated bytestream."); - return null; - } else { - log.debug("File surroage'" + fileSurrogate.getURI() - + "' had associated bytestream: '" + byteStream.getURI() - + "'"); - return byteStream; - } - } - - /** - * Find the filename for this file. - * - * @return the filename, or null if the file itself is - * null. - */ - public static String getFilename(Individual fileSurrogate) { - if (fileSurrogate == null) { - return null; - } - - String filename = fileSurrogate - .getDataValue(VitroVocabulary.FS_FILENAME); - - if (filename == null) { - log.error("File had no filename: '" + fileSurrogate.getURI() + "'"); - } else { - log.debug("Filename for '" + fileSurrogate.getURI() + "' was '" - + filename + "'"); - } - return filename; - } - - /** - * Find the MIME type for this file. - * - * @return the MIME type, or null if the file itself is - * null. - */ - public static String getMimeType(Individual fileSurrogate) { - if (fileSurrogate == null) { - return null; - } - - String mimeType = fileSurrogate - .getDataValue(VitroVocabulary.FS_MIME_TYPE); - - if (mimeType == null) { - log.error("File had no mimeType: '" + fileSurrogate.getURI() + "'"); - } else { - log.debug("mimeType for '" + fileSurrogate.getURI() + "' was '" - + mimeType + "'"); - } - return mimeType; - } - - /** - * Return the URI for this individual, or null if the - * individual is null. - */ - private static String getUri(Individual entity) { - if (entity == null) { - return null; - } else { - return entity.getURI(); - } - } - - /** - * Locate the URI of the bytestream of the main image for this entity. - * - * @return the URI, or null if there is no such bytestream, or - * if the entity itself is null. - */ - public static String getMainImageBytestreamUri(Individual entity) { - Individual mainFile = getMainImage(entity); - Individual byteStream = getBytestreamForFile(mainFile); - return getUri(byteStream); - } - - /** - * Find the filename of the main image for this entity. - * - * @return the filename, or null if there is no such image. - */ - public static String getMainImageFilename(Individual entity) { - Individual mainFile = getMainImage(entity); - return getFilename(mainFile); - } - - /** - * Locate the individual that represents the bytestream of the thumbnail of - * the main image for this entity. - * - * @return the URI, or null if there is no such thumbnail - * image, or if the entity itself is null. - */ - public static String getThumbnailBytestreamUri(Individual entity) { - Individual mainFile = getMainImage(entity); - Individual thumbFile = getThumbnailForImage(mainFile); - Individual byteStream = getBytestreamForFile(thumbFile); - return getUri(byteStream); - } - - /** - * Find the filename of the thumbnail of the main image. - * - * @return the filename, or null if there is no such thumbnail - * image, or if the entity itself is null. - */ - public static String getThumbnailFilename(Individual entity) { - Individual mainFile = getMainImage(entity); - Individual thumbFile = getThumbnailForImage(mainFile); - return getFilename(thumbFile); - } - - // ---------------------------------------------------------------------- - // Instance methods -- need access to a WebappDaoFactory - // ---------------------------------------------------------------------- - - private final IndividualDao individualDao; - private final ObjectPropertyStatementDao objectPropertyStatementDao; - private final DataPropertyStatementDao dataPropertyStatementDao; - - public FileModelHelper(WebappDaoFactory webappDaoFactory) { - this.individualDao = webappDaoFactory.getIndividualDao(); - this.objectPropertyStatementDao = webappDaoFactory - .getObjectPropertyStatementDao(); - this.dataPropertyStatementDao = webappDaoFactory - .getDataPropertyStatementDao(); - } - - /** - * Some of these methods require an Individual as an argument. - */ - public Individual getIndividualByUri(String uri) { - return individualDao.getIndividualByURI(uri); - } - - /** - * If this URI represents a ByteStream object, we need to find it's - * surrogate object in order to find the mime type. - * - * @return the mime type, or null if we couldn't find the mime - * type, or if the bytestream object itself is null. - */ - public String getMimeTypeForBytestream(String bytestreamUri) { - if (bytestreamUri == null) { - return null; - } - - ObjectPropertyStatement opStmt = new ObjectPropertyStatementImpl(null, - VitroVocabulary.FS_DOWNLOAD_LOCATION, bytestreamUri); - List stmts = objectPropertyStatementDao - .getObjectPropertyStatements(opStmt); - if (stmts.size() > 1) { - String uris = ""; - for (ObjectPropertyStatement stmt : stmts) { - uris += "'" + stmt.getSubjectURI() + "' "; - } - log.warn("Found " + stmts.size() + " Individuals that claim '" - + bytestreamUri + "' as its bytestream:" + uris); - } - if (stmts.isEmpty()) { - log.warn("No individual claims '" + "' as its bytestream."); - return null; - } - Individual surrogate = individualDao.getIndividualByURI(stmts.get(0) - .getSubjectURI()); - - return getMimeType(surrogate); - } - - /** - * Create a file surrogate individual in the model. - */ - public Individual createFileIndividual(String mimeType, String filename, - Individual byteStream) { - Individual file = new IndividualImpl(); - file.setVClassURI(VitroVocabulary.FS_FILE_CLASS); - - String uri = null; - try { - uri = individualDao.insertNewIndividual(file); - } catch (InsertException e) { - throw new IllegalStateException( - "Failed to create the file individual.", e); - } - - dataPropertyStatementDao - .insertNewDataPropertyStatement(new DataPropertyStatementImpl( - uri, VitroVocabulary.FS_FILENAME, filename)); - dataPropertyStatementDao - .insertNewDataPropertyStatement(new DataPropertyStatementImpl( - uri, VitroVocabulary.FS_MIME_TYPE, mimeType)); - objectPropertyStatementDao - .insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl( - uri, VitroVocabulary.FS_DOWNLOAD_LOCATION, byteStream - .getURI())); - - return individualDao.getIndividualByURI(uri); - } - - /** - * Create a bytestream individual in the model. - */ - public Individual createByteStreamIndividual() { - Individual byteStream = new IndividualImpl(); - byteStream.setVClassURI(VitroVocabulary.FS_BYTESTREAM_CLASS); - - String uri = null; - try { - uri = individualDao.insertNewIndividual(byteStream); - } catch (InsertException e) { - throw new IllegalStateException( - "Failed to create the bytestream individual.", e); - } - - return individualDao.getIndividualByURI(uri); - } - - /** - * Store this file surrogate as the main image on this entity. - */ - public void setAsMainImageOnEntity(Individual person, - Individual imageSurrogate) { - person.setMainImageUri(imageSurrogate.getURI()); - individualDao.updateIndividual(person); - log.debug("Set main image '" + getUri(imageSurrogate) + "' on '" - + person.getURI() + "'"); - } - - /** - * Remove the current main image from this entity. - * - * @return the file surrogate, or null if there was none. - */ - public Individual removeMainImage(Individual person) { - Individual mainImage = getMainImage(person); - person.setMainImageUri(null); - individualDao.updateIndividual(person); - log.debug("Removed main image '" + getUri(mainImage) + "' from '" - + person.getURI() + "'"); - return mainImage; - } - - /** - * Remove the current thumbnail from this entity; - * - * @return the file surrogate, or null if there was none. - */ - public Individual removeThumbnail(Individual person) { - Individual mainImage = getMainImage(person); - Individual thumbnail = getThumbnailForImage(mainImage); - if (thumbnail == null) { - log.debug("No thumbnail to remove from '" + person.getURI() + "'"); - return null; - } - ObjectPropertyStatement stmt = new ObjectPropertyStatementImpl( - mainImage.getURI(), VitroVocabulary.FS_THUMBNAIL_IMAGE, - thumbnail.getURI()); - objectPropertyStatementDao.deleteObjectPropertyStatement(stmt); - return thumbnail; - } - - /** - * Store this file surrogate as the thumbnail on this entity. - */ - public void setThumbnailOnIndividual(Individual entity, - Individual thumbnailSurrogate) { - String mainImageUri = entity.getMainImageUri(); - objectPropertyStatementDao - .insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl( - mainImageUri, VitroVocabulary.FS_THUMBNAIL_IMAGE, - thumbnailSurrogate.getURI())); - } - - /** - * Are there any ObjectPropertyStatements in the model whose object is this - * file surrogate? - */ - public boolean isFileReferenced(Individual surrogate) { - if (surrogate == null) { - return false; - } - ObjectPropertyStatement opStmt = new ObjectPropertyStatementImpl(null, - null, surrogate.getURI()); - List stmts = objectPropertyStatementDao - .getObjectPropertyStatements(opStmt); - if (log.isDebugEnabled()) { - log.debug(stmts.size() + " statements referencing '" - + surrogate.getURI() + "'"); - for (ObjectPropertyStatement stmt : stmts) { - log.debug("'" + stmt.getSubjectURI() + "' -- '" - + stmt.getPropertyURI() + "' -- '" - + stmt.getObjectURI() + "'"); - } - } - return !stmts.isEmpty(); - } - - /** - * This file is being deleted; remove both the surrogate and its bytestream - * from the model. - */ - public void removeFileFromModel(Individual surrogate) { - Individual bytestream = getBytestreamForFile(surrogate); - if (bytestream != null) { - individualDao.deleteIndividual(bytestream); - } - if (surrogate != null) { - individualDao.deleteIndividual(surrogate); - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/UploadedFileHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/UploadedFileHelper.java new file mode 100644 index 000000000..bdd671e04 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/UploadedFileHelper.java @@ -0,0 +1,247 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filestorage; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.InsertException; +import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileAlreadyExistsException; +import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; + +/** + * A helper object to handle the mundane details of dealing with uploaded files + * in the model. + */ +public class UploadedFileHelper { + private static final Log log = LogFactory.getLog(UploadedFileHelper.class); + + private final FileStorage fileStorage; + private final WebappDaoFactory wadf; + private final IndividualDao individualDao; + private final DataPropertyStatementDao dataPropertyStatementDao; + private final ObjectPropertyStatementDao objectPropertyStatementDao; + + public UploadedFileHelper(FileStorage fileStorage, WebappDaoFactory wadf) { + this.fileStorage = fileStorage; + this.wadf = wadf; + this.individualDao = wadf.getIndividualDao(); + this.dataPropertyStatementDao = wadf.getDataPropertyStatementDao(); + this.objectPropertyStatementDao = wadf.getObjectPropertyStatementDao(); + } + + /** + * We have a filename, a mimetype, and some content. Create a file in the + * file storage system and in the model. + * + * @return information about the newly created file. + */ + public FileInfo createFile(String filename, String mimeType, + InputStream inputStream) throws FileAlreadyExistsException, + IOException { + if (filename == null) { + throw new NullPointerException("filename may not be null."); + } + if (mimeType == null) { + throw new NullPointerException("mimeType may not be null."); + } + if (inputStream == null) { + throw new NullPointerException("inputStream may not be null."); + } + + // Create the file individuals in the model + Individual byteStream = createByteStreamIndividual(); + String bytestreamUri = byteStream.getURI(); + Individual file = createFileIndividual(mimeType, filename, byteStream); + String fileUri = file.getURI(); + + // Store the file in the FileStorage system. + fileStorage.createFile(bytestreamUri, filename, inputStream); + + // Figure out the alias URL + String aliasUrl = FileServingHelper.getBytestreamAliasUrl( + bytestreamUri, filename); + + // And wrap it all up in a tidy little package. + return new FileInfo.Builder().setFilename(filename) + .setMimeType(mimeType).setUri(fileUri) + .setBytestreamUri(bytestreamUri) + .setBytestreamAliasUrl(aliasUrl).build(); + } + + /** + * Record this image file and thumbnail on this entity. + */ + public void setImagesOnEntity(String entityUri, FileInfo mainInfo, + FileInfo thumbInfo) { + if (entityUri == null) { + throw new NullPointerException("entityUri may not be null."); + } + if (mainInfo == null) { + throw new NullPointerException("mainInfo may not be null."); + } + if (thumbInfo == null) { + throw new NullPointerException("thumbInfo may not be null."); + } + + Individual entity = individualDao.getIndividualByURI(entityUri); + if (entity == null) { + throw new NullPointerException("No entity found for URI '" + + entityUri + "'."); + } + + // Add the thumbnail file to the main image file. + objectPropertyStatementDao + .insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl( + mainInfo.getUri(), VitroVocabulary.FS_THUMBNAIL_IMAGE, + thumbInfo.getUri())); + + // Add the main image file to the entity. + entity.setMainImageUri(mainInfo.getUri()); + individualDao.updateIndividual(entity); + + log.debug("Set images on '" + entity.getURI() + "': main=" + mainInfo + + ", thumb=" + thumbInfo); + } + + /** + * If this Individual has an image, remove it and the thumbnail. If the + * image file and/or the thumbnail file have no other references, delete + * them. + * + * Note: after this operation, entity is stale. + */ + public void removeMainImage(Individual entity) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri(wadf, entity); + if (imageInfo == null) { + log.debug("No image to remove from '" + entity.getURI() + "'"); + return; + } + + // Remove the main image from the entity. + entity.setMainImageUri(null); + individualDao.updateIndividual(entity); + + // Remove the thumbnail from the main image. + ObjectPropertyStatement stmt = new ObjectPropertyStatementImpl( + imageInfo.getMainImage().getUri(), + VitroVocabulary.FS_THUMBNAIL_IMAGE, imageInfo.getThumbnail() + .getUri()); + objectPropertyStatementDao.deleteObjectPropertyStatement(stmt); + + // If nobody else is using them, get rid of then. + deleteIfNotReferenced(imageInfo.getMainImage()); + deleteIfNotReferenced(imageInfo.getThumbnail()); + } + + /** + * Create a bytestream individual in the model. It's just a naked individual + * with no properties. + */ + private Individual createByteStreamIndividual() { + Individual byteStream = new IndividualImpl(); + byteStream.setVClassURI(VitroVocabulary.FS_BYTESTREAM_CLASS); + + String uri = null; + try { + uri = individualDao.insertNewIndividual(byteStream); + } catch (InsertException e) { + throw new IllegalStateException( + "Failed to create the bytestream individual.", e); + } + + return individualDao.getIndividualByURI(uri); + } + + /** + * Create a file surrogate individual in the model. It has data properties + * for filename and mimeType. It also has a link to its bytestream + * Individual. + */ + private Individual createFileIndividual(String mimeType, String filename, + Individual byteStream) { + Individual file = new IndividualImpl(); + file.setVClassURI(VitroVocabulary.FS_FILE_CLASS); + + String uri = null; + try { + uri = individualDao.insertNewIndividual(file); + } catch (InsertException e) { + throw new IllegalStateException( + "Failed to create the file individual.", e); + } + + dataPropertyStatementDao + .insertNewDataPropertyStatement(new DataPropertyStatementImpl( + uri, VitroVocabulary.FS_FILENAME, filename)); + dataPropertyStatementDao + .insertNewDataPropertyStatement(new DataPropertyStatementImpl( + uri, VitroVocabulary.FS_MIME_TYPE, mimeType)); + objectPropertyStatementDao + .insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl( + uri, VitroVocabulary.FS_DOWNLOAD_LOCATION, byteStream + .getURI())); + + return individualDao.getIndividualByURI(uri); + } + + /** + * If nobody is using this file any more, delete its bytestream from the + * file system, and delete both the surrogate and the bytestream from the + * model. + */ + private void deleteIfNotReferenced(FileInfo file) { + if (!isFileReferenced(file.getUri())) { + try { + fileStorage.deleteFile(file.getBytestreamUri()); + individualDao.deleteIndividual(file.getBytestreamUri()); + individualDao.deleteIndividual(file.getUri()); + } catch (IOException e) { + throw new IllegalStateException("Can't delete the file: '" + + file.getBytestreamUri(), e); + } + } + } + + /** + * Are there any ObjectPropertyStatements in the model whose object is this + * file surrogate? + */ + private boolean isFileReferenced(String surrogateUri) { + if (surrogateUri == null) { + return false; + } + + ObjectPropertyStatement opStmt = new ObjectPropertyStatementImpl(null, + null, surrogateUri); + List stmts = objectPropertyStatementDao + .getObjectPropertyStatements(opStmt); + if (log.isDebugEnabled()) { + log.debug(stmts.size() + " statements referencing '" + surrogateUri + + "'"); + for (ObjectPropertyStatement stmt : stmts) { + log.debug("'" + stmt.getSubjectURI() + "' -- '" + + stmt.getPropertyURI() + "' -- '" + + stmt.getObjectURI() + "'"); + } + } + return !stmts.isEmpty(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/FileInfo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/FileInfo.java index f1e3c0cc8..53cd50c0e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/FileInfo.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/FileInfo.java @@ -2,11 +2,162 @@ package edu.cornell.mannlib.vitro.webapp.filestorage.model; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; + /** * An immutable packet of information about an uploaded file, with a builder * class to permit incremental construction. */ public class FileInfo { + private static final Log log = LogFactory.getLog(FileInfo.class); + + // ---------------------------------------------------------------------- + // static Factory methods. + // ---------------------------------------------------------------------- + + /** + * If this request URL represents a BytestreamAliasURL, find the bytestream + * URI, find the surrogate, and get the info. Otherwise, return null. + */ + public static FileInfo instanceFromAliasUrl( + WebappDaoFactory webappDaoFactory, String path) { + String bytestreamUri = FileServingHelper.getBytestreamUri(path); + if (bytestreamUri == null) { + return null; + } + return instanceFromBytestreamUri(webappDaoFactory, bytestreamUri); + } + + /** + * If this URI represents a file bytestream, find its surrogate and get its + * info. Otherwise, return null. + */ + public static FileInfo instanceFromBytestreamUri( + WebappDaoFactory webappDaoFactory, String bytestreamUri) { + IndividualDao individualDao = webappDaoFactory.getIndividualDao(); + Individual entity = individualDao.getIndividualByURI(bytestreamUri); + if (!isFileBytestream(entity)) { + return null; + } + + ObjectPropertyStatementDao objectPropertyStatementDao = webappDaoFactory + .getObjectPropertyStatementDao(); + ObjectPropertyStatement opStmt = new ObjectPropertyStatementImpl(null, + VitroVocabulary.FS_DOWNLOAD_LOCATION, entity.getURI()); + List stmts = objectPropertyStatementDao + .getObjectPropertyStatements(opStmt); + + if (stmts.size() > 1) { + String uris = ""; + for (ObjectPropertyStatement stmt : stmts) { + uris += "'" + stmt.getSubjectURI() + "' "; + } + log.warn("Found " + stmts.size() + " Individuals that claim '" + + entity.getURI() + "' as its bytestream:" + uris); + } + if (stmts.isEmpty()) { + log.warn("No individual claims '" + entity.getURI() + + "' as its bytestream."); + return null; + } + + String surrogateUri = stmts.get(0).getSubjectURI(); + return instanceFromSurrogateUri(webappDaoFactory, surrogateUri); + } + + /** + * If this URI represents a file surrogate, get its info. Otherwise, return + * null. + */ + public static FileInfo instanceFromSurrogateUri( + WebappDaoFactory webappDaoFactory, String uri) { + IndividualDao individualDao = webappDaoFactory.getIndividualDao(); + Individual surrogate = individualDao.getIndividualByURI(uri); + if (!isFileSurrogate(surrogate)) { + return null; + } + + String filename = surrogate.getDataValue(VitroVocabulary.FS_FILENAME); + if (filename == null) { + log.error("File had no filename: '" + uri + "'"); + } else { + log.debug("Filename for '" + uri + "' was '" + filename + "'"); + } + + String mimeType = surrogate.getDataValue(VitroVocabulary.FS_MIME_TYPE); + if (mimeType == null) { + log.error("File had no mimeType: '" + uri + "'"); + } else { + log.debug("mimeType for '" + uri + "' was '" + mimeType + "'"); + } + + String bytestreamUri; + Individual byteStream = surrogate + .getRelatedIndividual(VitroVocabulary.FS_DOWNLOAD_LOCATION); + if (byteStream == null) { + bytestreamUri = null; + log.error("File surrogate '" + uri + + "' had no associated bytestream."); + } else { + bytestreamUri = byteStream.getURI(); + log.debug("File surroage'" + uri + "' had associated bytestream: '" + + byteStream.getURI() + "'"); + } + + String bytestreamAliasUrl = FileServingHelper.getBytestreamAliasUrl( + bytestreamUri, filename); + + return new FileInfo.Builder().setUri(uri).setFilename(filename) + .setMimeType(mimeType).setBytestreamUri(bytestreamUri) + .setBytestreamAliasUrl(bytestreamAliasUrl).build(); + } + + /** + * Is this a FileByteStream individual? + */ + private static boolean isFileBytestream(Individual entity) { + if (entity == null) { + return false; + } + if (entity.isVClass(VitroVocabulary.FS_BYTESTREAM_CLASS)) { + log.debug("Entity '" + entity.getURI() + "' is a bytestream"); + return true; + } + log.debug("Entity '" + entity.getURI() + "' is not a bytestream"); + return false; + } + + /** + * Is this a File individual? + */ + private static boolean isFileSurrogate(Individual entity) { + if (entity == null) { + return false; + } + if (entity.isVClass(VitroVocabulary.FS_FILE_CLASS)) { + log.debug("Entity '" + entity.getURI() + "' is a file surrogate"); + return true; + } + log.debug("Entity '" + entity.getURI() + "' is not a file surrogate"); + return false; + } + + // ---------------------------------------------------------------------- + // The instance variables and methods. + // ---------------------------------------------------------------------- + private final String uri; private final String filename; private final String mimeType; @@ -48,6 +199,10 @@ public class FileInfo { + bytestreamAliasUrl + "]"; } + // ---------------------------------------------------------------------- + // The builder. + // ---------------------------------------------------------------------- + /** * A builder class allows us to supply the values one at a time, and then * freeze them into an immutable object. @@ -88,4 +243,5 @@ public class FileInfo { return new FileInfo(this); } } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/ImageInfo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/ImageInfo.java new file mode 100644 index 000000000..beca0c9c1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/model/ImageInfo.java @@ -0,0 +1,127 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filestorage.model; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; + +/** + * An immutable packet of information about an iamge file and its thumbnail. + */ +public class ImageInfo { + private static final Log log = LogFactory.getLog(ImageInfo.class); + + public static final ImageInfo EMPTY_IMAGE_INFO = emptyInstance(); + + // ---------------------------------------------------------------------- + // static Factory methods. + // ---------------------------------------------------------------------- + + /** + * This is a place holder for an Individual with no image. + */ + private static ImageInfo emptyInstance() { + FileInfo emptyFileInfo = new FileInfo.Builder().build(); + return new ImageInfo(emptyFileInfo, emptyFileInfo); + } + + /** + * If this Individual has a main image and a thumbnail, return their info. + * Otherwise, return null. + */ + public static ImageInfo instanceFromEntityUri( + WebappDaoFactory webappDaoFactory, Individual entity) { + if (webappDaoFactory == null) { + throw new NullPointerException("webappDaoFactory may not be null."); + } + + if (entity == null) { + return null; + } + + IndividualDao individualDao = webappDaoFactory.getIndividualDao(); + + String mainImageUri = entity.getMainImageUri(); + if (mainImageUri == null) { + log.debug("Entity '" + entity.getURI() + + "' had no associated main image."); + return null; + } else { + log.debug("Entity '" + entity.getURI() + + "' had associated main image: '" + mainImageUri + "'"); + } + + Individual mainFile = individualDao.getIndividualByURI(mainImageUri); + if (mainFile == null) { + log.error("Entity '" + entity.getURI() + + "' has a main image URI that does not refer to an " + + "individual: mainImageURI=" + mainImageUri); + return null; + } + + Individual thumbFile = mainFile + .getRelatedIndividual(VitroVocabulary.FS_THUMBNAIL_IMAGE); + if (thumbFile == null) { + log.warn("Main image file '" + mainImageUri + + "' had no associated thumbnail."); + return null; + } else { + log.debug("Main image file '" + mainImageUri + + "' had associated thumbnail: '" + thumbFile.getURI() + + "'"); + } + + FileInfo mainInfo = FileInfo.instanceFromSurrogateUri(webappDaoFactory, + mainFile.getURI()); + if (mainInfo == null) { + log.error("Entity '" + entity.getURI() + + "' has a mainImage that is not a File " + + "surrogate: mainImageURI=" + mainImageUri); + return null; + } + + FileInfo thumbInfo = FileInfo.instanceFromSurrogateUri( + webappDaoFactory, thumbFile.getURI()); + if (thumbInfo == null) { + log.error("Entity '" + entity.getURI() + + "' has a mainImage with a thumbnail that is not a File " + + "surrogate: mainImageURI=" + mainImageUri + + ", thumbnailURI=" + thumbFile.getURI()); + return null; + } + + return new ImageInfo(mainInfo, thumbInfo); + } + + // ---------------------------------------------------------------------- + // instance fields and methods. + // ---------------------------------------------------------------------- + + private final FileInfo mainImage; + private final FileInfo thumbnail; + + public ImageInfo(FileInfo mainImage, FileInfo thumbnail) { + if (mainImage == null) { + throw new NullPointerException("mainImage may not be null."); + } + if (thumbnail == null) { + throw new NullPointerException("thumbnail may not be null."); + } + this.mainImage = mainImage; + this.thumbnail = thumbnail; + } + + public FileInfo getMainImage() { + return mainImage; + } + + public FileInfo getThumbnail() { + return thumbnail; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java index abe0d8217..eca034c65 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java @@ -23,10 +23,9 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; /** *

@@ -79,9 +78,10 @@ public class FileServingServlet extends VitroHttpServlet { String path = request.getServletPath() + request.getPathInfo(); log.debug("Path is '" + path + "'"); - String uri = FileServingHelper.getBytestreamUri(path); - log.debug("Bytestream URI is '" + uri + "'"); - if (uri == null) { + FileInfo fileInfo = FileInfo.instanceFromAliasUrl(request + .getFullWebappDaoFactory(), path); + log.debug("File info is '" + fileInfo + "'"); + if (fileInfo == null) { String message = "The request path is not valid for the File servlet: '" + path + "'"; log.error(message); @@ -91,12 +91,7 @@ public class FileServingServlet extends VitroHttpServlet { // Validate that the file exists, with the requested URI and filename. String requestedFilename = getFilename(path); - String actualFilename = fileStorage.getFilename(uri); - if (actualFilename == null) { - log.debug("Requested a non-existent file: " + path); - response.sendError(SC_NOT_FOUND, ("File not found: " + path)); - return; - } + String actualFilename = fileInfo.getFilename(); if (!actualFilename.equals(requestedFilename) && !actualFilename.equals(decode(requestedFilename))) { log.warn("The requested filename does not match the " @@ -107,13 +102,12 @@ public class FileServingServlet extends VitroHttpServlet { } // Get the MIME type. - String mimeType = new FileModelHelper(request.getFullWebappDaoFactory()) - .getMimeTypeForBytestream(uri); + String mimeType = fileInfo.getMimeType(); // Open the actual byte stream. InputStream in; try { - in = fileStorage.getInputStream(uri, actualFilename); + in = fileStorage.getInputStream(fileInfo.getBytestreamUri(), actualFilename); } catch (FileNotFoundException e) { log.error(e, e); response.sendError(SC_INTERNAL_SERVER_ERROR, e.toString()); 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 index fd2b35a10..bc45ad247 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java @@ -6,7 +6,7 @@ import java.io.File; import com.hp.hpl.jena.rdf.model.Model; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; /** @@ -23,12 +23,12 @@ public interface FSUController { /** 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(); - /** A file model helper with access to the DAO layer. */ - FileModelHelper getFileModelHelper(); - /** Where to store the files that were translated. */ File getTranslatedDirectory(); 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 index faf53f367..b7262e6a8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java @@ -13,7 +13,7 @@ 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.FileModelHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper; import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; /** @@ -104,7 +104,7 @@ public class FileStorageUpdater implements FSUController { private final Model model; private final FileStorage fileStorage; - private final FileModelHelper fileModelHelper; + private final UploadedFileHelper uploadedFileHelper; private final ImageDirectoryWithBackup imageDirectoryWithBackup; private final File upgradeDirectory; @@ -115,7 +115,7 @@ public class FileStorageUpdater implements FSUController { File webappImageDirectory) { this.model = model; this.fileStorage = fileStorage; - this.fileModelHelper = new FileModelHelper(wadf); + this.uploadedFileHelper = new UploadedFileHelper(fileStorage, wadf); this.upgradeDirectory = new File(uploadDirectory, "upgrade"); this.imageDirectoryWithBackup = new ImageDirectoryWithBackup(new File( @@ -201,7 +201,7 @@ public class FileStorageUpdater implements FSUController { model.createProperty(IMAGETHUMB)).isEmpty()) { return true; } - + return false; } @@ -238,8 +238,8 @@ public class FileStorageUpdater implements FSUController { } @Override - public FileModelHelper getFileModelHelper() { - return this.fileModelHelper; + public UploadedFileHelper getUploadedFileHelper() { + return this.uploadedFileHelper; } @Override 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 index 753bba376..39409487b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java @@ -16,9 +16,9 @@ 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.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; +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, @@ -27,15 +27,15 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; */ public class ImageSchemaTranslater extends FsuScanner { private final ImageDirectoryWithBackup imageDirectoryWithBackup; - protected final FileModelHelper fileModelHelper; protected final FileStorage fileStorage; + protected final UploadedFileHelper uploadedFileHelper; public ImageSchemaTranslater(FSUController controller) { super(controller); this.imageDirectoryWithBackup = controller .getImageDirectoryWithBackup(); this.fileStorage = controller.getFileStorage(); - this.fileModelHelper = controller.getFileModelHelper(); + this.uploadedFileHelper = controller.getUploadedFileHelper(); } /** @@ -79,10 +79,6 @@ public class ImageSchemaTranslater extends FsuScanner { return; } - translateMainImage(resource, mainImages.get(0)); - translated.add(mainImages.get(0)); - ResourceWrapper.removeAll(resource, imageProperty); - List thumbnails = getValues(resource, thumbProperty); if (thumbnails.size() != 1) { updateLog.error(resource, "has " + thumbnails.size() @@ -90,63 +86,47 @@ public class ImageSchemaTranslater extends FsuScanner { return; } - translateThumbnail(resource, thumbnails.get(0)); + 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 the main image into the new system - */ - private void translateMainImage(Resource resource, String path) { - Individual file = translateFile(resource, path, "main image"); - Individual person = fileModelHelper.getIndividualByUri(resource - .getURI()); - fileModelHelper.setAsMainImageOnEntity(person, file); - } - - /** - * Translate the thumbnail into the new system. - */ - private void translateThumbnail(Resource resource, String path) { - Individual file = translateFile(resource, path, "thumbnail"); - Individual person = fileModelHelper.getIndividualByUri(resource - .getURI()); - fileModelHelper.setThumbnailOnIndividual(person, file); } /** * Translate an image file into the new system *

    - *
  • Create a new File, FileByteStream.
  • *
  • Attempt to infer MIME type.
  • *
  • Copy into the File system.
  • + *
  • Create the File and Bytestream individuals in the model.
  • *
- * - * @return the new File surrogate. */ - private Individual translateFile(Resource resource, String path, - String label) { + private FileInfo translateFile(Resource resource, String path, String label) { File oldFile = imageDirectoryWithBackup.getExistingFile(path); String filename = getSimpleFilename(path); String mimeType = guessMimeType(resource, filename); - // Create the file individuals in the model - Individual byteStream = fileModelHelper.createByteStreamIndividual(); - Individual file = fileModelHelper.createFileIndividual(mimeType, - filename, byteStream); - - updateLog.log(resource, "translating " + label + " '" + path - + "' into the file storage as '" + file.getURI() + "'"); - InputStream inputStream = null; try { - // Store the file in the FileStorage system. inputStream = new FileInputStream(oldFile); - fileStorage.createFile(byteStream.getURI(), filename, inputStream); + // 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 { @@ -156,8 +136,6 @@ public class ImageSchemaTranslater extends FsuScanner { } } } - - return file; } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/jsptags/PropertyEditLinks.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/jsptags/PropertyEditLinks.java index 35709659d..0f8df88ea 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/jsptags/PropertyEditLinks.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/jsptags/PropertyEditLinks.java @@ -43,9 +43,10 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.RdfLiteralHash; -import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; @@ -470,19 +471,22 @@ public class PropertyEditLinks extends TagSupport{ protected LinkStruct[] doImageLinks(Individual entity, IdentifierBundle ids, PolicyIface policy, String contextPath) { - Individual mainImage = FileModelHelper.getMainImage(entity); - Individual thumbnail = FileModelHelper.getThumbnailForImage(mainImage); + VitroRequest vreq = new VitroRequest((HttpServletRequest) pageContext + .getRequest()); + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri(vreq + .getFullWebappDaoFactory(), entity); String subjectUri = entity.getURI(); String predicateUri = VitroVocabulary.IND_MAIN_IMAGE; - if (thumbnail == null) { + if (imageInfo == null) { EditLinkAccess[] accesses = policyToAccess(ids, policy, subjectUri, predicateUri); if (contains(accesses, EditLinkAccess.ADDNEW)) { log.debug("permission to ADD main image to " + subjectUri); - boolean isPerson = entity.isVClass("http://xmlns.com/foaf/0.1/Person"); + boolean isPerson = entity + .isVClass("http://xmlns.com/foaf/0.1/Person"); if (isPerson) { return new LinkStruct[] { getImageLink(subjectUri, contextPath, "edit", "upload an image", "add") }; @@ -496,7 +500,7 @@ public class PropertyEditLinks extends TagSupport{ } } else { ObjectPropertyStatement prop = new ObjectPropertyStatementImpl( - subjectUri, predicateUri, mainImage.getURI()); + subjectUri, predicateUri, imageInfo.getMainImage().getUri()); EditLinkAccess[] allowedAccessTypeArray = policyToAccess(ids, policy, prop); @@ -520,8 +524,7 @@ public class PropertyEditLinks extends TagSupport{ } return links.toArray(new LinkStruct[links.size()]); } - } - + } /* ********************* utility methods ********************************* */ protected static String makeRelativeHref( String baseUrl, String ... queries ) {