diff --git a/vspace/pom.xml b/vspace/pom.xml index ecc30325a..fb84a8f4c 100644 --- a/vspace/pom.xml +++ b/vspace/pom.xml @@ -10,16 +10,15 @@ 1.7.5 - 5.0.19.RELEASE + 5.3.0 Kay-SR8 - 5.3.10.RELEASE + 5.5.7 3.0.13.RELEASE - 5.11.1 + 5.15.0 0.5 admin $2a$04$ug2wdYfAW8Ey/DwjUdPuLufgrMqbhNnTmr1QEUNZnoWF1xGitSBae $2a$04$QhdsxRoZPJw/G06aDkP6COLARKtbdTxVvxtKPZUE0dFlNKFMZsXRe - debug com.mysql.jdbc.Driver @@ -41,6 +40,7 @@ v0.16.1 + http://localhost:8080 @@ -300,14 +300,14 @@ org.hibernate - hibernate-entitymanager - 5.3.2.Final + hibernate-core + 5.4.24.Final mysql mysql-connector-java - 8.0.16 + 8.0.28 @@ -421,4 +421,4 @@ - + \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/config/ConfigConstants.java b/vspace/src/main/java/edu/asu/diging/vspace/config/ConfigConstants.java new file mode 100644 index 000000000..a351f298a --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/config/ConfigConstants.java @@ -0,0 +1,12 @@ +package edu.asu.diging.vspace.config; + +public interface ConfigConstants { + public final static String EXHIBITION_LANGUAGE_LIST_PROPERTY= "exhibition-language-list"; + + public final static String LABEL= "label"; + + public final static String CODE= "code"; + + public final static String LANGUAGES= "languages"; + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/config/ExhibitionLanguageConfig.java b/vspace/src/main/java/edu/asu/diging/vspace/config/ExhibitionLanguageConfig.java new file mode 100644 index 000000000..4b7353750 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/config/ExhibitionLanguageConfig.java @@ -0,0 +1,57 @@ +package edu.asu.diging.vspace.config; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.stereotype.Component; + +import edu.asu.diging.vspace.core.model.impl.ExhibitionLanguage; +import org.springframework.core.env.MutablePropertySources; + + +@Component +@PropertySource(value= "classpath:exhibitionLanguages.properties" , factory=JsonPropertySourceFactory.class) +@Configuration +public class ExhibitionLanguageConfig { + + @Autowired + private Environment environment; + + private List exhibitionLanguageList = new ArrayList(); + + /** + * Fetches the configured language list from environment property source and stores in exhibitionLanguageList + * + */ + @PostConstruct + public void init() { + + org.springframework.core.env.PropertySource propertySource = ((AbstractEnvironment) environment).getPropertySources().get(ConfigConstants.EXHIBITION_LANGUAGE_LIST_PROPERTY); + if( propertySource != null ) { + Map languageMap = (Map) propertySource.getSource(); + exhibitionLanguageList = (List) languageMap.get(ConfigConstants.LANGUAGES); + } + + } + + public List getExhibitionLanguageList() { + return exhibitionLanguageList; + } + public void setExhibitionLanguageList(List exhibitionLanguageList) { + this.exhibitionLanguageList = exhibitionLanguageList; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/config/JsonPropertySourceFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/config/JsonPropertySourceFactory.java new file mode 100644 index 000000000..de43ee62c --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/config/JsonPropertySourceFactory.java @@ -0,0 +1,29 @@ +package edu.asu.diging.vspace.config; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertySourceFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertySourceFactory implements PropertySourceFactory { + + + /** + * Converts language json read from properties file to a map and stores in property source. + * + */ + @Override + public org.springframework.core.env.PropertySource createPropertySource(String name, EncodedResource resource) + throws IOException { + Map readValue = new ObjectMapper() + .readValue(resource.getInputStream(), Map.class); + return new MapPropertySource(ConfigConstants.EXHIBITION_LANGUAGE_LIST_PROPERTY, readValue); + } +} + diff --git a/vspace/src/main/java/edu/asu/diging/vspace/config/SecurityContext.java b/vspace/src/main/java/edu/asu/diging/vspace/config/SecurityContext.java index d04db3b66..494ce166d 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/config/SecurityContext.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/config/SecurityContext.java @@ -51,7 +51,7 @@ protected void configure(HttpSecurity http) throws Exception { .authorizeRequests() // Anyone can access the urls .antMatchers("/", "/exhibit/**", "/api/**", "/resources/**", "/login", - "/logout", "/register", "/reset/**", "/setup/admin", "/404").permitAll() + "/logout", "/register", "/reset/**", "/setup/admin", "/404","/preview/**").permitAll() // The rest of the our application is protected. .antMatchers("/users/**", "/admin/**", "/staff/user/**").hasRole("ADMIN") .antMatchers("/staff/**").hasAnyRole("STAFF", "ADMIN") diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/ExhibitionDataAspect.java b/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/ExhibitionDataAspect.java index 6e729db36..b3a67339c 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/ExhibitionDataAspect.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/ExhibitionDataAspect.java @@ -1,9 +1,12 @@ package edu.asu.diging.vspace.core.aspects; + import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletRequest; + import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; @@ -13,6 +16,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.ui.Model; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import edu.asu.diging.vspace.core.auth.impl.AuthenticationFacade; @@ -25,6 +31,7 @@ import edu.asu.diging.vspace.core.services.IExhibitionManager; import edu.asu.diging.vspace.core.services.IModuleManager; import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.web.exhibit.view.ExhibitionConstants; @Component @Aspect @@ -49,22 +56,23 @@ public void setExhibition(JoinPoint jp) { Class returnType = signature.getReturnType(); // only if there is a model object injected and if we're returning a string // (assuming that returning a string implies rendering of a view afterwards - if(args!=null && returnType==String.class) { - for(Object obj : args) { - if(obj instanceof Model && !(obj instanceof RedirectAttributes)) { - if(!((Model) obj).containsAttribute("exhibition")) { + if (args != null && returnType == String.class) { + for (Object obj : args) { + if (obj instanceof Model && !(obj instanceof RedirectAttributes)) { + if (!((Model) obj).containsAttribute("exhibition")) { ((Model) obj).addAttribute("exhibition", exhibitionManager.getStartExhibition()); } if (!((Model) obj).containsAttribute("publishedSpaces")) { - List publishedSpaces=spaceManager.getSpacesWithStatus(SpaceStatus.PUBLISHED); - /* (non-Javadoc) - * Added to show spaces with null status and accommodate existing spaces with null space status + List publishedSpaces = spaceManager.getSpacesWithStatus(SpaceStatus.PUBLISHED); + /* + * (non-Javadoc) Added to show spaces with null status and accommodate existing + * spaces with null space status */ publishedSpaces.addAll(spaceManager.getSpacesWithStatus(null)); ((Model) obj).addAttribute("publishedSpaces", publishedSpaces); } } - } + } } } @@ -73,13 +81,14 @@ public Object showExhibition(ProceedingJoinPoint jp) throws Throwable { Object[] args = jp.getArgs(); MethodSignature signature = (MethodSignature) jp.getSignature(); int indexOfModel = (Arrays.asList(signature.getParameterTypes())).indexOf(Model.class); - Exhibition exhibition = (Exhibition) exhibitionManager.getStartExhibition(); + Exhibition exhibition = (Exhibition) exhibitionManager.getStartExhibition(); // If there is no exhibition, we go back to root url page. - if(exhibition==null) { + if (exhibition == null) { return "redirect:/"; } - //If no exhibition mode has been setup for existing exhibition, we skip modes and aspects. - if(exhibition.getMode() == null) { + // If no exhibition mode has been setup for existing exhibition, we skip modes + // and aspects. + if (exhibition.getMode() == null) { return jp.proceed(); } Map ids = getIds(args, signature); @@ -89,66 +98,77 @@ public Object showExhibition(ProceedingJoinPoint jp) throws Throwable { } /** - * Based on exhibition mode, get the redirect page or pass control to controller. - * @param jp The joinpoint variable, used to fetch request parameters and proceed with the request. - * @param spaceId Current spaceId that is requested to be viewed by user. - * @param moduleId The moduleId that the user has requested to view. - * @param modelIndex Index of the model information in the reuest parameters. - * @param exhibition Current exhibition that is being shown to user. - * @return returns the page to load upon aspect completion. - * @throws Throwable + * Based on exhibition mode, get the redirect page or pass control to + * controller. + * + * @param jp The joinpoint variable, used to fetch request parameters + * and proceed with the request. + * @param spaceId Current spaceId that is requested to be viewed by user. + * @param moduleId The moduleId that the user has requested to view. + * @param modelIndex Index of the model information in the reuest parameters. + * @param exhibition Current exhibition that is being shown to user. + * @return returns the page to load upon aspect completion. + * @throws Throwable */ - private Object redirectRequest(ProceedingJoinPoint jp, String spaceId, String moduleId, int modelIndex, Exhibition exhibition) throws Throwable{ + private Object redirectRequest(ProceedingJoinPoint jp, String spaceId, String moduleId, int modelIndex, + Exhibition exhibition) throws Throwable { ISpace space = spaceManager.getSpace(spaceId); IModule module = moduleManager.getModule(moduleId); Object[] args = jp.getArgs(); ExhibitionModes exhibitionMode = exhibition.getMode(); // If exhibition is set to offline, set the custom message or default message. - if(exhibitionMode.equals(ExhibitionModes.OFFLINE)) { - String modeValue = exhibition.getCustomMessage().equals("") == false ? exhibition.getCustomMessage() : exhibitionMode.getValue(); + if (exhibitionMode.equals(ExhibitionModes.OFFLINE)) { + String modeValue = exhibition.getCustomMessage().equals("") == false ? exhibition.getCustomMessage() + : exhibitionMode.getValue(); ((Model) args[modelIndex]).addAttribute("modeValue", modeValue); } - if(exhibition.isAboutPageConfigured()) { + if (exhibition.isAboutPageConfigured()) { ((Model) args[modelIndex]).addAttribute("aboutPageConfigured", true); } else { ((Model) args[modelIndex]).addAttribute("aboutPageConfigured", false); } // If exhibition is set to maintenance, set the default message. - if(exhibitionMode.equals(ExhibitionModes.MAINTENANCE)) { + if (exhibitionMode.equals(ExhibitionModes.MAINTENANCE)) { ((Model) args[modelIndex]).addAttribute("modeValue", exhibitionMode.getValue()); } + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()) + .getRequest(); + Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); + String previewId = (String) pathVariables.get(ExhibitionConstants.PREVIEW_ID); // If user is not logged in and exhibition is not active, show maintenance page. - if(authFacade.getAuthenticatedUser()==null && !exhibitionMode.equals(ExhibitionModes.ACTIVE)) { - return "maintenance"; + if (authFacade.getAuthenticatedUser() == null && !exhibitionMode.equals(ExhibitionModes.ACTIVE) && previewId==null) { + return "/exhibition/maintenance"; } // If the space and module Id is not found, show message on screen. - if(space==null && module==null) { + if (space == null && module == null) { return "redirect:/exhibit/404"; } - // If user is logged in and exhibition is not active, show exhibition with pop up message. - if(authFacade.getAuthenticatedUser()!=null && !exhibitionMode.equals(ExhibitionModes.ACTIVE)) { + // If user is logged in and exhibition is not active, show exhibition with pop + // up message. + if (authFacade.getAuthenticatedUser() != null && !exhibitionMode.equals(ExhibitionModes.ACTIVE)) { return jp.proceed(); } return jp.proceed(); } - /** * Method to get the space or module id's from the request body. + * * @param args The request parameters from the original request. - * @param signature Contains the information about the arguments present in args. - * @return A map with spaceId and moduleId from the request args. + * @param signature Contains the information about the arguments present in + * args. + * @return A map with spaceId and moduleId from the request args. */ - private Map getIds(Object[] args, MethodSignature signature) { + private Map getIds(Object[] args, MethodSignature signature) { Map res = new HashMap<>(); - for(int i=0; i 2) { - String prefix = ((String) args[i]).substring(0,3); - if(prefix.equalsIgnoreCase(IdPrefix.SPACEID.getValue())) { + for (int i = 0; i < signature.getParameterTypes().length; ++i) { + if (signature.getParameterTypes()[i].equals(String.class)) { + if (args[i] != null && ((String) args[i]).length() > 2) { + String prefix = ((String) args[i]).substring(0, 3); + if (prefix.equalsIgnoreCase(IdPrefix.SPACEID.getValue())) { res.put(IdPrefix.SPACEID, (String) args[i]); } - if(prefix.equalsIgnoreCase(IdPrefix.MODULEID.getValue())) { + if (prefix.equalsIgnoreCase(IdPrefix.MODULEID.getValue())) { res.put(IdPrefix.MODULEID, (String) args[i]); } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/PreviewDataAspect.java b/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/PreviewDataAspect.java new file mode 100644 index 000000000..30399cddf --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/aspects/PreviewDataAspect.java @@ -0,0 +1,70 @@ +package edu.asu.diging.vspace.core.aspects; + +import java.util.Arrays; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.ui.Model; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.HandlerMapping; + +import edu.asu.diging.vspace.core.model.impl.Exhibition; +import edu.asu.diging.vspace.core.services.IExhibitionManager; +import edu.asu.diging.vspace.web.exhibit.view.ExhibitionConstants; + +/** + * + * This aspect intercepts the controller for the public site. It performs checks and adds information needed + * for the preview site if the preview site is requested. + * @author prachikharge + * + */ +@Component +@Aspect +public class PreviewDataAspect { + + @Autowired + private IExhibitionManager exhibitionManager; + + /** + * This method does the following: + * + * 1. Checks if the requested url is for the preview (if it contains a preview id) + * 2. Checks if the preview id is correct (if not showing a 404) + * 3. Adds the preview id into the model and sets isExhPreview to true + * + * @param jp + * @return + * @throws Throwable + */ + @Around("execution(public * edu.asu.diging.vspace.web.exhibit..*Controller.*(..)) || execution(public * edu.asu.diging.vspace.web.HomeController.*(..))") + public Object checkPreview(ProceedingJoinPoint jp) throws Throwable { + Object[] args = jp.getArgs(); + MethodSignature signature = (MethodSignature) jp.getSignature(); + int indexOfModel = (Arrays.asList(signature.getParameterTypes())).indexOf(Model.class); + Exhibition exhibition = (Exhibition) exhibitionManager.getStartExhibition(); + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()) + .getRequest(); + Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); + String previewId = (String) pathVariables.get(ExhibitionConstants.PREVIEW_ID); + if (exhibition != null && previewId != null && exhibition.getPreviewId() != null) { + if (!exhibition.getPreviewId().equals(previewId)) { + return "redirect:/exhibit/404"; + } + if (indexOfModel >= 0) { + ((Model) args[indexOfModel]).addAttribute("isExhPreview", true); + ((Model) args[indexOfModel]).addAttribute(ExhibitionConstants.PREVIEW_ID, previewId); + } + } + return jp.proceed(); + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/data/SpaceTextBlockRepository.java b/vspace/src/main/java/edu/asu/diging/vspace/core/data/SpaceTextBlockRepository.java new file mode 100644 index 000000000..253b70f14 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/data/SpaceTextBlockRepository.java @@ -0,0 +1,14 @@ +package edu.asu.diging.vspace.core.data; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import edu.asu.diging.vspace.core.model.impl.SpaceTextBlock; + +@Repository +@JaversSpringDataAuditable +public interface SpaceTextBlockRepository extends PagingAndSortingRepository { + +} + diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoContentBlockRepository.java b/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoContentBlockRepository.java new file mode 100644 index 000000000..1c7da6c07 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoContentBlockRepository.java @@ -0,0 +1,13 @@ +package edu.asu.diging.vspace.core.data; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import edu.asu.diging.vspace.core.model.impl.VideoBlock; + +@Repository +@JaversSpringDataAuditable +public interface VideoContentBlockRepository extends PagingAndSortingRepository { + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoRepository.java b/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoRepository.java new file mode 100644 index 000000000..5da09ef66 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/data/VideoRepository.java @@ -0,0 +1,14 @@ +package edu.asu.diging.vspace.core.data; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import edu.asu.diging.vspace.core.model.impl.VSVideo; + +@Repository +@JaversSpringDataAuditable +public interface VideoRepository extends PagingAndSortingRepository { + +} + diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/data/display/SpaceTextBlockDisplayRepository.java b/vspace/src/main/java/edu/asu/diging/vspace/core/data/display/SpaceTextBlockDisplayRepository.java new file mode 100644 index 000000000..516bc2262 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/data/display/SpaceTextBlockDisplayRepository.java @@ -0,0 +1,23 @@ +package edu.asu.diging.vspace.core.data.display; + +import java.util.List; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.model.display.impl.SpaceTextBlockDisplay; + +@Repository +@JaversSpringDataAuditable +public interface SpaceTextBlockDisplayRepository extends PagingAndSortingRepository { + + @Query("SELECT d FROM SpaceTextBlockDisplay d WHERE d.spaceTextBlock.space.id = ?1") + public List findSpaceTextBlockDisplaysForSpace(String spaceId); + + public void deleteBySpaceTextBlock(ISpaceTextBlock spaceTextBlock); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/exception/LanguageListConfigurationNotFoundException.java b/vspace/src/main/java/edu/asu/diging/vspace/core/exception/LanguageListConfigurationNotFoundException.java new file mode 100644 index 000000000..f5ca44086 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/exception/LanguageListConfigurationNotFoundException.java @@ -0,0 +1,27 @@ +package edu.asu.diging.vspace.core.exception; + +public class LanguageListConfigurationNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public LanguageListConfigurationNotFoundException() { + super(); + } + + public LanguageListConfigurationNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public LanguageListConfigurationNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public LanguageListConfigurationNotFoundException(String message) { + super(message); + } + + public LanguageListConfigurationNotFoundException(Throwable cause) { + super(cause); + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/exception/VideoCouldNotBeStoredException.java b/vspace/src/main/java/edu/asu/diging/vspace/core/exception/VideoCouldNotBeStoredException.java new file mode 100644 index 000000000..391a81ea8 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/exception/VideoCouldNotBeStoredException.java @@ -0,0 +1,31 @@ +package edu.asu.diging.vspace.core.exception; + +public class VideoCouldNotBeStoredException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public VideoCouldNotBeStoredException() { + super(); + } + + public VideoCouldNotBeStoredException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public VideoCouldNotBeStoredException(String message, Throwable cause) { + super(message, cause); + } + + public VideoCouldNotBeStoredException(String message) { + super(message); + } + + public VideoCouldNotBeStoredException(Throwable cause) { + super(cause); + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IExhibitionFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IExhibitionFactory.java index c5d9218bc..217807926 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IExhibitionFactory.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IExhibitionFactory.java @@ -1,9 +1,18 @@ package edu.asu.diging.vspace.core.factory; import edu.asu.diging.vspace.core.model.IExhibition; +import edu.asu.diging.vspace.core.model.impl.Exhibition; public interface IExhibitionFactory { IExhibition createExhibition(); + /** + * Updates the exhibition object with preview id + * + * @param exhibitionObj + * @return + */ + void updatePreviewId(Exhibition exhibitionObj); + } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockDisplayFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockDisplayFactory.java new file mode 100644 index 000000000..d528f9a57 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockDisplayFactory.java @@ -0,0 +1,8 @@ +package edu.asu.diging.vspace.core.factory; + +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; + +public interface ISpaceTextBlockDisplayFactory { + ISpaceTextBlockDisplay createSpaceTextBlockDisplay(ISpaceTextBlock textBlock, float positionX, float positionY, float height, float width); +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockFactory.java new file mode 100644 index 000000000..3930b51e0 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/ISpaceTextBlockFactory.java @@ -0,0 +1,8 @@ +package edu.asu.diging.vspace.core.factory; + +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; + +public interface ISpaceTextBlockFactory { + ISpaceTextBlock createSpaceTextBlock(String text, ISpace space); +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoBlockFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoBlockFactory.java new file mode 100644 index 000000000..7f8d80566 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoBlockFactory.java @@ -0,0 +1,10 @@ +package edu.asu.diging.vspace.core.factory; + +import edu.asu.diging.vspace.core.model.ISlide; +import edu.asu.diging.vspace.core.model.IVSVideo; +import edu.asu.diging.vspace.core.model.IVideoBlock; + +public interface IVideoBlockFactory { + + IVideoBlock createVideoBlock(ISlide slide, IVSVideo video); +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoFactory.java new file mode 100644 index 000000000..459477509 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/IVideoFactory.java @@ -0,0 +1,11 @@ +package edu.asu.diging.vspace.core.factory; + +import edu.asu.diging.vspace.core.model.IVSVideo; + +public interface IVideoFactory { + + IVSVideo createVideo(String filename, Long size, String fileType); + + IVSVideo createVideo(String url); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/ExhibitionFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/ExhibitionFactory.java index 7b982ba2d..9194a6ad1 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/ExhibitionFactory.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/ExhibitionFactory.java @@ -1,22 +1,44 @@ package edu.asu.diging.vspace.core.factory.impl; +import java.util.UUID; + import org.springframework.stereotype.Service; import edu.asu.diging.vspace.core.factory.IExhibitionFactory; +import edu.asu.diging.vspace.core.model.ExhibitionModes; import edu.asu.diging.vspace.core.model.IExhibition; import edu.asu.diging.vspace.core.model.impl.Exhibition; @Service public class ExhibitionFactory implements IExhibitionFactory { - /* - * (non-Javadoc) + public static final String EXH_PREVIEW = "EXH_PREVIEW_"; + + /** + * This method create an Exhibition with a previewId and its status has been set + * to active by default. This previewId is generated randomly every time an + * exhibition got created. * - * @see edu.asu.diging.vspace.core.model.impl.Exhibition + * @return an Exhibition object after creation. */ @Override public IExhibition createExhibition() { - return new Exhibition(); + Exhibition exhibitionObj = new Exhibition(); + updatePreviewId(exhibitionObj); + return exhibitionObj; + } + /** + * Updates the exhibition object with preview id + * + * @param exhibitionObj + * @return + */ + @Override + public void updatePreviewId(Exhibition exhibitionObj) { + UUID randomUUID = UUID.randomUUID(); + String randomString = randomUUID.toString().replaceAll("-", ""); + exhibitionObj.setPreviewId(EXH_PREVIEW + randomString.substring(0, 8)); + exhibitionObj.setMode(ExhibitionModes.ACTIVE); } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockDisplayFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockDisplayFactory.java new file mode 100644 index 000000000..75645d398 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockDisplayFactory.java @@ -0,0 +1,29 @@ +package edu.asu.diging.vspace.core.factory.impl; + +import org.springframework.stereotype.Service; + +import edu.asu.diging.vspace.core.factory.ISpaceTextBlockDisplayFactory; +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.model.display.impl.SpaceTextBlockDisplay; + +@Service +public class SpaceTextBlockDisplayFactory implements ISpaceTextBlockDisplayFactory { + + /* + * (non-Javadoc) + * + * @see edu.asu.diging.vspace.core.factory.impl.IModuleLinkDisplayFactory# + * createModuleLinkDisplay(edu.asu.diging.vspace.core.model.IModuleLink) + */ + @Override + public ISpaceTextBlockDisplay createSpaceTextBlockDisplay(ISpaceTextBlock textBlock, float positionX, float positionY, float height, float width) { + ISpaceTextBlockDisplay display = new SpaceTextBlockDisplay(); + display.setSpaceTextBlock(textBlock); + display.setPositionX(positionX); + display.setPositionY(positionY); + display.setHeight(height); + display.setWidth(width); + return display; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockFactory.java new file mode 100644 index 000000000..b12aaeaaf --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/SpaceTextBlockFactory.java @@ -0,0 +1,21 @@ +package edu.asu.diging.vspace.core.factory.impl; + +import org.springframework.stereotype.Service; + +import edu.asu.diging.vspace.core.factory.ISpaceTextBlockFactory; +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.impl.SpaceTextBlock; + +@Service +public class SpaceTextBlockFactory implements ISpaceTextBlockFactory { + + @Override + public ISpaceTextBlock createSpaceTextBlock(String text, ISpace space) { + ISpaceTextBlock textBlock = new SpaceTextBlock(); + textBlock.setText(text); + textBlock.setSpace(space); + return textBlock; + } + +} \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoBlockFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoBlockFactory.java new file mode 100644 index 000000000..a014b1264 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoBlockFactory.java @@ -0,0 +1,30 @@ +package edu.asu.diging.vspace.core.factory.impl; + +import org.springframework.stereotype.Service; + +import edu.asu.diging.vspace.core.factory.IVideoBlockFactory; +import edu.asu.diging.vspace.core.model.ISlide; +import edu.asu.diging.vspace.core.model.IVSVideo; +import edu.asu.diging.vspace.core.model.IVideoBlock; +import edu.asu.diging.vspace.core.model.impl.VideoBlock; + +@Service +public class VideoBlockFactory implements IVideoBlockFactory { + + /* + * (non-Javadoc) + * + * @see + * edu.asu.diging.vspace.core.factory.impl.IVideoBlockFactory#createVideoBlock( + * edu.asu.diging.vspace.core.model.ISlide, + * edu.asu.diging.vspace.core.model.IVSVideo) + */ + @Override + public IVideoBlock createVideoBlock(ISlide slide, IVSVideo video) { + IVideoBlock videoBlock = new VideoBlock(); + videoBlock.setVideo(video); + videoBlock.setSlide(slide); + + return videoBlock; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoFactory.java b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoFactory.java new file mode 100644 index 000000000..decb08861 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/factory/impl/VideoFactory.java @@ -0,0 +1,38 @@ +package edu.asu.diging.vspace.core.factory.impl; + +import org.springframework.stereotype.Service; + +import edu.asu.diging.vspace.core.factory.IVideoFactory; +import edu.asu.diging.vspace.core.model.IVSVideo; +import edu.asu.diging.vspace.core.model.impl.VSVideo; + +/** + * @author skhar + * + */ +@Service +public class VideoFactory implements IVideoFactory { + + /* + * (non-Javadoc) + * + * @see + * edu.asu.diging.vspace.core.factory.impl.IImageFactory#createImage(java.lang. + * String, java.lang.String) + */ + @Override + public IVSVideo createVideo(String filename, Long size, String fileType) { + IVSVideo video = new VSVideo(); + video.setFilename(filename); + video.setFileSize(size); + video.setFileType(fileType); + return video; + } + + public IVSVideo createVideo(String url) { + IVSVideo video = new VSVideo(); + video.setUrl(url); + return video; + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/file/IStorageEngine.java b/vspace/src/main/java/edu/asu/diging/vspace/core/file/IStorageEngine.java index 7167ccf40..8b3c9f4ad 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/file/IStorageEngine.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/file/IStorageEngine.java @@ -7,9 +7,9 @@ public interface IStorageEngine { - String storeFile(byte[] fileContent, String filename, String directory) throws FileStorageException; + String storeFile(byte[] fileContent, String filename, String directory) throws FileStorageException; - byte[] getImageContent(String directory, String filename) throws IOException; + byte[] getMediaContent(String directory, String filename) throws IOException; - boolean renameImage(IVSImage image, String newFileName); + boolean renameImage(IVSImage image, String newFileName); } \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/file/impl/StorageEngine.java b/vspace/src/main/java/edu/asu/diging/vspace/core/file/impl/StorageEngine.java index a37a4f3b3..779d0d863 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/file/impl/StorageEngine.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/file/impl/StorageEngine.java @@ -51,7 +51,7 @@ public String storeFile(byte[] fileContent, String filename, String directory) t } @Override - public byte[] getImageContent(String directory, String filename) throws IOException { + public byte[] getMediaContent(String directory, String filename) throws IOException { File fileObject = new File(path + File.separator + directory + File.separator + filename); URLConnection con = fileObject.toURI().toURL().openConnection(); diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibition.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibition.java index d1ad447da..883cc6b4a 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibition.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibition.java @@ -1,5 +1,10 @@ package edu.asu.diging.vspace.core.model; +import java.util.List; +import java.util.Set; + +import edu.asu.diging.vspace.core.model.impl.ExhibitionLanguage; + public interface IExhibition extends IVSpaceElement { /* @@ -26,4 +31,6 @@ public interface IExhibition extends IVSpaceElement { void setAboutPageConfigured(boolean aboutPageConfigured); + List getLanguages(); + } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibitionLanguage.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibitionLanguage.java new file mode 100644 index 000000000..fd868906e --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IExhibitionLanguage.java @@ -0,0 +1,13 @@ +package edu.asu.diging.vspace.core.model; + +public interface IExhibitionLanguage extends IVSpaceElement { + + String getCode(); + + String getLabel(); + + boolean isDefault(); + + void setDefault(boolean isDefault); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/ISpaceTextBlock.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/ISpaceTextBlock.java new file mode 100644 index 000000000..216c774e3 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/ISpaceTextBlock.java @@ -0,0 +1,12 @@ +package edu.asu.diging.vspace.core.model; + +public interface ISpaceTextBlock extends IVSpaceElement{ + + ISpace getSpace(); + + void setSpace(ISpace space); + + String getText(); + + void setText(String text); +} \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSImage.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSImage.java index 9220a2cd1..51b5e62e4 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSImage.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSImage.java @@ -2,27 +2,7 @@ import java.util.List; -public interface IVSImage extends IVSpaceElement { - - String getFilename(); - - void setFilename(String filename); - - String getParentPath(); - - void setParentPath(String parentPath); - - void setFileType(String fileType); - - String getFileType(); - - void setWidth(int width); - - int getWidth(); - - void setHeight(int height); - - int getHeight(); +public interface IVSImage extends IVSMedia { void setCategories(List categories); diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSMedia.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSMedia.java new file mode 100644 index 000000000..2df5dc818 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSMedia.java @@ -0,0 +1,31 @@ +package edu.asu.diging.vspace.core.model; + +/** + * @author skhar + * + *IVSMedia is a class to hold common settings for Media classes + *IVSVideo and IVSImage classes. + */ +public interface IVSMedia extends IVSpaceElement{ + + String getFilename(); + + void setFilename(String filename); + + String getParentPath(); + + void setParentPath(String parentPath); + + void setFileType(String fileType); + + String getFileType(); + + void setWidth(int width); + + int getWidth(); + + void setHeight(int height); + + int getHeight(); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSVideo.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSVideo.java new file mode 100644 index 000000000..08147421f --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVSVideo.java @@ -0,0 +1,17 @@ +package edu.asu.diging.vspace.core.model; + +public interface IVSVideo extends IVSMedia { + + void setFileSize(Long fileSize); + + Long getFileSize(); + + public String getUrl(); + + public void setUrl(String url); + + public void setTitle(String title); + + public String getTitle(); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVideoBlock.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVideoBlock.java new file mode 100644 index 000000000..31705bbbb --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/IVideoBlock.java @@ -0,0 +1,13 @@ +package edu.asu.diging.vspace.core.model; + +public interface IVideoBlock extends IContentBlock { + + void setVideo(IVSVideo video); + + IVSVideo getVideo(); + + void setId(String id); + + String getId(); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/ISpaceTextBlockDisplay.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/ISpaceTextBlockDisplay.java new file mode 100644 index 000000000..c71d1b5b1 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/ISpaceTextBlockDisplay.java @@ -0,0 +1,31 @@ +package edu.asu.diging.vspace.core.model.display; + +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.IVSpaceElement; + +public interface ISpaceTextBlockDisplay extends IVSpaceElement{ + + String getId(); + + void setId(String id); + + void setSpaceTextBlock(ISpaceTextBlock textBlock); + + ISpaceTextBlock getSpaceTextBlock(); + + float getPositionX(); + + void setPositionX(float positionX); + + float getPositionY(); + + void setPositionY(float positionY); + + float getHeight(); + + void setHeight(float height); + + float getWidth(); + + void setWidth(float width); +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/impl/SpaceTextBlockDisplay.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/impl/SpaceTextBlockDisplay.java new file mode 100644 index 000000000..8f6ef4521 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/display/impl/SpaceTextBlockDisplay.java @@ -0,0 +1,93 @@ +package edu.asu.diging.vspace.core.model.display.impl; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; + +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.model.impl.SpaceTextBlock; +import edu.asu.diging.vspace.core.model.impl.VSpaceElement; + +@Entity +public class SpaceTextBlockDisplay extends VSpaceElement implements ISpaceTextBlockDisplay{ + @Id + @GeneratedValue(generator = "spacetextblock_display_id_generator") + @GenericGenerator(name = "spacetextblock_display_id_generator", + parameters = @Parameter(name = "prefix", value = "STBD"), + strategy = "edu.asu.diging.vspace.core.data.IdGenerator") + private String id; + + @OneToOne(targetEntity = SpaceTextBlock.class) + private ISpaceTextBlock spaceTextBlock; + + private float positionX; + private float positionY; + + private float height; + private float width; + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public ISpaceTextBlock getSpaceTextBlock() { + return spaceTextBlock; + } + + @Override + public void setSpaceTextBlock(ISpaceTextBlock spaceTextBlock) { + this.spaceTextBlock = spaceTextBlock; + } + + @Override + public float getPositionX() { + return positionX; + } + + @Override + public void setPositionX(float positionX) { + this.positionX=positionX; + } + + @Override + public float getPositionY() { + return positionY; + } + + @Override + public void setPositionY(float positionY) { + this.positionY=positionY; + } + + @Override + public float getHeight() { + return height; + } + + @Override + public void setHeight(float height) { + this.height=height; + } + + @Override + public float getWidth() { + return width; + } + + @Override + public void setWidth(float width) { + this.width=width; + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/Exhibition.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/Exhibition.java index 4937ecbb4..9616e4e49 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/Exhibition.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/Exhibition.java @@ -1,15 +1,26 @@ package edu.asu.diging.vspace.core.model.impl; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.OneToMany; import javax.persistence.OneToOne; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; import edu.asu.diging.vspace.core.model.ExhibitionModes; +import edu.asu.diging.vspace.core.model.IContentBlock; import edu.asu.diging.vspace.core.model.IExhibition; +import edu.asu.diging.vspace.core.model.IExhibitionLanguage; +import edu.asu.diging.vspace.core.model.IExternalLink; import edu.asu.diging.vspace.core.model.ISpace; /** @@ -37,6 +48,11 @@ public class Exhibition extends VSpaceElement implements IExhibition { private String customMessage; private boolean aboutPageConfigured; + + @OneToMany(targetEntity = ExhibitionLanguage.class, mappedBy = "exhibition", cascade = CascadeType.ALL, orphanRemoval=true) + private List languages = new ArrayList(); + + private String previewId; /* * (non-Javadoc) @@ -89,7 +105,7 @@ public String getTitle() { public void setTitle(String title) { this.title = title; } - + public ExhibitionModes getMode() { return mode; } @@ -116,4 +132,35 @@ public void setAboutPageConfigured(boolean aboutPageConfigured) { this.aboutPageConfigured = aboutPageConfigured; } + public List getLanguages() { + return languages; + } + + public void setLanguages(List languages) { + this.languages = languages; + } + + public String getPreviewId() { + return previewId; + } + + public void setPreviewId(String previewId) { + this.previewId = previewId; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return Objects.equals(id, ((Exhibition) obj).id); + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/ExhibitionLanguage.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/ExhibitionLanguage.java new file mode 100644 index 000000000..2935fa06c --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/ExhibitionLanguage.java @@ -0,0 +1,103 @@ +package edu.asu.diging.vspace.core.model.impl; + +import java.util.Objects; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; +import edu.asu.diging.vspace.core.model.IExhibitionLanguage; + +@Entity +public class ExhibitionLanguage extends VSpaceElement implements IExhibitionLanguage { + + @Id + @GeneratedValue(generator = "exhibit_language_id_generator") + @GenericGenerator(name = "exhibit_language_id_generator", parameters = @Parameter(name = "prefix", value = "LANG"), strategy = "edu.asu.diging.vspace.core.data.IdGenerator") + private String id; + + private String label; + + @ManyToOne(targetEntity = Exhibition.class) + private Exhibition exhibition; + + private String code; + + private boolean isDefault; + + public ExhibitionLanguage() { + super(); + } + + public ExhibitionLanguage(String label, String code, Exhibition exhibition) { + this.label=label; + this.code=code; + this.exhibition=exhibition; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.setId(id); + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public Exhibition getExhibition() { + return exhibition; + } + + public void setExhibition(Exhibition exhibition) { + this.exhibition = exhibition; + } + + @Override + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + @Override + public boolean isDefault() { + return isDefault; + } + + @Override + public void setDefault(boolean isDefault) { + this.isDefault = isDefault; + } + + @Override + public int hashCode() { + return Objects.hash(code, exhibition, label); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ExhibitionLanguage other = (ExhibitionLanguage) obj; + return Objects.equals(code, other.code) && Objects.equals(exhibition, other.exhibition) + && Objects.equals(label, other.label); + } + + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/SpaceTextBlock.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/SpaceTextBlock.java new file mode 100644 index 000000000..6ba731497 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/SpaceTextBlock.java @@ -0,0 +1,63 @@ +package edu.asu.diging.vspace.core.model.impl; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.Lob; +import javax.persistence.ManyToOne; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; + +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; + +@Entity +public class SpaceTextBlock extends VSpaceElement implements ISpaceTextBlock { + + @Id + @GeneratedValue(generator = "spacetextblock_id_generator") + @GenericGenerator(name = "spacetextblock_id_generator", + parameters = @Parameter(name = "prefix", value = "STB"), + strategy = "edu.asu.diging.vspace.core.data.IdGenerator") + private String id; + + @ManyToOne(targetEntity=Space.class) + @JoinColumn(name="space_id", nullable=false) + private ISpace space; + + + @Lob + private String text; + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public ISpace getSpace() { + return space; + } + + @Override + public void setSpace(ISpace space) { + this.space = space; + } + + @Override + public String getText() { + return text; + } + + @Override + public void setText(String text) { + this.text = text; + } +} \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSImage.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSImage.java index b54491173..054947ee0 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSImage.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSImage.java @@ -8,7 +8,6 @@ import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import javax.persistence.Lob; import javax.persistence.OneToMany; import org.hibernate.annotations.GenericGenerator; @@ -19,22 +18,13 @@ import edu.asu.diging.vspace.core.model.ImageCategory; @Entity -public class VSImage extends VSpaceElement implements IVSImage { +public class VSImage extends VSMedia implements IVSImage { @Id @GeneratedValue(generator = "image_id_generator") @GenericGenerator(name = "image_id_generator", parameters = @Parameter(name = "prefix", value = "IMG"), strategy = "edu.asu.diging.vspace.core.data.IdGenerator") private String id; - @Lob - private String filename; - @Lob - private String parentPath; - private String fileType; - - private int height; - private int width; - @OneToMany(targetEntity = Tag.class) private List tags; @@ -62,77 +52,6 @@ public void setId(String id) { this.id = id; } - /* - * (non-Javadoc) - * - * @see edu.asu.diging.vspace.core.model.impl.IImage#getFilename() - */ - @Override - public String getFilename() { - return filename; - } - - /* - * (non-Javadoc) - * - * @see - * edu.asu.diging.vspace.core.model.impl.IImage#setFilename(java.lang.String) - */ - @Override - public void setFilename(String filename) { - this.filename = filename; - } - - /* - * (non-Javadoc) - * - * @see edu.asu.diging.vspace.core.model.impl.IImage#getParentPath() - */ - @Override - public String getParentPath() { - return parentPath; - } - - /* - * (non-Javadoc) - * - * @see - * edu.asu.diging.vspace.core.model.impl.IImage#setParentPath(java.lang.String) - */ - @Override - public void setParentPath(String parentPath) { - this.parentPath = parentPath; - } - - @Override - public String getFileType() { - return fileType; - } - - @Override - public void setFileType(String fileType) { - this.fileType = fileType; - } - - @Override - public int getHeight() { - return height; - } - - @Override - public void setHeight(int height) { - this.height = height; - } - - @Override - public int getWidth() { - return width; - } - - @Override - public void setWidth(int width) { - this.width = width; - } @Override public List getTags() { diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSMedia.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSMedia.java new file mode 100644 index 000000000..f5aca2517 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSMedia.java @@ -0,0 +1,60 @@ +package edu.asu.diging.vspace.core.model.impl; + +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; + +import edu.asu.diging.vspace.core.model.IVSMedia; + +@MappedSuperclass +public abstract class VSMedia extends VSpaceElement implements IVSMedia { + + @Lob + private String filename; + @Lob + private String parentPath; + private String fileType; + + private int height; + private int width; + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getParentPath() { + return parentPath; + } + + public void setParentPath(String parentPath) { + this.parentPath = parentPath; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSVideo.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSVideo.java new file mode 100644 index 000000000..6f4658f3f --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSVideo.java @@ -0,0 +1,67 @@ +package edu.asu.diging.vspace.core.model.impl; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; + +import edu.asu.diging.vspace.core.model.IVSVideo; + +@Entity +public class VSVideo extends VSMedia implements IVSVideo{ + + @Id + @GeneratedValue(generator = "video_id_generator") + @GenericGenerator(name = "video_id_generator", parameters = @Parameter(name = "prefix", value = "VID"), strategy = "edu.asu.diging.vspace.core.data.IdGenerator") + private String id; + + private String url; + + private Long fileSize; + + private String title; + + @Override + public void setFileSize(Long fileSize) { + this.fileSize = fileSize; + } + + @Override + public Long getFileSize() { + return fileSize; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + + } + + @Override + public String getUrl() { + return url; + } + + @Override + public void setUrl(String url) { + this.url = url; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public String getTitle() { + return title; + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSpaceElement.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSpaceElement.java index 2fafe4cdf..2e034ac63 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSpaceElement.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VSpaceElement.java @@ -9,6 +9,7 @@ @MappedSuperclass public abstract class VSpaceElement implements IVSpaceElement { + private String name; @Lob private String description; private String createdBy; diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VideoBlock.java b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VideoBlock.java new file mode 100644 index 000000000..a57cdbc65 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/model/impl/VideoBlock.java @@ -0,0 +1,26 @@ +package edu.asu.diging.vspace.core.model.impl; + +import javax.persistence.Entity; +import javax.persistence.OneToOne; + +import edu.asu.diging.vspace.core.model.IVSVideo; +import edu.asu.diging.vspace.core.model.IVideoBlock; + +@Entity +public class VideoBlock extends ContentBlock implements IVideoBlock { + + @OneToOne(targetEntity = VSVideo.class) + private IVSVideo video; + + public VideoBlock() { + } + + public IVSVideo getVideo() { + return video; + } + + public void setVideo(IVSVideo video) { + this.video = video; + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IContentBlockManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IContentBlockManager.java index 647a8f721..7553478fb 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IContentBlockManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IContentBlockManager.java @@ -1,14 +1,15 @@ package edu.asu.diging.vspace.core.services; import java.util.List; - import edu.asu.diging.vspace.core.exception.BlockDoesNotExistException; import edu.asu.diging.vspace.core.exception.ImageCouldNotBeStoredException; +import edu.asu.diging.vspace.core.exception.VideoCouldNotBeStoredException; import edu.asu.diging.vspace.core.model.IChoiceBlock; import edu.asu.diging.vspace.core.model.IContentBlock; import edu.asu.diging.vspace.core.model.IImageBlock; import edu.asu.diging.vspace.core.model.ITextBlock; import edu.asu.diging.vspace.core.model.IVSImage; +import edu.asu.diging.vspace.core.model.IVideoBlock; import edu.asu.diging.vspace.core.model.impl.ContentBlock; import edu.asu.diging.vspace.core.model.impl.TextBlock; import edu.asu.diging.vspace.core.services.impl.CreationReturnValue; @@ -19,21 +20,28 @@ public interface IContentBlockManager { CreationReturnValue createImageBlock(String slideId, byte[] image, String filename, Integer contentOrder) throws ImageCouldNotBeStoredException; - + CreationReturnValue createImageBlock(String slideId, IVSImage image, Integer contentOrder); + public CreationReturnValue createVideoBlock(String slideId, byte[] video, Long size, String fileName, String url, + Integer contentOrder, String title) throws VideoCouldNotBeStoredException; + List getAllContentBlocks(String slideId); void deleteTextBlockById(String blockid, String slideId) throws BlockDoesNotExistException; void deleteImageBlockById(String blockid, String slideId) throws BlockDoesNotExistException; + void deleteVideoBlockById(String blockId,String slideId) throws BlockDoesNotExistException; + void deleteChoiceBlockById(String blockid, String slideId) throws BlockDoesNotExistException; void updateTextBlock(TextBlock textBlock); IImageBlock getImageBlock(String imgBlockId); + IVideoBlock getVideoBlock(String videoBlockId); + ITextBlock getTextBlock(String textBlockId); IChoiceBlock getChoiceBlock(String choiceBlockId); @@ -42,10 +50,15 @@ CreationReturnValue createImageBlock(String slideId, byte[] image, String filena void updateImageBlock(IImageBlock imageBlock, IVSImage image); + void updateVideoBlock(IVideoBlock videoBlock, byte[] video, Long fileSize, String url, String filename, + String title) throws VideoCouldNotBeStoredException; + IChoiceBlock createChoiceBlock(String slideId, List selectedChoices, Integer contentOrder, boolean showsAll); Integer findMaxContentOrder(String slideId); void updateContentOrder(List contentBlockList) throws BlockDoesNotExistException; + + void saveVideoBlock(IVideoBlock videoBlock); } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IExhibitionManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IExhibitionManager.java index afd44964b..e1df7f7c9 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/IExhibitionManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/IExhibitionManager.java @@ -34,4 +34,6 @@ public interface IExhibitionManager { IExhibition getStartExhibition(); + void updateExhibitionLanguages(Exhibition exhibition, List languages, String defaultLanguage); + } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceTextBlockManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceTextBlockManager.java new file mode 100644 index 000000000..b76dfca58 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/ISpaceTextBlockManager.java @@ -0,0 +1,19 @@ +package edu.asu.diging.vspace.core.services; + +import java.util.List; + +import edu.asu.diging.vspace.core.exception.SpaceDoesNotExistException; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; + +public interface ISpaceTextBlockManager { + ISpaceTextBlockDisplay createTextBlock(String id, float positionX, float positionY,String text, + float height, float width) throws SpaceDoesNotExistException; + + List getSpaceTextBlockDisplays(String spaceId); + + void deleteTextBlock(String blockId); + + ISpaceTextBlockDisplay updateTextBlock(String id, float positionX, float positionY, String textBlockIdValueEdit, + String textBlockDisplayId, String text, float height, float width); + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ContentBlockManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ContentBlockManager.java index 0d60a956b..cda886b49 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ContentBlockManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ContentBlockManager.java @@ -14,13 +14,18 @@ import edu.asu.diging.vspace.core.data.ImageContentBlockRepository; import edu.asu.diging.vspace.core.data.ImageRepository; import edu.asu.diging.vspace.core.data.TextContentBlockRepository; +import edu.asu.diging.vspace.core.data.VideoContentBlockRepository; +import edu.asu.diging.vspace.core.data.VideoRepository; import edu.asu.diging.vspace.core.exception.BlockDoesNotExistException; import edu.asu.diging.vspace.core.exception.FileStorageException; import edu.asu.diging.vspace.core.exception.ImageCouldNotBeStoredException; +import edu.asu.diging.vspace.core.exception.VideoCouldNotBeStoredException; import edu.asu.diging.vspace.core.factory.IChoiceBlockFactory; import edu.asu.diging.vspace.core.factory.IImageBlockFactory; import edu.asu.diging.vspace.core.factory.IImageFactory; import edu.asu.diging.vspace.core.factory.ITextBlockFactory; +import edu.asu.diging.vspace.core.factory.IVideoBlockFactory; +import edu.asu.diging.vspace.core.factory.IVideoFactory; import edu.asu.diging.vspace.core.file.IStorageEngine; import edu.asu.diging.vspace.core.model.IChoice; import edu.asu.diging.vspace.core.model.IChoiceBlock; @@ -29,11 +34,15 @@ import edu.asu.diging.vspace.core.model.ISlide; import edu.asu.diging.vspace.core.model.ITextBlock; import edu.asu.diging.vspace.core.model.IVSImage; +import edu.asu.diging.vspace.core.model.IVSVideo; +import edu.asu.diging.vspace.core.model.IVideoBlock; import edu.asu.diging.vspace.core.model.impl.ChoiceBlock; import edu.asu.diging.vspace.core.model.impl.ContentBlock; import edu.asu.diging.vspace.core.model.impl.ImageBlock; import edu.asu.diging.vspace.core.model.impl.TextBlock; import edu.asu.diging.vspace.core.model.impl.VSImage; +import edu.asu.diging.vspace.core.model.impl.VSVideo; +import edu.asu.diging.vspace.core.model.impl.VideoBlock; import edu.asu.diging.vspace.core.services.IContentBlockManager; import edu.asu.diging.vspace.core.services.ISlideManager; @@ -47,24 +56,36 @@ public class ContentBlockManager implements IContentBlockManager { @Autowired private IImageFactory imageFactory; + @Autowired + private IVideoFactory videoFactory; + @Autowired private ITextBlockFactory textBlockFactory; @Autowired private IImageBlockFactory imageBlockFactory; + @Autowired + private IVideoBlockFactory videoBlockFactory; + @Autowired private IChoiceBlockFactory choiceBlockFactory; @Autowired private ImageRepository imageRepo; + @Autowired + private VideoRepository videoRepo; + @Autowired private TextContentBlockRepository textBlockRepo; @Autowired private ImageContentBlockRepository imageBlockRepo; + @Autowired + private VideoContentBlockRepository videoBlockRepo; + @Autowired private ChoiceContentBlockRepository choiceBlockRepo; @@ -113,6 +134,24 @@ private IVSImage saveImage(byte[] image, String filename) { return null; } + private IVSVideo saveVideoWithUrl(String url, String title) { + IVSVideo vidContent = videoFactory.createVideo(url); + vidContent.setTitle(title); + return videoRepo.save((VSVideo) vidContent); + } + + private IVSVideo saveVideo(byte[] video, Long size, String filename, String title) { + if (video != null && video.length > 0) { + Tika tika = new Tika(); + String contentType = tika.detect(video); + IVSVideo slideContentVideo = videoFactory.createVideo(filename, size, contentType); + slideContentVideo.setTitle(title); + slideContentVideo = videoRepo.save((VSVideo) slideContentVideo); + return slideContentVideo; + } + return null; + } + private void storeImageFile(byte[] image, IVSImage slideContentImage, String filename) throws ImageCouldNotBeStoredException { if (slideContentImage != null) { @@ -127,6 +166,20 @@ private void storeImageFile(byte[] image, IVSImage slideContentImage, String fil } } + private void storeVideoFile(byte[] video, IVSVideo slideContentVideo, String filename) + throws VideoCouldNotBeStoredException { + if (slideContentVideo != null) { + String relativePath = null; + try { + relativePath = storage.storeFile(video, filename, slideContentVideo.getId()); + } catch (FileStorageException e) { + throw new VideoCouldNotBeStoredException(e); + } + slideContentVideo.setParentPath(relativePath); + videoRepo.save((VSVideo) slideContentVideo); + } + } + /* * (non-Javadoc) * @@ -136,7 +189,6 @@ private void storeImageFile(byte[] image, IVSImage slideContentImage, String fil @Override public CreationReturnValue createImageBlock(String slideId, byte[] image, String filename, Integer contentOrder) throws ImageCouldNotBeStoredException { - ISlide slide = slideManager.getSlide(slideId); IVSImage slideContentImage = saveImage(image, filename); CreationReturnValue returnValue = new CreationReturnValue(); @@ -149,7 +201,7 @@ public CreationReturnValue createImageBlock(String slideId, byte[] image, String returnValue.setElement(imageBlock); return returnValue; } - + /** * (non-Javadoc) * @@ -169,7 +221,40 @@ public CreationReturnValue createImageBlock(String slideId, IVSImage image, Inte returnValue.setElement(imageBlock); return returnValue; } - + + /* + * (non-Javadoc) + * + * @see edu.asu.diging.vspace.core.services.impl.IContentBlockManager# + * createVideoBlock(java.lang.String, java.util.Arrays, java.lang.String) + */ + @Override + public CreationReturnValue createVideoBlock(String slideId, byte[] video, Long size, String fileName, String url, + Integer contentOrder, String title) throws VideoCouldNotBeStoredException { + ISlide slide = slideManager.getSlide(slideId); + CreationReturnValue returnValue = new CreationReturnValue(); + returnValue.setErrorMsgs(new ArrayList<>()); + IVSVideo slideContentVideo = storeVideo(video, size, fileName, url, title); + IVideoBlock vidBlock = videoBlockFactory.createVideoBlock(slide, slideContentVideo); + vidBlock.setContentOrder(contentOrder); + VideoBlock videoBlock = videoBlockRepo.save((VideoBlock) vidBlock); + returnValue.setElement(videoBlock); + return returnValue; + } + + private IVSVideo storeVideo(byte[] video, Long size, String fileName, String url, String title) + throws VideoCouldNotBeStoredException { + IVSVideo slideContentVideo = null; + if (video != null) { + slideContentVideo = saveVideo(video, size, fileName, title); + storeVideoFile(video, slideContentVideo, fileName); + slideContentVideo.setUrl(null); + } else if (url != null && !url.isEmpty()) { + slideContentVideo = saveVideoWithUrl(url, title); + } + return slideContentVideo; + } + /** * Delete a text block using an id and also decrease content order by 1 of all * the slide's block which are after this block @@ -233,6 +318,36 @@ public void deleteImageBlockById(String blockId, String slideId) throws BlockDoe } + /** + * Delete an video block using an id and also decrease content order by 1 of all + * the slide's block which are after this block + * + * @param blockId - id of resource to be deleted. If the id is null then the + * functions returns nothing. + * @param slideId - id of the slide in which the Image block with blockId is + * present. + */ + + @Override + public void deleteVideoBlockById(String blockId, String slideId) throws BlockDoesNotExistException { + if (blockId == null) { + return; + } + Integer contentOrder = null; + Optional contentBlock = contentBlockRepository.findById(blockId); + if (contentBlock.isPresent()) { + contentOrder = contentBlock.get().getContentOrder(); + } else { + throw new BlockDoesNotExistException("Block Id not present"); + } + try { + videoBlockRepo.deleteById(blockId); + updateContentOrder(slideId, contentOrder); + } catch (EmptyResultDataAccessException e) { + throw new BlockDoesNotExistException(e); + } + } + /** * Delete a choices block using an id and also decrease content order by 1 of * all the slide's block which are after this block @@ -276,13 +391,22 @@ public void updateImageBlock(IImageBlock imageBlock, byte[] image, String filena imageBlock.setImage(slideContentImage); imageBlockRepo.save((ImageBlock) imageBlock); } - + @Override public void updateImageBlock(IImageBlock imageBlock, IVSImage image) { imageBlock.setImage(image); imageBlockRepo.save((ImageBlock) imageBlock); } - + + @Override + public void updateVideoBlock(IVideoBlock videoBlock, byte[] video, Long fileSize, String url, String filename, + String title) throws VideoCouldNotBeStoredException { + IVSVideo slideContentVideo = storeVideo(video, fileSize, filename, url, title); + + videoBlock.setVideo(slideContentVideo); + videoBlockRepo.save((VideoBlock) videoBlock); + } + @Override public IImageBlock getImageBlock(String imgBlockId) { Optional imgBlock = imageBlockRepo.findById(imgBlockId); @@ -292,6 +416,15 @@ public IImageBlock getImageBlock(String imgBlockId) { return null; } + @Override + public IVideoBlock getVideoBlock(String videoBlockId) { + Optional videoBlock = videoBlockRepo.findById(videoBlockId); + if (videoBlock.isPresent()) { + return videoBlock.get(); + } + return null; + } + @Override public ITextBlock getTextBlock(String textBlockId) { Optional textBlock = textBlockRepo.findById(textBlockId); @@ -387,4 +520,9 @@ private void updateContentOrder(String slideId, Integer contentOrder) { contentBlockRepository.saveAll(contentBlockList); } } + + @Override + public void saveVideoBlock(IVideoBlock videoBlock){ + videoRepo.save((VSVideo) videoBlock.getVideo()); + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ExhibitionManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ExhibitionManager.java index 12902ed23..f4284c2b4 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ExhibitionManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/ExhibitionManager.java @@ -2,16 +2,28 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import javax.transaction.Transactional; +import org.apache.commons.collections.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import edu.asu.diging.vspace.config.ConfigConstants; +import edu.asu.diging.vspace.config.ExhibitionLanguageConfig; import edu.asu.diging.vspace.core.data.ExhibitionRepository; +import edu.asu.diging.vspace.core.exception.LanguageListConfigurationNotFoundException; +import edu.asu.diging.vspace.core.factory.impl.ExhibitionFactory; import edu.asu.diging.vspace.core.model.IExhibition; +import edu.asu.diging.vspace.core.model.IExhibitionLanguage; import edu.asu.diging.vspace.core.model.impl.Exhibition; +import edu.asu.diging.vspace.core.model.impl.ExhibitionLanguage; import edu.asu.diging.vspace.core.services.IExhibitionManager; @Transactional @@ -20,6 +32,12 @@ public class ExhibitionManager implements IExhibitionManager { @Autowired private ExhibitionRepository exhibitRepo; + + @Autowired + private ExhibitionLanguageConfig exhibitionLanguageConfig; + + @Autowired + private ExhibitionFactory exhibitFactory; /* * (non-Javadoc) @@ -62,8 +80,71 @@ public IExhibition getStartExhibition() { // for now we just take the first one created, there shouldn't be more than one List exhibitions = exhibitRepo.findAllByOrderByIdAsc(); if (exhibitions.size() > 0) { - return exhibitions.get(0); + Exhibition exhibition = exhibitions.get(0); + String previewId = exhibition.getPreviewId(); + if(previewId==null || previewId.isEmpty()) { + exhibitFactory.updatePreviewId(exhibition); + } + return exhibition; } return null; } + + /** + * Updates the Exhibition with given list of languages. It fetches the language from exhibitionLanguageConfig using code. + * + * @param exhibition + * @param defaultLanguage + * @param languages + * @throws LanguageListConfigurationNotFoundException + */ + @Override + public void updateExhibitionLanguages(Exhibition exhibition, List codes, String defaultLanguage) { + if(CollectionUtils.isEmpty(exhibitionLanguageConfig.getExhibitionLanguageList())) { + throw new LanguageListConfigurationNotFoundException("Exhibition Language Configuration not found"); + } + + if(CollectionUtils.isEmpty(codes) ) { + return; + } + + // Adds defaultLanguage to codes list if not already exists. + if(!StringUtils.isEmpty(defaultLanguage) && !codes.contains(defaultLanguage)) { + codes.add(defaultLanguage); + } + + exhibitionLanguageConfig.getExhibitionLanguageList().stream() + .filter(languageConfig -> codes.contains(languageConfig.get(ConfigConstants.CODE))) + .forEach(languageMap -> { + IExhibitionLanguage exhibitionLanguage = addExhibitionLanguage(exhibition , languageMap); + exhibitionLanguage.setDefault(exhibitionLanguage.getCode().equalsIgnoreCase(defaultLanguage)); + }); + + // Removes exhibition langauge if unselected. + exhibition.getLanguages().removeAll(exhibition.getLanguages().stream() + .filter(language -> !codes.contains(language.getCode())).collect(Collectors.toList())); + + } + + /** + * Adds exhibitionLanguage to exhibition if not already present. If already present, returns exhibitionLanguage from the exhibition. + * + * @param exhibition + * @param languageMap + * @return + */ + private IExhibitionLanguage addExhibitionLanguage(Exhibition exhibition, Map languageMap) { + IExhibitionLanguage exhibitionLanguage = new ExhibitionLanguage((String) languageMap.get(ConfigConstants.LABEL), + (String) languageMap.get(ConfigConstants.CODE), exhibition); + + int index = exhibition.getLanguages().indexOf(exhibitionLanguage); + if( index < 0 ) { + exhibition.getLanguages().add(exhibitionLanguage); + } else { + exhibitionLanguage = exhibition.getLanguages().get(index); + } + + return exhibitionLanguage; + } + } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceDisplayManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceDisplayManager.java index 260b9a55d..2eb4e665e 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceDisplayManager.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceDisplayManager.java @@ -64,7 +64,7 @@ public ISpaceDisplay getBySpace(ISpace space) { if(image.getWidth()<=0 || image.getHeight()<=0) { try { ImageData data = imageService - .getImageData(storage.getImageContent(image.getId(), image.getFilename())); + .getImageData(storage.getMediaContent(image.getId(), image.getFilename())); image.setWidth(data.getWidth()); image.setHeight(data.getHeight()); } catch (IOException e) { diff --git a/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceTextBlockManager.java b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceTextBlockManager.java new file mode 100644 index 000000000..0bd60943b --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/core/services/impl/SpaceTextBlockManager.java @@ -0,0 +1,83 @@ +package edu.asu.diging.vspace.core.services.impl; + +import java.util.List; +import java.util.Optional; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import edu.asu.diging.vspace.core.data.SpaceTextBlockRepository; +import edu.asu.diging.vspace.core.data.display.SpaceTextBlockDisplayRepository; +import edu.asu.diging.vspace.core.factory.ISpaceTextBlockDisplayFactory; +import edu.asu.diging.vspace.core.factory.ISpaceTextBlockFactory; +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.ISpaceTextBlock; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.model.display.impl.SpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.model.impl.SpaceTextBlock; +import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.core.services.ISpaceTextBlockManager; + +@Transactional +@Service +public class SpaceTextBlockManager implements ISpaceTextBlockManager{ + @Autowired + private ISpaceManager spaceManager; + + @Autowired + private ISpaceTextBlockFactory spaceTextBlockFactory; + + @Autowired + private ISpaceTextBlockDisplayFactory spaceTextBlockDisplayFactory; + + @Autowired + private SpaceTextBlockRepository spaceTextBlockRepo; + + @Autowired + private SpaceTextBlockDisplayRepository spaceTextBlockDisplayRepo; + + @Override + public ISpaceTextBlockDisplay createTextBlock(String id, float positionX, float positionY, String text, + float height, float width){ + ISpace source = spaceManager.getSpace(id); + ISpaceTextBlock textBlock=spaceTextBlockFactory.createSpaceTextBlock(text, source); + ISpaceTextBlockDisplay spaceTextBlockDisplay = spaceTextBlockDisplayFactory.createSpaceTextBlockDisplay(textBlock,positionX,positionY,height, width); + spaceTextBlockRepo.save((SpaceTextBlock) textBlock); + return spaceTextBlockDisplayRepo.save((SpaceTextBlockDisplay)spaceTextBlockDisplay); + } + + @Override + public List getSpaceTextBlockDisplays(String spaceId) { + return spaceTextBlockDisplayRepo.findSpaceTextBlockDisplaysForSpace(spaceId); + } + + @Override + public void deleteTextBlock(String blockId) { + Optional spaceTextBlock = spaceTextBlockRepo.findById(blockId); + if(spaceTextBlock.isPresent()) { + spaceTextBlockDisplayRepo.deleteBySpaceTextBlock(spaceTextBlock.get()); + spaceTextBlockRepo.delete(spaceTextBlock.get()); + } + } + @Override + public ISpaceTextBlockDisplay updateTextBlock(String id, float positionX, float positionY, String textBlockId, + String textBlockDisplayId, String text, float height, float width) { + + Optional spaceTextBlock = spaceTextBlockRepo.findById(textBlockId); + Optional spaceTextBlockDisplay = spaceTextBlockDisplayRepo.findById(textBlockDisplayId); + if(spaceTextBlock.isPresent() && spaceTextBlockDisplay.isPresent()) { + ISpaceTextBlock spaceTextBlockEdit = spaceTextBlock.get(); + spaceTextBlockEdit.setText(text); + ISpaceTextBlockDisplay spaceTextBlockDisplayEdit = spaceTextBlockDisplay.get(); + spaceTextBlockDisplayEdit.setHeight(height); + spaceTextBlockDisplayEdit.setWidth(width); + spaceTextBlockDisplayEdit.setPositionX(positionX); + spaceTextBlockDisplayEdit.setPositionY(positionY); + spaceTextBlockRepo.save((SpaceTextBlock)spaceTextBlockEdit); + return spaceTextBlockDisplayRepo.save((SpaceTextBlockDisplay)spaceTextBlockDisplayEdit); + } + return null; + } +} 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 60a6c8149..4133a169d 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 @@ -6,11 +6,14 @@ import org.springframework.security.core.context.SecurityContextHolder; 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.simpleusers.core.model.Role; import edu.asu.diging.vspace.core.model.IExhibition; import edu.asu.diging.vspace.core.services.IExhibitionManager; import edu.asu.diging.vspace.core.services.ISetupManager; +import edu.asu.diging.vspace.web.exhibit.view.ExhibitionConstants; @Controller public class HomeController { @@ -21,8 +24,10 @@ public class HomeController { @Autowired private ISetupManager setupManager; - @RequestMapping(value = "/") - public String home(Model model) { + @RequestMapping(value = { "/", "/preview/{" + ExhibitionConstants.PREVIEW_ID + "}" }) + public String home(Model model, + @PathVariable(name = ExhibitionConstants.PREVIEW_ID, required = false) String previewId) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (!setupManager.isSetup()) { return "setup"; @@ -30,26 +35,32 @@ public String home(Model model) { IExhibition exhibition = exhibitionManager.getStartExhibition(); if (exhibition != null && exhibition.getStartSpace() != null) { - if(!(authentication instanceof AnonymousAuthenticationToken)) { - return "redirect:/staff/dashboard/"; + if (previewId != null) { + return "redirect:/preview/{previewId}/space/" + exhibition.getStartSpace().getId(); } else { - return "redirect:/exhibit/space/" + exhibition.getStartSpace().getId(); - } + if (!(authentication instanceof AnonymousAuthenticationToken) && + (authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(Role.ADMIN) || r.getAuthority().equals("ROLE_STAFF")))) { + return "redirect:/staff/dashboard/"; + } else { + return "redirect:/exhibit/space/" + exhibition.getStartSpace().getId(); + } + } } return "home"; } - @RequestMapping(value ="/login") + + @RequestMapping(value = "/login") public String login() { return "login"; } - @RequestMapping(value = "/403") + @RequestMapping(value = "/403") public String accessDenied() { return "accessDenied"; } - @RequestMapping(value= {"/404", "/exhibit/404"}) - public String error404(){ + @RequestMapping(value = { "/404", "/exhibit/404" }) + public String error404() { return "badrequest"; } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/api/ImageApiController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/api/ImageApiController.java index 80297ec08..4ced5d35c 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/api/ImageApiController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/api/ImageApiController.java @@ -20,7 +20,7 @@ @RestController public class ImageApiController { - + public static final String API_IMAGE_PATH = "/api/image/"; private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -36,7 +36,7 @@ public ResponseEntity getImage(@PathVariable String id) { IVSImage image = imageRepo.findById(id).get(); byte[] imageContent = null; try { - imageContent = storage.getImageContent(image.getId(), image.getFilename()); + imageContent = storage.getMediaContent(image.getId(), image.getFilename()); } catch (IOException e) { logger.error("Could not retrieve image.", e); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/api/VideoApiController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/api/VideoApiController.java new file mode 100644 index 000000000..b5ffd068c --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/api/VideoApiController.java @@ -0,0 +1,52 @@ +package edu.asu.diging.vspace.web.api; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.CacheControl; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import edu.asu.diging.vspace.core.data.VideoRepository; +import edu.asu.diging.vspace.core.exception.VideoCouldNotBeStoredException; +import edu.asu.diging.vspace.core.file.IStorageEngine; +import edu.asu.diging.vspace.core.model.IVSVideo; + +@RestController +public class VideoApiController { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private VideoRepository videoRepo; + + @Autowired + private IStorageEngine storage; + + @RequestMapping(value="/api/video/{id}") + public ResponseEntity getVideo(@PathVariable String id, HttpServletResponse response, + HttpServletRequest request) { + IVSVideo video = null; + byte[] videoContent = null; + try { + video = videoRepo.findById(id).get(); + videoContent = storage.getMediaContent(video.getId(), video.getFilename()); + } catch (IOException | IllegalArgumentException e) { + logger.error("Could not retrieve video.", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + return ResponseEntity.status(HttpStatus.OK) + .header("Content-Type", video.getFileType()) + .header("Content-Length", String.valueOf(videoContent.length)).body(videoContent); + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exception/ExhibitionExceptionHandler.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exception/ExhibitionExceptionHandler.java index fa5b7d37e..58ac0caeb 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/exception/ExhibitionExceptionHandler.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exception/ExhibitionExceptionHandler.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; +import edu.asu.diging.vspace.core.exception.LanguageListConfigurationNotFoundException; import edu.asu.diging.vspace.core.exception.ModuleNotFoundException; import edu.asu.diging.vspace.core.exception.SequenceNotFoundException; import edu.asu.diging.vspace.core.exception.SlideNotFoundException; @@ -23,6 +24,7 @@ public class ExhibitionExceptionHandler { private static final String sequence_not_found="sequence_not_found"; private static final String slide_not_found="slide_not_found"; private static final String slide_not_found_in_sequence="slide_not_found_in_sequence"; + private static final String language_list_configuration_not_found="language_list_configuration_not_found"; @ExceptionHandler({ ModuleNotFoundException.class }) protected ModelAndView handleModuleNotFoundException(HttpServletRequest request, ModuleNotFoundException ex) { @@ -90,5 +92,19 @@ protected ModelAndView handleSpaceNotFoundException(HttpServletRequest request, modelAndView.setViewName("module"); return modelAndView; } + + @ExceptionHandler({ LanguageListConfigurationNotFoundException.class }) + protected ModelAndView handleLanguageListConfigurationNotFoundException(HttpServletRequest request, + LanguageListConfigurationNotFoundException ex) { + ModelAndView modelAndView = new ModelAndView(); + modelAndView.addObject("error_code", language_list_configuration_not_found); + modelAndView.addObject("showAlert", true); + modelAndView.addObject("message", ex.getMessage()); + logger.error("LanguageListConfigurationNotFound Occured:: URL=" + request.getRequestURL()); + logger.error("Code:: "+language_list_configuration_not_found+" Cause:: " + ex); + modelAndView.addObject("url", request.getRequestURL()); + modelAndView.setViewName("module"); + return modelAndView; + } } \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionConstants.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionConstants.java new file mode 100644 index 000000000..6e9c8efef --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionConstants.java @@ -0,0 +1,5 @@ +package edu.asu.diging.vspace.web.exhibit.view; + +public interface ExhibitionConstants { + public static final String PREVIEW_ID = "previewId"; +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionModuleController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionModuleController.java index 1a4c4f656..a01ec3776 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionModuleController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionModuleController.java @@ -25,9 +25,11 @@ public class ExhibitionModuleController { @Autowired private ISpaceManager spaceManager; - @RequestMapping(value = "/exhibit/{spaceId}/module/{id}") - public String module(@PathVariable("id") String id, @PathVariable("spaceId") String spaceId, Model model) + @RequestMapping(value = { "/exhibit/{spaceId}/module/{id}", "/preview/{"+ExhibitionConstants.PREVIEW_ID+"}/{spaceId}/module/{id}" }) + public String module(@PathVariable("id") String id, @PathVariable("spaceId") String spaceId, + @PathVariable(name = ExhibitionConstants.PREVIEW_ID, required = false) String previewId, Model model) throws SpaceNotFoundException, ModuleNotFoundException { + ISpace space = spaceManager.getSpace(spaceId); if (space == null) { return "redirect:/exhibit/404"; @@ -42,6 +44,10 @@ public String module(@PathVariable("id") String id, @PathVariable("spaceId") Str return "/exhibition/module"; } String startSequenceID = module.getStartSequence().getId(); - return "redirect:/exhibit/{spaceId}/module/" + id + "/sequence/" + startSequenceID; + if (previewId != null) { + return "redirect:/preview/" + previewId + "/" + spaceId + "/module/" + id + "/sequence/" + startSequenceID; + } else { + return "redirect:/exhibit/" + spaceId + "/module/" + id + "/sequence/" + startSequenceID; + } } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSequencesController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSequencesController.java index a2ce5d69f..9aaa2ab63 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSequencesController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSequencesController.java @@ -37,46 +37,58 @@ public class ExhibitionSequencesController { @Autowired private SequenceHistory sequenceHistory; - @RequestMapping(value = "/exhibit/{spaceId}/module/{moduleId}/sequence/{sequenceId}") + @RequestMapping(value = { + "/exhibit/{spaceId}/module/{moduleId}/sequence/{sequenceId}", + "/preview/{"+ExhibitionConstants.PREVIEW_ID+"}/{spaceId}/module/{moduleId}/sequence/{sequenceId}" }) public String sequence(Model model, @PathVariable("sequenceId") String sequenceId, @PathVariable("moduleId") String moduleId, @PathVariable("spaceId") String spaceId, - @RequestParam(required = false, name="branchingPoint") String branchingPointId, - @RequestParam(required = false, name="previousSequenceId") String previousSequenceId, - @RequestParam(required = false, name="clearHistory") Boolean clearHistory) - throws ModuleNotFoundException, SequenceNotFoundException, SlidesInSequenceNotFoundException, SpaceNotFoundException { + @PathVariable(name = ExhibitionConstants.PREVIEW_ID, required = false) String previewId, + @RequestParam(required = false, name = "branchingPoint") String branchingPointId, + @RequestParam(required = false, name = "previousSequenceId") String previousSequenceId, + @RequestParam(required = false, name = "clearHistory") Boolean clearHistory) throws ModuleNotFoundException, + SequenceNotFoundException, SlidesInSequenceNotFoundException, SpaceNotFoundException { + ISpace space = spaceManager.getSpace(spaceId); if (space == null) { return "redirect:/exhibit/404"; } IModule module = moduleManager.getModule(moduleId); + model.addAttribute("module", module); if (module == null) { return "redirect:/exhibit/404"; } - model.addAttribute("module", module); if (module.getStartSequence() == null) { - model.addAttribute("showAlert", true); - model.addAttribute("message", "Sorry, module has not been configured yet."); - return "/exhibition/module"; + return moduleNotConfigured(model, previewId); } - ISequence sequenceExist=moduleManager.checkIfSequenceExists(moduleId, sequenceId); - if (sequenceExist==null) { + ISequence sequenceExist = moduleManager.checkIfSequenceExists(moduleId, sequenceId); + if (sequenceExist == null) { throw new SequenceNotFoundException(sequenceId); } List slides = sequenceManager.getSequence(sequenceId).getSlides(); if (slides.size() == 0) { - model.addAttribute("showAlert", true); - model.addAttribute("message", "Sorry, module has not been configured yet."); - return "/exhibition/module"; + return moduleNotConfigured(model, previewId); } String firstSlideId = slides.get(0).getId(); - if(sequenceHistory.hasHistory()){ - if(clearHistory!=null && clearHistory==true) { - sequenceHistory.flushFromHistory(); - } + if (sequenceHistory.hasHistory() && (clearHistory != null && clearHistory == true)) { + sequenceHistory.flushFromHistory(); } - return String.format("redirect:/exhibit/%s/module/%s/sequence/%s/slide/%s?branchingPoint=%s&previousSequenceId=%s", - spaceId,moduleId,sequenceId,firstSlideId,(branchingPointId != null ? branchingPointId : ""),(previousSequenceId != null ? previousSequenceId : "")); + if (previewId != null) { + return String.format( + "redirect:/preview/{previewId}/{spaceId}/module/{moduleId}/sequence/{sequenceId}/slide/%s?branchingPoint=%s&previousSequenceId=%s", + firstSlideId,(branchingPointId != null ? branchingPointId : ""), + (previousSequenceId != null ? previousSequenceId : "")); + } + return String.format( + "redirect:/exhibit/{spaceId}/module/{moduleId}/sequence/{sequenceId}/slide/%s?branchingPoint=%s&previousSequenceId=%s", + firstSlideId, (branchingPointId != null ? branchingPointId : ""), + (previousSequenceId != null ? previousSequenceId : "")); + + } + private String moduleNotConfigured(Model model, String previewId) { + model.addAttribute("showAlert", true); + model.addAttribute("message", "Sorry, module has not been configured yet."); + return "/exhibition/module"; } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSlideController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSlideController.java index ccea4e4c7..07e92d654 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSlideController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSlideController.java @@ -47,15 +47,18 @@ public class ExhibitionSlideController { @Autowired private SequenceHistory sequenceHistory; - @RequestMapping(value = "/exhibit/{spaceId}/module/{moduleId}/sequence/{sequenceId}/slide/{slideId}", method = RequestMethod.GET) + @RequestMapping(value = { + "/exhibit/{spaceId}/module/{moduleId}/sequence/{sequenceId}/slide/{slideId}", + "/preview/{"+ExhibitionConstants.PREVIEW_ID+"}/{spaceId}/module/{moduleId}/sequence/{sequenceId}/slide/{slideId}" + }, method = RequestMethod.GET) public String slide(Model model, @PathVariable("slideId") String slideId, @PathVariable("moduleId") String moduleId, @PathVariable("sequenceId") String sequenceId, @PathVariable("spaceId") String spaceId, - @RequestParam(required=false, name="back") boolean back, - @RequestParam(required = false, name="branchingPoint") String branchingPointId, - @RequestParam(required = false, name="previousSequenceId") String previousSequenceId) - throws ModuleNotFoundException, SequenceNotFoundException, - SlidesInSequenceNotFoundException, SlideNotFoundException, SpaceDoesNotExistException, - SpaceNotFoundException { + @PathVariable(name = ExhibitionConstants.PREVIEW_ID, required = false) String previewId, + @RequestParam(required = false, name = "back") boolean back, + @RequestParam(required = false, name = "branchingPoint") String branchingPointId, + @RequestParam(required = false, name = "previousSequenceId") String previousSequenceId) + throws ModuleNotFoundException, SequenceNotFoundException, SlidesInSequenceNotFoundException, + SlideNotFoundException, SpaceDoesNotExistException, SpaceNotFoundException { ISpace space = spaceManager.getSpace(spaceId); if (space == null) { @@ -67,14 +70,12 @@ public String slide(Model model, @PathVariable("slideId") String slideId, @PathV return "redirect:/exhibit/404"; } if (module.getStartSequence() == null) { - model.addAttribute("showAlert", true); - model.addAttribute("message", "Sorry, module has not been configured yet."); - return "/exhibition/module"; + return moduleNotConfigured(model); } String startSequenceId = module.getStartSequence().getId(); model.addAttribute("startSequenceId", startSequenceId); - ISequence sequenceExist=moduleManager.checkIfSequenceExists(moduleId, sequenceId); - if (sequenceExist==null) { + ISequence sequenceExist = moduleManager.checkIfSequenceExists(moduleId, sequenceId); + if (sequenceExist == null) { throw new SequenceNotFoundException(sequenceId); } List sequenceSlides = sequenceManager.getSequence(sequenceId).getSlides(); @@ -101,27 +102,25 @@ public String slide(Model model, @PathVariable("slideId") String slideId, @PathV if (slideIndex > 0) { prevSlideId = sequenceSlides.get(slideIndex - 1).getId(); } - model.addAttribute("sequences",moduleManager.getModuleSequences(moduleId)); - model.addAttribute("sequence",sequenceExist); + model.addAttribute("sequences", moduleManager.getModuleSequences(moduleId)); + model.addAttribute("sequence", sequenceExist); model.addAttribute("slides", sequenceSlides); model.addAttribute("currentSequenceId", sequenceId); model.addAttribute("nextSlide", nextSlideId); model.addAttribute("prevSlide", prevSlideId); model.addAttribute("currentSlideCon", currentSlide); - if(currentSlide instanceof BranchingPoint) { - model.addAttribute("choices", ((BranchingPoint)currentSlide).getChoices()); - if(back && sequenceHistory.peekBranchingPointId().equalsIgnoreCase(slideId)) { - sequenceHistory.popFromHistory(); - } + if (currentSlide instanceof BranchingPoint) { + handleBranchingPoint(model, slideId, back, currentSlide); } - if(branchingPointId!=null && !branchingPointId.isEmpty()){ - sequenceHistory.addToHistory(previousSequenceId,branchingPointId); + if (branchingPointId != null && !branchingPointId.isEmpty()) { + sequenceHistory.addToHistory(previousSequenceId, branchingPointId); } - if(sequenceHistory.hasHistory()) { + if (sequenceHistory.hasHistory()) { model.addAttribute("showBackToPreviousChoice", true); model.addAttribute("previousSequenceId", sequenceHistory.peekSequenceId()); - model.addAttribute("previousBranchingPoint", ((BranchingPoint)slideManager.getSlide(sequenceHistory.peekBranchingPointId()))); + model.addAttribute("previousBranchingPoint", + ((BranchingPoint) slideManager.getSlide(sequenceHistory.peekBranchingPointId()))); } model.addAttribute("numOfSlides", sequenceSlides.size()); @@ -130,4 +129,17 @@ public String slide(Model model, @PathVariable("slideId") String slideId, @PathV model.addAttribute("spaceName", spaceManager.getSpace(spaceId).getName()); return "exhibition/module"; } + + private void handleBranchingPoint(Model model, String slideId, boolean back, ISlide currentSlide) { + model.addAttribute("choices", ((BranchingPoint) currentSlide).getChoices()); + if (back && sequenceHistory.peekBranchingPointId().equalsIgnoreCase(slideId)) { + sequenceHistory.popFromHistory(); + } + } + + private String moduleNotConfigured(Model model) { + model.addAttribute("showAlert", true); + model.addAttribute("message", "Sorry, module has not been configured yet."); + return "/exhibition/module"; + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSpaceController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSpaceController.java index fbeca4fd8..dc7738b8a 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSpaceController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/exhibit/view/ExhibitionSpaceController.java @@ -23,6 +23,7 @@ import edu.asu.diging.vspace.core.services.ISpaceDisplayManager; import edu.asu.diging.vspace.core.services.ISpaceLinkManager; import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.core.services.ISpaceTextBlockManager; @Controller public class ExhibitionSpaceController { @@ -50,8 +51,11 @@ public class ExhibitionSpaceController { @Autowired private SequenceHistory sequenceHistory; + + @Autowired + private ISpaceTextBlockManager spaceTextBlockManager; - @RequestMapping(value = "/exhibit/space/{id}") + @RequestMapping(value = { "/exhibit/space/{id}", "/preview/{"+ExhibitionConstants.PREVIEW_ID+"}/space/{id}" }) public String space(@PathVariable("id") String id, Model model) { ISpace space = spaceManager.getSpace(id); List spaceLinks; @@ -71,6 +75,7 @@ public String space(@PathVariable("id") String id, Model model) { model.addAttribute("exhibitionConfig", exhibition); model.addAttribute("space", space); model.addAttribute("moduleList", moduleLinkManager.getLinkDisplays(id)); + model.addAttribute("spaceTextBlocks", spaceTextBlockManager.getSpaceTextBlockDisplays(id)); if (space.isShowUnpublishedLinks()) { spaceLinks = spaceLinkManager.getLinkDisplays(id); } else { diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddModuleController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddModuleController.java index 5fdc75d05..cdf8976e5 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddModuleController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddModuleController.java @@ -17,23 +17,24 @@ @Controller public class AddModuleController { - - @Autowired - private IModuleFactory moduleFactory; - - @Autowired - private IModuleManager moduleManager; - - @RequestMapping(value="/staff/module/add", method=RequestMethod.GET) - public String showAddModule(Model model) { - model.addAttribute("module", new ModuleForm()); - return "staff/modules/add"; - } - @RequestMapping(value="/staff/module/add", method=RequestMethod.POST) - public String addModule(Model model, @ModelAttribute ModuleForm moduleForm, Principal principal) { - IModule module = moduleFactory.createModule(moduleForm); - moduleManager.storeModule(module); + + @Autowired + private IModuleFactory moduleFactory; + + @Autowired + private IModuleManager moduleManager; + + @RequestMapping(value = "/staff/module/add", method = RequestMethod.GET) + public String showAddModule(Model model) { + model.addAttribute("module", new ModuleForm()); + return "staff/modules/add"; + } + + @RequestMapping(value = "/staff/module/add", method = RequestMethod.POST) + public String addModule(Model model, @ModelAttribute ModuleForm moduleForm, Principal principal) { + IModule module = moduleFactory.createModule(moduleForm); + moduleManager.storeModule(module); String moduleId = module.getId(); return "redirect:/staff/module/" + moduleId; - } + } } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddSpaceTextBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddSpaceTextBlockController.java new file mode 100644 index 000000000..cd1506ecf --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddSpaceTextBlockController.java @@ -0,0 +1,71 @@ +package edu.asu.diging.vspace.web.staff; + +import java.io.IOException; + +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 org.springframework.web.bind.annotation.RequestParam; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.asu.diging.vspace.core.exception.SpaceDoesNotExistException; +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.core.services.ISpaceTextBlockManager; + +@Controller +public class AddSpaceTextBlockController { + + @Autowired + private ISpaceManager spaceManager; + + @Autowired + private ISpaceTextBlockManager spaceTextBlockManager; + + + @RequestMapping(value = "/staff/space/{id}/textblock", method = RequestMethod.POST) + public ResponseEntity createSpaceTextBlock(@PathVariable("id") String id, @RequestParam("x") String x, + @RequestParam("y") String y, @RequestParam("textContent") String text, + @RequestParam("height") String height, @RequestParam("width") String width) + throws IOException{ + + ISpace source = spaceManager.getSpace(id); + if (source == null) { + return new ResponseEntity<>("{'error': 'Space could not be found.'}", HttpStatus.NOT_FOUND); + } + + if (x == null || x.trim().isEmpty() || y == null || y.trim().isEmpty()) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("errorMessage", "No block coordinates specified."); + return new ResponseEntity(mapper.writeValueAsString(node), HttpStatus.BAD_REQUEST); + } + + ISpaceTextBlockDisplay display=null; + try { + display = spaceTextBlockManager.createTextBlock(id, new Float(x), new Float(y), + text, new Float(height), new Float(width)); + } catch (SpaceDoesNotExistException e) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("errorMessage", "space could not be found."); + return new ResponseEntity<>(mapper.writeValueAsString(node), HttpStatus.INTERNAL_SERVER_ERROR); + } + ObjectMapper mapper = new ObjectMapper(); + ObjectNode textNode = mapper.createObjectNode(); + textNode.put("id", display.getSpaceTextBlock().getId()); + textNode.put("displayId", display.getId()); + textNode.put("x", display.getPositionX()); + textNode.put("y", display.getPositionY()); + + return new ResponseEntity<>(mapper.writeValueAsString(textNode), HttpStatus.OK); + } + +} \ No newline at end of file diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddVideoBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddVideoBlockController.java new file mode 100644 index 000000000..4fa2efbf4 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/AddVideoBlockController.java @@ -0,0 +1,67 @@ +package edu.asu.diging.vspace.web.staff; + +import java.io.IOException; +import java.security.Principal; + +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 org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.asu.diging.vspace.core.exception.VideoCouldNotBeStoredException; +import edu.asu.diging.vspace.core.services.IContentBlockManager; +import edu.asu.diging.vspace.core.services.impl.CreationReturnValue; + +@Controller +public class AddVideoBlockController { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private IContentBlockManager contentBlockManager; + + @RequestMapping(value = "/staff/module/{moduleId}/slide/{id}/video", method = RequestMethod.POST) + public ResponseEntity addVideoBlock(@PathVariable("id") String slideId, + @PathVariable("moduleId") String moduleId, @RequestParam(required = false) MultipartFile videoFile, + @RequestParam(required = false) String url, @RequestParam(required = false) String videoTitle, + Principal principal, RedirectAttributes attributes) throws IOException { + + Integer contentOrder = contentBlockManager.findMaxContentOrder(slideId); + contentOrder = contentOrder == null ? 0 : contentOrder + 1; + String videoId; + try { + if (videoFile == null && url.isEmpty()) { + throw new VideoCouldNotBeStoredException(); + } + byte[] video = null; + String fileName = null; + if (videoFile != null) { + video = videoFile.getBytes(); + fileName = videoFile.getOriginalFilename(); + } + CreationReturnValue videoBlockValue = contentBlockManager.createVideoBlock(slideId, video, + (videoFile != null) ? videoFile.getSize() : null, fileName, url, contentOrder, videoTitle); + videoId = videoBlockValue.getElement().getId(); + } catch (VideoCouldNotBeStoredException e) { + logger.warn("Video block could not be stored, bad request.", e); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("errorMessage", "Video Content block cannot be stored."); + return new ResponseEntity<>(mapper.writeValueAsString(node), HttpStatus.INTERNAL_SERVER_ERROR); + } + + return new ResponseEntity<>(videoId, HttpStatus.OK); + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DashboardController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DashboardController.java index c5006800c..dd12c48ab 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DashboardController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DashboardController.java @@ -12,15 +12,19 @@ import edu.asu.diging.vspace.core.data.ModuleRepository; import edu.asu.diging.vspace.core.data.SpaceRepository; +import edu.asu.diging.vspace.core.factory.impl.ExhibitionFactory; +import edu.asu.diging.vspace.core.model.ExhibitionModes; +import edu.asu.diging.vspace.core.model.impl.Exhibition; import edu.asu.diging.vspace.core.model.impl.Module; import edu.asu.diging.vspace.core.model.impl.Space; +import edu.asu.diging.vspace.core.services.IExhibitionManager; import edu.asu.diging.vspace.core.services.ISpaceLinkManager; import edu.asu.diging.simpleusers.core.model.Role; @Controller public class DashboardController { - + private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired @@ -28,20 +32,32 @@ public class DashboardController { @Autowired private ModuleRepository moduleRepo; - + @Autowired private ISpaceLinkManager spaceLinkManager; + @Autowired + private IExhibitionManager exhibitManager; + @RequestMapping("/staff/dashboard") public String displayDashboard(Model model, Authentication authentication) { - if(authentication.getAuthorities().stream() - .anyMatch(r -> r.getAuthority().equals(Role.ADMIN))) { + if (authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(Role.ADMIN))) { model.addAttribute("spaceLinksSize", spaceLinkManager.getCountOfSpaceLinksWithSourceNull()); } List recentSpaces = spaceRepo.findTop5ByOrderByCreationDateDesc(); List recentModules = moduleRepo.findTop5ByOrderByCreationDateDesc(); + + Exhibition exhibition = (Exhibition) exhibitManager.getStartExhibition(); + String previewId = null; + ExhibitionModes exhibitionMode = null; + if (exhibition != null) { + previewId = exhibition.getPreviewId(); + exhibitionMode = exhibition.getMode(); + } model.addAttribute("recentSpaces", recentSpaces); model.addAttribute("recentModules", recentModules); + model.addAttribute("previewId", previewId); + model.addAttribute("exhibitionMode", exhibitionMode!=null?exhibitionMode.name():null); return "staff/dashboard/dashboard"; } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceTextBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceTextBlockController.java new file mode 100644 index 000000000..0ae10a49e --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteSpaceTextBlockController.java @@ -0,0 +1,24 @@ +package edu.asu.diging.vspace.web.staff; + +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.services.ISpaceTextBlockManager; + +@Controller +public class DeleteSpaceTextBlockController { + @Autowired + private ISpaceTextBlockManager spaceTextBlockManager; + + @RequestMapping(value = "/staff/space/{id}/textblock/{blockId}", method = RequestMethod.DELETE) + public ResponseEntity deleteSpaceTextBlock(@PathVariable("id") String spaceId, @PathVariable("blockId") String blockId) { + spaceTextBlockManager.deleteTextBlock(blockId); + return new ResponseEntity(HttpStatus.OK); + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteVideoBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteVideoBlockController.java new file mode 100644 index 000000000..712cc0cbc --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/DeleteVideoBlockController.java @@ -0,0 +1,38 @@ +package edu.asu.diging.vspace.web.staff; + +import java.io.IOException; + +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.BlockDoesNotExistException; +import edu.asu.diging.vspace.core.services.IContentBlockManager; + +@Controller +public class DeleteVideoBlockController { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private IContentBlockManager contentBlockManager; + + @RequestMapping(value = "/staff/module/{moduleId}/slide/{id}/video/{blockId}", method = RequestMethod.DELETE) + public ResponseEntity deleteVideoBlock(@PathVariable("id") String slideId, + @PathVariable("blockId") String blockId) throws IOException { + try { + contentBlockManager.deleteVideoBlockById(blockId, slideId); + } catch (BlockDoesNotExistException e) { + logger.warn("Video Id does not exist, bad request.", e); + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditSpaceTextBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditSpaceTextBlockController.java new file mode 100644 index 000000000..6c2a46dd1 --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditSpaceTextBlockController.java @@ -0,0 +1,57 @@ +package edu.asu.diging.vspace.web.staff; + +import java.io.IOException; + +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 org.springframework.web.bind.annotation.RequestParam; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.asu.diging.vspace.core.model.ISpace; +import edu.asu.diging.vspace.core.model.display.ISpaceTextBlockDisplay; +import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.core.services.ISpaceTextBlockManager; + +@Controller +public class EditSpaceTextBlockController{ + + @Autowired + private ISpaceManager spaceManager; + + @Autowired + private ISpaceTextBlockManager spaceTextBlockManager; + + @RequestMapping(value = "/staff/space/link/textblock/{id}", method = RequestMethod.POST) + public ResponseEntity editSpaceTextBlock(@PathVariable("id") String id, @RequestParam("x") String x, + @RequestParam("y") String y, @RequestParam("textBlockId") String textBlockId, @RequestParam("textBlockDisplayId") String textBlockDisplayId, + @RequestParam("textContentEdit") String text, + @RequestParam("height") String height, @RequestParam("width") String width) + throws IOException{ + + ISpace source = spaceManager.getSpace(id); + if (source == null) { + return new ResponseEntity<>("{'error': 'Space could not be found.'}", HttpStatus.NOT_FOUND); + } + + ISpaceTextBlockDisplay display = (ISpaceTextBlockDisplay) spaceTextBlockManager.updateTextBlock(id, new Float(x), new Float(y), + textBlockId, textBlockDisplayId, text, new Float(height), new Float(width)); + + ObjectMapper mapper = new ObjectMapper(); + ObjectNode linkNode = mapper.createObjectNode(); + linkNode.put("id", textBlockId); + linkNode.put("x", x); + linkNode.put("y", y); + linkNode.put("width", width); + linkNode.put("height", height); + linkNode.put("textContent", text); + return new ResponseEntity<>(mapper.writeValueAsString(linkNode), HttpStatus.OK); + } + +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditVideoBlockController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditVideoBlockController.java new file mode 100644 index 000000000..7a15cf34f --- /dev/null +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/EditVideoBlockController.java @@ -0,0 +1,61 @@ +package edu.asu.diging.vspace.web.staff; + +import java.io.IOException; +import java.security.Principal; + +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 org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.asu.diging.vspace.core.exception.VideoCouldNotBeStoredException; +import edu.asu.diging.vspace.core.model.IVideoBlock; +import edu.asu.diging.vspace.core.services.IContentBlockManager; + +@Controller +public class EditVideoBlockController { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private IContentBlockManager contentBlockManager; + + @RequestMapping(value = "/staff/module/{moduleId}/slide/{id}/video/{videoBlockId}", method = RequestMethod.POST) + public ResponseEntity editVideoBlock(@PathVariable("id") String slideId, + @PathVariable("videoBlockId") String blockId, @PathVariable("moduleId") String moduleId, + @RequestParam(value = "videoFile", required = false) MultipartFile file, + @RequestParam(value = "url", required = false) String videoUrl, + @RequestParam(value = "videoTitle", required = false) String videoTitle, Principal principal, + RedirectAttributes attributes) throws IOException { + + IVideoBlock videoBlock = contentBlockManager.getVideoBlock(blockId); + byte[] video = null; + String filename = null; + if (videoTitle != null && file != null) { + video = file.getBytes(); + filename = file.getOriginalFilename(); + } + try { + contentBlockManager.updateVideoBlock(videoBlock, video, (file != null) ? file.getSize() : null, + videoUrl, filename, videoTitle); + } catch (VideoCouldNotBeStoredException e) { + logger.error("Video block could not be stored, bad request.", e); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + node.put("errorMessage", "Video Content block cannot be stored."); + return new ResponseEntity<>(mapper.writeValueAsString(node), HttpStatus.INTERNAL_SERVER_ERROR); + } + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ExhibitionConfigurationController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ExhibitionConfigurationController.java index a90c8f544..d63b98eb1 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ExhibitionConfigurationController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/ExhibitionConfigurationController.java @@ -1,6 +1,12 @@ package edu.asu.diging.vspace.web.staff; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; @@ -14,6 +20,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.view.RedirectView; +import edu.asu.diging.vspace.config.ExhibitionLanguageConfig; import edu.asu.diging.vspace.core.data.SpaceRepository; import edu.asu.diging.vspace.core.factory.impl.ExhibitionFactory; import edu.asu.diging.vspace.core.model.ExhibitionModes; @@ -37,18 +44,33 @@ public class ExhibitionConfigurationController { @Autowired private ExhibitionFactory exhibitFactory; + + @Autowired + private ExhibitionLanguageConfig exhibitionLanguageConfig; + + + public static final String EXH_PREVIEW = "EXH_PREVIEW_"; + @RequestMapping("/staff/exhibit/config") public String showExhibitions(Model model) { // for now we assume there is just one exhibition + IExhibition exhibition = exhibitManager.getStartExhibition(); - if(exhibition!=null) { - model.addAttribute("exhibition", exhibition); - } else { - model.addAttribute("exhibition", new Exhibition()); + if(exhibition==null) { + exhibition = (Exhibition) exhibitFactory.createExhibition(); + } + if(exhibition.getLanguages() != null ) { + model.addAttribute("savedExhibitionLanguages", exhibition.getLanguages() + .stream().map(language -> language.getLabel()).collect(Collectors.toList())); + model.addAttribute("defaultLanguage",exhibition.getLanguages().stream() + .filter(language -> language.isDefault()).findFirst().orElse(null) ); + } model.addAttribute("exhibitionModes", Arrays.asList(ExhibitionModes.values())); model.addAttribute("spacesList", spaceRepo.findAll()); + model.addAttribute("languageList", exhibitionLanguageConfig.getExhibitionLanguageList()); + model.addAttribute("exhibition", exhibition); return "staff/exhibit/config"; } @@ -66,12 +88,14 @@ public RedirectView createOrUpdateExhibition(HttpServletRequest request, @RequestParam("spaceParam") String spaceID, @RequestParam("title") String title, @RequestParam("exhibitMode") ExhibitionModes exhibitMode, @RequestParam(value = "customMessage", required = false, defaultValue = "") String customMessage, + @RequestParam("exhibitLanguage") List languages, + @RequestParam("defaultExhibitLanguage") String defaultLanguage, RedirectAttributes attributes) throws IOException { ISpace startSpace = spaceManager.getSpace(spaceID); Exhibition exhibition; - if(exhibitID==null || exhibitID.isEmpty()) { + if (exhibitID == null || exhibitID.isEmpty()) { exhibition = (Exhibition) exhibitFactory.createExhibition(); } else { exhibition = (Exhibition) exhibitManager.getExhibitionById(exhibitID); @@ -79,7 +103,10 @@ public RedirectView createOrUpdateExhibition(HttpServletRequest request, exhibition.setStartSpace(startSpace); exhibition.setTitle(title); exhibition.setMode(exhibitMode); + exhibitManager.updateExhibitionLanguages(exhibition,languages,defaultLanguage); + if(exhibitMode.equals(ExhibitionModes.OFFLINE) && !customMessage.equals(ExhibitionModes.OFFLINE.getValue())) { + exhibition.setCustomMessage(customMessage); } exhibition = (Exhibition) exhibitManager.storeExhibition(exhibition); 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 b5a1a6866..e36571afb 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 @@ -22,6 +22,7 @@ import edu.asu.diging.vspace.core.services.ISpaceDisplayManager; import edu.asu.diging.vspace.core.services.ISpaceLinkManager; import edu.asu.diging.vspace.core.services.ISpaceManager; +import edu.asu.diging.vspace.core.services.ISpaceTextBlockManager; @Controller public class SpaceController { @@ -46,6 +47,9 @@ public class SpaceController { @Autowired private IExternalLinkManager externalLinkManager; + @Autowired + private ISpaceTextBlockManager spaceTextBlockManager; + @RequestMapping(STAFF_SPACE_PATH+"{id}") public String showSpace(@PathVariable String id, Model model) { @@ -59,6 +63,7 @@ public String showSpace(@PathVariable String id, Model model) { model.addAttribute("spaces", spaceManager.getAllSpaces()); model.addAttribute("display", spaceDisplayManager.getBySpace(space)); model.addAttribute("moduleList", moduleManager.getAllModules()); + model.addAttribute("spaceTextBlocks", spaceTextBlockManager.getSpaceTextBlockDisplays(id)); return "staff/spaces/space"; } @@ -74,7 +79,8 @@ public ResponseEntity> showSpaceLinks(@PathVariable String id responseData.put("spaceLinks", spaceLinkManager.getLinkDisplays(id)); responseData.put("externalLinks", externalLinkManager.getLinkDisplays(id)); responseData.put("moduleLinks", moduleLinkManager.getLinkDisplays(id)); + responseData.put("textBlocks", spaceTextBlockManager.getSpaceTextBlockDisplays(id)); return new ResponseEntity<>(responseData, HttpStatus.OK); } - + } diff --git a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/UpdateContentOrderController.java b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/UpdateContentOrderController.java index c510865cc..40339ce72 100644 --- a/vspace/src/main/java/edu/asu/diging/vspace/web/staff/UpdateContentOrderController.java +++ b/vspace/src/main/java/edu/asu/diging/vspace/web/staff/UpdateContentOrderController.java @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.mvc.support.RedirectAttributes; import edu.asu.diging.vspace.core.exception.BlockDoesNotExistException; import edu.asu.diging.vspace.core.model.impl.ContentBlock; diff --git a/vspace/src/main/resources/config.properties b/vspace/src/main/resources/config.properties index 5aacd55f2..40fb266c9 100644 --- a/vspace/src/main/resources/config.properties +++ b/vspace/src/main/resources/config.properties @@ -9,4 +9,5 @@ page_size=10 image_category_SPACE_BACKGROUND_IMAGE=Space Background Image image_category_SLIDE_IMAGE=Slide Image image_category_LINK_IMAGE=Link Image -buildNum=${buildNumber} \ No newline at end of file +buildNum=${buildNumber} +baseUrl=${baseUrl} \ No newline at end of file diff --git a/vspace/src/main/resources/exhibitionLanguages.properties b/vspace/src/main/resources/exhibitionLanguages.properties new file mode 100644 index 000000000..492b3ab2e --- /dev/null +++ b/vspace/src/main/resources/exhibitionLanguages.properties @@ -0,0 +1,197 @@ +{ +"languages": [ + { "code": "aa", "label": "Afar" }, + { "code": "ab", "label": "Abkhazian" }, + { "code": "ae", "label": "Avestan" }, + { "code": "af", "label": "Afrikaans" }, + { "code": "ak", "label": "Akan" }, + { "code": "am", "label": "Amharic" }, + { "code": "an", "label": "Aragonese" }, + { "code": "ar", "label": "Arabic" }, + { "code": "as", "label": "Assamese" }, + { "code": "av", "label": "Avaric" }, + { "code": "ay", "label": "Aymara" }, + { "code": "az", "label": "Azerbaijani" }, + { "code": "ba", "label": "Bashkir" }, + { "code": "be", "label": "Belarusian" }, + { "code": "bg", "label": "Bulgarian" }, + { "code": "bh", "label": "Bihari languages" }, + { "code": "bi", "label": "Bislama" }, + { "code": "bm", "label": "Bambara" }, + { "code": "bn", "label": "Bengali" }, + { "code": "bo", "label": "Tibetan" }, + { "code": "br", "label": "Breton" }, + { "code": "bs", "label": "Bosnian" }, + { "code": "ca", "label": "Catalan; Valencian" }, + { "code": "ce", "label": "Chechen" }, + { "code": "ch", "label": "Chamorro" }, + { "code": "co", "label": "Corsican" }, + { "code": "cr", "label": "Cree" }, + { "code": "cs", "label": "Czech" }, + { + "code": "cu", + "label": "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic" + }, + { "code": "cv", "label": "Chuvash" }, + { "code": "cy", "label": "Welsh" }, + { "code": "da", "label": "Danish" }, + { "code": "de", "label": "German" }, + { "code": "dv", "label": "Divehi; Dhivehi; Maldivian" }, + { "code": "dz", "label": "Dzongkha" }, + { "code": "ee", "label": "Ewe" }, + { "code": "el", "label": "Greek, Modern (1453-)" }, + { "code": "en", "label": "English" }, + { "code": "eo", "label": "Esperanto" }, + { "code": "es", "label": "Spanish; Castilian" }, + { "code": "et", "label": "Estonian" }, + { "code": "eu", "label": "Basque" }, + { "code": "fa", "label": "Persian" }, + { "code": "ff", "label": "Fulah" }, + { "code": "fi", "label": "Finnish" }, + { "code": "fj", "label": "Fijian" }, + { "code": "fo", "label": "Faroese" }, + { "code": "fr", "label": "French" }, + { "code": "fy", "label": "Western Frisian" }, + { "code": "ga", "label": "Irish" }, + { "code": "gd", "label": "Gaelic; Scomttish Gaelic" }, + { "code": "gl", "label": "Galician" }, + { "code": "gn", "label": "Guarani" }, + { "code": "gu", "label": "Gujarati" }, + { "code": "gv", "label": "Manx" }, + { "code": "ha", "label": "Hausa" }, + { "code": "he", "label": "Hebrew" }, + { "code": "hi", "label": "Hindi" }, + { "code": "ho", "label": "Hiri Motu" }, + { "code": "hr", "label": "Croatian" }, + { "code": "ht", "label": "Haitian; Haitian Creole" }, + { "code": "hu", "label": "Hungarian" }, + { "code": "hy", "label": "Armenian" }, + { "code": "hz", "label": "Herero" }, + { + "code": "ia", + "label": "Interlingua (International Auxiliary Language Association)" + }, + { "code": "id", "label": "Indonesian" }, + { "code": "ie", "label": "Interlingue; Occidental" }, + { "code": "ig", "label": "Igbo" }, + { "code": "ii", "label": "Sichuan Yi; Nuosu" }, + { "code": "ik", "label": "Inupiaq" }, + { "code": "io", "label": "Ido" }, + { "code": "is", "label": "Icelandic" }, + { "code": "it", "label": "Italian" }, + { "code": "iu", "label": "Inuktitut" }, + { "code": "ja", "label": "Japanese" }, + { "code": "jv", "label": "Javanese" }, + { "code": "ka", "label": "Georgian" }, + { "code": "kg", "label": "Kongo" }, + { "code": "ki", "label": "Kikuyu; Gikuyu" }, + { "code": "kj", "label": "Kuanyama; Kwanyama" }, + { "code": "kk", "label": "Kazakh" }, + { "code": "kl", "label": "Kalaallisut; Greenlandic" }, + { "code": "km", "label": "Central Khmer" }, + { "code": "kn", "label": "Kannada" }, + { "code": "ko", "label": "Korean" }, + { "code": "kr", "label": "Kanuri" }, + { "code": "ks", "label": "Kashmiri" }, + { "code": "ku", "label": "Kurdish" }, + { "code": "kv", "label": "Komi" }, + { "code": "kw", "label": "Cornish" }, + { "code": "ky", "label": "Kirghiz; Kyrgyz" }, + { "code": "la", "label": "Latin" }, + { "code": "lb", "label": "Luxembourgish; Letzeburgesch" }, + { "code": "lg", "label": "Ganda" }, + { "code": "li", "label": "Limburgan; Limburger; Limburgish" }, + { "code": "ln", "label": "Lingala" }, + { "code": "lo", "label": "Lao" }, + { "code": "lt", "label": "Lithuanian" }, + { "code": "lu", "label": "Luba-Katanga" }, + { "code": "lv", "label": "Latvian" }, + { "code": "mg", "label": "Malagasy" }, + { "code": "mh", "label": "Marshallese" }, + { "code": "mi", "label": "Maori" }, + { "code": "mk", "label": "Macedonian" }, + { "code": "ml", "label": "Malayalam" }, + { "code": "mn", "label": "Mongolian" }, + { "code": "mr", "label": "Marathi" }, + { "code": "ms", "label": "Malay" }, + { "code": "mt", "label": "Maltese" }, + { "code": "my", "label": "Burmese" }, + { "code": "na", "label": "Nauru" }, + { + "code": "nb", + "label": "Bokmål, Norwegian; Norwegian Bokmål" + }, + { "code": "nd", "label": "Ndebele, North; North Ndebele" }, + { "code": "ne", "label": "Nepali" }, + { "code": "ng", "label": "Ndonga" }, + { "code": "nl", "label": "Dutch; Flemish" }, + { "code": "nn", "label": "Norwegian Nynorsk; Nynorsk, Norwegian" }, + { "code": "no", "label": "Norwegian" }, + { "code": "nr", "label": "Ndebele, South; South Ndebele" }, + { "code": "nv", "label": "Navajo; Navaho" }, + { "code": "ny", "label": "Chichewa; Chewa; Nyanja" }, + { "code": "oc", "label": "Occitan (post 1500)" }, + { "code": "oj", "label": "Ojibwa" }, + { "code": "om", "label": "Oromo" }, + { "code": "or", "label": "Oriya" }, + { "code": "os", "label": "Ossetian; Ossetic" }, + { "code": "pa", "label": "Panjabi; Punjabi" }, + { "code": "pi", "label": "Pali" }, + { "code": "pl", "label": "Polish" }, + { "code": "ps", "label": "Pushto; Pashto" }, + { "code": "pt", "label": "Portuguese" }, + { "code": "qu", "label": "Quechua" }, + { "code": "rm", "label": "Romansh" }, + { "code": "rn", "label": "Rundi" }, + { "code": "ro", "label": "Romanian; Moldavian; Moldovan" }, + { "code": "ru", "label": "Russian" }, + { "code": "rw", "label": "Kinyarwanda" }, + { "code": "sa", "label": "Sanskrit" }, + { "code": "sc", "label": "Sardinian" }, + { "code": "sd", "label": "Sindhi" }, + { "code": "se", "label": "Northern Sami" }, + { "code": "sg", "label": "Sango" }, + { "code": "si", "label": "Sinhala; Sinhalese" }, + { "code": "sk", "label": "Slovak" }, + { "code": "sl", "label": "Slovenian" }, + { "code": "sm", "label": "Samoan" }, + { "code": "sn", "label": "Shona" }, + { "code": "so", "label": "Somali" }, + { "code": "sq", "label": "Albanian" }, + { "code": "sr", "label": "Serbian" }, + { "code": "ss", "label": "Swati" }, + { "code": "st", "label": "Sotho, Southern" }, + { "code": "su", "label": "Sundanese" }, + { "code": "sv", "label": "Swedish" }, + { "code": "sw", "label": "Swahili" }, + { "code": "ta", "label": "Tamil" }, + { "code": "te", "label": "Telugu" }, + { "code": "tg", "label": "Tajik" }, + { "code": "th", "label": "Thai" }, + { "code": "ti", "label": "Tigrinya" }, + { "code": "tk", "label": "Turkmen" }, + { "code": "tl", "label": "Tagalog" }, + { "code": "tn", "label": "Tswana" }, + { "code": "to", "label": "Tonga (Tonga Islands)" }, + { "code": "tr", "label": "Turkish" }, + { "code": "ts", "label": "Tsonga" }, + { "code": "tt", "label": "Tatar" }, + { "code": "tw", "label": "Twi" }, + { "code": "ty", "label": "Tahitian" }, + { "code": "ug", "label": "Uighur; Uyghur" }, + { "code": "uk", "label": "Ukrainian" }, + { "code": "ur", "label": "Urdu" }, + { "code": "uz", "label": "Uzbek" }, + { "code": "ve", "label": "Venda" }, + { "code": "vi", "label": "Vietlabelse" }, + { "code": "vo", "label": "Volapük" }, + { "code": "wa", "label": "Walloon" }, + { "code": "wo", "label": "Wolof" }, + { "code": "xh", "label": "Xhosa" }, + { "code": "yi", "label": "Yiddish" }, + { "code": "yo", "label": "Yoruba" }, + { "code": "za", "label": "Zhuang; Chuang" }, + { "code": "zh", "label": "Chinese" }, + { "code": "zu", "label": "Zulu" } +] +} \ No newline at end of file diff --git a/vspace/src/main/webapp/WEB-INF/views/exhibition/module.html b/vspace/src/main/webapp/WEB-INF/views/exhibition/module.html index 52d604115..f2153bf87 100644 --- a/vspace/src/main/webapp/WEB-INF/views/exhibition/module.html +++ b/vspace/src/main/webapp/WEB-INF/views/exhibition/module.html @@ -64,10 +64,10 @@ diff --git a/vspace/src/main/webapp/WEB-INF/views/exhibition/space.html b/vspace/src/main/webapp/WEB-INF/views/exhibition/space.html index 215c8d724..48d3936f7 100644 --- a/vspace/src/main/webapp/WEB-INF/views/exhibition/space.html +++ b/vspace/src/main/webapp/WEB-INF/views/exhibition/space.html @@ -233,7 +233,8 @@ $("#Module_1").css("margin-bottom", "60px"); } } - $("#space a").remove(); + $("#space a").remove(); + $(".Info_cz_Class").remove(); drawLinks(); } @@ -333,8 +334,9 @@ let spaceHeight = $("#bgImage").css("height"); $("#Module_1").css("height",spaceHeight); $( window ).resize(function() { - $("#space a").remove(); - drawLinks(); + $("#space a").remove(); + $(".Info_cz_Class").remove(); + drawLinks(); }); drawLinks(); toggleImgSize(false); @@ -343,16 +345,24 @@ function drawLinks() { var spaceLinks = [[${spaceLinks}]]; var moduleLinks = [[${moduleList}]]; + var isExhPreview =[[${isExhPreview}]]; var externalLinks = [[${externalLinkList}]]; + var spaceTextBlocks = [[${spaceTextBlocks}]]; var height = parseInt($("#bgImage").css("height")); var width = parseInt($("#bgImage").css("width")); let relativeHeight = ([(${display?.width})]/width)*height; - spaceLinks.forEach(function(link,index){ + spaceLinks.forEach(function(link,index) { if(link!=null){ var posX = parseInt($("#space").css('margin-left')) + $("#space").position().left; var posY = $("#space").position().top; var spaceLink = $(''); - spaceLink.attr("href", link.link.targetSpace.id); + if(isExhPreview=== true){ + spaceLink.attr("href",[[@{|/preview/${previewId}/space/|}]]+link.link.targetSpace.id); + } + else{ + spaceLink.attr("href", link.link.targetSpace.id); + } + var linkDisplay; if(link.type=="ALERT"){ linkDisplay = $(''); @@ -389,7 +399,12 @@ var posX = parseInt($("#space").css('margin-left')) + $("#space").position().left; var posY = $("#space").position().top; var moduleLink = $(''); - var moduleLinkURL = [[@{|/exhibit/${space?.id}/module/|}]]+link.link.module.id; + var moduleLinkURL = null; + if(isExhPreview=== true){ + moduleLinkURL = [[@{|/preview/${previewId}/${space?.id}/module/|}]]+link.link.module.id; + } else{ + moduleLinkURL = [[@{|/exhibit/${space?.id}/module/|}]]+link.link.module.id; + } moduleLink.attr("href", moduleLinkURL); var linkDisplay; if(link.type=="IMAGE" && link.image != null){ @@ -457,6 +472,22 @@ }); } }) + + spaceTextBlocks.forEach(function(block,index){ + if(block!=null){ + var posX = parseInt($("#space").css('margin-left')) + $("#space").position().left; + var posY = $("#space").position().top; + var heightText = (block.height*height)/100; + var widthText = (block.width*width)/100; + var textBlock = $(''); + textBlock.css('position', 'absolute'); + var linkPosX=(width*block.positionX)/[(${display.width})]; + var linkPosY=(height*block.positionY)/relativeHeight; + textBlock.css('left', linkPosX + posX); + textBlock.css('top', linkPosY + posY); + $("#space").append(textBlock); + } + }) } @@ -506,7 +537,7 @@ th:unless="${exhibitionConfig.customMessage != '' && exhibitionConfig.mode == 'OFFLINE'}">[[${exhibitionConfig.mode?.value}]]
-
+
×
    @@ -515,8 +546,16 @@
