diff --git a/vspace/pom.xml b/vspace/pom.xml index 2fe6a3f17..6ac373715 100644 --- a/vspace/pom.xml +++ b/vspace/pom.xml @@ -191,7 +191,14 @@ 4.12 test - + + + org.springframework + spring-test + test + + + org.mockito diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/SortByField.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/SortByField.java new file mode 100644 index 000000000..45544073d --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/SortByField.java @@ -0,0 +1,15 @@ +package edu.asu.diging.vspace.core.model; + +public enum SortByField { + CREATION_DATE("creationDate"); + + private final String value; + + private SortByField(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IImageService.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IImageService.java index 71e0d6c90..97255d51e 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IImageService.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IImageService.java @@ -1,12 +1,22 @@ package edu.asu.diging.vspace.core.services; + import edu.asu.diging.vspace.core.model.IVSImage; +import edu.asu.diging.vspace.core.model.impl.VSImage; import edu.asu.diging.vspace.core.services.impl.model.ImageData; +import java.util.List; public interface IImageService { ImageData getImageData(byte[] image); ImageData getImageDimensions(IVSImage image, int width, int height); + + long getTotalPages(); + + List getImages(int pageNo); + + long getTotalImageCount(); + int validatePageNumber(int pageNo); } \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceManager.java index 8c7294eee..cab8fdda8 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceManager.java @@ -2,6 +2,7 @@ import java.util.List; +import edu.asu.diging.vspace.core.exception.SpaceDoesNotExistException; import edu.asu.diging.vspace.core.model.ISpace; import edu.asu.diging.vspace.core.services.impl.CreationReturnValue; @@ -14,5 +15,6 @@ public interface ISpaceManager { ISpace getFullyLoadedSpace(String id); List getAllSpaces(); - + + void deleteSpaceById(String id) throws SpaceDoesNotExistException; } \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ImageService.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ImageService.java index 364c698d6..5e4b2b179 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ImageService.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ImageService.java @@ -3,22 +3,37 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.List; import javax.imageio.ImageIO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import edu.asu.diging.vspace.core.data.ImageRepository; import edu.asu.diging.vspace.core.model.IVSImage; +import edu.asu.diging.vspace.core.model.SortByField; +import edu.asu.diging.vspace.core.model.impl.VSImage; import edu.asu.diging.vspace.core.services.IImageService; import edu.asu.diging.vspace.core.services.impl.model.ImageData; @Service public class ImageService implements IImageService { - + private final Logger logger = LoggerFactory.getLogger(getClass()); + @Autowired + private ImageRepository imageRepo; + + @Value("${page_size}") + private int pageSize; /* * (non-Javadoc) * @@ -62,4 +77,55 @@ public ImageData getImageDimensions(IVSImage image, int width, int height) { Float newHeight = (new Float(width) / new Float(imageWidth)) * new Float(imageHeight); return new ImageData(newHeight.intValue(), width); } + + /** + * Method to return the requested images + * + * @param pageNo. if pageNo<1, 1st page is returned, if pageNo>total pages,last page is returned + * @return list of images in the requested pageNo + */ + @Override + public List getImages(int pageNo) { + pageNo = validatePageNumber(pageNo); + Pageable sortByRequestedField = PageRequest.of(pageNo-1, pageSize, Sort.by(SortByField.CREATION_DATE.getValue())); + Page images = imageRepo.findAll(sortByRequestedField); + return images.getContent(); + } + + /** + * Method to return the total pages sufficient to display all images + * + * @return totalPages required to display all images in DB + */ + @Override + public long getTotalPages() { + return (imageRepo.count() % pageSize == 0) ? imageRepo.count() / pageSize : (imageRepo.count() / pageSize) + 1; + } + + /** + * Method to return the total image count + * + * @return total count of images in DB + */ + @Override + public long getTotalImageCount() { + return imageRepo.count(); + } + + /** + * Method to return page number after validation + * + * @param pageNo page provided by calling method + * @return 1 if pageNo less than 1 and lastPage if pageNo greater than totalPages. + */ + @Override + public int validatePageNumber(int pageNo) { + long totalPages = getTotalPages(); + if(pageNo<1) { + return 1; + } else if(pageNo>totalPages) { + return (totalPages == 0)? 1:(int) totalPages; + } + return pageNo; + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceManager.java index a95bbbae0..6b7e3bca7 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceManager.java @@ -9,12 +9,14 @@ import org.apache.tika.Tika; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.PropertySource; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; import edu.asu.diging.vspace.core.data.ImageRepository; import edu.asu.diging.vspace.core.data.SpaceRepository; import edu.asu.diging.vspace.core.data.display.SpaceDisplayRepository; import edu.asu.diging.vspace.core.exception.FileStorageException; +import edu.asu.diging.vspace.core.exception.SpaceDoesNotExistException; import edu.asu.diging.vspace.core.factory.IImageFactory; import edu.asu.diging.vspace.core.factory.ISpaceDisplayFactory; import edu.asu.diging.vspace.core.file.IStorageEngine; @@ -35,23 +37,22 @@ public class SpaceManager implements ISpaceManager { @Autowired private SpaceRepository spaceRepo; - + @Autowired private SpaceDisplayRepository spaceDisplayRepo; @Autowired private ImageRepository imageRepo; - @Autowired private IStorageEngine storage; - + @Autowired private ISpaceDisplayFactory spaceDisplayFactory; @Autowired private IImageFactory imageFactory; - + @Autowired private IImageService imageService; @@ -59,20 +60,23 @@ public class SpaceManager implements ISpaceManager { * (non-Javadoc) * * @see - * edu.asu.diging.vspace.core.services.impl.ISpaceManager#storeSpace(edu.asu. - * diging.vspace.core.model.ISpace, java.lang.String) + * edu.asu.diging.vspace.core.services.impl.ISpaceManager#storeSpace(edu. + * asu. diging.vspace.core.model.ISpace, java.lang.String) */ @Override public CreationReturnValue storeSpace(ISpace space, byte[] image, String filename) { IVSImage bgImage = null; - List displays = spaceDisplayRepo.getBySpace(space); + List displays = null; + if (space.getId() != null) { + displays = spaceDisplayRepo.getBySpace(space); + } ISpaceDisplay spaceDisplay; if (displays == null || displays.isEmpty()) { spaceDisplay = spaceDisplayFactory.createSpaceDisplay(); } else { spaceDisplay = displays.get(0); } - + if (image != null && image.length > 0) { Tika tika = new Tika(); String contentType = tika.detect(image); @@ -94,15 +98,15 @@ public CreationReturnValue storeSpace(ISpace space, byte[] image, String filenam bgImage.setParentPath(relativePath); ImageData imageData = imageService.getImageData(image); if (imageData != null) { - bgImage.setHeight(imageData.getHeight()); - bgImage.setWidth(imageData.getWidth()); + bgImage.setHeight(imageData.getHeight()); + bgImage.setWidth(imageData.getWidth()); } imageRepo.save((VSImage) bgImage); space.setImage(bgImage); spaceDisplay.setHeight(bgImage.getHeight()); spaceDisplay.setWidth(bgImage.getWidth()); } - + space = spaceRepo.save((Space) space); spaceDisplay.setSpace(space); spaceDisplayRepo.save((SpaceDisplay) spaceDisplay); @@ -138,4 +142,22 @@ public List getAllSpaces() { spaceRepo.findAll().forEach(s -> spaces.add(s)); return spaces; } + + /** + * Method to delete space based on id + * + * @param id + * if id is null throws exception, else delete corresponding + * space + * @throws SpaceDoesNotExistException + */ + @Override + public void deleteSpaceById(String id) throws SpaceDoesNotExistException { + try { + spaceRepo.deleteById(id); + } catch (IllegalArgumentException | EmptyResultDataAccessException exception) { + throw new SpaceDoesNotExistException(exception); + } + + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/HomeController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/HomeController.java index 10c927267..69bff1079 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/HomeController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/HomeController.java @@ -26,4 +26,9 @@ public String home(Model model) { public String login() { return "login"; } + + @RequestMapping(value = "/403") + public String accessDenied() { + return "accessDenied"; + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceController.java new file mode 100644 index 000000000..625947171 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceController.java @@ -0,0 +1,34 @@ +package edu.asu.diging.vspace.web.staff; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import edu.asu.diging.vspace.core.exception.SpaceDoesNotExistException; +import edu.asu.diging.vspace.core.services.ISpaceManager; + +@Controller +public class DeleteSpaceController { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ISpaceManager spaceManager; + + @RequestMapping(value = "/staff/space/{id}", method = RequestMethod.DELETE) + public ResponseEntity deleteSpace(@PathVariable String id) { + try { + spaceManager.deleteSpaceById(id); + } catch (SpaceDoesNotExistException spaceDoesNotExistException) { + logger.error("Could not delete space.", spaceDoesNotExistException); + return new ResponseEntity<>("Invalid input. Please try again", HttpStatus.BAD_REQUEST); + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ListImagesController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ListImagesController.java new file mode 100644 index 000000000..ba18c8cca --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ListImagesController.java @@ -0,0 +1,30 @@ +package edu.asu.diging.vspace.web.staff; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import edu.asu.diging.vspace.core.services.IImageService; + +@Controller +public class ListImagesController { + + @Autowired + private IImageService imageService; + + @RequestMapping("/staff/images/list/{page}") + public String listSpaces(@PathVariable String page, Model model) { + int pageNo; + try { + pageNo = imageService.validatePageNumber(Integer.parseInt(page)); + } catch (NumberFormatException numberFormatException) { + pageNo = 1; + } + model.addAttribute("totalPages", imageService.getTotalPages()); + model.addAttribute("currentPageNumber", pageNo); + model.addAttribute("totalImageCount", imageService.getTotalImageCount()); + model.addAttribute("images", imageService.getImages(pageNo)); + return "staff/images/list"; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/SpaceController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/SpaceController.java index e5050c96e..b937a6221 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/SpaceController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/SpaceController.java @@ -12,21 +12,21 @@ @Controller public class SpaceController { - - @Autowired - private ISpaceManager spaceManager; - - @Autowired - private ILinkManager linkManager; - @RequestMapping("/staff/space/{id}") - public String showSpace(@PathVariable String id, Model model) { - ISpace space = spaceManager.getFullyLoadedSpace(id); - model.addAttribute("space", space); - model.addAttribute("spaceLinks", linkManager.getSpaceLinkDisplays(id)); - model.addAttribute("externalLinks", linkManager.getExternalLinkDisplays(id)); - model.addAttribute("spaces", spaceManager.getAllSpaces()); - - return "staff/space"; - } + @Autowired + private ISpaceManager spaceManager; + + @Autowired + private ILinkManager linkManager; + + @RequestMapping("/staff/space/{id}") + public String showSpace(@PathVariable String id, Model model) { + ISpace space = spaceManager.getFullyLoadedSpace(id); + model.addAttribute("space", space); + model.addAttribute("spaceLinks", linkManager.getSpaceLinkDisplays(id)); + model.addAttribute("externalLinks", linkManager.getExternalLinkDisplays(id)); + model.addAttribute("spaces", spaceManager.getAllSpaces()); + return "staff/space"; + } + } diff --git a/vspace/src/main/resources/config.properties b/vspace/src/main/resources/config.properties index f6e73c573..6aaf72383 100644 --- a/vspace/src/main/resources/config.properties +++ b/vspace/src/main/resources/config.properties @@ -16,3 +16,4 @@ uploads_path=${uploaded.files.path} bg_image_suffix=_background bg_image_max_width=800 bg_image_max_height=1000 +page_size=10 \ No newline at end of file diff --git a/vspace/src/main/webapp/WEB-INF/tiles-defs.xml b/vspace/src/main/webapp/WEB-INF/tiles-defs.xml index 270ce1f1b..92b28e36b 100644 --- a/vspace/src/main/webapp/WEB-INF/tiles-defs.xml +++ b/vspace/src/main/webapp/WEB-INF/tiles-defs.xml @@ -57,7 +57,9 @@ - + + + @@ -121,4 +123,9 @@ + + + + + \ No newline at end of file diff --git a/vspace/src/main/webapp/WEB-INF/tiles/skeleton_bt4.jsp b/vspace/src/main/webapp/WEB-INF/tiles/skeleton_bt4.jsp index 92316c651..c65f39876 100644 --- a/vspace/src/main/webapp/WEB-INF/tiles/skeleton_bt4.jsp +++ b/vspace/src/main/webapp/WEB-INF/tiles/skeleton_bt4.jsp @@ -64,6 +64,14 @@ Modules + + +