- +
+ × + +
+ @@ -595,4 +642,4 @@

- + \ No newline at end of file diff --git a/vspace/src/main/webapp/WEB-INF/views/layouts/navbar.html b/vspace/src/main/webapp/WEB-INF/views/layouts/navbar.html index f8a806500..7694fcd94 100644 --- a/vspace/src/main/webapp/WEB-INF/views/layouts/navbar.html +++ b/vspace/src/main/webapp/WEB-INF/views/layouts/navbar.html @@ -4,7 +4,7 @@ -
+
+
+ +
\ No newline at end of file diff --git a/vspace/src/main/webapp/WEB-INF/views/staff/dashboard/dashboard.html b/vspace/src/main/webapp/WEB-INF/views/staff/dashboard/dashboard.html index 27b72d6fc..92c34a168 100644 --- a/vspace/src/main/webapp/WEB-INF/views/staff/dashboard/dashboard.html +++ b/vspace/src/main/webapp/WEB-INF/views/staff/dashboard/dashboard.html @@ -47,12 +47,41 @@ /*[/]*/ +

Welcome back!

- View your most recent edits, or create new items. + + View your most recent edits, or create new items.

Spaces

diff --git a/vspace/src/main/webapp/WEB-INF/views/staff/exhibit/config.html b/vspace/src/main/webapp/WEB-INF/views/staff/exhibit/config.html index 8041016a7..9570eec5f 100644 --- a/vspace/src/main/webapp/WEB-INF/views/staff/exhibit/config.html +++ b/vspace/src/main/webapp/WEB-INF/views/staff/exhibit/config.html @@ -1,7 +1,7 @@ - + + } + +

Exhibition Configuration

- +
@@ -41,13 +66,28 @@

Exhibition Configuration

- + +
+
+
+ + +
+ +
+ +
diff --git a/vspace/src/main/webapp/WEB-INF/views/staff/modules/sequences/sequence.html b/vspace/src/main/webapp/WEB-INF/views/staff/modules/sequences/sequence.html index 14eb0e0c9..d85208c61 100644 --- a/vspace/src/main/webapp/WEB-INF/views/staff/modules/sequences/sequence.html +++ b/vspace/src/main/webapp/WEB-INF/views/staff/modules/sequences/sequence.html @@ -1,348 +1,696 @@ - - - - - - - - - - - -
- - -
-
-
-

Sequence: [[${sequence.name}]]

-

[[${sequence.description}]]

- - -
- - - - - -
- -
- -
- -
- - - -
- - -
-
- - + + + + + + + + + + + +
+ + +
+
+
+

Sequence: [[${sequence.name}]]

+

[[${sequence.description}]]

+ + +
+ + + + + +
+ +
+ +
+
+
+ + + +
+ +
+
+
+ + + + + + + + + + + + + +
+ + +
+
+
+

Sequence: [[${sequence.name}]]

+

[[${sequence.description}]]

+ + +
+ + + + + +
+ +
+ +
+
+
+ + + +
+ +
+
+
+ + diff --git a/vspace/src/main/webapp/WEB-INF/views/staff/modules/slides/slide.html b/vspace/src/main/webapp/WEB-INF/views/staff/modules/slides/slide.html index 3b146c8ae..810bbdc55 100644 --- a/vspace/src/main/webapp/WEB-INF/views/staff/modules/slides/slide.html +++ b/vspace/src/main/webapp/WEB-INF/views/staff/modules/slides/slide.html @@ -6,6 +6,8 @@ + @@ -952,6 +1355,8 @@

Slide: [[${sli +     +  

@@ -1009,6 +1414,31 @@
Are you sure you want to delete this
+ +
+ +
+
+

[[${contents.video.title}]]

+
+ + +
+ + + + + + + +

[[${contents.text}]]

diff --git a/vspace/src/main/webapp/WEB-INF/views/staff/spaces/space.html b/vspace/src/main/webapp/WEB-INF/views/staff/spaces/space.html index 088a20ff7..8fcb2c646 100644 --- a/vspace/src/main/webapp/WEB-INF/views/staff/spaces/space.html +++ b/vspace/src/main/webapp/WEB-INF/views/staff/spaces/space.html @@ -1,3 +1,4 @@ + '); + setLinkPosition(textBlock,block,false,isModal,false, posX, posY, posXModal, posYModal, true); + $(divId).append(textBlock); + if(spanId === "textBlockId-"){ + $('#'+spanId+block.spaceTextBlock.id).css('cursor', 'pointer'); + $('#'+spanId+block.spaceTextBlock.id).click(function(e) { + var blockData = $('#'+spanId+block.spaceTextBlock.id).data(); + makeTextBlockEditable(blockData["blockid"],blockData["linkId"],blockData["text"],block.positionX,block.positionY,blockData["width"],blockData["height"]); + }); + } + + if(block.spaceTextBlock.id === selectedTextBlockId) { + var textModalBlock = $("#textModalBlockId-"+selectedTextBlockId).find("textarea")[0]; + + tHeight = textModalBlock.clientHeight; + tWidth = textModalBlock.clientWidth; + + var height = modalBgImageHeight; + var width = modalBgImageWidth; + textModalBlock.style["resize"] = "both"; + textModalBlock.onmouseup = function (e) { + if (tHeight !== textModalBlock.clientHeight || tWidth !== textModalBlock.clientWidth ) { + tHeight = textModalBlock.clientHeight; + tWidth = textModalBlock.clientWidth; + let percentileHeight = (tHeight*100)/height; + let percentileWidth = (tWidth*100)/width; + $("#textBoxWidthIDEdit").val(percentileWidth); + $("#textBoxHeightIDEdit").val(percentileHeight); + $("#textContentIDForEdit").val(textModalBlock.value); + } + }; + } + } +} + function drawLinks(){ $(".Info_cz_Class").remove(); $(".imageLink").remove(); $(".alertLink").remove(); $(".ellipse_class").remove(); $(".unpublishedSpaceClass").remove(); + $(".textBlockClass").remove(); $(".deletedSpaceClass").remove(); $.ajax({ @@ -215,6 +261,8 @@ var spaceLinks = data['spaceLinks']; var externalLinks = data['externalLinks']; var moduleLinks = data['moduleLinks']; + var textBlocks = data['textBlocks']; + var posXModal = $("#bgImage").position().left; var posYModal = $("#bgImage").position().top; var posX = $("#main-bgImage").position().left; @@ -253,11 +301,73 @@ var divId = "#main-space"; generateExternalLinks(link,spanId,divId,false, posX, posY, posXModal, posYModal); }) + + textBlocks.forEach(function(block,index){ + var spanId= "textModalBlockId-"; + var divId = "#space"; + var imageHeight = modalBgImageHeight; + var imageWidth = modalBgImageWidth; + generateTextBlock(block,spanId,divId,true, posX, posY, posXModal, posYModal, imageHeight, imageWidth); + }) + + textBlocks.forEach(function(block,index){ + var spanId= "textBlockId-"; + var divId = "#main-space"; + var imageHeight = parseInt($("#main-bgImage").css("height")); + var imageWidth = parseInt($("#main-bgImage").css("width")); + generateTextBlock(block,spanId,divId,false, posX, posY, posXModal, posYModal, imageHeight, imageWidth); + }) } }); } //--------- show links functions -------------- +function showTextBlock(textBlock, show){ + $("#textB").remove(); + $("#text").remove(); + var posX = $("#bgImage").position().left; + var posY = $("#bgImage").position().top; + var imageHeight = modalBgImageHeight; + var imageWidth = modalBgImageWidth; + var textArea = $(""); + textArea.css('width', (textBlock["width"]*imageWidth)/100); + textArea.css('height', (textBlock["height"]*imageHeight)/100); + textArea.css('resize', 'both'); + textArea.text(textBlock["text"]); + var spaceTextBlock; + spaceTextBlock = $(''); + spaceTextBlock.css('position', 'absolute'); + spaceTextBlock.css('left', textBlock["x"] + posX); + spaceTextBlock.css('top', textBlock["y"] + posY); + spaceTextBlock.css('font-size', "12px"); + + if (textBlock["id"]) { + spaceTextBlock.attr("data-link-id", textBlock["id"]); + spaceTextBlock.css('cursor', 'pointer'); + spaceTextBlock.click(function(e) { + makeTextBlockEditable(textBlock["displayId"], textBlock["id"], textBlock["text"], textBlock["x"], textBlock["y"], textBlock["width"], textBlock["height"]); + }); + } + spaceTextBlock.append(textArea); + $("#space").append(spaceTextBlock); +} + +function showTextBlockEdit(textBlock){ + textBlock["x"]=storeX; + textBlock["y"]=storeY; + var selectedClass = '#textModalBlockId-'+selectedTextBlockId; + var selectedTextArea = "#textModalBlockId-"+selectedTextBlockId+" .textBlock"; + var posX = $("#bgImage").position().left; + var posY = $("#bgImage").position().top; + var imageHeight = modalBgImageHeight; + var imageWidth = modalBgImageWidth; + $(selectedClass).css('left', textBlock["x"]+posX); + $(selectedClass).css('top', textBlock["y"]); + $(selectedTextArea).css('width', (textBlock["width"]*imageWidth)/100); + $(selectedTextArea).css('height', (textBlock["height"]*imageHeight)/100); + $(selectedTextArea).text(textBlock["text"]); +} + function showSpaceLink(spaceLink, show, x, y) { $("#space_label").remove(); $("#link").remove(); @@ -384,6 +494,7 @@ updateLinkProperties(selectedLinkClass,selectedLabelClass,moduleLink["rotation"],posX,posY,moduleLink["moduleLinkLabel"]); } + function showSpaceLinkEdit(spaceLink, show, posX, posY) { spaceLink["x"]=storeX; spaceLink["y"]=storeY; @@ -442,6 +553,7 @@ $("#editExternalLinkInfo").hide(); $("#editSpaceLinkInfo").hide(); $("#editModuleLinkInfo").hide(); + $("#editTextBlockInfo").hide(); $("#createExternalLinkAlert").hide(); $("#createSpaceLinkAlert").hide(); $("#createModuleLinkAlert").hide(); @@ -538,6 +650,26 @@ return info; } +function createTextBlockInfo() { + var info = {}; + info["x"] = storeX; + info["y"] = storeY; + info["text"] = $("#textContentID").val(); + info["height"] = $("#textBoxHeightID").val(); + info["width"] = $("#textBoxWidthID").val(); + return info; +} + +function editTextBlockInfo() { + var info = {}; + info["x"] = storeX; + info["y"] = storeY; + info["text"] = $("#textContentIDForEdit").val(); + info["height"] = $("#textBoxHeightIDEdit").val(); + info["width"] = $("#textBoxWidthIDEdit").val(); + return info; +} + function editModuleLinkInfo() { var info = {}; info["x"] = storeX; @@ -610,6 +742,8 @@ drawLinks(); $("#space").css("display", "-webkit-box"); $(formToShow).css("display", "flex"); + modalBgImageHeight = parseInt($("#bgImage").css("height")); + modalBgImageWidth = parseInt($("#bgImage").css("width")); } function makeModuleLinksEditable(moduleLinkName, moduleLinkId, rotation, selectedModuleId, posXEdit, posYEdit, displayLinkId, linkType) { @@ -636,7 +770,7 @@ $("#bgImage").on("click", function(e){ e.preventDefault(); var posX = $(this).position().left; - var posY = $(this).position().top; + var posY = $(this).position().top; storeX = e.pageX - $(this).offset().left; storeY = e.pageY - $(this).offset().top + 25; showModuleLinkEdit(editModuleLinkInfo(), false, storeX,storeY); @@ -656,8 +790,9 @@ $("#externalLinkLabelEdit").val(linkName); $("#externalLinkIdValueEdit").val(linkId); $("#externalLinkURLEdit").val(externalLinkURL); - $('#extTypeEdit option[value="'+linkType+'"]').attr("selected", "selected"); - $('#extTabOpenEdit option[value="'+tabOpenType+'"]').attr("selected", "selected"); + $('#extTypeEdit option[value="'+linkType+'"]').prop("selected", true); + $('#extTabOpenEdit option[value="'+tabOpenType+'"]').prop("selected",true); + resetHighlighting(); $('[data-link-id="' + linkId + '"]').css("color", "#c1bb88"); @@ -677,6 +812,29 @@ displayForms("#editExternalLinkInfo"); } +function makeTextBlockEditable(blockDisplayId,blockId,text,posX,posY,width,height){ + selectedTextBlockId=blockId; + storeX=posX; + storeY=posY; + $("#textBlockId").val(blockId); + $("#textBlockXEdit").val(posX); + $("#textBlockYEdit").val(posY); + $("#textBlockDisplayId").val(blockDisplayId); + $("#textBoxWidthIDEdit").val(width); + $("#textBoxHeightIDEdit").val(height); + $("#textContentIDForEdit").val(text); + resetHighlighting(); + $("#bgImage").on("click", function(e){ + e.preventDefault(); + var posX = $(this).position().left; + var posY = $(this).position().top; + storeX = e.pageX - $(this).offset().left; + storeY = e.pageY - $(this).offset().top + 25; + showTextBlockEdit(editTextBlockInfo()); + }); + hideLinkInfoTabs(); + displayForms("#editTextBlockInfo"); +} function resetHighlighting() { // reset icon links $('[data-link-id]').css("color", "red"); @@ -686,7 +844,43 @@ $('div[data-link-id]').addClass("alert-primary"); // reset image links - $('img[data-link-id]').css("border-width", "0"); + $('img[data-link-id]').css("border-width", "0"); +} + +function getTextArea(x,y) { + var posX = $("#bgImage").position().left; + var posY = $("#bgImage").position().top; + var text = $(''); + text.css('position', 'absolute'); + text.css('left', x + posX); + text.css('top', y); + $("#space").append(text); + + var textB = $('#textB')[0], + tHeight = textB.clientHeight, + tWidth = textB.clientWidth; + + var height = modalBgImageHeight; + var width = modalBgImageWidth; + + $("#textBoxWidthID").val(tWidth); + $("#textBoxHeightID").val(tHeight); + textB.onmouseup = function (e) { + if (tHeight !== textB.clientHeight || tWidth !== textB.clientWidth ) { + tHeight = textB.clientHeight; + tWidth = textB.clientWidth; + let percentileHeight = (tHeight*100)/height; + let percentileWidth = (tWidth*100)/width; + $("#textBoxWidthID").val(percentileWidth); + $("#textBoxHeightID").val(percentileHeight); + $("#textContentID").val(textB.value); + } + }; + var percentileHeight = (tHeight*100)/height; + var percentileWidth = (tWidth*100)/width; + $("#textBoxWidthID").val(percentileWidth); + $("#textBoxHeightID").val(percentileHeight); + $("#textContentID").val(textB.value); } $(function(){ @@ -706,6 +900,27 @@ }); // -------- buttons that open modals (e.g. to create space links) ------ + + $("#addTextBlock").click(function(e){ + hideLinkInfoTabs(); + $("#changeBgImgAlert").hide(); + $("#bgImage").off("click"); + $("#bgImage").on("click", function(e){ + e.preventDefault(); + $("#external-arrow").remove(); + $("#space_label").remove(); + $("#link").remove(); + $("#text").remove(); + var posX = $(this).position().left; + var posY = $(this).position().top; + storeX = e.pageX - $(this).offset().left; + storeY = e.pageY - $(this).offset().top + 25; + getTextArea(storeX,storeY); + }); + hideLinkInfoTabs(); + displayForms("#addTextFormInfo"); + }); + $("#addSpaceLinkButton").click(function(e) { $("#createExternalLinkAlert").hide(); $("#changeBgImgAlert").hide(); @@ -739,7 +954,6 @@ var posY = $(this).position().top; storeX = e.pageX - $(this).offset().left; storeY = e.pageY - $(this).offset().top + 25; - showModuleLink(createModuleLinkInfo(), false, storeX, storeY); }); hideLinkInfoTabs(); @@ -760,7 +974,6 @@ var posY = $(this).position().top; storeX = e.pageX - $(this).offset().left; storeY = e.pageY - $(this).offset().top + 25; - showExternalLinks(createExternalLinkInfo(), false, storeX, storeY); }); hideLinkInfoTabs(); @@ -776,6 +989,97 @@ // ----------- submit buttons (e.g. to create space links) ------------------ + + $("#addTextBlockBtn").click(function(e) { + e.preventDefault(); + $("#space").scrollTop(0); + if (storeX == undefined || storeY == undefined) { + $("#errorMsg").text("Please click on the image to specify where the new block should be located.") + $('#errorAlert').show(); + return; + } + + $("#addTextX").val(storeX); + $("#addTextY").val(storeY - 25); + + var form = $("#addTextForm"); + var formData = new FormData(form[0]); + + var textBlockInfo = createTextBlockInfo(); + + $.ajax({ + type: "POST", + url: "[(@{'/staff/space/'+${space.id}+'/textblock?'+${_csrf.parameterName}+'='+${_csrf.token}})]", + cache : false, + contentType : false, + processData : false, + enctype: 'multipart/form-data', + data: formData, + beforeSend: function () { + $(".saveLoader").show(); + }, + complete: function () { + $(".saveLoader").hide(); + }, + success: function(data) { + var linkData = JSON.parse(data); + $("#bgImage").off("click"); + textBlockInfo["id"] = linkData["id"]; + textBlockInfo["displayId"]=linkData["displayId"]; + textBlockInfo["x"]=linkData["x"]; + textBlockInfo["y"]=linkData["y"]; + showTextBlock(textBlockInfo, true); + $("#errorMsg").text(""); + $('#errorAlert').hide(); + $("#addTextFormInfo").hide(); + $("#space").css("display", "none"); + form[0].reset(); + drawLinks(); + } + }); + }); + + $("#editTextBlockBtn").click(function(e) { + e.preventDefault(); + $("#space").scrollTop(0); + var blockId = $("#textBlockId").val(); + if (storeX == undefined || storeY == undefined) { + $("#errorMsg").text("Please click on the image to specify where the new link should be located.") + $('#errorAlert').show(); + return; + } + var linkedTextBlock = $("#textBlockId").val(); + $("#textBlockXEdit").val(storeX); + $("#textBlockYEdit").val(storeY - 25); + var form = $("#editTextBlockForm"); + var formData = new FormData(form[0]); + var textBlockInfo = editTextBlockInfo(); + $.ajax({ + type: "POST", + url: "[(@{'/staff/space/link/textblock/'+${space.id}+'?'+${_csrf.parameterName}+'='+${_csrf.token}})]", + cache: false, + contentType : false, + processData : false, + enctype: 'multipart/form-data', + data: formData, + success: function(data) { + var linkData = JSON.parse(data); + $("#bgImage").off("click"); + textBlockInfo["id"] = linkData["id"]; + textBlockInfo["text"]=linkData["textContent"]; + textBlockInfo["x"]=linkData["x"]; + textBlockInfo["y"]=linkData["y"]; + textBlockInfo["height"]=linkData["height"]; + textBlockInfo["width"]=linkData["width"]; + showTextBlockEdit(textBlockInfo); + hideLinkInfoTabs(); + $("#space").css("display", "none"); + selectedTextBlockId=undefined; + drawLinks(); + } + }); + }); + $("#createSpaceLinkBtn").click(function(e) { e.preventDefault(); $('#errorAlert').hide(); @@ -789,7 +1093,6 @@ $('#errorAlert').show(); return; } - if (spaceName == undefined || spaceName == "Choose...") { $("#errorMsg").text("Please select a space in Linked Space dropdown.") $('#errorAlert').show(); @@ -1102,7 +1405,6 @@ var externalLinkLabel = $("#externalLinkLabel").val(); var type = $("#extType option:selected").text(); - if (externalLink == undefined || externalLink == "") { $("#errorMsg").text("Please provide the link to the external link.") $('#errorAlert').show(); @@ -1234,6 +1536,26 @@ } }); }); + + $("#deleteTextBlockButton").click(function() { + var blockId = $("#textBlockId").val(); + $.ajax({ + url: "[(@{'/staff/space/'+${space.id}+'/textblock/'})]"+ blockId + '?[(${_csrf.parameterName})]=[(${_csrf.token})]', + method: "DELETE", + beforeSend: function () { + $(".saveLoader").show(); + }, + complete: function () { + $(".saveLoader").hide(); + }, + success:function(data) { + $('[data-link-id="' + blockId + '"]').remove(); + hideLinkInfoTabs(); + $("#space").css("display", "none"); + drawLinks(); + } + }); + }); $("#closeAlert").click(function() { $('#errorAlert').hide(); @@ -1251,7 +1573,7 @@ showExternalLinks(externalLink); }); - // space links + // space links $('#spaceLinkRotation').change(function() { $('#link').css('transform', 'rotate(' +$('#spaceLinkRotation').val()+ 'deg)'); }); @@ -1306,6 +1628,7 @@ }); // ------------ Cancel buttons ----------------- + $(".cancelSpaceLinkBtn").click(function() { storeX = null; storeY = null; @@ -1348,6 +1671,19 @@ $("#ext_label").remove(); $("#space").hide(); $("#createExternalLinkAlert").hide(); + $("#bgImage").off("click"); + $('#errorAlert').hide(); + drawLinks(); + }); + + $(".cancelAddTextBlockBtn").click(function() { + storeX = null; + storeY = null; + $("#space").scrollTop(0); + $("#textContentID").val(""); + $("span#text").remove(); + $("#space").hide(); + $("#addTextFormInfo").hide(); $('#errorAlert').hide(); $("#bgImage").off("click"); drawLinks(); @@ -1392,6 +1728,18 @@ $("#editExternalLinkInfo").hide(); drawLinks(); }); + + $("#closeEditTextBlockInfo").click(function(e) { + e.preventDefault(); + selectedTextBlockId=undefined; + $("#textBoxHeightIDEdit").val(""); + $("#textBoxWidthIDEdit").val(""); + $("#textContentIDForEdit").val(""); + resetHighlighting(); + $("#space").hide(); + $("#editTextBlockInfo").hide(); + drawLinks(); + }); });