mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 14:12:11 +00:00
Merge branch 'master' into ubilabs--rcapp--develop
This commit is contained in:
commit
f6f6a1d1b8
91 files changed
+5652
-3398
No files matched your search
@@ -1,47 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.dashboards.gwt"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9998 com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||
</launchConfiguration>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.dashboards.gwt"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9998 com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||
</launchConfiguration>
|
||||
+4
-3
@@ -7,6 +7,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class EventLogo extends Image {
|
||||
|
||||
@@ -22,9 +23,9 @@ public class EventLogo extends Image {
|
||||
sailingServiceAsync.getEventById(eventUUID, true, new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onSuccess(final EventDTO event) {
|
||||
final String logoUrl = event.getLogoImageURL();
|
||||
if (logoUrl != null) {
|
||||
eventLogo.getElement().setAttribute("src", logoUrl);
|
||||
final ImageDTO logo = event.getLogoImage();
|
||||
if (logo != null) {
|
||||
eventLogo.getElement().setAttribute("src", logo.getSourceRef());
|
||||
} else {
|
||||
eventLogo.getElement().getStyle().setVisibility(Visibility.HIDDEN);
|
||||
}
|
||||
|
||||
Executable → Regular
+2187
-2065
File diff suppressed because it is too large.
Load diff
+12
-1
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.domain.persistence.impl;
|
||||
|
||||
|
||||
public enum FieldNames {
|
||||
// general:
|
||||
TIME_AS_MILLIS, KNOT_SPEED, DEGREE_BEARING, LAT_DEG, LNG_DEG,
|
||||
@@ -18,6 +19,8 @@ public enum FieldNames {
|
||||
EVENT_IMAGE_URLS,
|
||||
EVENT_VIDEO_URLS,
|
||||
EVENT_SPONSOR_IMAGE_URLS,
|
||||
EVENT_IMAGES,
|
||||
EVENT_VIDEOS,
|
||||
EVENT_OFFICIAL_WEBSITE_URL,
|
||||
EVENT_LOGO_IMAGE_URL,
|
||||
|
||||
@@ -128,5 +131,13 @@ public enum FieldNames {
|
||||
RACE_LOG_ADDITIONAL_SCORING_INFORMATION_TYPE,
|
||||
|
||||
// Handicap factors
|
||||
REGATTA_LOG_TIME_ON_TIME_FACTOR, REGATTA_LOG_TIME_ON_DISTANCE_SECONDS_ALLOWANCE_PER_NAUTICAL_MILE, REGATTA_RANKING_METRIC, REGATTA_RANKING_METRIC_TYPE
|
||||
REGATTA_LOG_TIME_ON_TIME_FACTOR, REGATTA_LOG_TIME_ON_DISTANCE_SECONDS_ALLOWANCE_PER_NAUTICAL_MILE, REGATTA_RANKING_METRIC, REGATTA_RANKING_METRIC_TYPE,
|
||||
|
||||
// image fields
|
||||
IMAGE_URL, IMAGE_LOCALE, IMAGE_TITLE, IMAGE_SUBTITLE, IMAGE_MIMETYPE, IMAGE_COPYRIGHT, IMAGE_CREATEDATDATE,
|
||||
IMAGE_WIDTH_IN_PX, IMAGE_HEIGHT_IN_PX, IMAGE_TAGS,
|
||||
|
||||
// video fields
|
||||
VIDEO_URL, VIDEO_LOCALE, VIDEO_TITLE, VIDEO_SUBTITLE, VIDEO_MIMETYPE, VIDEO_COPYRIGHT, VIDEO_CREATEDATDATE,
|
||||
VIDEO_TAGS, VIDEO_THUMBNAIL_URL, VIDEO_LENGTH_IN_SECONDS;
|
||||
}
|
||||
+56
-1
@@ -112,6 +112,8 @@ import com.sap.sse.common.TypeBasedServiceFinder;
|
||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
private static Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName());
|
||||
@@ -514,6 +516,10 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
serverCollection.remove(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* StoreEvent() uses some deprecated methods of event to keep backward compatibility.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void storeEvent(Event event) {
|
||||
DBCollection eventCollection = database.getCollection(CollectionNames.EVENTS.name());
|
||||
@@ -546,6 +552,18 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
sponsorImageURLs.add(sponsorImageURL.toString());
|
||||
}
|
||||
eventDBObject.put(FieldNames.EVENT_SPONSOR_IMAGE_URLS.name(), sponsorImageURLs);
|
||||
BasicDBList images = new BasicDBList();
|
||||
for (ImageDescriptor image : event.getImages()) {
|
||||
DBObject imageObject = createImageObject(image);
|
||||
images.add(imageObject);
|
||||
}
|
||||
eventDBObject.put(FieldNames.EVENT_IMAGES.name(), images);
|
||||
BasicDBList videos = new BasicDBList();
|
||||
for (VideoDescriptor video: event.getVideos()) {
|
||||
DBObject videoObject = createVideoObject(video);
|
||||
videos.add(videoObject);
|
||||
}
|
||||
eventDBObject.put(FieldNames.EVENT_VIDEOS.name(), videos);
|
||||
eventCollection.update(query, eventDBObject, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE);
|
||||
// now store the links to the leaderboard groups
|
||||
DBCollection linksCollection = database.getCollection(CollectionNames.LEADERBOARD_GROUP_LINKS_FOR_EVENTS.name());
|
||||
@@ -1208,7 +1226,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
DBObject entry = (DBObject) JSON.parse(json.toString());
|
||||
collection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeAllCompetitors() {
|
||||
logger.info("Removing all persistent competitor info");
|
||||
@@ -1403,4 +1421,41 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
result.put(FieldNames.REGATTA_LOG_TIME_ON_DISTANCE_SECONDS_ALLOWANCE_PER_NAUTICAL_MILE.name(), event.getTimeOnDistanceAllowancePerNauticalMile().asSeconds());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
private DBObject createImageObject(ImageDescriptor image) {
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.IMAGE_URL.name(), image.getURL().toString());
|
||||
result.put(FieldNames.IMAGE_LOCALE.name(), image.getLocale() != null ? image.getLocale().toLanguageTag() : null);
|
||||
result.put(FieldNames.IMAGE_TITLE.name(), image.getTitle());
|
||||
result.put(FieldNames.IMAGE_SUBTITLE.name(), image.getSubtitle());
|
||||
result.put(FieldNames.IMAGE_COPYRIGHT.name(), image.getCopyright());
|
||||
result.put(FieldNames.IMAGE_WIDTH_IN_PX.name(), image.getWidthInPx());
|
||||
result.put(FieldNames.IMAGE_HEIGHT_IN_PX.name(), image.getHeightInPx());
|
||||
storeTimePoint(image.getCreatedAtDate(), result, FieldNames.IMAGE_CREATEDATDATE);
|
||||
BasicDBList tags = new BasicDBList();
|
||||
for (String tag : image.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.put(FieldNames.IMAGE_TAGS.name(), tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
private DBObject createVideoObject(VideoDescriptor video) {
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.VIDEO_URL.name(), video.getURL().toString());
|
||||
result.put(FieldNames.VIDEO_LOCALE.name(), video.getLocale() != null ? video.getLocale().toLanguageTag() : null);
|
||||
result.put(FieldNames.VIDEO_THUMBNAIL_URL.name(), video.getThumbnailURL() != null ? video.getThumbnailURL().toString() : null);
|
||||
result.put(FieldNames.VIDEO_TITLE.name(), video.getTitle());
|
||||
result.put(FieldNames.VIDEO_SUBTITLE.name(), video.getSubtitle());
|
||||
result.put(FieldNames.VIDEO_MIMETYPE.name(), video.getMimeType() != null ? video.getMimeType().name() : null);
|
||||
result.put(FieldNames.VIDEO_COPYRIGHT.name(), video.getCopyright());
|
||||
result.put(FieldNames.VIDEO_LENGTH_IN_SECONDS.name(), video.getLengthInSeconds());
|
||||
storeTimePoint(video.getCreatedAtDate(), result, FieldNames.VIDEO_CREATEDATDATE);
|
||||
BasicDBList tags = new BasicDBList();
|
||||
for (String tag : video.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.put(FieldNames.VIDEO_TAGS.name(), tags);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+12
-52
@@ -1,19 +1,20 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.Renamable;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.WithMedia;
|
||||
|
||||
/**
|
||||
* Base interface for an Event consisting of all static information, which might be shared
|
||||
* by the server and an Android application.
|
||||
*/
|
||||
public interface EventBase extends Named, WithDescription, Renamable, WithID {
|
||||
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
|
||||
|
||||
void setDescription(String description);
|
||||
|
||||
@@ -41,6 +42,7 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID {
|
||||
void setPublic(boolean isPublic);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to image resources that can be
|
||||
* used to represent the event, e.g., on a web page.
|
||||
*
|
||||
@@ -48,70 +50,29 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID {
|
||||
*/
|
||||
Iterable<URL> getImageURLs();
|
||||
|
||||
void addImageURL(URL imageURL);
|
||||
|
||||
void removeImageURL(URL imageURL);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
|
||||
*
|
||||
* @return the sponsors' logos; always non-<code>null</code> but possibly empty
|
||||
*/
|
||||
Iterable<URL> getSponsorImageURLs();
|
||||
|
||||
void addSponsorImageURL(URL sponsorImageURL);
|
||||
|
||||
void removeSponsorImageURL(URL sponsorImageURL);
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getSponsorImageURLs() current contents of the sponsorship image URL sequence} by the image URLs in
|
||||
* <code>sponsorImageURLs</code>.
|
||||
*
|
||||
* @param sponsorImageURLs
|
||||
* if <code>null</code>, the internal sequence of sponsorship image URLs is cleared but remains valid (non-
|
||||
* <code>null</code>)
|
||||
*/
|
||||
void setSponsorImageURLs(Iterable<URL> sponsorImageURLs);
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* An optional logo image; may return <code>null</code>.
|
||||
*/
|
||||
URL getLogoImageURL();
|
||||
|
||||
void setLogoImageURL(URL logoImageURL);
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getImageURLs() current contents of the image URL sequence} by the image URLs in
|
||||
* <code>imageURLs</code>.
|
||||
*
|
||||
* @param imageURLs
|
||||
* if <code>null</code>, the internal sequence of image URLs is cleared but remains valid (non-
|
||||
* <code>null</code>)
|
||||
*/
|
||||
void setImageURLs(Iterable<URL> imageURLs);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
|
||||
* used to represent the event, e.g., on a web page.
|
||||
*
|
||||
* @return a non-<code>null</code> value which may be empty
|
||||
*/
|
||||
Iterable<URL> getVideoURLs();
|
||||
|
||||
void addVideoURL(URL videoURL);
|
||||
|
||||
void removeVideoURL(URL videoURL);
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getVideoURLs() current contents of the video URL sequence} by the video URLs in
|
||||
* <code>videoURLs</code>.
|
||||
*
|
||||
* @param videoURLs
|
||||
* if <code>null</code>, the internal sequence of image URLs is cleared but remains valid (non-
|
||||
* <code>null</code>)
|
||||
*/
|
||||
void setVideoURLs(Iterable<URL> videoURLs);
|
||||
|
||||
/**
|
||||
* @return the URL of the event's official web site, or <code>null</code> if such a site does not exist or its URL
|
||||
* is not known
|
||||
@@ -122,9 +83,8 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID {
|
||||
|
||||
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
|
||||
|
||||
/**
|
||||
* For the images references by the image URLs in {@link #getImageURLs()}, {@link #getSponsorImageURLs()} and {@link #getLogoImageURL()}
|
||||
* determines the image dimensions.
|
||||
*/
|
||||
ImageSize getImageSize(URL imageURL) throws InterruptedException, ExecutionException;
|
||||
/**
|
||||
* Sets and converts all event images and videos from the old URL based format to the new richer format
|
||||
* */
|
||||
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
|
||||
}
|
||||
+204
-82
@@ -3,7 +3,10 @@ package com.sap.sailing.domain.base.impl;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
@@ -11,6 +14,16 @@ import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MediaDescriptor;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.MediaUtils;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
|
||||
public abstract class EventBaseImpl implements EventBase {
|
||||
private static final long serialVersionUID = -5749964088848611074L;
|
||||
@@ -22,11 +35,9 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
private final UUID id;
|
||||
private TimePoint startDate;
|
||||
private TimePoint endDate;
|
||||
private ConcurrentLinkedQueue<URL> imageURLs;
|
||||
private ConcurrentLinkedQueue<URL> videoURLs;
|
||||
private ConcurrentLinkedQueue<URL> sponsorImageURLs;
|
||||
private URL logoImageURL;
|
||||
private URL officialWebsiteURL;
|
||||
private ConcurrentLinkedQueue<ImageDescriptor> images;
|
||||
private ConcurrentLinkedQueue<VideoDescriptor> videos;
|
||||
|
||||
protected EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, UUID id) {
|
||||
this(name, startDate, endDate, new VenueImpl(venueName), isPublic, id);
|
||||
@@ -43,21 +54,17 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
this.endDate = endDate;
|
||||
this.venue = venue;
|
||||
this.isPublic = isPublic;
|
||||
this.imageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
this.videoURLs = new ConcurrentLinkedQueue<URL>();
|
||||
this.sponsorImageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
this.images = new ConcurrentLinkedQueue<ImageDescriptor>();
|
||||
this.videos = new ConcurrentLinkedQueue<VideoDescriptor>();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
if (imageURLs == null) {
|
||||
imageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
if (images == null) {
|
||||
images = new ConcurrentLinkedQueue<ImageDescriptor>();
|
||||
}
|
||||
if (videoURLs == null) {
|
||||
videoURLs = new ConcurrentLinkedQueue<URL>();
|
||||
}
|
||||
if (sponsorImageURLs == null) {
|
||||
sponsorImageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
if (videos == null) {
|
||||
videos = new ConcurrentLinkedQueue<VideoDescriptor>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,87 +135,41 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
|
||||
@Override
|
||||
public Iterable<URL> getImageURLs() {
|
||||
return Collections.unmodifiableCollection(imageURLs);
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
for (ImageDescriptor image : images) {
|
||||
if (!image.hasTag(MediaTagConstants.SPONSOR) && !image.hasTag(MediaTagConstants.LOGO)) {
|
||||
result.add(image.getURL());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addImageURL(URL imageURL) {
|
||||
if (!imageURLs.contains(imageURL)) {
|
||||
imageURLs.add(imageURL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImageURL(URL imageURL) {
|
||||
imageURLs.remove(imageURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageURLs(Iterable<URL> imageURLs) {
|
||||
this.imageURLs.clear();
|
||||
if (imageURLs != null) {
|
||||
Util.addAll(imageURLs, this.imageURLs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<URL> getVideoURLs() {
|
||||
return Collections.unmodifiableCollection(videoURLs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVideoURL(URL videoURL) {
|
||||
if (!videoURLs.contains(videoURL)) {
|
||||
videoURLs.add(videoURL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVideoURL(URL videoURL) {
|
||||
videoURLs.remove(videoURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoURLs(Iterable<URL> videoURLs) {
|
||||
this.videoURLs.clear();
|
||||
if (videoURLs != null) {
|
||||
Util.addAll(videoURLs, this.videoURLs);
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
for(VideoDescriptor video: videos) {
|
||||
result.add(video.getURL());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<URL> getSponsorImageURLs() {
|
||||
return Collections.unmodifiableCollection(sponsorImageURLs);
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
for(MediaDescriptor media : findMediaWithTag(images, MediaTagConstants.SPONSOR)) {
|
||||
result.add(media.getURL());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSponsorImageURL(URL sponsorImageURL) {
|
||||
if (!sponsorImageURLs.contains(sponsorImageURL)) {
|
||||
sponsorImageURLs.add(sponsorImageURL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSponsorImageURL(URL sponsorImageURL) {
|
||||
sponsorImageURLs.remove(sponsorImageURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSponsorImageURLs(Iterable<URL> sponsorImageURLs) {
|
||||
this.sponsorImageURLs.clear();
|
||||
if (sponsorImageURLs != null) {
|
||||
Util.addAll(sponsorImageURLs, this.sponsorImageURLs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getLogoImageURL() {
|
||||
return logoImageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogoImageURL(URL logoImageURL) {
|
||||
this.logoImageURL = logoImageURL;
|
||||
URL result = null;
|
||||
ImageDescriptor media = findImageWithTag(MediaTagConstants.LOGO);
|
||||
if(media != null) {
|
||||
result = media.getURL();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,4 +182,165 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
this.officialWebsiteURL = officialWebsiteURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ImageDescriptor> getImages() {
|
||||
return Collections.unmodifiableCollection(images);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addImage(ImageDescriptor image) {
|
||||
if (!images.contains(image)) {
|
||||
images.add(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImage(ImageDescriptor image) {
|
||||
images.remove(image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImages(Iterable<ImageDescriptor> images) {
|
||||
this.images.clear();
|
||||
if (images != null) {
|
||||
Util.addAll(images, this.images);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<VideoDescriptor> getVideos() {
|
||||
return Collections.unmodifiableCollection(videos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVideo(VideoDescriptor video) {
|
||||
if (!videos.contains(video)) {
|
||||
videos.add(video);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVideo(VideoDescriptor video) {
|
||||
videos.remove(video);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideos(Iterable<VideoDescriptor> videos) {
|
||||
this.videos.clear();
|
||||
if (videos != null) {
|
||||
Util.addAll(videos, this.videos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageDescriptor findImageWithTag(String tagName) {
|
||||
ImageDescriptor result = null;
|
||||
List<ImageDescriptor> mediaWithTag = findMediaWithTag(images, tagName);
|
||||
if(mediaWithTag.size() > 0) {
|
||||
result = mediaWithTag.get(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VideoDescriptor findVideoWithTag(String tagName) {
|
||||
VideoDescriptor result = null;
|
||||
List<VideoDescriptor> mediaWithTag = findMediaWithTag(videos, tagName);
|
||||
if(mediaWithTag.size() > 0) {
|
||||
result = mediaWithTag.get(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ImageDescriptor> findImagesWithTag(String tagName) {
|
||||
return findMediaWithTag(images, tagName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VideoDescriptor> findVideosWithTag(String tagName) {
|
||||
return findMediaWithTag(videos, tagName);
|
||||
}
|
||||
|
||||
private <T extends MediaDescriptor> List<T> findMediaWithTag(Iterable<T> media, String tagName) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (T mediaEntry : media) {
|
||||
if(mediaEntry.hasTag(tagName)) {
|
||||
result.add(mediaEntry);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets and converts all event images and videos from the old URL based format to the new richer format
|
||||
*/
|
||||
public boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs,
|
||||
URL logoImageURL, Map<URL, ImageSize> imageSizes) {
|
||||
boolean changed = false;
|
||||
|
||||
for (URL url : imageURLs) {
|
||||
if (!hasMedia(images, url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, getStartDate(), imageSizes.get(url));
|
||||
String urlAsString = url.toString();
|
||||
if (urlAsString.toLowerCase().indexOf("stage") > 0) {
|
||||
image.addTag(MediaTagConstants.STAGE);
|
||||
} else if (urlAsString.toLowerCase().indexOf("eventteaser") > 0) {
|
||||
image.addTag(MediaTagConstants.TEASER);
|
||||
} else {
|
||||
image.addTag(MediaTagConstants.GALLERY);
|
||||
}
|
||||
addImage(image);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
for (URL url : sponsorImageURLs) {
|
||||
if (!hasMedia(images, url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, getStartDate(), imageSizes.get(url));
|
||||
image.addTag(MediaTagConstants.SPONSOR);
|
||||
addImage(image);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (logoImageURL != null && !hasMedia(images, logoImageURL)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(logoImageURL, getStartDate(), imageSizes.get(logoImageURL));
|
||||
image.addTag(MediaTagConstants.LOGO);
|
||||
addImage(image);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
for (URL url : videoURLs) {
|
||||
if (!hasMedia(videos, url)) {
|
||||
MimeType mimeType = MediaUtils.detectMimeTypeFromUrl(url.toString());
|
||||
VideoDescriptor video = new VideoDescriptorImpl(url, mimeType, getStartDate());
|
||||
addVideo(video);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private ImageDescriptor migrateImageURLtoImage(URL url, TimePoint createdAt, ImageSize imageSize) {
|
||||
ImageDescriptorImpl image = new ImageDescriptorImpl(url, createdAt);
|
||||
if (imageSize != null) {
|
||||
image.setSize(imageSize.getWidth(), imageSize.getHeight());
|
||||
} else {
|
||||
Pair<Integer, Integer> imageDimensions = MediaUtils.getImageDimensions(url);
|
||||
if (imageDimensions != null) {
|
||||
image.setSize(imageDimensions);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
private boolean hasMedia(Iterable<? extends MediaDescriptor> media, URL url) {
|
||||
for (MediaDescriptor mediaEntry : media) {
|
||||
if (url.equals(mediaEntry.getURL())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +1,11 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
/**
|
||||
* A simplified implementation of the {@link EventBase} interface which maintains an immutable collection of
|
||||
@@ -23,7 +18,6 @@ import com.sap.sse.common.media.ImageSize;
|
||||
public class StrippedEventImpl extends EventBaseImpl {
|
||||
private static final long serialVersionUID = 5608501747499933988L;
|
||||
private final Iterable<LeaderboardGroupBase> leaderboardGroups;
|
||||
private final Map<URL, ImageSize> imageSizes;
|
||||
|
||||
public StrippedEventImpl(String name, TimePoint startDate, TimePoint endDate, String venueName,
|
||||
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups) {
|
||||
@@ -34,20 +28,10 @@ public class StrippedEventImpl extends EventBaseImpl {
|
||||
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups) {
|
||||
super(name, startDate, endDate, venue, isPublic, id);
|
||||
this.leaderboardGroups = leaderboardGroups;
|
||||
this.imageSizes = new HashMap<URL, ImageSize>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<LeaderboardGroupBase> getLeaderboardGroups() {
|
||||
return leaderboardGroups;
|
||||
}
|
||||
|
||||
public void setImageSize(URL imageURL, ImageSize imageSize) {
|
||||
imageSizes.put(imageURL, imageSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageSize getImageSize(URL imageURL) throws InterruptedException, ExecutionException {
|
||||
return imageSizes.get(imageURL);
|
||||
}
|
||||
}
|
||||
-17
@@ -1,15 +1,11 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
@@ -17,8 +13,6 @@ import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.impl.EventImpl;
|
||||
import com.sap.sailing.domain.common.impl.ImageSizeImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
@@ -56,15 +50,4 @@ public class CalculateImageSizeFromUrlTest {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventImageSize() throws MalformedURLException, InterruptedException, ExecutionException {
|
||||
Event e = new EventImpl("Event Name", /* startDate */ null, /* endDate */ null, "Kiel", /* isPublic */ true, UUID.randomUUID());
|
||||
int width = Math.max(10, (int) (200. * Math.random()));
|
||||
int height = Math.max(10, (int) (100. * Math.random()));
|
||||
URL imageURL = new URL("http://placekitten.com/" + width + "/" + height);
|
||||
e.addImageURL(imageURL);
|
||||
ImageSize expectedSize = new ImageSizeImpl(width, height);
|
||||
assertEquals(expectedSize, e.getImageSize(imageURL));
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,49 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
/**
|
||||
* An event is a group of {@link Regatta regattas} carried out at a common venue within a common time frame. For
|
||||
* example, Kiel Week 2011 is an event, and the International German Championship 2011 held, e.g., in Travem�nde, is an event,
|
||||
* too.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface Event extends EventBase {
|
||||
Iterable<Regatta> getRegattas();
|
||||
|
||||
void addRegatta(Regatta regatta);
|
||||
|
||||
void removeRegatta(Regatta regatta);
|
||||
|
||||
/**
|
||||
* For events, the ID is always a UUID.
|
||||
*/
|
||||
UUID getId();
|
||||
|
||||
/**
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of leaderboard groups that were previously
|
||||
* {@link #addLeaderboardGroup(LeaderboardGroup) added} to this event, in the order of their addition. Therefore, to
|
||||
* change the iteration order, {@link #removeLeaderboardGroup(LeaderboardGroup)} and
|
||||
* {@link #addLeaderboardGroup(LeaderboardGroup)} need to be used.
|
||||
*/
|
||||
@Override
|
||||
Iterable<LeaderboardGroup> getLeaderboardGroups();
|
||||
|
||||
void addLeaderboardGroup(LeaderboardGroup leaderboardGroup);
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if and only if a leaderboard group equal to <code>leaderboardGroup</code> was part of
|
||||
* {@link #getLeaderboardGroups()} and therefore was actually removed
|
||||
*/
|
||||
boolean removeLeaderboardGroup(LeaderboardGroup leaderboardGroup);
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getLeaderboardGroups() current contents of the leaderboard groups sequence} by the
|
||||
* leaderboard groups in <code>leaderboardGroups</code>.
|
||||
*/
|
||||
void setLeaderboardGroups(Iterable<LeaderboardGroup> leaderboardGroups);
|
||||
|
||||
/**
|
||||
* For the images references by the image URLs in {@link #getImageURLs()}, {@link #getSponsorImageURLs()} and {@link #getLogoImageURL()}
|
||||
* determines the image dimensions. The retrieval of the image size is started when the URL is added to this event, and the result is
|
||||
* cached. Should the image change its size afterwards or change its availability status, this event won't notice unless the image is
|
||||
* removed from this event and added again.<p>
|
||||
*
|
||||
* Note that exceptions may result should the image be unavailable. If the image URL leads to a document that is not an image,
|
||||
* <code>null</code> will result.
|
||||
*/
|
||||
ImageSize getImageSize(URL imageURL) throws InterruptedException, ExecutionException;
|
||||
|
||||
}
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
|
||||
/**
|
||||
* An event is a group of {@link Regatta regattas} carried out at a common venue within a common time frame. For
|
||||
* example, Kiel Week 2011 is an event, and the International German Championship 2011 held, e.g., in Travem�nde, is an event,
|
||||
* too.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface Event extends EventBase {
|
||||
Iterable<Regatta> getRegattas();
|
||||
|
||||
void addRegatta(Regatta regatta);
|
||||
|
||||
void removeRegatta(Regatta regatta);
|
||||
|
||||
/**
|
||||
* For events, the ID is always a UUID.
|
||||
*/
|
||||
UUID getId();
|
||||
|
||||
/**
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of leaderboard groups that were previously
|
||||
* {@link #addLeaderboardGroup(LeaderboardGroup) added} to this event, in the order of their addition. Therefore, to
|
||||
* change the iteration order, {@link #removeLeaderboardGroup(LeaderboardGroup)} and
|
||||
* {@link #addLeaderboardGroup(LeaderboardGroup)} need to be used.
|
||||
*/
|
||||
@Override
|
||||
Iterable<LeaderboardGroup> getLeaderboardGroups();
|
||||
|
||||
void addLeaderboardGroup(LeaderboardGroup leaderboardGroup);
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if and only if a leaderboard group equal to <code>leaderboardGroup</code> was part of
|
||||
* {@link #getLeaderboardGroups()} and therefore was actually removed
|
||||
*/
|
||||
boolean removeLeaderboardGroup(LeaderboardGroup leaderboardGroup);
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getLeaderboardGroups() current contents of the leaderboard groups sequence} by the
|
||||
* leaderboard groups in <code>leaderboardGroups</code>.
|
||||
*/
|
||||
void setLeaderboardGroups(Iterable<LeaderboardGroup> leaderboardGroups);
|
||||
}
|
||||
@@ -2,47 +2,26 @@ package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.common.impl.ImageSizeImpl;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
|
||||
public class EventImpl extends EventBaseImpl implements Event {
|
||||
private static final long serialVersionUID = 855135446595485715L;
|
||||
private static final Logger logger = Logger.getLogger(EventImpl.class.getName());
|
||||
|
||||
private final Set<Regatta> regattas;
|
||||
|
||||
private ConcurrentLinkedQueue<LeaderboardGroup> leaderboardGroups;
|
||||
|
||||
private transient ConcurrentHashMap<URL, Future<ImageSize>> imageSizeFetchers;
|
||||
private transient ExecutorService executor;
|
||||
|
||||
public EventImpl(String name, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, UUID id) {
|
||||
this(name, startDate, endDate, new VenueImpl(venueName), isPublic, id);
|
||||
}
|
||||
@@ -54,8 +33,6 @@ public class EventImpl extends EventBaseImpl implements Event {
|
||||
super(name, startDate, endDate, venue, isPublic, id);
|
||||
this.regattas = new HashSet<Regatta>();
|
||||
this.leaderboardGroups = new ConcurrentLinkedQueue<>();
|
||||
this.imageSizeFetchers = new ConcurrentHashMap<>();
|
||||
this.executor = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
@@ -63,8 +40,6 @@ public class EventImpl extends EventBaseImpl implements Event {
|
||||
if (leaderboardGroups == null) {
|
||||
leaderboardGroups = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
this.imageSizeFetchers = new ConcurrentHashMap<>();
|
||||
this.executor = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,110 +81,4 @@ public class EventImpl extends EventBaseImpl implements Event {
|
||||
public boolean removeLeaderboardGroup(LeaderboardGroup leaderboardGroup) {
|
||||
return leaderboardGroups.remove(leaderboardGroup);
|
||||
}
|
||||
|
||||
private Future<ImageSize> getOrCreateImageSizeCalculator(final URL imageURL) {
|
||||
Future<ImageSize> imageSizeFetcher = imageSizeFetchers.get(imageURL);
|
||||
if (imageSizeFetcher == null) {
|
||||
imageSizeFetcher = executor.submit(new Callable<ImageSize>() {
|
||||
@Override
|
||||
public ImageSize call() throws IOException {
|
||||
ImageSize result = null;
|
||||
ImageInputStream in = null;
|
||||
try {
|
||||
URLConnection conn = imageURL.openConnection();
|
||||
in = ImageIO.createImageInputStream(conn.getInputStream());
|
||||
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
|
||||
if (readers.hasNext()) {
|
||||
ImageReader reader = readers.next();
|
||||
try {
|
||||
reader.setInput(in);
|
||||
result = new ImageSizeImpl(reader.getWidth(0), reader.getHeight(0));
|
||||
} finally {
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
logger.log(Level.SEVERE, "Stale image link "+imageURL+" for event "+getName()+". Please double-check and replace or remove.", ioe);
|
||||
throw ioe;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
imageSizeFetchers.put(imageURL, imageSizeFetcher);
|
||||
}
|
||||
return imageSizeFetcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageSize getImageSize(URL imageURL) throws InterruptedException, ExecutionException {
|
||||
Future<ImageSize> imageSizeCalculator = getOrCreateImageSizeCalculator(imageURL);
|
||||
return imageSizeCalculator.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addImageURL(URL imageURL) {
|
||||
super.addImageURL(imageURL);
|
||||
refreshImageSizeFetcher(imageURL);
|
||||
}
|
||||
|
||||
private void refreshImageSizeFetcher(URL imageURL) {
|
||||
if (imageURL != null) {
|
||||
removeImageSizeFetcher(imageURL);
|
||||
getOrCreateImageSizeCalculator(imageURL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImageURL(URL imageURL) {
|
||||
super.removeImageURL(imageURL);
|
||||
removeImageSizeFetcher(imageURL);
|
||||
}
|
||||
|
||||
private void removeImageSizeFetcher(URL imageURL) {
|
||||
if (imageURL != null) {
|
||||
imageSizeFetchers.remove(imageURL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageURLs(Iterable<URL> imageURLs) {
|
||||
super.setImageURLs(imageURLs);
|
||||
if (imageURLs != null) {
|
||||
for (URL imageURL : imageURLs) {
|
||||
refreshImageSizeFetcher(imageURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSponsorImageURL(URL sponsorImageURL) {
|
||||
super.addSponsorImageURL(sponsorImageURL);
|
||||
refreshImageSizeFetcher(sponsorImageURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSponsorImageURL(URL sponsorImageURL) {
|
||||
super.removeSponsorImageURL(sponsorImageURL);
|
||||
removeImageSizeFetcher(sponsorImageURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSponsorImageURLs(Iterable<URL> sponsorImageURLs) {
|
||||
super.setSponsorImageURLs(sponsorImageURLs);
|
||||
if (sponsorImageURLs != null) {
|
||||
for (URL imageURL : sponsorImageURLs) {
|
||||
refreshImageSizeFetcher(imageURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogoImageURL(URL logoImageURL) {
|
||||
super.setLogoImageURL(logoImageURL);
|
||||
refreshImageSizeFetcher(logoImageURL);
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -3,18 +3,13 @@
|
||||
xmlns:r="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.raceListLive"
|
||||
xmlns:o="urn:import:com.sap.sailing.gwt.home.client.place.event.overview">
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:style>
|
||||
.space-top {
|
||||
margin-top: 2em;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<o:EventOverviewStage ui:field="stage" />
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<r:RacesListLive ui:field="racesListLive" addStyleNames="{style.space-top}" />
|
||||
<r:RacesListLive ui:field="racesListLive" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmediumbig}" />
|
||||
</div>
|
||||
</div>
|
||||
<g:SimplePanel ui:field="content" addStyleNames="{style.space-top}" />
|
||||
<g:SimplePanel ui:field="content" />
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+7
-46
@@ -1,52 +1,20 @@
|
||||
.countdown {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.countdown_content {
|
||||
font-size: inherit;
|
||||
}
|
||||
.countdown_content_panewrapper {
|
||||
font-size: 0;
|
||||
}
|
||||
.countdown_content_pane {
|
||||
border: 0.2em solid #fff;
|
||||
background: #008fcc;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
margin-right: 0.333333333333333em;
|
||||
padding: 0.666666666666667em 0.333333333333333em;
|
||||
border-radius: 0.666666666666667em;
|
||||
width: 4.666666666666667em;
|
||||
height: 4.666666666666667em;
|
||||
text-shadow: none;
|
||||
box-shadow: 0 0 18px rgba(0,0,0,0.13), 0 2px 6px rgba(0,0,0,0.25);
|
||||
}
|
||||
.countdown_content_panefirst,
|
||||
.countdown_content_panesecond,
|
||||
.countdown_content_panethird,
|
||||
.countdown_content_panefourth {
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.countdown_content_pane_count {
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.countdown_content_pane_unit {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.countdown {
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
height: 28.333333333333332em;
|
||||
margin-top: 1.333333333333333em;
|
||||
}
|
||||
@media (max-width: 976px) {
|
||||
.countdown {
|
||||
height: 22em;
|
||||
}
|
||||
}
|
||||
.countdown_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 67.8em 50.46666666666667em;
|
||||
background-position: center -0.933333333333333em;
|
||||
background-image: url("../images/home/countdown-thumbnail.png");
|
||||
}
|
||||
.countdown_content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
@@ -63,12 +31,6 @@
|
||||
font-size: 1.466666666666667em;
|
||||
color: #f6f9fc;
|
||||
}
|
||||
.countdown_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
.countdown_info {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
@@ -95,7 +57,6 @@
|
||||
margin-top: 0.181818181818182em;
|
||||
}
|
||||
.countdown_info_lable {
|
||||
width: 3.333333333333333em;
|
||||
display: inline-block;
|
||||
padding-left: 0.4em;
|
||||
margin-left: 1.333333333333333em;
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import com.sap.sailing.gwt.home.client.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.countdown.CountdownResources.LocalCss;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.countdownTimer.CountdownTimer;
|
||||
import com.sap.sailing.gwt.home.client.shared.stage.StageResources;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.EventOverviewRaceTickerStageDTO;
|
||||
@@ -72,7 +73,7 @@ public class Countdown extends Composite {
|
||||
}
|
||||
|
||||
if(data.getStartTime() != null) {
|
||||
this.tickerContainer.setWidget(new CountdownTicker(data.getStartTime()));
|
||||
this.tickerContainer.setWidget(new CountdownTimer(data.getStartTime()));
|
||||
} else {
|
||||
this.tickerContainer.setWidget(null);
|
||||
}
|
||||
|
||||
+2
-10
@@ -12,17 +12,9 @@ public interface CountdownResources extends ClientBundle {
|
||||
|
||||
public interface LocalCss extends CssResource {
|
||||
String countdown();
|
||||
String countdown_content();
|
||||
String countdown_content_panewrapper();
|
||||
String countdown_content_pane();
|
||||
String countdown_content_panefirst();
|
||||
String countdown_content_panesecond();
|
||||
String countdown_content_panethird();
|
||||
String countdown_content_panefourth();
|
||||
String countdown_content_pane_count();
|
||||
String countdown_content_pane_unit();
|
||||
String countdown_content_title();
|
||||
String countdown_image();
|
||||
String countdown_content();
|
||||
String countdown_content_title();
|
||||
String countdown_info();
|
||||
String countdown_info_text();
|
||||
String countdown_info_text_title();
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" >
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.countdown.CountdownResources" />
|
||||
<g:HTMLPanel ui:field="countdown" addStyleNames="{local_res.css.countdown_content_panewrapper}">
|
||||
<div ui:field="majorContainer" class="{local_res.css.countdown_content_pane} {local_res.css.countdown_content_panefirst}">
|
||||
<div ui:field="majorValue" class="{local_res.css.countdown_content_pane_count}"></div>
|
||||
<div ui:field="majorUnit" class="{local_res.css.countdown_content_pane_unit}"></div>
|
||||
</div>
|
||||
<div ui:field="minorContainer" class="{local_res.css.countdown_content_pane} {local_res.css.countdown_content_panesecond}">
|
||||
<div ui:field="minorValue" class="{local_res.css.countdown_content_pane_count}"></div>
|
||||
<div ui:field="minorUnit" class="{local_res.css.countdown_content_pane_unit}"></div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Styles for countdown on the stage
|
||||
*/
|
||||
.countdowntimer {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.countdowntimer_content {
|
||||
font-size: inherit;
|
||||
}
|
||||
.countdowntimer_content_panewrapper {
|
||||
font-size: 0;
|
||||
}
|
||||
.countdowntimer_content_pane {
|
||||
border: 0.2em solid #fff;
|
||||
background: #008fcc;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
margin-right: 0.333333333333333em;
|
||||
padding: 0.666666666666667em 0.333333333333333em;
|
||||
border-radius: 0.666666666666667em;
|
||||
width: 4.666666666666667em;
|
||||
height: 4.666666666666667em;
|
||||
text-shadow: none;
|
||||
box-shadow: 0 0 18px rgba(0,0,0,0.13), 0 2px 6px rgba(0,0,0,0.25);
|
||||
}
|
||||
.countdowntimer_content_panefirst,
|
||||
.countdowntimer_content_panesecond,
|
||||
.countdowntimer_content_panethird,
|
||||
.countdowntimer_content_panefourth {
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.countdowntimer_content_pane_count {
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.countdowntimer_content_pane_unit {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
+7
-6
@@ -1,24 +1,24 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.partials.countdown;
|
||||
package com.sap.sailing.gwt.home.client.place.event.partials.countdownTimer;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown.CountdownListener;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown.RemainingTime;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class CountdownTicker extends Composite {
|
||||
public class CountdownTimer extends Widget {
|
||||
|
||||
private static CountdownTickerUiBinder uiBinder = GWT.create(CountdownTickerUiBinder.class);
|
||||
|
||||
interface CountdownTickerUiBinder extends UiBinder<Widget, CountdownTicker> {
|
||||
interface CountdownTickerUiBinder extends UiBinder<Element, CountdownTimer> {
|
||||
}
|
||||
|
||||
@UiField DivElement majorContainer, majorValue, majorUnit;
|
||||
@@ -26,8 +26,9 @@ public class CountdownTicker extends Composite {
|
||||
|
||||
private final Countdown countdown;
|
||||
|
||||
public CountdownTicker(Date startTime) {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
public CountdownTimer(Date startTime) {
|
||||
CountdownTimerResources.INSTANCE.css().ensureInjected();
|
||||
setElement(uiBinder.createAndBindUi(this));
|
||||
this.countdown = new Countdown(new MillisecondsTimePoint(startTime), new CountdownTickerListener());
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared">
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.countdownTimer.CountdownTimerResources" />
|
||||
<div class="{local_res.css.countdowntimer}">
|
||||
<div class="{local_res.css.countdowntimer_content}">
|
||||
<div ui:field="majorContainer" class="{local_res.css.countdowntimer_content_pane} {local_res.css.countdowntimer_content_panefirst}">
|
||||
<div ui:field="majorValue" class="{local_res.css.countdowntimer_content_pane_count}"></div>
|
||||
<div ui:field="majorUnit" class="{local_res.css.countdowntimer_content_pane_unit}"></div>
|
||||
</div>
|
||||
<div ui:field="minorContainer" class="{local_res.css.countdowntimer_content_pane} {local_res.css.countdowntimer_content_panesecond}">
|
||||
<div ui:field="minorValue" class="{local_res.css.countdowntimer_content_pane_count}"></div>
|
||||
<div ui:field="minorUnit" class="{local_res.css.countdowntimer_content_pane_unit}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:UiBinder>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.partials.countdownTimer;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
|
||||
public interface CountdownTimerResources extends ClientBundle {
|
||||
public static final CountdownTimerResources INSTANCE = GWT.create(CountdownTimerResources.class);
|
||||
|
||||
@Source("CountdownTimer.gss")
|
||||
LocalCss css();
|
||||
|
||||
public interface LocalCss extends CssResource {
|
||||
String countdowntimer();
|
||||
String countdowntimer_content();
|
||||
String countdowntimer_content_panewrapper();
|
||||
String countdowntimer_content_pane();
|
||||
String countdowntimer_content_panefirst();
|
||||
String countdowntimer_content_panesecond();
|
||||
String countdowntimer_content_panethird();
|
||||
String countdowntimer_content_panefourth();
|
||||
String countdowntimer_content_pane_count();
|
||||
String countdowntimer_content_pane_unit();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -103,7 +103,7 @@ public class EventHeader extends Composite {
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
String logoUrl = event.getLogoImageURL() != null ? event.getLogoImageURL() : EventHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString();
|
||||
String logoUrl = event.getLogoImage() != null ? event.getLogoImage().getSourceRef() : EventHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString();
|
||||
eventLogo.getStyle().setBackgroundImage("url(" + logoUrl + ")");
|
||||
eventLogo.setTitle(event.getDisplayName());
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<o:EventOverviewStage ui:field="stage" />
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<r:RacesListLive ui:field="racesListLive" />
|
||||
<r:RacesListLive ui:field="racesListLive" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmediumbig}" />
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class SeriesHeader extends Composite {
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
String logoUrl = series.getLogoImageURL() != null ? series.getLogoImageURL() : SeriesHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString();
|
||||
String logoUrl = series.getLogoImage() != null ? series.getLogoImage().getSourceRef() : SeriesHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString();
|
||||
eventLogo.getStyle().setBackgroundImage("url(" + logoUrl + ")");
|
||||
eventLogo.setTitle(series.getDisplayName());
|
||||
eventName.setInnerText(series.getDisplayName());
|
||||
|
||||
+54
-47
@@ -14,9 +14,6 @@ import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
@@ -42,8 +39,8 @@ import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO.EventSeriesSt
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventState;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaUtils;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingImageDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.start.EventStageDTO;
|
||||
@@ -57,9 +54,11 @@ import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.util.ServiceTrackerFactory;
|
||||
|
||||
/**
|
||||
@@ -93,7 +92,6 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 3947782997746039939L;
|
||||
private static final Logger logger = Logger.getLogger(HomeServiceImpl.class.getName());
|
||||
|
||||
private static final int MAX_STAGE_EVENTS = 5;
|
||||
private static final int MAX_RECENT_EVENTS = 3;
|
||||
@@ -183,14 +181,14 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
|
||||
EventReferenceDTO eventRef = new EventReferenceDTO(holder.event);
|
||||
|
||||
Iterable<URL> videosOfEvent = holder.event.getVideoURLs();
|
||||
Iterable<VideoDescriptor> videosOfEvent = holder.event.getVideos();
|
||||
if (!Util.isEmpty(videosOfEvent) && result.getVideos().size() < MAX_VIDEO_COUNT) {
|
||||
URL youTubeRandomUrl = HomeServiceUtil.getRandomURL(videosOfEvent);
|
||||
VideoDescriptor youTubeRandomUrl = HomeServiceUtil.getRandomVideo(videosOfEvent);
|
||||
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(youTubeRandomUrl.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, youTubeRandomUrl.toString(), type, //
|
||||
holder.event.getEndDate().asDate() // FIXME: using event enddate for now
|
||||
MimeType type = youTubeRandomUrl.getMimeType();
|
||||
if (MediaConstants.SUPPORTED_VIDEO_TYPES.contains(type)) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, youTubeRandomUrl.getURL().toString(), type, //
|
||||
youTubeRandomUrl.getCreatedAtDate().asDate()
|
||||
);
|
||||
candidate.setTitle(holder.event.getName());
|
||||
result.addVideo(candidate);
|
||||
@@ -217,22 +215,18 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
EventBase event = holder.event;
|
||||
EventReferenceDTO eventRef = new EventReferenceDTO(holder.event);
|
||||
|
||||
for (URL url : HomeServiceUtil.getSailingLovesPhotographyImages(event)) {
|
||||
try {
|
||||
ImageSize imageSize = event.getImageSize(url);
|
||||
if(imageSize != null) {
|
||||
// TODO: do we habe a title?
|
||||
photoGalleryUrls.add(new SailingImageDTO(eventRef, url.toString(), imageSize, null));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
for (ImageDescriptor url : HomeServiceUtil.getSailingLovesPhotographyImages(event)) {
|
||||
if(url.hasSize()) {
|
||||
SailingImageDTO sailingImageDTO = new SailingImageDTO(eventRef, url.getURL().toString(), null);
|
||||
sailingImageDTO.setSizeInPx(url.getWidthInPx(), url.getHeightInPx());
|
||||
photoGalleryUrls.add(sailingImageDTO);
|
||||
}
|
||||
}
|
||||
for (URL videoUrl : event.getVideoURLs()) {
|
||||
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(videoUrl.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, videoUrl.toString(), type, //
|
||||
holder.event.getEndDate().asDate() // FIXME: using event enddate for now
|
||||
for (VideoDescriptor videoUrl : event.getVideos()) {
|
||||
MimeType type = videoUrl.getMimeType();
|
||||
if (MediaConstants.SUPPORTED_VIDEO_TYPES.contains(type)) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, videoUrl.getURL().toString(), type, //
|
||||
videoUrl.getCreatedAtDate().asDate()
|
||||
);
|
||||
candidate.setTitle(holder.event.getName());
|
||||
videoCandidates.add(candidate);
|
||||
@@ -281,7 +275,8 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
EventViewDTO dto = new EventViewDTO();
|
||||
mapToMetadataDTO(event, dto);
|
||||
|
||||
dto.setLogoImageURL(event.getLogoImageURL() == null ? null : event.getLogoImageURL().toString());
|
||||
ImageDescriptor logoImage = event.findImageWithTag(MediaTagConstants.LOGO);
|
||||
dto.setLogoImage(logoImage != null ? convertToImageDTO(logoImage) : null);
|
||||
dto.setOfficialWebsiteURL(event.getOfficialWebsiteURL() == null ? null : event.getOfficialWebsiteURL().toString());
|
||||
|
||||
dto.setHasMedia(HomeServiceUtil.hasMedia(event));
|
||||
@@ -345,8 +340,8 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
dto.setType(dto.getRegattas().size() == 1 ? EventType.SINGLE_REGATTA: EventType.MULTI_REGATTA);
|
||||
}
|
||||
|
||||
// TODO fmittag: put in correct event ID
|
||||
if("406cffc2-b491-4f7e-b78e-a21abd97006a".equals(event.getId().toString())) {
|
||||
// Special solution for Kieler Woche 2015
|
||||
if("a9d6c5d5-cac3-47f2-9b5c-506e441819a1".equals(event.getId().toString())) {
|
||||
dto.setSailorsInfoURL("http://sailorsinfo.kieler-woche.de/");
|
||||
}
|
||||
|
||||
@@ -373,7 +368,8 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
|
||||
EventSeriesViewDTO dto = new EventSeriesViewDTO();
|
||||
dto.setId(id);
|
||||
dto.setLogoImageURL(o.getLogoImageURL() == null ? null : o.getLogoImageURL().toString());
|
||||
ImageDescriptor logoImage = o.findImageWithTag(MediaTagConstants.LOGO);
|
||||
dto.setLogoImage(logoImage != null ? convertToImageDTO(logoImage) : null);
|
||||
// TODO implement correctly. We currently do not show media for series.
|
||||
dto.setHasMedia(false);
|
||||
|
||||
@@ -430,25 +426,20 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
EventReferenceDTO eventRef = new EventReferenceDTO(event);
|
||||
|
||||
String eventName = event.getName();
|
||||
// TODO implement correctly and fill metadata
|
||||
MediaDTO media = new MediaDTO();
|
||||
for(URL url : HomeServiceUtil.getPhotoGalleryImageURLs(event)) {
|
||||
ImageSize imageSize = null;
|
||||
try {
|
||||
imageSize = event.getImageSize(url);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.log(Level.FINE, "Was unable to obtain image size for "+url+" earlier.", e);
|
||||
}
|
||||
SailingImageDTO entry = new SailingImageDTO(eventRef, url.toString(), imageSize, //
|
||||
event.getEndDate().asDate() // FIXME: using the event end date for now, we need a better solution for migration
|
||||
);
|
||||
entry.setTitle(eventName);
|
||||
for(ImageDescriptor image : HomeServiceUtil.getPhotoGalleryImages(event)) {
|
||||
SailingImageDTO entry = new SailingImageDTO(eventRef, image.getURL().toString(), image.getCreatedAtDate().asDate());
|
||||
entry.setSizeInPx(image.getWidthInPx(), image.getHeightInPx());
|
||||
entry.setTitle(image.getTitle() != null ? image.getTitle(): eventName);
|
||||
entry.setSubtitle(image.getSubtitle());
|
||||
entry.setTags(image.getTags());
|
||||
entry.setCopyright(image.getCopyright());
|
||||
media.addPhoto(entry);
|
||||
}
|
||||
for(URL url : event.getVideoURLs()) {
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(url.toString());
|
||||
if (type.mediaType == MediaType.video) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, url.toString(), type, null);
|
||||
for(VideoDescriptor url : event.getVideos()) {
|
||||
MimeType type = url.getMimeType();
|
||||
if (MediaConstants.SUPPORTED_VIDEO_TYPES.contains(type)) {
|
||||
SailingVideoDTO candidate = new SailingVideoDTO(eventRef, url.getURL().toString(), type, null);
|
||||
media.addVideo(candidate);
|
||||
}
|
||||
}
|
||||
@@ -534,4 +525,20 @@ public class HomeServiceImpl extends ProxiedRemoteServiceServlet implements Home
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ImageDTO convertToImageDTO(ImageDescriptor image) {
|
||||
ImageDTO result = new ImageDTO(image.getURL().toString(), image.getCreatedAtDate() != null ? image.getCreatedAtDate().asDate() : null);
|
||||
result.setCopyright(image.getCopyright());
|
||||
result.setTitle(image.getTitle());
|
||||
result.setSubtitle(image.getSubtitle());
|
||||
result.setMimeType(image.getMimeType());
|
||||
result.setSizeInPx(image.getWidthInPx(), image.getHeightInPx());
|
||||
result.setLocale(image.getLocale() != null ? image.getLocale().toString() : null);
|
||||
List<String> tags = new ArrayList<String>();
|
||||
for(String tag: image.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.setTags(tags);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+189
-126
@@ -1,15 +1,13 @@
|
||||
package com.sap.sailing.gwt.server;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
@@ -25,20 +23,23 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata.RegattaState;
|
||||
import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventState;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.MediaDescriptor;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public final class HomeServiceUtil {
|
||||
|
||||
private HomeServiceUtil() {
|
||||
}
|
||||
|
||||
private static final int MINIMUM_IMAGE_HEIGHT_FOR_SAILING_PHOTOGRAPHY_IN_PIXELS = 500;
|
||||
private static final String STAGE_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE = "stage";
|
||||
private static final String THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE = "eventteaser";
|
||||
|
||||
public static String findEventThumbnailImageUrlAsString(EventBase event) {
|
||||
URL url = findEventThumbnailImageUrl(event);
|
||||
return url == null ? null : url.toString();
|
||||
ImageDescriptor url = findEventThumbnailImage(event);
|
||||
return url == null ? null : url.getURL().toString();
|
||||
}
|
||||
|
||||
public static boolean isFakeSeries(EventBase event) {
|
||||
@@ -100,47 +101,43 @@ public final class HomeServiceUtil {
|
||||
return EventState.RUNNING;
|
||||
}
|
||||
|
||||
private static URL findEventThumbnailImageUrl(EventBase event) {
|
||||
private static ImageDescriptor findEventThumbnailImage(EventBase event) {
|
||||
|
||||
final class ImageHolder {
|
||||
|
||||
final int PERFECT_HEIGHT = 240;
|
||||
final int PERFECT_WIDTH = 370;
|
||||
final double PERFECT_RATIO = PERFECT_HEIGHT / (double) PERFECT_WIDTH;
|
||||
final URL url;
|
||||
final int height;
|
||||
final int width;
|
||||
final int size;
|
||||
final double ratio;
|
||||
final ImageDescriptor image;
|
||||
final boolean stage;
|
||||
|
||||
ImageHolder() {
|
||||
this(null, null);
|
||||
this(null);
|
||||
}
|
||||
|
||||
ImageHolder(URL url, ImageSize imageSize) {
|
||||
this(url, imageSize == null ? -1 : imageSize.getWidth(), imageSize == null ? -1 : imageSize.getHeight());
|
||||
}
|
||||
|
||||
ImageHolder(URL url, int width, int height) {
|
||||
this.url = url;
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
if(width == -1 || height == -1) {
|
||||
this.size = -1;
|
||||
ImageHolder(ImageDescriptor image) {
|
||||
this.image = image;
|
||||
this.stage = image == null ? false : hasTag(image, MediaTagConstants.STAGE);
|
||||
this.height = image == null || image.getHeightInPx() == null ? 0 : image.getHeightInPx();
|
||||
this.width = image == null || image.getWidthInPx() == null ? 0 : image.getWidthInPx();
|
||||
this.size = height * width;
|
||||
if(width == 0) {
|
||||
this.ratio = -1;
|
||||
} else {
|
||||
this.size = height * width;
|
||||
this.ratio = height / (double) width;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isBetterWorstcaseThan(ImageHolder otherImageHolder) {
|
||||
|
||||
if (isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.url != null && url.toString().contains(STAGE_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE)) {
|
||||
if (stage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -175,13 +172,13 @@ public final class HomeServiceUtil {
|
||||
}
|
||||
|
||||
boolean isNull() {
|
||||
return size == -1;
|
||||
return image == null;
|
||||
}
|
||||
}
|
||||
|
||||
// search for name pattern
|
||||
for (URL imageUrl : event.getImageURLs()) {
|
||||
if (imageUrl.toString().toLowerCase().contains(THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE)) {
|
||||
for (ImageDescriptor imageUrl : event.getImages()) {
|
||||
if (hasTag(imageUrl, MediaTagConstants.TEASER)) {
|
||||
return imageUrl;
|
||||
}
|
||||
}
|
||||
@@ -189,16 +186,11 @@ public final class HomeServiceUtil {
|
||||
ImageHolder actualWorstcase = new ImageHolder();
|
||||
ImageHolder bestFit = new ImageHolder();
|
||||
|
||||
for (URL candidateImageUrl : getPhotoGalleryImageURLs(event)) {
|
||||
ImageHolder candidate;
|
||||
try {
|
||||
candidate = new ImageHolder(candidateImageUrl, event.getImageSize(candidateImageUrl));
|
||||
} catch (Exception e) {
|
||||
candidate = new ImageHolder(candidateImageUrl, -1, -1);
|
||||
}
|
||||
for (ImageDescriptor candidateImage : getPhotoGalleryImages(event)) {
|
||||
ImageHolder candidate = new ImageHolder(candidateImage);
|
||||
|
||||
if (candidate.isPerfectFit()) {
|
||||
return candidate.url;
|
||||
return candidate.image;
|
||||
}
|
||||
|
||||
if (candidate.fitsRatio() && candidate.isBigEnough()) {
|
||||
@@ -214,20 +206,20 @@ public final class HomeServiceUtil {
|
||||
}
|
||||
|
||||
if (!bestFit.isNull()) {
|
||||
return bestFit.url;
|
||||
return bestFit.image;
|
||||
}
|
||||
if (!actualWorstcase.isNull()) {
|
||||
return actualWorstcase.url;
|
||||
return actualWorstcase.image;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The stage image is determined from the {@link #imageURLs} collection by a series of heuristics and fall-back
|
||||
* The stage image is determined from the {@link #images} collection by a series of heuristics and fall-back
|
||||
* rules:
|
||||
* <ol>
|
||||
* <li>If one or more image URLs has "stage" (ignoring case) in its name, only they are considered candidates.</li>
|
||||
* <li>If no image URL has "stage" (ignoring case) in its name, all images from {@link #imageURLs} are considered
|
||||
* <li>If one or more image has {@link MediaConstants#STAGE} tag, only they are considered candidates.</li>
|
||||
* <li>If no image has {@link MediaConstants#STAGE} tag, all images are considered
|
||||
* candidates.</li>
|
||||
* <li>From all candidates, the one with the biggest known size (determined by the product of width and height) is
|
||||
* chosen.</li>
|
||||
@@ -235,107 +227,88 @@ public final class HomeServiceUtil {
|
||||
* </ol>
|
||||
*/
|
||||
public static String getStageImageURLAsString(final EventBase event) {
|
||||
URL url = getStageImageURL(event);
|
||||
return url == null ? null : url.toString();
|
||||
ImageDescriptor image = getStageImage(event);
|
||||
return image == null ? null : image.getURL().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The stage image is determined from the {@link #imageURLs} collection by a series of heuristics and fall-back
|
||||
* The stage image is determined from the {@link #images} collection by a series of heuristics and fall-back
|
||||
* rules:
|
||||
* <ol>
|
||||
* <li>If one or more image URLs has "stage" (ignoring case) in its name, only they are considered candidates.</li>
|
||||
* <li>If no image URL has "stage" (ignoring case) in its name, all images from {@link #imageURLs} are considered
|
||||
* <li>If one or more image has {@link MediaConstants#STAGE} tag, only they are considered candidates.</li>
|
||||
* <li>If no image has {@link MediaConstants#STAGE} tag, all images are considered
|
||||
* candidates.</li>
|
||||
* <li>From all candidates, the one with the biggest known size (determined by the product of width and height) is
|
||||
* chosen.</li>
|
||||
* <li>If the size isn't known for any candidate, the first candidate in {@link #imageURLs} is picked.</li>
|
||||
* </ol>
|
||||
*/
|
||||
public static URL getStageImageURL(final EventBase event) {
|
||||
final URL result;
|
||||
if (Util.isEmpty(event.getImageURLs())) {
|
||||
result = null;
|
||||
} else {
|
||||
Comparator<URL> stageImageComparator = new Comparator<URL>() {
|
||||
@Override
|
||||
public int compare(URL url1, URL url2) {
|
||||
String o1 = url1.toString();
|
||||
String o2 = url2.toString();
|
||||
int result;
|
||||
int o1NameHack = o1.toLowerCase().contains(STAGE_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE) ? 1 :
|
||||
o1.toLowerCase().contains(THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE) ? -1 : 0;
|
||||
int o2NameHack = o2.toLowerCase().contains(STAGE_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE) ? 1 :
|
||||
o2.toLowerCase().contains(THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE) ? -1 : 0;
|
||||
final int preResultBasedOnNameHack = o1NameHack - o2NameHack;
|
||||
if (preResultBasedOnNameHack == 0) {
|
||||
try {
|
||||
result = compareBySize(url1, url2);
|
||||
} catch (Exception e) {
|
||||
result = 0;
|
||||
}
|
||||
} else {
|
||||
result = preResultBasedOnNameHack;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int compareBySize(URL o1, URL o2) throws InterruptedException, ExecutionException {
|
||||
final int result;
|
||||
final ImageSize o1Size = event.getImageSize(o1);
|
||||
final ImageSize o2Size = event.getImageSize(o2);
|
||||
result = (o1Size == null ? 0 : (o1Size.getWidth() * o1Size.getHeight()))
|
||||
- (o2Size == null ? 0 : (o2Size.getWidth() * o2Size.getHeight()));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
List<URL> sortedImageURLs = new ArrayList<>();
|
||||
for (URL url : event.getImageURLs()) {
|
||||
sortedImageURLs.add(url);
|
||||
}
|
||||
Collections.sort(sortedImageURLs, stageImageComparator);
|
||||
result = sortedImageURLs.get(sortedImageURLs.size() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> getPhotoGalleryImageURLsAsString(EventBase event) {
|
||||
List<URL> urls = getPhotoGalleryImageURLs(event);
|
||||
List<String> result = new ArrayList<String>(urls.size());
|
||||
for (URL url : urls) {
|
||||
result.add(url.toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<URL> getPhotoGalleryImageURLs(EventBase event) {
|
||||
URL stageImageURL = getStageImageURL(event); // if set, exclude stage image from photo gallery
|
||||
List<URL> result = new ArrayList<>();
|
||||
Iterable<URL> imageURLs = event.getImageURLs();
|
||||
public static ImageDescriptor getStageImage(final EventBase event) {
|
||||
ImageDescriptor bestMatch = null;
|
||||
|
||||
boolean first = true;
|
||||
for (Iterator<URL> iter = imageURLs.iterator(); iter.hasNext(); ) {
|
||||
URL imageUrl = iter.next();
|
||||
if(imageUrl.toString().toLowerCase().contains(THUMBNAIL_IMAGE_URL_SUBSTRING_INDICATOR_CASE_INSENSITIVE)) {
|
||||
for(ImageDescriptor candidate : event.getImages()) {
|
||||
if(bestMatch == null || isBetterStageImage(candidate, bestMatch)) {
|
||||
bestMatch = candidate;
|
||||
continue;
|
||||
}
|
||||
if ((first && !iter.hasNext()) || !Util.equalsWithNull(imageUrl, stageImageURL)) {
|
||||
result.add(imageUrl);
|
||||
}
|
||||
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
private static boolean isBetterStageImage(ImageDescriptor candidate, ImageDescriptor reference) {
|
||||
boolean stage = hasTag(candidate, MediaTagConstants.STAGE);
|
||||
boolean stageRef = hasTag(reference, MediaTagConstants.STAGE);
|
||||
if(stage != stageRef) {
|
||||
return stage;
|
||||
}
|
||||
boolean teaser = hasTag(candidate, MediaTagConstants.TEASER);
|
||||
boolean teaserRef = hasTag(reference, MediaTagConstants.TEASER);
|
||||
if(teaser != teaserRef) {
|
||||
return !teaser;
|
||||
}
|
||||
|
||||
int size = candidate.getArea();
|
||||
int sizeRef = candidate.getArea();
|
||||
if(size != sizeRef) {
|
||||
return size > sizeRef;
|
||||
}
|
||||
return candidate.getCreatedAtDate().compareTo(reference.getCreatedAtDate()) > 0;
|
||||
}
|
||||
|
||||
public static List<String> getPhotoGalleryImageURLsAsString(EventBase event) {
|
||||
List<ImageDescriptor> urls = getPhotoGalleryImages(event);
|
||||
List<String> result = new ArrayList<String>(urls.size());
|
||||
for (ImageDescriptor url : urls) {
|
||||
result.add(url.getURL().toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<ImageDescriptor> getPhotoGalleryImages(EventBase event) {
|
||||
ImageDescriptor stageImage = getStageImage(event); // if set, exclude stage image from photo gallery
|
||||
List<ImageDescriptor> result = new ArrayList<>();
|
||||
Iterable<ImageDescriptor> imageURLs = event.getImages();
|
||||
|
||||
boolean first = true;
|
||||
for (Iterator<ImageDescriptor> iter = imageURLs.iterator(); iter.hasNext(); ) {
|
||||
ImageDescriptor image = iter.next();
|
||||
if(hasTag(image, MediaTagConstants.TEASER)) {
|
||||
continue;
|
||||
}
|
||||
if ((first && !iter.hasNext()) || !Util.equalsWithNull(image, stageImage)) {
|
||||
result.add(image);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<URL> getSailingLovesPhotographyImages(EventBase event) {
|
||||
final List<URL> acceptedImages = new LinkedList<>();
|
||||
for (URL candidateImageUrl : event.getImageURLs()) {
|
||||
try {
|
||||
ImageSize imageSize = event.getImageSize(candidateImageUrl);
|
||||
if (imageSize != null && imageSize.getHeight() > MINIMUM_IMAGE_HEIGHT_FOR_SAILING_PHOTOGRAPHY_IN_PIXELS) {
|
||||
acceptedImages.add(candidateImageUrl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO what should we do here?
|
||||
public static List<ImageDescriptor> getSailingLovesPhotographyImages(EventBase event) {
|
||||
final List<ImageDescriptor> acceptedImages = new LinkedList<>();
|
||||
for (ImageDescriptor candidateImageUrl : event.getImages()) {
|
||||
if (candidateImageUrl.hasSize() && candidateImageUrl.getHeightInPx() > MINIMUM_IMAGE_HEIGHT_FOR_SAILING_PHOTOGRAPHY_IN_PIXELS) {
|
||||
acceptedImages.add(candidateImageUrl);
|
||||
}
|
||||
}
|
||||
return acceptedImages;
|
||||
@@ -389,12 +362,16 @@ public final class HomeServiceUtil {
|
||||
}
|
||||
|
||||
public static boolean hasPhotos(Event event) {
|
||||
// FIXME filter teaser images
|
||||
return Util.size(event.getImageURLs()) > 1;
|
||||
for(ImageDescriptor image : event.getImages()) {
|
||||
if(!hasTag(image, MediaTagConstants.TEASER)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasVideos(Event event) {
|
||||
return !Util.isEmpty(event.getVideoURLs());
|
||||
return !Util.isEmpty(event.getVideos());
|
||||
}
|
||||
|
||||
public static boolean isPartOfEvent(Event event, Regatta regattaEntity) {
|
||||
@@ -406,11 +383,97 @@ public final class HomeServiceUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static URL getRandomURL(Iterable<URL> urls) {
|
||||
public static VideoDescriptor getRandomVideo(Iterable<VideoDescriptor> urls) {
|
||||
if(Util.isEmpty(urls)) {
|
||||
return null;
|
||||
}
|
||||
int size = Util.size(urls);
|
||||
return Util.get(urls, new Random(size).nextInt(size));
|
||||
}
|
||||
|
||||
public static VideoDescriptor getStageVideo(Event event, Locale locale, Collection<String> rankedTags, boolean acceptOtherTags) {
|
||||
VideoDescriptor bestMatch = null;
|
||||
|
||||
for (VideoDescriptor videoCandidate : event.getVideos()) {
|
||||
if(!MediaConstants.SUPPORTED_VIDEO_TYPES.contains(videoCandidate.getMimeType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!acceptOtherTags && !hasOneTag(videoCandidate, rankedTags)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LocaleMatch localeMatch = matchLocale(videoCandidate, locale);
|
||||
if(localeMatch == LocaleMatch.NO_MATCH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(bestMatch == null) {
|
||||
bestMatch = videoCandidate;
|
||||
continue;
|
||||
}
|
||||
|
||||
int compareByTag = compareByTag(videoCandidate, bestMatch, rankedTags);
|
||||
if(compareByTag > 0 || (compareByTag == 0 && isBetter(videoCandidate, bestMatch, locale))) {
|
||||
bestMatch = videoCandidate;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
private static int compareByTag(VideoDescriptor videoCandidate, VideoDescriptor bestMatch,
|
||||
Collection<String> rankedTags) {
|
||||
for(String rankedTag : rankedTags) {
|
||||
boolean hasTag = hasTag(videoCandidate, rankedTag);
|
||||
boolean hasTagBestMatch = hasTag(bestMatch, rankedTag);
|
||||
if(hasTag != hasTagBestMatch) {
|
||||
return hasTag ? 1 : -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static boolean isBetter(VideoDescriptor candidate, VideoDescriptor reference, Locale locale) {
|
||||
LocaleMatch localeMatch = matchLocale(candidate, locale);
|
||||
LocaleMatch localeMatchRef = matchLocale(reference, locale);
|
||||
if(localeMatch != localeMatchRef) {
|
||||
return localeMatch.compareTo(localeMatchRef) < 0 ? true : false;
|
||||
}
|
||||
|
||||
// TODO filter by length
|
||||
|
||||
return candidate.getCreatedAtDate().compareTo(reference.getCreatedAtDate()) > 0;
|
||||
}
|
||||
|
||||
private static boolean hasTag(MediaDescriptor videoCandidate, String tag) {
|
||||
return Util.contains(videoCandidate.getTags(), tag);
|
||||
}
|
||||
|
||||
private static boolean hasOneTag(MediaDescriptor videoCandidate, Collection<String> acceptedTags) {
|
||||
for(String tag : videoCandidate.getTags()) {
|
||||
if(acceptedTags.contains(tag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private enum LocaleMatch {
|
||||
PERFECT, NOT_TAGGED, EN_FALLBACK, NO_MATCH
|
||||
}
|
||||
|
||||
private static LocaleMatch matchLocale(VideoDescriptor videoCandidate, Locale locale) {
|
||||
Locale localeOfCandidate = videoCandidate.getLocale();
|
||||
if(localeOfCandidate == null) {
|
||||
return LocaleMatch.NOT_TAGGED;
|
||||
}
|
||||
if(videoCandidate.getLocale().equals(locale)) {
|
||||
return LocaleMatch.PERFECT;
|
||||
}
|
||||
if(videoCandidate.getLocale().equals(Locale.ENGLISH)) {
|
||||
return LocaleMatch.EN_FALLBACK;
|
||||
}
|
||||
return LocaleMatch.NO_MATCH;
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -8,6 +8,8 @@ import java.util.List;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class EventCreateDialog extends EventDialog {
|
||||
|
||||
@@ -29,9 +31,9 @@ public class EventCreateDialog extends EventDialog {
|
||||
endDateBox.setFormat("dd/mm/yyyy hh:ii");
|
||||
officialWebsiteURLEntryField = createTextBox(null);
|
||||
officialWebsiteURLEntryField.setVisibleLength(50);
|
||||
logoImageURLEntryField = createTextBox(null);
|
||||
logoImageURLEntryField.setVisibleLength(50);
|
||||
isPublicCheckBox = createCheckbox("");
|
||||
isPublicCheckBox.setValue(false);
|
||||
imagesListComposite.fillImages(Collections.<ImageDTO>emptyList());
|
||||
videosListComposite.fillVideos(Collections.<VideoDTO>emptyList());
|
||||
}
|
||||
}
|
||||
+10
-14
@@ -23,8 +23,9 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class EventDetailsComposite extends Composite {
|
||||
private EventDTO event;
|
||||
@@ -38,11 +39,9 @@ public class EventDetailsComposite extends Composite {
|
||||
private final Label isPublic;
|
||||
private final Anchor officialWebsiteURL;
|
||||
private final Anchor eventOverviewURL;
|
||||
private final Anchor logoImageURL;
|
||||
private final SimpleStringListComposite courseAreaNamesList;
|
||||
private final SimpleStringListComposite imageURLList;
|
||||
private final SimpleStringListComposite videoURLList;
|
||||
private final SimpleStringListComposite sponsorImageURLList;
|
||||
private final SimpleStringListComposite leaderboardGroupList;
|
||||
|
||||
private final CaptionPanel mainPanel;
|
||||
@@ -70,11 +69,9 @@ public class EventDetailsComposite extends Composite {
|
||||
isPublic = createLabelAndValueWidget(grid, currentRow++, stringMessages.isPublic(), "IsPublicLabel");
|
||||
officialWebsiteURL = createAnchorAndValueWidget(grid, currentRow++, stringMessages.eventOfficialWebsiteURL(), "OfficialWebsiteURLLabel");
|
||||
eventOverviewURL = createAnchorAndValueWidget(grid, currentRow++, stringMessages.eventOverviewURL(), "EventOverviewURLLabel");
|
||||
logoImageURL = createAnchorAndValueWidget(grid, currentRow++, stringMessages.eventLogoImageURL(), "LogoImageURLLabel");
|
||||
courseAreaNamesList = createLableAndValueListWidget(grid, currentRow++, stringMessages.courseAreas(), "CourseAreaValueList");
|
||||
imageURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.imageURLs(), "ImageURLValueList");
|
||||
videoURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.videoURLs(), "VideoURLValueList");
|
||||
sponsorImageURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.sponsorImageURLs(), "SponsorImageURLValueList");
|
||||
imageURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.images(), "ImageURLValueList");
|
||||
videoURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.videos(), "VideoURLValueList");
|
||||
leaderboardGroupList = createLableAndValueListWidget(grid, currentRow++, stringMessages.leaderboardGroups(), "LeaderboardGroupValueList");
|
||||
|
||||
for(int i=0; i < rows; i++) {
|
||||
@@ -136,8 +133,6 @@ public class EventDetailsComposite extends Composite {
|
||||
String regattaOverviewLink = EntryPointLinkFactory.createRegattaOverviewLink(regattaOverviewURLParameters);
|
||||
eventOverviewURL.setText(regattaOverviewLink);
|
||||
eventOverviewURL.setHref(regattaOverviewLink);
|
||||
logoImageURL.setText(event.getLogoImageURL());
|
||||
logoImageURL.setHref(event.getLogoImageURL());
|
||||
|
||||
List<String> courseAreaNames = new ArrayList<>();
|
||||
if (event.venue.getCourseAreas() != null && event.venue.getCourseAreas().size() > 0) {
|
||||
@@ -148,14 +143,15 @@ public class EventDetailsComposite extends Composite {
|
||||
courseAreaNamesList.setValues(courseAreaNames);
|
||||
|
||||
List<String> imageURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getImageURLs(), imageURLStringsAsList);
|
||||
for(ImageDTO image: event.getImages()) {
|
||||
imageURLStringsAsList.add(image.getSourceRef());
|
||||
}
|
||||
imageURLList.setValues(imageURLStringsAsList);
|
||||
List<String> videoURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getVideoURLs(), videoURLStringsAsList);
|
||||
for(VideoDTO video: event.getVideos()) {
|
||||
videoURLStringsAsList.add(video.getSourceRef());
|
||||
}
|
||||
videoURLList.setValues(videoURLStringsAsList);
|
||||
List<String> sponsorImageURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getSponsorImageURLs(), sponsorImageURLStringsAsList);
|
||||
sponsorImageURLList.setValues(sponsorImageURLStringsAsList);
|
||||
List<String> leaderboardGroupNamesAsList = new ArrayList<>();
|
||||
for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) {
|
||||
leaderboardGroupNamesAsList.add(leaderboardGroupDTO.getName());
|
||||
|
||||
+15
-35
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -30,6 +29,8 @@ import com.sap.sailing.gwt.ui.shared.VenueDTO;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringConstantsListEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO> {
|
||||
protected StringMessages stringMessages;
|
||||
@@ -41,14 +42,12 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
protected CheckBox isPublicCheckBox;
|
||||
protected UUID id;
|
||||
protected TextBox officialWebsiteURLEntryField;
|
||||
protected TextBox logoImageURLEntryField;
|
||||
protected StringListInlineEditorComposite courseAreaNameList;
|
||||
protected StringListInlineEditorComposite imageURLList;
|
||||
protected StringListInlineEditorComposite videoURLList;
|
||||
protected StringListInlineEditorComposite sponsorImageURLList;
|
||||
protected StringConstantsListEditorComposite leaderboardGroupList;
|
||||
protected List<LeaderboardGroupDTO> availableLeaderboardGroups;
|
||||
|
||||
protected ImagesListComposite imagesListComposite;
|
||||
protected VideosListComposite videosListComposite;
|
||||
|
||||
protected static class EventParameterValidator implements Validator<EventDTO> {
|
||||
|
||||
private StringMessages stringMessages;
|
||||
@@ -133,21 +132,6 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
SuggestedCourseAreaNames.suggestedCourseAreaNames, stringMessages.enterCourseAreaName(), 50));
|
||||
courseAreaNameList.addValueChangeHandler(valueChangeHandler);
|
||||
final List<String> imageSuggestionURLs = Arrays.asList(new String[] { "http://", "https://", "http://www.", "https://www" });
|
||||
imageURLList = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(),
|
||||
/* suggestValues */ imageSuggestionURLs, stringMessages.enterImageURL(), 80));
|
||||
imageURLList.addValueChangeHandler(valueChangeHandler);
|
||||
List<String> videoURLSuggestions = new ArrayList<>(imageSuggestionURLs);
|
||||
videoURLSuggestions.add("http://www.youtube.com/watch?v=");
|
||||
videoURLList = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(),
|
||||
/* suggestValues */ videoURLSuggestions, stringMessages.enterVideoURL(), 80));
|
||||
videoURLList.addValueChangeHandler(valueChangeHandler);
|
||||
sponsorImageURLList = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(),
|
||||
/* suggestValues */ imageSuggestionURLs, stringMessages.enterSponsorImageURL(), 80));
|
||||
sponsorImageURLList.addValueChangeHandler(valueChangeHandler);
|
||||
List<String> leaderboardGroupNames = new ArrayList<>();
|
||||
for(LeaderboardGroupDTO leaderboardGroupDTO: availableLeaderboardGroups) {
|
||||
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
|
||||
@@ -156,6 +140,9 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
new StringConstantsListEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(),
|
||||
leaderboardGroupNames, "Select a leaderboard group..."));
|
||||
leaderboardGroupList.addValueChangeHandler(valueChangeHandler);
|
||||
|
||||
imagesListComposite = new ImagesListComposite(stringMessages);
|
||||
videosListComposite = new VideosListComposite(stringMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +157,6 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
result.setName(nameEntryField.getText());
|
||||
result.setDescription(descriptionEntryField.getText());
|
||||
result.setOfficialWebsiteURL(officialWebsiteURLEntryField.getText().trim().isEmpty() ? null : officialWebsiteURLEntryField.getText().trim());
|
||||
result.setLogoImageURL(logoImageURLEntryField.getText().trim().isEmpty() ? null : logoImageURLEntryField.getText().trim());
|
||||
result.startDate = startDateBox.getValue();
|
||||
result.endDate = endDateBox.getValue();
|
||||
result.isPublic = isPublicCheckBox.getValue();
|
||||
@@ -182,14 +168,11 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
courseAreaDTO.setName(courseAreaName);
|
||||
courseAreas.add(courseAreaDTO);
|
||||
}
|
||||
for (String imageURL : imageURLList.getValue()) {
|
||||
result.addImageURL(imageURL);
|
||||
for(ImageDTO image: imagesListComposite.getAllImages()) {
|
||||
result.addImage(image);
|
||||
}
|
||||
for (String videoURL : videoURLList.getValue()) {
|
||||
result.addVideoURL(videoURL);
|
||||
}
|
||||
for (String sponsorImageURL : sponsorImageURLList.getValue()) {
|
||||
result.addSponsorImageURL(sponsorImageURL);
|
||||
for(VideoDTO video: videosListComposite.getAllVideos()) {
|
||||
result.addVideo(video);
|
||||
}
|
||||
result.venue = new VenueDTO(venueEntryField.getText(), courseAreas);
|
||||
return result;
|
||||
@@ -204,7 +187,7 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
|
||||
Grid formGrid = new Grid(8, 2);
|
||||
Grid formGrid = new Grid(7, 2);
|
||||
panel.add(formGrid);
|
||||
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
|
||||
@@ -221,17 +204,14 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
formGrid.setWidget(5, 1, isPublicCheckBox);
|
||||
formGrid.setWidget(6, 0, new Label(stringMessages.eventOfficialWebsiteURL() + ":"));
|
||||
formGrid.setWidget(6, 1, officialWebsiteURLEntryField);
|
||||
formGrid.setWidget(7, 0, new Label(stringMessages.eventLogoImageURL() + ":"));
|
||||
formGrid.setWidget(7, 1, logoImageURLEntryField);
|
||||
|
||||
TabLayoutPanel tabPanel = new TabLayoutPanel(30, Unit.PX);
|
||||
tabPanel.setHeight("250px");
|
||||
panel.add(tabPanel);
|
||||
tabPanel.add(new ScrollPanel(leaderboardGroupList), stringMessages.leaderboardGroups());
|
||||
tabPanel.add(new ScrollPanel(courseAreaNameList), stringMessages.courseAreas());
|
||||
tabPanel.add(new ScrollPanel(imageURLList), stringMessages.imageURLs());
|
||||
tabPanel.add(new ScrollPanel(videoURLList), stringMessages.videoURLs());
|
||||
tabPanel.add(new ScrollPanel(sponsorImageURLList), stringMessages.sponsorImageURLs());
|
||||
tabPanel.add(new ScrollPanel(imagesListComposite), "Images");
|
||||
tabPanel.add(new ScrollPanel(videosListComposite), "Videos");
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
+2
-12
@@ -8,7 +8,6 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class EventEditDialog extends EventDialog {
|
||||
public EventEditDialog(EventDTO event, Collection<EventDTO> otherExistingEvents, List<LeaderboardGroupDTO> availableLeaderboardGroups, StringMessages stringMessages, DialogCallback<EventDTO> callback) {
|
||||
@@ -37,22 +36,13 @@ public class EventEditDialog extends EventDialog {
|
||||
}
|
||||
officialWebsiteURLEntryField = createTextBox(event.getOfficialWebsiteURL());
|
||||
officialWebsiteURLEntryField.setVisibleLength(50);
|
||||
logoImageURLEntryField = createTextBox(event.getLogoImageURL());
|
||||
logoImageURLEntryField.setVisibleLength(50);
|
||||
courseAreaNameList.setValue(courseAreaNames);
|
||||
List<String> imageURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getImageURLs(), imageURLStringsAsList);
|
||||
imageURLList.setValue(imageURLStringsAsList);
|
||||
List<String> videoURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getVideoURLs(), videoURLStringsAsList);
|
||||
videoURLList.setValue(videoURLStringsAsList);
|
||||
List<String> sponsorImageURLStringsAsList = new ArrayList<>();
|
||||
Util.addAll(event.getSponsorImageURLs(), sponsorImageURLStringsAsList);
|
||||
sponsorImageURLList.setValue(sponsorImageURLStringsAsList);
|
||||
List<String> leaderboardGroupNames = new ArrayList<>();
|
||||
for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) {
|
||||
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
|
||||
}
|
||||
leaderboardGroupList.setValue(leaderboardGroupNames);
|
||||
imagesListComposite.fillImages(event.getImages());
|
||||
videosListComposite.fillVideos(event.getVideos());
|
||||
}
|
||||
}
|
||||
+10
-28
@@ -283,12 +283,12 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
return builder.toSafeHtml();
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<EventDTO> imageURLsColumn = new TextColumn<EventDTO>() {
|
||||
|
||||
TextColumn<EventDTO> imagesColumn = new TextColumn<EventDTO>() {
|
||||
@Override
|
||||
public String getValue(EventDTO event) {
|
||||
String result = "";
|
||||
int imageCount = Util.size(event.getImageURLs());
|
||||
int imageCount = Util.size(event.getImages());
|
||||
if(imageCount > 0) {
|
||||
result = imageCount + " image(s)";
|
||||
}
|
||||
@@ -296,11 +296,11 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<EventDTO> videoURLsColumn = new TextColumn<EventDTO>() {
|
||||
TextColumn<EventDTO> videosColumn = new TextColumn<EventDTO>() {
|
||||
@Override
|
||||
public String getValue(EventDTO event) {
|
||||
String result = "";
|
||||
int videoCount = Util.size(event.getVideoURLs());
|
||||
int videoCount = Util.size(event.getVideos());
|
||||
if(videoCount > 0) {
|
||||
result = videoCount + " video(s)";
|
||||
}
|
||||
@@ -308,18 +308,6 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<EventDTO> sponsorImageURLsColumn = new TextColumn<EventDTO>() {
|
||||
@Override
|
||||
public String getValue(EventDTO event) {
|
||||
String result = "";
|
||||
int sponsorImageCount = Util.size(event.getSponsorImageURLs());
|
||||
if(sponsorImageCount > 0) {
|
||||
result = sponsorImageCount + " sponsor image(s)";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
SafeHtmlCell associatedRegattasCell = new SafeHtmlCell();
|
||||
Column<EventDTO, SafeHtml> associatedRegattasColumn = new Column<EventDTO, SafeHtml>(associatedRegattasCell) {
|
||||
@Override
|
||||
@@ -358,9 +346,6 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
isPublicColumn.setSortable(true);
|
||||
startEndDateColumn.setSortable(true);
|
||||
courseAreasColumn.setSortable(true);
|
||||
imageURLsColumn.setSortable(true);
|
||||
videoURLsColumn.setSortable(true);
|
||||
sponsorImageURLsColumn.setSortable(true);
|
||||
leaderboardGroupsColumn.setSortable(true);
|
||||
|
||||
table.addColumn(eventSelectionCheckboxColumn, eventSelectionCheckboxColumn.getHeader());
|
||||
@@ -370,9 +355,8 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
table.addColumn(isPublicColumn, stringMessages.isPublic());
|
||||
table.addColumn(courseAreasColumn, stringMessages.courseAreas());
|
||||
table.addColumn(leaderboardGroupsColumn, stringMessages.leaderboardGroups());
|
||||
table.addColumn(imageURLsColumn, stringMessages.imageURLs());
|
||||
table.addColumn(videoURLsColumn, stringMessages.videoURLs());
|
||||
table.addColumn(sponsorImageURLsColumn, stringMessages.sponsorImageURLs());
|
||||
table.addColumn(imagesColumn, stringMessages.images());
|
||||
table.addColumn(videosColumn, stringMessages.videos());
|
||||
table.addColumn(associatedRegattasColumn, stringMessages.regattas());
|
||||
table.addColumn(eventActionColumn, stringMessages.actions());
|
||||
table.setSelectionModel(eventSelectionCheckboxColumn.getSelectionModel(), eventSelectionCheckboxColumn.getSelectionManager());
|
||||
@@ -507,8 +491,7 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
sailingService.updateEvent(oldEvent.id, oldEvent.getName(), updatedEvent.getDescription(),
|
||||
updatedEvent.startDate, updatedEvent.endDate, updatedEvent.venue,
|
||||
updatedEvent.isPublic, updatedEventLeaderboardGroupIds,
|
||||
updatedEvent.getOfficialWebsiteURL(), updatedEvent.getLogoImageURL(),
|
||||
updatedEvent.getImageURLs(), updatedEvent.getVideoURLs(), updatedEvent.getSponsorImageURLs(),
|
||||
updatedEvent.getOfficialWebsiteURL(), updatedEvent.getImages(), updatedEvent.getVideos(),
|
||||
new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
@@ -579,9 +562,8 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
courseAreaNames.add(courseAreaDTO.getName());
|
||||
}
|
||||
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
|
||||
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
|
||||
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
|
||||
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
|
||||
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getOfficialWebsiteURL(),
|
||||
newEvent.getImages(), newEvent.getVideos(), new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
errorReporter.reportError("Error trying to create new event " + newEvent.getName() + ": " + t.getMessage());
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.text.shared.SafeHtmlRenderer;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.controls.ImagesBarCell;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
|
||||
public class ImageConfigImagesBarCell extends ImagesBarCell {
|
||||
static final String ACTION_REMOVE = "ACTION_REMOVE";
|
||||
static final String ACTION_EDIT = "ACTION_EDIT";
|
||||
private final StringMessages stringMessages;
|
||||
private static AdminConsoleResources resources = GWT.create(AdminConsoleResources.class);
|
||||
|
||||
public ImageConfigImagesBarCell(StringMessages stringMessages) {
|
||||
super();
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
public ImageConfigImagesBarCell(SafeHtmlRenderer<String> renderer, StringMessages stringMessages) {
|
||||
super();
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<ImageSpec> getImageSpecs() {
|
||||
return Arrays.asList(
|
||||
new ImageSpec(ACTION_EDIT, stringMessages.actionEdit(), makeImagePrototype(resources.editIcon())),
|
||||
new ImageSpec(ACTION_REMOVE, stringMessages.actionRemove(), makeImagePrototype(IconResources.INSTANCE.removeIcon()))
|
||||
);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class ImageCreateDialog extends ImageDialog {
|
||||
|
||||
public ImageCreateDialog(String initialTag, StringMessages stringMessages, DialogCallback<ImageDTO> callback) {
|
||||
super(new ImageParameterValidator(stringMessages), stringMessages, callback);
|
||||
createdAtLabel = new Label(creationDate.toString());
|
||||
titleTextBox = createTextBox(null);
|
||||
titleTextBox.setVisibleLength(50);
|
||||
subtitleTextBox = createTextBox(null);
|
||||
subtitleTextBox.setVisibleLength(50);
|
||||
copyrightTextBox = createTextBox(null);
|
||||
copyrightTextBox.setVisibleLength(50);
|
||||
widthInPxBox = createIntegerBox(null, 10);
|
||||
heightInPxBox = createIntegerBox(null, 10);
|
||||
List<String> tags = new ArrayList<>();
|
||||
if(initialTag != null && !initialTag.isEmpty()) {
|
||||
tags.add(initialTag);
|
||||
}
|
||||
tagsListEditor.setValue(tags);
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.Style.Position;
|
||||
import com.google.gwt.dom.client.Style.Visibility;
|
||||
import com.google.gwt.event.dom.client.LoadEvent;
|
||||
import com.google.gwt.event.dom.client.LoadHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
|
||||
import com.sap.sse.gwt.adminconsole.URLFieldWithFileUpload;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public abstract class ImageDialog extends DataEntryDialog<ImageDTO> {
|
||||
protected final StringMessages stringMessages;
|
||||
protected final URLFieldWithFileUpload imageURLAndUploadComposite;
|
||||
protected final Date creationDate;
|
||||
protected Label createdAtLabel;
|
||||
protected TextBox titleTextBox;
|
||||
protected TextBox subtitleTextBox;
|
||||
protected TextBox copyrightTextBox;
|
||||
protected IntegerBox widthInPxBox;
|
||||
protected IntegerBox heightInPxBox;
|
||||
protected StringListInlineEditorComposite tagsListEditor;
|
||||
|
||||
final Image image;
|
||||
|
||||
protected static class ImageParameterValidator implements Validator<ImageDTO> {
|
||||
private StringMessages stringMessages;
|
||||
|
||||
public ImageParameterValidator(StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(ImageDTO imageToValidate) {
|
||||
String errorMessage = null;
|
||||
|
||||
if(imageToValidate.getSourceRef() == null || imageToValidate.getSourceRef().isEmpty()) {
|
||||
errorMessage = stringMessages.pleaseEnterNonEmptyUrl();
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public ImageDialog(ImageParameterValidator validator, StringMessages stringMessages, DialogCallback<ImageDTO> callback) {
|
||||
super(stringMessages.image(), null, stringMessages.ok(), stringMessages.cancel(), validator,
|
||||
callback);
|
||||
this.stringMessages = stringMessages;
|
||||
this.creationDate = new Date();
|
||||
getDialogBox().getWidget().setWidth("730px");
|
||||
|
||||
image = new Image();
|
||||
image.addLoadHandler(new LoadHandler() {
|
||||
@Override
|
||||
public void onLoad(LoadEvent event) {
|
||||
int width = image.getOffsetWidth();
|
||||
int height = image.getOffsetHeight();
|
||||
|
||||
if(width > 0 && height > 0) {
|
||||
widthInPxBox.setValue(width);
|
||||
heightInPxBox.setValue(height);
|
||||
}
|
||||
}
|
||||
});
|
||||
image.getElement().getStyle().setPosition(Position.ABSOLUTE);
|
||||
image.getElement().getStyle().setVisibility(Visibility.HIDDEN);
|
||||
|
||||
imageURLAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
||||
imageURLAndUploadComposite.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
validate();
|
||||
image.setUrl(event.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
tagsListEditor = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
MediaConstants.imageTagSuggestions, "Enter tags for the image", 50));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageDTO getResult() {
|
||||
ImageDTO result = new ImageDTO(imageURLAndUploadComposite.getURL(), creationDate);
|
||||
result.setTitle(titleTextBox.getValue());
|
||||
result.setSubtitle(subtitleTextBox.getValue());
|
||||
result.setCopyright(copyrightTextBox.getValue());
|
||||
if(widthInPxBox.getValue() != null && heightInPxBox.getValue() != null) {
|
||||
result.setSizeInPx(widthInPxBox.getValue(), heightInPxBox.getValue());
|
||||
}
|
||||
List<String> tags = new ArrayList<String>();
|
||||
for (String tag: tagsListEditor.getValue()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.setTags(tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
final VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("100%");
|
||||
Widget additionalWidget = super.getAdditionalWidget();
|
||||
if (additionalWidget != null) {
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
|
||||
Grid formGrid = new Grid(8, 2);
|
||||
panel.add(formGrid);
|
||||
|
||||
formGrid.setWidget(0, 0, new Label("Created at:"));
|
||||
formGrid.setWidget(0, 1, createdAtLabel);
|
||||
formGrid.setWidget(1, 0, new Label("Image URL:"));
|
||||
formGrid.setWidget(1, 1, imageURLAndUploadComposite);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.title() + ":"));
|
||||
formGrid.setWidget(2, 1, titleTextBox);
|
||||
formGrid.setWidget(3, 0, new Label("Subtitle:"));
|
||||
formGrid.setWidget(3, 1, subtitleTextBox);
|
||||
formGrid.setWidget(4, 0, new Label("Copyright:"));
|
||||
formGrid.setWidget(4, 1, copyrightTextBox);
|
||||
formGrid.setWidget(5, 0, new Label("Width in px:"));
|
||||
formGrid.setWidget(5, 1, widthInPxBox);
|
||||
formGrid.setWidget(6, 0, new Label("Height in px:"));
|
||||
formGrid.setWidget(6, 1, heightInPxBox);
|
||||
formGrid.setWidget(7, 0, new Label("Tags:"));
|
||||
formGrid.setWidget(7, 1, tagsListEditor);
|
||||
|
||||
panel.add(image);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
imageURLAndUploadComposite.setFocus(true);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class ImageEditDialog extends ImageDialog {
|
||||
public ImageEditDialog(ImageDTO image, StringMessages stringMessages, DialogCallback<ImageDTO> callback) {
|
||||
super(new ImageParameterValidator(stringMessages), stringMessages, callback);
|
||||
createdAtLabel = new Label(image.getCreatedAtDate().toString());
|
||||
imageURLAndUploadComposite.setURL(image.getSourceRef());
|
||||
titleTextBox = createTextBox(image.getTitle());
|
||||
titleTextBox.setVisibleLength(50);
|
||||
subtitleTextBox = createTextBox(image.getSubtitle());
|
||||
subtitleTextBox.setVisibleLength(50);
|
||||
copyrightTextBox = createTextBox(image.getCopyright());
|
||||
copyrightTextBox.setVisibleLength(50);
|
||||
widthInPxBox = createIntegerBox(image.getWidthInPx(), 10);
|
||||
heightInPxBox = createIntegerBox(image.getHeightInPx(), 10);
|
||||
List<String> tags = new ArrayList<String>();
|
||||
tags.addAll(image.getTags());
|
||||
tagsListEditor.setValue(tags);
|
||||
}
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.cell.client.AbstractCell;
|
||||
import com.google.gwt.cell.client.FieldUpdater;
|
||||
import com.google.gwt.cell.client.SafeHtmlCell;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
|
||||
import com.google.gwt.safehtml.shared.SafeHtml;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
|
||||
import com.google.gwt.user.cellview.client.TextColumn;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SingleSelectionModel;
|
||||
import com.sap.sailing.domain.common.impl.NaturalComparator;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
/**
|
||||
* /** A composite showing the list of media images
|
||||
*
|
||||
* @author Frank Mittag (C5163974)
|
||||
*/
|
||||
public class ImagesListComposite extends Composite {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
private CellTable<ImageDTO> imageTable;
|
||||
private SingleSelectionModel<ImageDTO> imageSelectionModel;
|
||||
private ListDataProvider<ImageDTO> imageListDataProvider;
|
||||
private final Label noImagesLabel;
|
||||
|
||||
private final SimplePanel mainPanel;
|
||||
private final VerticalPanel panel;
|
||||
|
||||
public static class AnchorCell extends AbstractCell<SafeHtml> {
|
||||
@Override
|
||||
public void render(com.google.gwt.cell.client.Cell.Context context, SafeHtml safeHtml, SafeHtmlBuilder sb) {
|
||||
sb.append(safeHtml);
|
||||
}
|
||||
}
|
||||
|
||||
interface AnchorTemplates extends SafeHtmlTemplates {
|
||||
@SafeHtmlTemplates.Template("<a target=\"_blank\" href=\"{0}\">{1}</a>")
|
||||
SafeHtml cell(String url, String displayName);
|
||||
}
|
||||
|
||||
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
|
||||
|
||||
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
|
||||
|
||||
public ImagesListComposite(final StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
|
||||
mainPanel = new SimplePanel();
|
||||
panel = new VerticalPanel();
|
||||
mainPanel.setWidget(panel);
|
||||
|
||||
HorizontalPanel imagesControlsPanel = new HorizontalPanel();
|
||||
imagesControlsPanel.setSpacing(5);
|
||||
panel.add(imagesControlsPanel);
|
||||
|
||||
Button addPhotoBtn = new Button("Add gallery photo");
|
||||
addPhotoBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateImageDialog(MediaTagConstants.GALLERY);
|
||||
}
|
||||
});
|
||||
imagesControlsPanel.add(addPhotoBtn);
|
||||
|
||||
Button addStateImageBtn = new Button("Add stage image");
|
||||
addStateImageBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateImageDialog(MediaTagConstants.STAGE);
|
||||
}
|
||||
});
|
||||
imagesControlsPanel.add(addStateImageBtn);
|
||||
|
||||
Button addEventTeaseImageBtn = new Button("Add teaser image");
|
||||
addEventTeaseImageBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateImageDialog(MediaTagConstants.TEASER);
|
||||
}
|
||||
});
|
||||
imagesControlsPanel.add(addEventTeaseImageBtn);
|
||||
|
||||
Button addLogoImageBtn = new Button("Add event logo");
|
||||
addLogoImageBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateImageDialog(MediaTagConstants.LOGO);
|
||||
}
|
||||
});
|
||||
imagesControlsPanel.add(addLogoImageBtn);
|
||||
|
||||
imageSelectionModel = new SingleSelectionModel<ImageDTO>();
|
||||
imageListDataProvider = new ListDataProvider<ImageDTO>();
|
||||
imageTable = createImagesTable();
|
||||
imageTable.ensureDebugId("ImagesCellTable");
|
||||
imageTable.setVisible(false);
|
||||
|
||||
imageSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
|
||||
@Override
|
||||
public void onSelectionChange(SelectionChangeEvent event) {
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(imageTable);
|
||||
|
||||
noImagesLabel = new Label("No images defined yet.");
|
||||
noImagesLabel.ensureDebugId("NoImagesLabel");
|
||||
noImagesLabel.setWordWrap(false);
|
||||
panel.add(noImagesLabel);
|
||||
|
||||
initWidget(mainPanel);
|
||||
}
|
||||
|
||||
private CellTable<ImageDTO> createImagesTable() {
|
||||
CellTable<ImageDTO> table = new CellTable<ImageDTO>(/* pageSize */10000, tableRes);
|
||||
imageListDataProvider.addDataDisplay(table);
|
||||
table.setWidth("100%");
|
||||
|
||||
AnchorCell anchorCell = new AnchorCell();
|
||||
Column<ImageDTO, SafeHtml> shortImageNameColumn = new Column<ImageDTO, SafeHtml>(anchorCell) {
|
||||
@Override
|
||||
public SafeHtml getValue(ImageDTO image) {
|
||||
String linkName = "";
|
||||
String link = image.getSourceRef();
|
||||
if(link.endsWith("/")) {
|
||||
link = link.substring(0, link.length() - 1);
|
||||
}
|
||||
int index = link.lastIndexOf("/");
|
||||
if(index > 0) {
|
||||
linkName = link.substring(index+1, link.length());
|
||||
}
|
||||
return ANCHORTEMPLATE.cell(image.getSourceRef(), linkName);
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<ImageDTO> titleColumn = new TextColumn<ImageDTO>() {
|
||||
@Override
|
||||
public String getValue(ImageDTO image) {
|
||||
return image.getTitle() != null ? image.getTitle() : "";
|
||||
}
|
||||
};
|
||||
TextColumn<ImageDTO> sizeColumn = new TextColumn<ImageDTO>() {
|
||||
@Override
|
||||
public String getValue(ImageDTO image) {
|
||||
String imageSize = "";
|
||||
if (image.getWidthInPx() != null && image.getHeightInPx() != null) {
|
||||
imageSize = image.getWidthInPx() + " x " + image.getHeightInPx();
|
||||
}
|
||||
return imageSize;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<ImageDTO> createdAtDateColumn = new TextColumn<ImageDTO>() {
|
||||
@Override
|
||||
public String getValue(ImageDTO image) {
|
||||
return DateAndTimeFormatterUtil.formatDateAndTime(image.getCreatedAtDate());
|
||||
}
|
||||
};
|
||||
|
||||
SafeHtmlCell tagsCell = new SafeHtmlCell();
|
||||
Column<ImageDTO, SafeHtml> tagsColumn = new Column<ImageDTO, SafeHtml>(tagsCell) {
|
||||
@Override
|
||||
public SafeHtml getValue(ImageDTO image) {
|
||||
SafeHtmlBuilder builder = new SafeHtmlBuilder();
|
||||
int tagsCount = image.getTags().size();
|
||||
int i = 1;
|
||||
for (String tag : image.getTags()) {
|
||||
builder.appendEscaped(tag);
|
||||
if (i < tagsCount) {
|
||||
builder.appendHtmlConstant(", ");
|
||||
// not more than 4 tags per line
|
||||
if (i % 4 == 0) {
|
||||
builder.appendHtmlConstant("<br>");
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return builder.toSafeHtml();
|
||||
}
|
||||
};
|
||||
|
||||
ImagesBarColumn<ImageDTO, ImageConfigImagesBarCell> imageActionColumn = new ImagesBarColumn<ImageDTO, ImageConfigImagesBarCell>(
|
||||
new ImageConfigImagesBarCell(stringMessages));
|
||||
imageActionColumn.setFieldUpdater(new FieldUpdater<ImageDTO, String>() {
|
||||
@Override
|
||||
public void update(int index, ImageDTO image, String value) {
|
||||
if (ImageConfigImagesBarCell.ACTION_REMOVE.equals(value)) {
|
||||
imageListDataProvider.getList().remove(image);
|
||||
updateTableVisisbilty();
|
||||
} else if (ImageConfigImagesBarCell.ACTION_EDIT.equals(value)) {
|
||||
openEditImageDialog(image);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
titleColumn.setSortable(true);
|
||||
createdAtDateColumn.setSortable(true);
|
||||
|
||||
table.addColumn(shortImageNameColumn, "Short name:");
|
||||
table.addColumn(titleColumn, stringMessages.title());
|
||||
table.addColumn(createdAtDateColumn, "Created At");
|
||||
table.addColumn(sizeColumn, "Size");
|
||||
table.addColumn(tagsColumn, "Tags");
|
||||
table.addColumn(imageActionColumn, stringMessages.actions());
|
||||
table.addColumnSortHandler(getImageTableColumnSortHandler(imageListDataProvider.getList(), titleColumn, createdAtDateColumn));
|
||||
table.getColumnSortList().push(createdAtDateColumn);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private ListHandler<ImageDTO> getImageTableColumnSortHandler(List<ImageDTO> imageRecords,
|
||||
TextColumn<ImageDTO> titleColumn, TextColumn<ImageDTO> createdAtDateColumn) {
|
||||
ListHandler<ImageDTO> result = new ListHandler<ImageDTO>(imageRecords);
|
||||
result.setComparator(titleColumn, new Comparator<ImageDTO>() {
|
||||
@Override
|
||||
public int compare(ImageDTO i1, ImageDTO i2) {
|
||||
return new NaturalComparator().compare(i1.getTitle(), i2.getTitle());
|
||||
}
|
||||
});
|
||||
result.setComparator(createdAtDateColumn, new Comparator<ImageDTO>() {
|
||||
@Override
|
||||
public int compare(ImageDTO e1, ImageDTO e2) {
|
||||
int result;
|
||||
if (e1.getCreatedAtDate() != null && e2.getCreatedAtDate() != null) {
|
||||
result = e2.getCreatedAtDate().compareTo(e1.getCreatedAtDate());
|
||||
} else if (e1.getCreatedAtDate() == null && e2.getCreatedAtDate() != null) {
|
||||
result = 1;
|
||||
} else if (e1.getCreatedAtDate() != null && e2.getCreatedAtDate() == null) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private void openCreateImageDialog(String initialTag) {
|
||||
ImageCreateDialog dialog = new ImageCreateDialog(initialTag, stringMessages, new DialogCallback<ImageDTO>() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ok(ImageDTO newImage) {
|
||||
imageListDataProvider.getList().add(newImage);
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void openEditImageDialog(final ImageDTO selectedImage) {
|
||||
ImageEditDialog dialog = new ImageEditDialog(selectedImage, stringMessages, new DialogCallback<ImageDTO>() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ok(ImageDTO updatedImage) {
|
||||
imageListDataProvider.getList().remove(selectedImage);
|
||||
imageListDataProvider.getList().add(updatedImage);
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void updateTableVisisbilty() {
|
||||
if (imageListDataProvider.getList().isEmpty()) {
|
||||
imageTable.setVisible(false);
|
||||
noImagesLabel.setVisible(true);
|
||||
} else {
|
||||
imageTable.setVisible(true);
|
||||
noImagesLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void fillImages(List<ImageDTO> images) {
|
||||
imageSelectionModel.clear();
|
||||
imageListDataProvider.getList().clear();
|
||||
imageListDataProvider.getList().addAll(images);
|
||||
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
|
||||
public List<ImageDTO> getAllImages() {
|
||||
return imageListDataProvider.getList();
|
||||
}
|
||||
}
|
||||
+1
-16
@@ -30,14 +30,11 @@ public class RegattaImportDialog extends DataEntryDialog<String>{
|
||||
protected CheckBox isPublicCheckBox;
|
||||
protected UUID id;
|
||||
protected TextBox officialWebsiteURLEntryField;
|
||||
protected TextBox logoImageURLEntryField;
|
||||
protected StringListInlineEditorComposite courseAreaNameList;
|
||||
protected StringListInlineEditorComposite imageURLList;
|
||||
protected StringListInlineEditorComposite videoURLList;
|
||||
protected StringListInlineEditorComposite sponsorImageURLList;
|
||||
|
||||
|
||||
|
||||
public RegattaImportDialog(StringMessages stringMessages, String message,
|
||||
com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator<String> validator,
|
||||
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback<String> callback) {
|
||||
@@ -53,7 +50,7 @@ public class RegattaImportDialog extends DataEntryDialog<String>{
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
|
||||
Grid formGrid = new Grid(8, 2);
|
||||
Grid formGrid = new Grid(7, 2);
|
||||
panel.add(formGrid);
|
||||
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
|
||||
@@ -70,8 +67,6 @@ public class RegattaImportDialog extends DataEntryDialog<String>{
|
||||
formGrid.setWidget(5, 1, isPublicCheckBox);
|
||||
formGrid.setWidget(6, 0, new Label(stringMessages.eventOfficialWebsiteURL() + ":"));
|
||||
formGrid.setWidget(6, 1, officialWebsiteURLEntryField);
|
||||
formGrid.setWidget(7, 0, new Label(stringMessages.eventLogoImageURL() + ":"));
|
||||
formGrid.setWidget(7, 1, logoImageURLEntryField);
|
||||
|
||||
panel.add(createHeadlineLabel(stringMessages.courseAreas()));
|
||||
panel.add(courseAreaNameList);
|
||||
@@ -89,7 +84,6 @@ public class RegattaImportDialog extends DataEntryDialog<String>{
|
||||
result.setName(nameEntryField.getText());
|
||||
result.setDescription(descriptionEntryField.getText());
|
||||
result.setOfficialWebsiteURL(officialWebsiteURLEntryField.getText().trim().isEmpty() ? null : officialWebsiteURLEntryField.getText().trim());
|
||||
result.setLogoImageURL(logoImageURLEntryField.getText().trim().isEmpty() ? null : logoImageURLEntryField.getText().trim());
|
||||
result.startDate = startDateBox.getValue();
|
||||
result.endDate = endDateBox.getValue();
|
||||
result.isPublic = isPublicCheckBox.getValue();
|
||||
@@ -101,15 +95,6 @@ public class RegattaImportDialog extends DataEntryDialog<String>{
|
||||
courseAreaDTO.setName(courseAreaName);
|
||||
courseAreas.add(courseAreaDTO);
|
||||
}
|
||||
for (String imageURL : imageURLList.getValue()) {
|
||||
result.addImageURL(imageURL);
|
||||
}
|
||||
for (String videoURL : videoURLList.getValue()) {
|
||||
result.addVideoURL(videoURL);
|
||||
}
|
||||
for (String sponsorImageURL : sponsorImageURLList.getValue()) {
|
||||
result.addSponsorImageURL(sponsorImageURL);
|
||||
}
|
||||
result.venue = new VenueDTO(venueEntryField.getText(), courseAreas);
|
||||
return "OK";
|
||||
}
|
||||
|
||||
+3
-3
@@ -246,9 +246,9 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
|
||||
courseAreaNames.add(courseAreaDTO.getName());
|
||||
}
|
||||
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
|
||||
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
|
||||
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
|
||||
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
|
||||
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getOfficialWebsiteURL(),
|
||||
newEvent.getImages(), newEvent.getVideos(),
|
||||
new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
errorReporter.reportError(stringMessages.errorTryingToCreateNewEvent(newEvent.getName(), t.getMessage()));
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.text.shared.SafeHtmlRenderer;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.controls.ImagesBarCell;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
|
||||
public class VideoConfigImagesBarCell extends ImagesBarCell {
|
||||
static final String ACTION_REMOVE = "ACTION_REMOVE";
|
||||
static final String ACTION_EDIT = "ACTION_EDIT";
|
||||
private final StringMessages stringMessages;
|
||||
private static AdminConsoleResources resources = GWT.create(AdminConsoleResources.class);
|
||||
|
||||
public VideoConfigImagesBarCell(StringMessages stringMessages) {
|
||||
super();
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
public VideoConfigImagesBarCell(SafeHtmlRenderer<String> renderer, StringMessages stringMessages) {
|
||||
super();
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<ImageSpec> getImageSpecs() {
|
||||
return Arrays.asList(
|
||||
new ImageSpec(ACTION_EDIT, stringMessages.actionEdit(), makeImagePrototype(resources.editIcon())),
|
||||
new ImageSpec(ACTION_REMOVE, stringMessages.actionRemove(), makeImagePrototype(IconResources.INSTANCE.removeIcon()))
|
||||
);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class VideoCreateDialog extends VideoDialog {
|
||||
|
||||
public VideoCreateDialog(StringMessages stringMessages, DialogCallback<VideoDTO> callback) {
|
||||
super(new VideoParameterValidator(stringMessages), stringMessages, callback);
|
||||
createdAtLabel = new Label(creationDate.toString());
|
||||
titleTextBox = createTextBox(null);
|
||||
titleTextBox.setVisibleLength(50);
|
||||
subtitleTextBox = createTextBox(null);
|
||||
subtitleTextBox.setVisibleLength(50);
|
||||
copyrightTextBox = createTextBox(null);
|
||||
copyrightTextBox.setVisibleLength(50);
|
||||
lengthIntegerBox = createIntegerBox(null, 10);
|
||||
tagsListEditor.setValue(Collections.<String>emptyList());
|
||||
setSelectedMimeType(MimeType.unknown);
|
||||
}
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.shared.GWT;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.gwt.adminconsole.URLFieldWithFileUpload;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public abstract class VideoDialog extends DataEntryDialog<VideoDTO> {
|
||||
private static final String NO_LOCALE_TEXT = "---";
|
||||
protected final StringMessages stringMessages;
|
||||
protected final URLFieldWithFileUpload videoURLAndUploadComposite;
|
||||
protected final Date creationDate;
|
||||
protected Label createdAtLabel;
|
||||
protected TextBox titleTextBox;
|
||||
protected TextBox subtitleTextBox;
|
||||
protected TextBox copyrightTextBox;
|
||||
protected final ListBox mimeTypeListBox;
|
||||
protected final ListBox localeListBox;
|
||||
protected IntegerBox lengthIntegerBox;
|
||||
protected final URLFieldWithFileUpload thumbnailURLAndUploadComposite;
|
||||
protected StringListInlineEditorComposite tagsListEditor;
|
||||
|
||||
protected static class VideoParameterValidator implements Validator<VideoDTO> {
|
||||
private StringMessages stringMessages;
|
||||
|
||||
public VideoParameterValidator(StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(VideoDTO videoToValidate) {
|
||||
String errorMessage = null;
|
||||
|
||||
if(videoToValidate.getSourceRef() == null || videoToValidate.getSourceRef().isEmpty()) {
|
||||
errorMessage = stringMessages.pleaseEnterNonEmptyUrl();
|
||||
} else if (videoToValidate.getMimeType() == null) {
|
||||
errorMessage = "You must select the mime type for the video.";
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public VideoDialog(VideoParameterValidator validator, StringMessages stringMessages, DialogCallback<VideoDTO> callback) {
|
||||
super(stringMessages.video(), null, stringMessages.ok(), stringMessages.cancel(), validator,
|
||||
callback);
|
||||
this.stringMessages = stringMessages;
|
||||
this.creationDate = new Date();
|
||||
getDialogBox().getWidget().setWidth("730px");
|
||||
|
||||
mimeTypeListBox = createListBox(false);
|
||||
mimeTypeListBox.addItem(MimeType.unknown.name());
|
||||
mimeTypeListBox.addItem(MimeType.aac.name());
|
||||
mimeTypeListBox.addItem(MimeType.mp4.name());
|
||||
mimeTypeListBox.addItem(MimeType.ogg.name());
|
||||
mimeTypeListBox.addItem(MimeType.ogv.name());
|
||||
mimeTypeListBox.addItem(MimeType.qt.name());
|
||||
mimeTypeListBox.addItem(MimeType.youtube.name());
|
||||
mimeTypeListBox.addItem(MimeType.vimeo.name());
|
||||
|
||||
GWT.debugger();
|
||||
localeListBox = createListBox(false);
|
||||
localeListBox.addItem(NO_LOCALE_TEXT, "");
|
||||
localeListBox.addItem("English", "en");
|
||||
localeListBox.addItem("German", "de");
|
||||
localeListBox.addItem("Russian", "ru");
|
||||
localeListBox.addItem("Chinese", "zh");
|
||||
|
||||
videoURLAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
||||
videoURLAndUploadComposite.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
validate();
|
||||
}
|
||||
});
|
||||
thumbnailURLAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
||||
|
||||
tagsListEditor = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
MediaConstants.videoTagSuggestions, "Enter tags for the video", 50));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VideoDTO getResult() {
|
||||
VideoDTO result = new VideoDTO(videoURLAndUploadComposite.getURL(), getSelectedMimeType(), creationDate);
|
||||
result.setTitle(titleTextBox.getValue());
|
||||
result.setSubtitle(subtitleTextBox.getValue());
|
||||
result.setCopyright(copyrightTextBox.getValue());
|
||||
result.setLocale(getSelectedLocale());
|
||||
List<String> tags = new ArrayList<String>();
|
||||
for (String tag: tagsListEditor.getValue()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.setTags(tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void setSelectedMimeType(MimeType mimeType) {
|
||||
for(int i = 0; i < mimeTypeListBox.getItemCount(); i++) {
|
||||
if(mimeTypeListBox.getItemText(i).equals(mimeType.name())) {
|
||||
mimeTypeListBox.setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MimeType getSelectedMimeType() {
|
||||
MimeType result = null;
|
||||
int selectedIndex = mimeTypeListBox.getSelectedIndex();
|
||||
if(selectedIndex >= 0) {
|
||||
result = MimeType.valueOf(mimeTypeListBox.getSelectedValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void setSelectedLocale(String locale) {
|
||||
for(int i = 0; i < localeListBox.getItemCount(); i++) {
|
||||
if(Util.equalsWithNull(localeListBox.getValue(i), locale)) {
|
||||
localeListBox.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
localeListBox.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
private String getSelectedLocale() {
|
||||
return localeListBox.getSelectedValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
final VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("100%");
|
||||
Widget additionalWidget = super.getAdditionalWidget();
|
||||
if (additionalWidget != null) {
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
|
||||
Grid formGrid = new Grid(10, 2);
|
||||
panel.add(formGrid);
|
||||
|
||||
formGrid.setWidget(0, 0, new Label("Created at:"));
|
||||
formGrid.setWidget(0, 1, createdAtLabel);
|
||||
formGrid.setWidget(1, 0, new Label("Video URL:"));
|
||||
formGrid.setWidget(1, 1, videoURLAndUploadComposite);
|
||||
formGrid.setWidget(2, 0, new Label("Mime Type:"));
|
||||
formGrid.setWidget(2, 1, mimeTypeListBox);
|
||||
|
||||
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.title() + ":"));
|
||||
formGrid.setWidget(3, 1, titleTextBox);
|
||||
formGrid.setWidget(4, 0, new Label("Subtitle:"));
|
||||
formGrid.setWidget(4, 1, subtitleTextBox);
|
||||
formGrid.setWidget(5, 0, new Label("Copyright:"));
|
||||
formGrid.setWidget(5, 1, copyrightTextBox);
|
||||
formGrid.setWidget(6, 0, new Label("Language:"));
|
||||
formGrid.setWidget(6, 1, localeListBox);
|
||||
formGrid.setWidget(7, 0, new Label("Tags:"));
|
||||
formGrid.setWidget(7, 1, tagsListEditor);
|
||||
|
||||
formGrid.setWidget(8, 0, new Label("Video-Length (s):"));
|
||||
formGrid.setWidget(8, 1, lengthIntegerBox);
|
||||
formGrid.setWidget(9, 0, new Label("Thumbnail-URL:"));
|
||||
formGrid.setWidget(9, 1, thumbnailURLAndUploadComposite);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
videoURLAndUploadComposite.setFocus(true);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class VideoEditDialog extends VideoDialog {
|
||||
public VideoEditDialog(VideoDTO video, StringMessages stringMessages, DialogCallback<VideoDTO> callback) {
|
||||
super(new VideoParameterValidator(stringMessages), stringMessages, callback);
|
||||
createdAtLabel = new Label(video.getCreatedAtDate().toString());
|
||||
videoURLAndUploadComposite.setURL(video.getSourceRef());
|
||||
titleTextBox = createTextBox(video.getTitle());
|
||||
titleTextBox.setVisibleLength(50);
|
||||
subtitleTextBox = createTextBox(video.getSubtitle());
|
||||
subtitleTextBox.setVisibleLength(50);
|
||||
copyrightTextBox = createTextBox(video.getCopyright());
|
||||
copyrightTextBox.setVisibleLength(50);
|
||||
lengthIntegerBox = createIntegerBox(video.getLengthInSeconds(), 10);
|
||||
List<String> tags = new ArrayList<String>();
|
||||
tags.addAll(video.getTags());
|
||||
tagsListEditor.setValue(tags);
|
||||
setSelectedMimeType(video.getMimeType());
|
||||
setSelectedLocale(video.getLocale());
|
||||
}
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.cell.client.AbstractCell;
|
||||
import com.google.gwt.cell.client.FieldUpdater;
|
||||
import com.google.gwt.cell.client.SafeHtmlCell;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
|
||||
import com.google.gwt.safehtml.shared.SafeHtml;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
|
||||
import com.google.gwt.user.cellview.client.TextColumn;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SingleSelectionModel;
|
||||
import com.sap.sailing.domain.common.impl.NaturalComparator;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
/**
|
||||
* /** A composite showing the list of media videos
|
||||
*
|
||||
* @author Frank Mittag (C5163974)
|
||||
*/
|
||||
public class VideosListComposite extends Composite {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
private CellTable<VideoDTO> videoTable;
|
||||
private SingleSelectionModel<VideoDTO> videoSelectionModel;
|
||||
private ListDataProvider<VideoDTO> videoListDataProvider;
|
||||
private final Label noVideosLabel;
|
||||
|
||||
private final SimplePanel mainPanel;
|
||||
private final VerticalPanel panel;
|
||||
|
||||
public static class AnchorCell extends AbstractCell<SafeHtml> {
|
||||
@Override
|
||||
public void render(com.google.gwt.cell.client.Cell.Context context, SafeHtml safeHtml, SafeHtmlBuilder sb) {
|
||||
sb.append(safeHtml);
|
||||
}
|
||||
}
|
||||
|
||||
interface AnchorTemplates extends SafeHtmlTemplates {
|
||||
@SafeHtmlTemplates.Template("<a target=\"_blank\" href=\"{0}\">{1}</a>")
|
||||
SafeHtml cell(String url, String displayName);
|
||||
}
|
||||
|
||||
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
|
||||
|
||||
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
|
||||
|
||||
public VideosListComposite(final StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
|
||||
mainPanel = new SimplePanel();
|
||||
panel = new VerticalPanel();
|
||||
mainPanel.setWidget(panel);
|
||||
|
||||
HorizontalPanel videosControlsPanel = new HorizontalPanel();
|
||||
videosControlsPanel.setSpacing(5);
|
||||
panel.add(videosControlsPanel);
|
||||
|
||||
Button createVideoBtn = new Button("Add video");
|
||||
createVideoBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateVideoDialog();
|
||||
}
|
||||
});
|
||||
videosControlsPanel.add(createVideoBtn);
|
||||
|
||||
videoSelectionModel = new SingleSelectionModel<VideoDTO>();
|
||||
videoListDataProvider = new ListDataProvider<VideoDTO>();
|
||||
videoTable = createVideosTable();
|
||||
videoTable.ensureDebugId("VideosCellTable");
|
||||
videoTable.setVisible(false);
|
||||
|
||||
videoSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
|
||||
@Override
|
||||
public void onSelectionChange(SelectionChangeEvent event) {
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(videoTable);
|
||||
|
||||
noVideosLabel = new Label("No videos defined yet.");
|
||||
noVideosLabel.ensureDebugId("NoVideosLabel");
|
||||
noVideosLabel.setWordWrap(false);
|
||||
panel.add(noVideosLabel);
|
||||
|
||||
initWidget(mainPanel);
|
||||
}
|
||||
|
||||
private CellTable<VideoDTO> createVideosTable() {
|
||||
CellTable<VideoDTO> table = new CellTable<VideoDTO>(/* pageSize */10000, tableRes);
|
||||
videoListDataProvider.addDataDisplay(table);
|
||||
table.setWidth("100%");
|
||||
|
||||
AnchorCell anchorCell = new AnchorCell();
|
||||
Column<VideoDTO, SafeHtml> shortVideoNameColumn = new Column<VideoDTO, SafeHtml>(anchorCell) {
|
||||
@Override
|
||||
public SafeHtml getValue(VideoDTO video) {
|
||||
String linkName = "";
|
||||
int index = video.getSourceRef().lastIndexOf("/");
|
||||
if(index > 0) {
|
||||
linkName = video.getSourceRef().substring(index+1, video.getSourceRef().length());
|
||||
}
|
||||
return ANCHORTEMPLATE.cell(video.getSourceRef(), linkName);
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<VideoDTO> titleColumn = new TextColumn<VideoDTO>() {
|
||||
@Override
|
||||
public String getValue(VideoDTO image) {
|
||||
return image.getTitle() != null ? image.getTitle() : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<VideoDTO> createdAtDateColumn = new TextColumn<VideoDTO>() {
|
||||
@Override
|
||||
public String getValue(VideoDTO video) {
|
||||
return DateAndTimeFormatterUtil.formatDateAndTime(video.getCreatedAtDate());
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<VideoDTO> mimeTypeColumn = new TextColumn<VideoDTO>() {
|
||||
@Override
|
||||
public String getValue(VideoDTO video) {
|
||||
return video.getMimeType() != null ? video.getMimeType().name() : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<VideoDTO> localeColumn = new TextColumn<VideoDTO>() {
|
||||
@Override
|
||||
public String getValue(VideoDTO video) {
|
||||
return video.getLocale() != null ? video.getLocale() : "";
|
||||
}
|
||||
};
|
||||
|
||||
SafeHtmlCell tagsCell = new SafeHtmlCell();
|
||||
Column<VideoDTO, SafeHtml> tagsColumn = new Column<VideoDTO, SafeHtml>(tagsCell) {
|
||||
@Override
|
||||
public SafeHtml getValue(VideoDTO video) {
|
||||
SafeHtmlBuilder builder = new SafeHtmlBuilder();
|
||||
int tagsCount = video.getTags().size();
|
||||
int i = 1;
|
||||
for (String tag : video.getTags()) {
|
||||
builder.appendEscaped(tag);
|
||||
if (i < tagsCount) {
|
||||
builder.appendHtmlConstant(", ");
|
||||
// not more than 4 tags per line
|
||||
if (i % 4 == 0) {
|
||||
builder.appendHtmlConstant("<br>");
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return builder.toSafeHtml();
|
||||
}
|
||||
};
|
||||
|
||||
ImagesBarColumn<VideoDTO, VideoConfigImagesBarCell> videoActionColumn = new ImagesBarColumn<VideoDTO, VideoConfigImagesBarCell>(
|
||||
new VideoConfigImagesBarCell(stringMessages));
|
||||
videoActionColumn.setFieldUpdater(new FieldUpdater<VideoDTO, String>() {
|
||||
@Override
|
||||
public void update(int index, VideoDTO video, String value) {
|
||||
if (ImageConfigImagesBarCell.ACTION_REMOVE.equals(value)) {
|
||||
videoListDataProvider.getList().remove(video);
|
||||
updateTableVisisbilty();
|
||||
} else if (ImageConfigImagesBarCell.ACTION_EDIT.equals(value)) {
|
||||
openEditVideoDialog(video);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
titleColumn.setSortable(true);
|
||||
createdAtDateColumn.setSortable(true);
|
||||
|
||||
table.addColumn(shortVideoNameColumn, "Short name");
|
||||
table.addColumn(titleColumn, stringMessages.title());
|
||||
table.addColumn(createdAtDateColumn, "Created At");
|
||||
table.addColumn(mimeTypeColumn, stringMessages.mimeType());
|
||||
table.addColumn(localeColumn, "Lang");
|
||||
table.addColumn(tagsColumn, "Tags");
|
||||
table.addColumn(videoActionColumn, stringMessages.actions());
|
||||
table.addColumnSortHandler(getVideoTableColumnSortHandler(videoListDataProvider.getList(), titleColumn, createdAtDateColumn));
|
||||
table.getColumnSortList().push(createdAtDateColumn);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private ListHandler<VideoDTO> getVideoTableColumnSortHandler(List<VideoDTO> videoRecords,
|
||||
TextColumn<VideoDTO> titleColumn, TextColumn<VideoDTO> createdAtDateColumn) {
|
||||
ListHandler<VideoDTO> result = new ListHandler<VideoDTO>(videoRecords);
|
||||
result.setComparator(titleColumn, new Comparator<VideoDTO>() {
|
||||
@Override
|
||||
public int compare(VideoDTO i1, VideoDTO i2) {
|
||||
return new NaturalComparator().compare(i1.getTitle(), i2.getTitle());
|
||||
}
|
||||
});
|
||||
result.setComparator(createdAtDateColumn, new Comparator<VideoDTO>() {
|
||||
@Override
|
||||
public int compare(VideoDTO e1, VideoDTO e2) {
|
||||
int result;
|
||||
if (e1.getCreatedAtDate() != null && e2.getCreatedAtDate() != null) {
|
||||
result = e2.getCreatedAtDate().compareTo(e1.getCreatedAtDate());
|
||||
} else if (e1.getCreatedAtDate() == null && e2.getCreatedAtDate() != null) {
|
||||
result = 1;
|
||||
} else if (e1.getCreatedAtDate() != null && e2.getCreatedAtDate() == null) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private void openCreateVideoDialog() {
|
||||
VideoCreateDialog dialog = new VideoCreateDialog(stringMessages, new DialogCallback<VideoDTO>() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ok(VideoDTO newVideo) {
|
||||
videoListDataProvider.getList().add(newVideo);
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void openEditVideoDialog(final VideoDTO selectedVideo) {
|
||||
VideoEditDialog dialog = new VideoEditDialog(selectedVideo, stringMessages, new DialogCallback<VideoDTO>() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ok(VideoDTO updatedVideo) {
|
||||
videoListDataProvider.getList().remove(selectedVideo);
|
||||
videoListDataProvider.getList().add(updatedVideo);
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void updateTableVisisbilty() {
|
||||
if (videoListDataProvider.getList().isEmpty()) {
|
||||
videoTable.setVisible(false);
|
||||
noVideosLabel.setVisible(true);
|
||||
} else {
|
||||
videoTable.setVisible(true);
|
||||
noVideosLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void fillVideos(List<VideoDTO> videos) {
|
||||
videoSelectionModel.clear();
|
||||
videoListDataProvider.getList().clear();
|
||||
videoListDataProvider.getList().addAll(videos);
|
||||
|
||||
updateTableVisisbilty();
|
||||
}
|
||||
|
||||
public List<VideoDTO> getAllVideos() {
|
||||
return videoListDataProvider.getList();
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -94,6 +94,8 @@ import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.gwt.client.filestorage.FileStorageManagementGwtService;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
/**
|
||||
* The client side stub for the RPC service. Usually, when a <code>null</code> date is passed to
|
||||
@@ -294,12 +296,10 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
||||
|
||||
EventDTO updateEvent(UUID eventId, String eventName, String eventDescription, Date startDate, Date endDate,
|
||||
VenueDTO venue, boolean isPublic, Iterable<UUID> leaderboardGroupIds, String officialWebsiteURL,
|
||||
String logoImageURL, Iterable<String> imageURLs, Iterable<String> videoURLs,
|
||||
Iterable<String> sponsorImageURLs) throws Exception;
|
||||
Iterable<ImageDTO> images, Iterable<VideoDTO> videos) throws Exception;
|
||||
|
||||
EventDTO createEvent(String eventName, String eventDescription, Date startDate, Date endDate, String venue,
|
||||
boolean isPublic, List<String> courseAreaNames, Iterable<String> imageURLs,
|
||||
Iterable<String> videoURLs, Iterable<String> sponsorImageURLs, String logoImageURL, String officialWebsiteURL) throws Exception;
|
||||
boolean isPublic, List<String> courseAreaNames, String officialWebsiteURL, Iterable<ImageDTO> images, Iterable<VideoDTO> videos) throws Exception;
|
||||
|
||||
void removeEvent(UUID eventId);
|
||||
|
||||
|
||||
+5
-4
@@ -83,6 +83,8 @@ import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.gwt.client.BuildVersionRetriever;
|
||||
import com.sap.sse.gwt.client.filestorage.FileStorageManagementGwtServiceAsync;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
/**
|
||||
* The async counterpart of {@link SailingService}
|
||||
@@ -365,13 +367,12 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
|
||||
void removeEvents(Collection<UUID> eventIds, AsyncCallback<Void> asyncCallback);
|
||||
|
||||
void createEvent(String eventName, String eventDescription, Date startDate, Date endDate, String venue, boolean isPublic,
|
||||
List<String> courseAreaNames, Iterable<String> imageURLs, Iterable<String> videoURLs,
|
||||
Iterable<String> sponsorImageURLs, String logoImageURL, String officialWebsiteURL, AsyncCallback<EventDTO> callback);
|
||||
List<String> courseAreaNames, String officialWebsiteURL, Iterable<ImageDTO> images, Iterable<VideoDTO> videos,
|
||||
AsyncCallback<EventDTO> callback);
|
||||
|
||||
void updateEvent(UUID eventId, String eventName, String eventDescription, Date startDate, Date endDate,
|
||||
VenueDTO venue, boolean isPublic, Iterable<UUID> leaderboardGroupIds, String officialWebsiteURL,
|
||||
String logoImageURL, Iterable<String> imageURLs, Iterable<String> videoURLs,
|
||||
Iterable<String> sponsorImageURLs, AsyncCallback<EventDTO> callback);
|
||||
Iterable<ImageDTO> images, Iterable<VideoDTO> videos, AsyncCallback<EventDTO> callback);
|
||||
|
||||
void createCourseArea(UUID eventId, String courseAreaName, AsyncCallback<Void> callback);
|
||||
|
||||
|
||||
+1
@@ -1082,6 +1082,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String photos();
|
||||
String videos();
|
||||
String image();
|
||||
String images();
|
||||
String video();
|
||||
String flagImageURL();
|
||||
String imageURLs();
|
||||
|
||||
+1
@@ -1056,6 +1056,7 @@ media=Media
|
||||
photos=Photos
|
||||
videos=Videos
|
||||
image=Image
|
||||
images=Images
|
||||
video=Video
|
||||
flagImageURL=Flag image URL (image renders with 18x12px)
|
||||
imageURLs=Image URLs
|
||||
|
||||
+1
@@ -1050,6 +1050,7 @@ media=Medien
|
||||
photos=Fotos
|
||||
videos=Videos
|
||||
image=Bild
|
||||
images=Bilder
|
||||
video=Video
|
||||
flagImageURL=Flaggenbild-URL (wird mit 18x12px Größe gezeigt)
|
||||
imageURLs=Bilder-URLs
|
||||
|
||||
+1
@@ -1010,6 +1010,7 @@ media=Media
|
||||
photos=Photos
|
||||
videos=Videos
|
||||
image=Image
|
||||
images=Images
|
||||
video=Video
|
||||
flagImageURL=Flag image URL (image renders with 18x12px)
|
||||
imageURLs=Image URLs
|
||||
|
||||
+124
-49
@@ -431,10 +431,18 @@ import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
import com.sap.sse.common.media.MediaUtils;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
import com.sap.sse.filestorage.FileStorageService;
|
||||
import com.sap.sse.filestorage.InvalidPropertiesException;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
import com.sap.sse.gwt.server.filestorage.FileStorageServiceDTOUtils;
|
||||
import com.sap.sse.gwt.shared.filestorage.FileStorageServiceDTO;
|
||||
import com.sap.sse.gwt.shared.filestorage.FileStorageServicePropertyErrorsDTO;
|
||||
@@ -3292,48 +3300,30 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
@Override
|
||||
public EventDTO updateEvent(UUID eventId, String eventName, String eventDescription, Date startDate, Date endDate,
|
||||
VenueDTO venue, boolean isPublic, Iterable<UUID> leaderboardGroupIds, String officialWebsiteURLString,
|
||||
String logoImageURLString, Iterable<String> imageURLStrings, Iterable<String> videoURLStrings,
|
||||
Iterable<String> sponsorImageURLStrings) throws MalformedURLException {
|
||||
Iterable<ImageDTO> images, Iterable<VideoDTO> videos) throws MalformedURLException {
|
||||
TimePoint startTimePoint = startDate != null ? new MillisecondsTimePoint(startDate) : null;
|
||||
TimePoint endTimePoint = endDate != null ? new MillisecondsTimePoint(endDate) : null;
|
||||
URL officialWebsiteURL = officialWebsiteURLString != null ? new URL(officialWebsiteURLString) : null;
|
||||
URL logoImageURL = logoImageURLString != null ? new URL(logoImageURLString) : null;
|
||||
List<URL> imageURLs = createURLsFromStrings(imageURLStrings);
|
||||
List<URL> videoURLs = createURLsFromStrings(videoURLStrings);
|
||||
List<URL> sponsorimagieURLs = createURLsFromStrings(sponsorImageURLStrings);
|
||||
List<ImageDescriptor> eventImages = convertToImages(images);
|
||||
List<VideoDescriptor> eventVideos = convertToVideos(videos);
|
||||
getService().apply(
|
||||
new UpdateEvent(eventId, eventName, eventDescription, startTimePoint, endTimePoint, venue.getName(),
|
||||
isPublic, leaderboardGroupIds, logoImageURL, officialWebsiteURL, imageURLs, videoURLs,
|
||||
sponsorimagieURLs));
|
||||
isPublic, leaderboardGroupIds, officialWebsiteURL, eventImages, eventVideos));
|
||||
return getEventById(eventId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param urlStrings
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private List<URL> createURLsFromStrings(Iterable<String> urlStrings) throws MalformedURLException {
|
||||
List<URL> imageURLs = new ArrayList<>();
|
||||
for (String imageURLString : urlStrings) {
|
||||
imageURLs.add(new URL(imageURLString));
|
||||
}
|
||||
return imageURLs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventDTO createEvent(String eventName, String eventDescription, Date startDate, Date endDate, String venue,
|
||||
boolean isPublic, List<String> courseAreaNames, Iterable<String> imageURLs,
|
||||
Iterable<String> videoURLs, Iterable<String> sponsorImageURLs, String logoImageURLAsString, String officialWebsiteURLAsString)
|
||||
boolean isPublic, List<String> courseAreaNames, String officialWebsiteURLAsString, Iterable<ImageDTO> images, Iterable<VideoDTO> videos)
|
||||
throws MalformedURLException {
|
||||
UUID eventUuid = UUID.randomUUID();
|
||||
TimePoint startTimePoint = startDate != null ? new MillisecondsTimePoint(startDate) : null;
|
||||
TimePoint endTimePoint = endDate != null ? new MillisecondsTimePoint(endDate) : null;
|
||||
List<ImageDescriptor> eventImages = convertToImages(images);
|
||||
List<VideoDescriptor> eventVideos = convertToVideos(videos);
|
||||
getService().apply(
|
||||
new CreateEvent(eventName, eventDescription, startTimePoint, endTimePoint, venue, isPublic, eventUuid,
|
||||
createURLsFromStrings(imageURLs), createURLsFromStrings(videoURLs),
|
||||
createURLsFromStrings(sponsorImageURLs),
|
||||
logoImageURLAsString == null ? null : new URL(logoImageURLAsString), officialWebsiteURLAsString == null ? null : new URL(officialWebsiteURLAsString)));
|
||||
officialWebsiteURLAsString == null ? null : new URL(officialWebsiteURLAsString), eventImages, eventVideos));
|
||||
for (String courseAreaName : courseAreaNames) {
|
||||
createCourseArea(eventUuid, courseAreaName);
|
||||
}
|
||||
@@ -3412,33 +3402,119 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
eventDTO.id = (UUID) event.getId();
|
||||
eventDTO.setDescription(event.getDescription());
|
||||
eventDTO.setOfficialWebsiteURL(event.getOfficialWebsiteURL() != null ? event.getOfficialWebsiteURL().toString() : null);
|
||||
if (event.getLogoImageURL() == null) {
|
||||
eventDTO.setLogoImageURL(null);
|
||||
} else {
|
||||
eventDTO.setLogoImageURL(event.getLogoImageURL().toString());
|
||||
setImageSize(event, eventDTO, event.getLogoImageURL());
|
||||
for(ImageDescriptor image: event.getImages()) {
|
||||
eventDTO.addImage(convertToImageDTO(image));
|
||||
}
|
||||
for(URL url: event.getSponsorImageURLs()) {
|
||||
eventDTO.addSponsorImageURL(url.toString());
|
||||
setImageSize(event, eventDTO, url);
|
||||
}
|
||||
for(URL url: event.getImageURLs()) {
|
||||
eventDTO.addImageURL(url.toString());
|
||||
setImageSize(event, eventDTO, url);
|
||||
}
|
||||
for(URL url: event.getVideoURLs()) {
|
||||
eventDTO.addVideoURL(url.toString());
|
||||
for(VideoDescriptor video: event.getVideos()) {
|
||||
eventDTO.addVideo(convertToVideoDTO(video));
|
||||
}
|
||||
}
|
||||
|
||||
private void setImageSize(EventBase event, EventBaseDTO eventDTO, URL imageURL) {
|
||||
try {
|
||||
eventDTO.setImageSize(imageURL.toString(), event.getImageSize(imageURL));
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.log(Level.FINE, "Was unable to obtain image size for "+imageURL+" earlier.", e);
|
||||
private List<ImageDescriptor> convertToImages(Iterable<ImageDTO> images) throws MalformedURLException {
|
||||
List<ImageDescriptor> eventImages = new ArrayList<ImageDescriptor>();
|
||||
for (ImageDTO image : images) {
|
||||
try {
|
||||
eventImages.add(convertToImage(image));
|
||||
} catch(Exception e) {
|
||||
// broken URLs are not being stored
|
||||
}
|
||||
}
|
||||
return eventImages;
|
||||
}
|
||||
|
||||
private List<VideoDescriptor> convertToVideos(Iterable<VideoDTO> videos) throws MalformedURLException {
|
||||
List<VideoDescriptor> eventVideos = new ArrayList<VideoDescriptor>();
|
||||
for (VideoDTO video : videos) {
|
||||
try {
|
||||
eventVideos.add(convertToVideo(video));
|
||||
} catch(Exception e) {
|
||||
// broken URLs are not being stored
|
||||
}
|
||||
}
|
||||
return eventVideos;
|
||||
}
|
||||
|
||||
private ImageDescriptor convertToImage(ImageDTO image) throws MalformedURLException {
|
||||
ImageDescriptor result = new ImageDescriptorImpl(new URL(image.getSourceRef()), new MillisecondsTimePoint(image.getCreatedAtDate()));
|
||||
result.setCopyright(image.getCopyright());
|
||||
result.setTitle(image.getTitle());
|
||||
result.setSubtitle(image.getSubtitle());
|
||||
result.setCopyright(image.getCopyright());
|
||||
result.setSize(image.getWidthInPx(), image.getHeightInPx());
|
||||
result.setLocale(toLocale(image.getLocale()));
|
||||
for (String tag : image.getTags()) {
|
||||
result.addTag(tag);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private VideoDescriptor convertToVideo(VideoDTO video) throws MalformedURLException {
|
||||
MimeType mimeType = video.getMimeType();
|
||||
if(mimeType == null || mimeType == MimeType.unknown) {
|
||||
mimeType = MediaUtils.detectMimeTypeFromUrl(video.getSourceRef());
|
||||
}
|
||||
VideoDescriptor result = new VideoDescriptorImpl(new URL(video.getSourceRef()), mimeType, new MillisecondsTimePoint(video.getCreatedAtDate()));
|
||||
result.setCopyright(video.getCopyright());
|
||||
result.setTitle(video.getTitle());
|
||||
result.setSubtitle(video.getSubtitle());
|
||||
result.setCopyright(video.getCopyright());
|
||||
result.setLengthInSeconds(video.getLengthInSeconds());
|
||||
if(video.getThumbnailRef() != null && !video.getThumbnailRef().isEmpty())
|
||||
result.setThumbnailURL(new URL(video.getThumbnailRef()));
|
||||
result.setLocale(toLocale(video.getLocale()));
|
||||
for (String tag : video.getTags()) {
|
||||
result.addTag(tag);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private ImageDTO convertToImageDTO(ImageDescriptor image) {
|
||||
ImageDTO result = new ImageDTO(image.getURL().toString(), image.getCreatedAtDate() != null ? image.getCreatedAtDate().asDate() : null);
|
||||
result.setCopyright(image.getCopyright());
|
||||
result.setTitle(image.getTitle());
|
||||
result.setSubtitle(image.getSubtitle());
|
||||
result.setMimeType(image.getMimeType());
|
||||
result.setSizeInPx(image.getWidthInPx(), image.getHeightInPx());
|
||||
result.setLocale(toLocaleName(image.getLocale()));
|
||||
List<String> tags = new ArrayList<String>();
|
||||
for(String tag: image.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.setTags(tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
private VideoDTO convertToVideoDTO(VideoDescriptor video) {
|
||||
VideoDTO result = new VideoDTO(video.getURL().toString(), video.getMimeType(),
|
||||
video.getCreatedAtDate() != null ? video.getCreatedAtDate().asDate() : null);
|
||||
result.setCopyright(video.getCopyright());
|
||||
result.setTitle(video.getTitle());
|
||||
result.setSubtitle(video.getSubtitle());
|
||||
result.setThumbnailRef(video.getThumbnailURL() != null ? video.getThumbnailURL().toString() : null);
|
||||
result.setLengthInSeconds(video.getLengthInSeconds());
|
||||
result.setLocale(toLocaleName(video.getLocale()));
|
||||
List<String> tags = new ArrayList<String>();
|
||||
for(String tag: video.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
result.setTags(tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Locale toLocale(String localeName) {
|
||||
if(localeName == null || localeName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return Locale.forLanguageTag(localeName);
|
||||
}
|
||||
|
||||
private String toLocaleName(Locale locale) {
|
||||
if(locale == null) {
|
||||
return null;
|
||||
}
|
||||
return locale.toString();
|
||||
}
|
||||
|
||||
private EventDTO convertToEventDTO(Event event, boolean withStatisticalData) {
|
||||
EventDTO eventDTO = new EventDTO(event.getName());
|
||||
copyEventBaseFieldsToDTO(event, eventDTO);
|
||||
@@ -4066,9 +4142,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
eventLeaderboardGroupUUIDs.add(lg.getId());
|
||||
}
|
||||
updateEvent(newEvent.id, newEvent.getName(), description, newEvent.startDate, newEvent.endDate, newEvent.venue,
|
||||
newEvent.isPublic, eventLeaderboardGroupUUIDs, newEvent.getLogoImageURL(),
|
||||
newEvent.getOfficialWebsiteURL(), newEvent.getImageURLs(), newEvent.getVideoURLs(),
|
||||
newEvent.getSponsorImageURLs());
|
||||
newEvent.isPublic, eventLeaderboardGroupUUIDs, newEvent.getOfficialWebsiteURL(),
|
||||
newEvent.getImages(), newEvent.getVideos());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+24
-47
@@ -10,6 +10,9 @@ import java.util.UUID;
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.dto.NamedDTO;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
private static final long serialVersionUID = 818666323178097939L;
|
||||
@@ -22,14 +25,9 @@ public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
|
||||
private String description;
|
||||
private List<? extends LeaderboardGroupBaseDTO> leaderboardGroups;
|
||||
private List<String> imageURLs = new ArrayList<>();
|
||||
private List<String> videoURLs = new ArrayList<>();
|
||||
private List<String> sponsorImageURLs = new ArrayList<>();
|
||||
private String logoImageURL;
|
||||
private String officialWebsiteURL;
|
||||
/** placeholder for social media URL's -> attributes will be implemented later on */
|
||||
private String facebookURL;
|
||||
private String twitterURL;
|
||||
private List<ImageDTO> images = new ArrayList<>();
|
||||
private List<VideoDTO> videos = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* For the image URL keys holds the sizes of these images if known. An image size is "known" by this object if it
|
||||
@@ -65,6 +63,17 @@ public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
this.imageSizes = new HashMap<String, ImageSize>();
|
||||
}
|
||||
|
||||
public ImageDTO getLogoImage() {
|
||||
ImageDTO result = null;
|
||||
for (ImageDTO image : images) {
|
||||
if (image.hasTag(MediaTagConstants.LOGO)) {
|
||||
result = image;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
Date now = new Date();
|
||||
if (startDate != null && endDate != null && (now.after(startDate) && now.before(endDate))) {
|
||||
@@ -81,14 +90,6 @@ public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getLogoImageURL() {
|
||||
return logoImageURL;
|
||||
}
|
||||
|
||||
public void setLogoImageURL(String logoImageURL) {
|
||||
this.logoImageURL = logoImageURL;
|
||||
}
|
||||
|
||||
public String getOfficialWebsiteURL() {
|
||||
return officialWebsiteURL;
|
||||
}
|
||||
@@ -110,30 +111,6 @@ public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
this.baseURL = baseURL;
|
||||
}
|
||||
|
||||
public void addImageURL(String imageURL) {
|
||||
imageURLs.add(imageURL);
|
||||
}
|
||||
|
||||
public void addVideoURL(String videoURL) {
|
||||
videoURLs.add(videoURL);
|
||||
}
|
||||
|
||||
public void addSponsorImageURL(String sponsorImageURL) {
|
||||
sponsorImageURLs.add(sponsorImageURL);
|
||||
}
|
||||
|
||||
public List<String> getImageURLs() {
|
||||
return imageURLs;
|
||||
}
|
||||
|
||||
public List<String> getVideoURLs() {
|
||||
return videoURLs;
|
||||
}
|
||||
|
||||
public List<String> getSponsorImageURLs() {
|
||||
return sponsorImageURLs;
|
||||
}
|
||||
|
||||
public Iterable<? extends LeaderboardGroupBaseDTO> getLeaderboardGroups() {
|
||||
return leaderboardGroups;
|
||||
}
|
||||
@@ -146,20 +123,20 @@ public class EventBaseDTO extends NamedDTO implements IsSerializable {
|
||||
this.isOnRemoteServer = isOnRemoteServer;
|
||||
}
|
||||
|
||||
public String getFacebookURL() {
|
||||
return facebookURL;
|
||||
public void addImage(ImageDTO image) {
|
||||
images.add(image);
|
||||
}
|
||||
|
||||
public void setFacebookURL(String facebookURL) {
|
||||
this.facebookURL = facebookURL;
|
||||
public List<ImageDTO> getImages() {
|
||||
return images;
|
||||
}
|
||||
|
||||
public String getTwitterURL() {
|
||||
return twitterURL;
|
||||
public void addVideo(VideoDTO video) {
|
||||
videos.add(video);
|
||||
}
|
||||
|
||||
public void setTwitterURL(String twitterURL) {
|
||||
this.twitterURL = twitterURL;
|
||||
public List<VideoDTO> getVideos() {
|
||||
return videos;
|
||||
}
|
||||
|
||||
public void setImageSize(String imageURL, ImageSize imageSize) {
|
||||
|
||||
+12
-13
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.shared.dispatch.event;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
@@ -10,12 +11,14 @@ import com.sap.sailing.gwt.ui.shared.dispatch.Action;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.DispatchContext;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.ResultWithTTL;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventState;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaUtils;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class GetEventOverviewStageAction implements Action<ResultWithTTL<EventOverviewStageDTO>> {
|
||||
private static final Collection<String> rankedTags = Arrays.asList(MediaTagConstants.LIVESTREAM, MediaTagConstants.FEATURED, MediaTagConstants.HIGHLIGHT);
|
||||
private static final Collection<String> rankedTagsFinished = Arrays.asList(MediaTagConstants.FEATURED, MediaTagConstants.HIGHLIGHT);
|
||||
|
||||
private UUID eventId;
|
||||
|
||||
public GetEventOverviewStageAction() {
|
||||
@@ -46,18 +49,14 @@ public class GetEventOverviewStageAction implements Action<ResultWithTTL<EventOv
|
||||
@GwtIncompatible
|
||||
public EventOverviewStageContentDTO getStageContent(DispatchContext context, Event event, EventState state, MillisecondsTimePoint now) {
|
||||
// Simple solution:
|
||||
// P1: Show the last video if available
|
||||
// P1: Show the best matching video if available
|
||||
// P2: Show Countdown for upcoming events
|
||||
// P3: Show Stage image without Countdown
|
||||
|
||||
Iterable<URL> videoURLs = event.getVideoURLs();
|
||||
for (int i = Util.size(videoURLs) - 1; i >= 0; i--) {
|
||||
// TODO fmittag/pgt: implement locale specific live stream using context.getClientLocaleName() or context.getClientLocale()
|
||||
String videoUrl = Util.get(videoURLs, i).toString();
|
||||
MimeType type = MediaUtils.detectMimeTypeFromUrl(videoUrl);
|
||||
if (type == MimeType.youtube || type == MimeType.vimeo || type == MimeType.mp4) {
|
||||
return new EventOverviewVideoStageDTO(EventOverviewVideoStageDTO.Type.MEDIA, type, videoUrl);
|
||||
}
|
||||
Collection<String> tags = state == EventState.FINISHED ? rankedTagsFinished : rankedTags;
|
||||
VideoDescriptor stageVideo = HomeServiceUtil.getStageVideo(event, context.getClientLocale(), tags, true);
|
||||
if(stageVideo != null) {
|
||||
return new EventOverviewVideoStageDTO(EventOverviewVideoStageDTO.Type.MEDIA, stageVideo.getMimeType(), stageVideo.getURL().toString());
|
||||
}
|
||||
String stageImageUrl = HomeServiceUtil.getStageImageURLAsString(event);
|
||||
if(state == EventState.UPCOMING || state == EventState.PLANNED) {
|
||||
|
||||
+6
-5
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class EventViewDTO extends EventMetadataDTO {
|
||||
|
||||
@@ -19,7 +20,7 @@ public class EventViewDTO extends EventMetadataDTO {
|
||||
private boolean hasMedia;
|
||||
private boolean hasAnalytics;
|
||||
private String seriesName;
|
||||
private String logoImageURL;
|
||||
private ImageDTO logoImage;
|
||||
private String officialWebsiteURL;
|
||||
private String sailorsInfoURL;
|
||||
|
||||
@@ -87,12 +88,12 @@ public class EventViewDTO extends EventMetadataDTO {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLogoImageURL(String logoImageURL) {
|
||||
this.logoImageURL = logoImageURL;
|
||||
public void setLogoImage(ImageDTO logoImage) {
|
||||
this.logoImage = logoImage;
|
||||
}
|
||||
|
||||
public String getLogoImageURL() {
|
||||
return logoImageURL;
|
||||
public ImageDTO getLogoImage() {
|
||||
return logoImage;
|
||||
}
|
||||
|
||||
public void setOfficialWebsiteURL(String officialWebsiteURL) {
|
||||
|
||||
+6
-5
@@ -7,12 +7,13 @@ import java.util.UUID;
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.general.LabelType;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class EventSeriesViewDTO implements IsSerializable {
|
||||
private UUID id;
|
||||
private String displayName;
|
||||
private ArrayList<EventMetadataDTO> events = new ArrayList<>();
|
||||
private String logoImageURL;
|
||||
private ImageDTO logoImage;
|
||||
private boolean hasMedia;
|
||||
private boolean hasAnalytics;
|
||||
|
||||
@@ -61,12 +62,12 @@ public class EventSeriesViewDTO implements IsSerializable {
|
||||
this.events.add(event);
|
||||
}
|
||||
|
||||
public String getLogoImageURL() {
|
||||
return logoImageURL;
|
||||
public ImageDTO getLogoImage() {
|
||||
return logoImage;
|
||||
}
|
||||
|
||||
public void setLogoImageURL(String logoImageURL) {
|
||||
this.logoImageURL = logoImageURL;
|
||||
public void setLogoImage(ImageDTO logoImage) {
|
||||
this.logoImage = logoImage;
|
||||
}
|
||||
|
||||
public boolean isHasMedia() {
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.gwt.ui.shared.media;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public final class MediaConstants {
|
||||
|
||||
public static final List<String> imageTagSuggestions = Arrays.asList(new String[] { MediaTagConstants.STAGE, MediaTagConstants.TEASER,
|
||||
MediaTagConstants.SPONSOR, MediaTagConstants.LOGO, MediaTagConstants.GALLERY });
|
||||
public static final List<String> videoTagSuggestions = Arrays.asList(new String[] { MediaTagConstants.LIVESTREAM, MediaTagConstants.HIGHLIGHT,MediaTagConstants.FEATURED });
|
||||
public static final Set<MimeType> SUPPORTED_VIDEO_TYPES = new HashSet<>(Arrays.asList(MimeType.youtube, MimeType.vimeo, MimeType.mp4));
|
||||
|
||||
private MediaConstants() {
|
||||
}
|
||||
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
package com.sap.sailing.gwt.ui.shared.media;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
/**
|
||||
* Temporary solution for mimetype detection for current videos.
|
||||
*
|
||||
* @author pgtaboada
|
||||
*
|
||||
*/
|
||||
public class MediaUtils {
|
||||
|
||||
/**
|
||||
* Youtube regex detection from:
|
||||
* http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url, mantish Mar 4
|
||||
* at 15:33
|
||||
*/
|
||||
@GwtIncompatible
|
||||
private static final Pattern YOUTUBE_ID_REGEX = Pattern
|
||||
.compile("^.*(youtu.be/|v/|u/\\w/|embed/|watch\\?v=|\\&v=)([^#\\&\\?]+).*$");
|
||||
|
||||
@GwtIncompatible
|
||||
private static final Pattern VIMEO_REGEX = Pattern.compile("^.*(vimeo\\.com\\/).*");
|
||||
|
||||
@GwtIncompatible
|
||||
private static final Pattern MP4_REGEX = Pattern.compile(".*\\.mp4$");
|
||||
|
||||
/**
|
||||
* Detect mimetype for given url.
|
||||
*
|
||||
* @param url
|
||||
* the source pointing to the video mediafile
|
||||
* @return mimetype detected or MimeType.unknown
|
||||
*/
|
||||
@GwtIncompatible
|
||||
public static MimeType detectMimeTypeFromUrl(String url) {
|
||||
|
||||
if (YOUTUBE_ID_REGEX.matcher(url).matches()) {
|
||||
return MimeType.youtube;
|
||||
} else if (VIMEO_REGEX.matcher(url).matches()) {
|
||||
return MimeType.vimeo;
|
||||
} else if (MP4_REGEX.matcher(url).matches()) {
|
||||
return MimeType.mp4;
|
||||
} else {
|
||||
return MimeType.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+6
-10
@@ -3,23 +3,19 @@ package com.sap.sailing.gwt.ui.shared.media;
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO;
|
||||
import com.sap.sse.common.media.ImageMetadataDTO;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
public class SailingImageDTO extends ImageMetadataDTO {
|
||||
public class SailingImageDTO extends ImageDTO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private EventReferenceDTO eventRef;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private SailingImageDTO() {
|
||||
protected SailingImageDTO() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SailingImageDTO(EventReferenceDTO eventRef, String imageURL, ImageSize size, Date createdAtDate) {
|
||||
super(imageURL, size, createdAtDate);
|
||||
public SailingImageDTO(EventReferenceDTO eventRef, String imageRef, Date createdAtDate) {
|
||||
super(imageRef, createdAtDate);
|
||||
this.eventRef = eventRef;
|
||||
|
||||
}
|
||||
|
||||
public EventReferenceDTO getEventRef() {
|
||||
|
||||
+4
-6
@@ -4,16 +4,14 @@ import java.util.Date;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoMetadataDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
public class SailingVideoDTO extends VideoMetadataDTO {
|
||||
public class SailingVideoDTO extends VideoDTO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private EventReferenceDTO eventRef;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private SailingVideoDTO() {
|
||||
/** for GWT */
|
||||
protected SailingVideoDTO() {
|
||||
}
|
||||
|
||||
public SailingVideoDTO(EventReferenceDTO eventRef, String srcReference, MimeType mimeType, Date createdAtDate) {
|
||||
|
||||
+156
-11
@@ -18,6 +18,7 @@ import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -89,6 +90,12 @@ import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
import com.sap.sse.common.media.MediaTagConstants;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
|
||||
public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest {
|
||||
private static final Logger logger = Logger.getLogger(TestStoringAndLoadingEventsAndRegattas.class.getName());
|
||||
@@ -137,14 +144,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
event.addLeaderboardGroup(lg1);
|
||||
event.addLeaderboardGroup(lg2);
|
||||
event.setDescription(eventDescription);
|
||||
event.addImageURL(new URL("http://some.host/with/some/file1.jpg"));
|
||||
event.addImageURL(new URL("http://some.host/with/some/file2.jpg"));
|
||||
event.addVideoURL(new URL("http://some.host/with/some/file1.mp4"));
|
||||
event.addVideoURL(new URL("http://some.host/with/some/file2.mp4"));
|
||||
event.addSponsorImageURL(new URL("http://some.host/with/some/file4.mp4"));
|
||||
event.addSponsorImageURL(new URL("http://some.host/with/some/file5.mp4"));
|
||||
event.setOfficialWebsiteURL(new URL("http://official.website.com"));
|
||||
event.setLogoImageURL(new URL("http://official.logo.com"));
|
||||
mof.storeEvent(event);
|
||||
|
||||
DomainObjectFactory dof = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
|
||||
@@ -169,7 +169,6 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
assertEquals(eventName, loadedEvent.getName());
|
||||
assertEquals(eventDescription, loadedEvent.getDescription());
|
||||
assertEquals(event.getOfficialWebsiteURL(), loadedEvent.getOfficialWebsiteURL());
|
||||
assertEquals(event.getLogoImageURL(), loadedEvent.getLogoImageURL());
|
||||
assertEquals(2, Util.size(loadedEvent.getLeaderboardGroups()));
|
||||
Iterator<LeaderboardGroup> lgIter = loadedEvent.getLeaderboardGroups().iterator();
|
||||
assertSame(lg1, lgIter.next());
|
||||
@@ -182,9 +181,6 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
for (CourseArea loadedCourseArea : loadedVenue.getCourseAreas()) {
|
||||
assertEquals(courseAreaNames[i++], loadedCourseArea.getName());
|
||||
}
|
||||
assertTrue("image URLs "+loadedEvent.getImageURLs()+" but expected "+event.getImageURLs(), Util.equals(event.getImageURLs(), loadedEvent.getImageURLs()));
|
||||
assertTrue("video URLs "+loadedEvent.getVideoURLs()+" but expected "+event.getVideoURLs(), Util.equals(event.getVideoURLs(), loadedEvent.getVideoURLs()));
|
||||
assertTrue("sponsor image URLs "+loadedEvent.getSponsorImageURLs()+" but expected "+event.getSponsorImageURLs(), Util.equals(event.getSponsorImageURLs(), loadedEvent.getSponsorImageURLs()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,6 +214,155 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
assertEquals(loadedRegatta.getEndDate(), regattaEndDate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadStoreSimpleEventWithImages() throws MalformedURLException {
|
||||
final URL imageURL = new URL("http://some.host/with/some/file2.jpg");
|
||||
final String copyright = "copyright by Alex";
|
||||
final String imageTitle = "My image title";
|
||||
final String imageSubtitle = "My image subtitle";
|
||||
final Integer imageWidth = 500;
|
||||
final Integer imageHeight = 300;
|
||||
final TimePoint createdAt = MillisecondsTimePoint.now();
|
||||
final String eventName = "Event Name";
|
||||
final String venueName = "Venue Name";
|
||||
final String courseAreaName = "Alpha";
|
||||
final Venue venue = new VenueImpl(venueName);
|
||||
CourseArea courseArea = DomainFactory.INSTANCE.getOrCreateCourseArea(UUID.randomUUID(), courseAreaName);
|
||||
venue.addCourseArea(courseArea);
|
||||
|
||||
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
|
||||
Event event = new EventImpl(eventName, eventStartDate, eventEndDate, venue, /*isPublic*/ true, UUID.randomUUID());
|
||||
|
||||
ImageDescriptor image1 = new ImageDescriptorImpl(imageURL, createdAt);
|
||||
image1.setCopyright(copyright);
|
||||
image1.setSize(imageWidth, imageHeight);
|
||||
image1.setTitle(imageTitle);
|
||||
image1.setSubtitle(imageSubtitle);
|
||||
image1.addTag("Tag1");
|
||||
image1.addTag("Tag2");
|
||||
image1.addTag("Tag3");
|
||||
event.addImage(image1);
|
||||
|
||||
ImageDescriptor image2 = new ImageDescriptorImpl(new URL("http://some.host/with/some/file2.jpg"), MillisecondsTimePoint.now());
|
||||
image2.setCopyright("copyright");
|
||||
event.addImage(image2);
|
||||
|
||||
mof.storeEvent(event);
|
||||
|
||||
DomainObjectFactory dof = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
|
||||
final Event loadedEvent = dof.loadEvent(eventName);
|
||||
assertEquals(2, Util.size(loadedEvent.getImages()));
|
||||
ImageDescriptor loadedImage1 = loadedEvent.getImages().iterator().next();
|
||||
assertNotNull(loadedImage1);
|
||||
assertEquals(imageURL, loadedImage1.getURL());
|
||||
assertEquals(copyright, loadedImage1.getCopyright());
|
||||
assertEquals(copyright, loadedImage1.getCopyright());
|
||||
assertEquals(imageTitle, loadedImage1.getTitle());
|
||||
assertEquals(imageSubtitle, loadedImage1.getSubtitle());
|
||||
assertEquals(createdAt, loadedImage1.getCreatedAtDate());
|
||||
assertEquals(imageWidth, loadedImage1.getWidthInPx());
|
||||
assertEquals(imageHeight, loadedImage1.getHeightInPx());
|
||||
assertEquals(3, Util.size(loadedImage1.getTags()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadStoreSimpleEventWithVideos() throws MalformedURLException {
|
||||
final URL videoURL = new URL("http://some.host/with/some/video.mpg");
|
||||
final URL videoThumbnailURL = new URL("http://some.host/with/some/video_thumbnail.jpg");
|
||||
final Locale locale = Locale.GERMAN;
|
||||
final Integer videoLengthInSeconds = 2 * 60 * 60 * 1000; // 2h
|
||||
final MimeType mimeType = MimeType.mp4;
|
||||
final String copyright = "copyright by Don";
|
||||
final String videoTitle = "My video title";
|
||||
final String videoSubtitle = "My video subtitle";
|
||||
final TimePoint createdAt = MillisecondsTimePoint.now();
|
||||
final String eventName = "Event Name";
|
||||
final String venueName = "Venue Name";
|
||||
final String courseAreaName = "Alpha";
|
||||
final Venue venue = new VenueImpl(venueName);
|
||||
CourseArea courseArea = DomainFactory.INSTANCE.getOrCreateCourseArea(UUID.randomUUID(), courseAreaName);
|
||||
venue.addCourseArea(courseArea);
|
||||
|
||||
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
|
||||
Event event = new EventImpl(eventName, eventStartDate, eventEndDate, venue, /*isPublic*/ true, UUID.randomUUID());
|
||||
|
||||
VideoDescriptor video1 = new VideoDescriptorImpl(videoURL, mimeType, createdAt);
|
||||
video1.setCopyright(copyright);
|
||||
video1.setTitle(videoTitle);
|
||||
video1.setLocale(locale);
|
||||
video1.setSubtitle(videoSubtitle);
|
||||
video1.setThumbnailURL(videoThumbnailURL);
|
||||
video1.setLengthInSeconds(videoLengthInSeconds);
|
||||
video1.addTag("Tag1");
|
||||
video1.addTag("Tag2");
|
||||
video1.addTag("Tag3");
|
||||
event.addVideo(video1);
|
||||
|
||||
VideoDescriptor video2 = new VideoDescriptorImpl(new URL("http://some.host/with/some/file2.ogg"), MimeType.ogg, MillisecondsTimePoint.now());
|
||||
video2.setCopyright("copyright");
|
||||
event.addVideo(video2);
|
||||
|
||||
mof.storeEvent(event);
|
||||
|
||||
DomainObjectFactory dof = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
|
||||
final Event loadedEvent = dof.loadEvent(eventName);
|
||||
assertEquals(2, Util.size(loadedEvent.getVideos()));
|
||||
VideoDescriptor loadedVideo1 = loadedEvent.getVideos().iterator().next();
|
||||
assertNotNull(loadedVideo1);
|
||||
assertEquals(videoURL, loadedVideo1.getURL());
|
||||
assertEquals(videoThumbnailURL, loadedVideo1.getThumbnailURL());
|
||||
assertEquals(videoLengthInSeconds, loadedVideo1.getLengthInSeconds());
|
||||
assertEquals(copyright, loadedVideo1.getCopyright());
|
||||
assertEquals(locale, loadedVideo1.getLocale());
|
||||
assertEquals(videoTitle, loadedVideo1.getTitle());
|
||||
assertEquals(videoSubtitle, loadedVideo1.getSubtitle());
|
||||
assertEquals(createdAt, loadedVideo1.getCreatedAtDate());
|
||||
assertEquals(3, Util.size(loadedVideo1.getTags()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
/**
|
||||
* We expected that the migration code creates also an image URL for each image we create.
|
||||
* Images with the 'Sponsor' tag should create a corresponding sponsor image URL
|
||||
* Videos should create a video URL.
|
||||
*/
|
||||
public void testLoadStoreSimpleEventWithImageAndVideoURLMigration() throws MalformedURLException {
|
||||
final URL imageURL = new URL("http://some.host/with/some/bla.jpg");
|
||||
final URL sponsorImageURL = new URL("http://some.host/with/some/sponsor.jpg");
|
||||
final URL videoURL = new URL("http://some.host/with/some/video.mpg");
|
||||
final TimePoint createdAt = MillisecondsTimePoint.now();
|
||||
final String eventName = "Event Name";
|
||||
final Venue venue = new VenueImpl("My Venue");
|
||||
CourseArea courseArea = DomainFactory.INSTANCE.getOrCreateCourseArea(UUID.randomUUID(), "Alfa");
|
||||
venue.addCourseArea(courseArea);
|
||||
|
||||
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
|
||||
Event event = new EventImpl(eventName, eventStartDate, eventEndDate, venue, /*isPublic*/ true, UUID.randomUUID());
|
||||
|
||||
ImageDescriptor image1 = new ImageDescriptorImpl(imageURL, createdAt);
|
||||
image1.addTag(MediaTagConstants.GALLERY);
|
||||
event.addImage(image1);
|
||||
|
||||
ImageDescriptor image2 = new ImageDescriptorImpl(sponsorImageURL, createdAt);
|
||||
event.addImage(image2);
|
||||
image2.addTag(MediaTagConstants.SPONSOR);
|
||||
|
||||
VideoDescriptor video1 = new VideoDescriptorImpl(videoURL, MimeType.mp4, createdAt);
|
||||
event.addVideo(video1);
|
||||
|
||||
mof.storeEvent(event);
|
||||
|
||||
DomainObjectFactory dof = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
|
||||
final Event loadedEvent = dof.loadEvent(eventName);
|
||||
assertEquals(2, Util.size(loadedEvent.getImages()));
|
||||
assertEquals(1, Util.size(loadedEvent.getVideos()));
|
||||
assertEquals(1, Util.size(loadedEvent.getImageURLs()));
|
||||
assertEquals(1, Util.size(loadedEvent.getSponsorImageURLs()));
|
||||
assertEquals(1, Util.size(loadedEvent.getVideoURLs()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLoadStoreRegattaConfiguration() {
|
||||
|
||||
|
||||
+141
-30
@@ -3,7 +3,10 @@ package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
@@ -17,7 +20,15 @@ import com.sap.sailing.domain.common.impl.ImageSizeImpl;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
|
||||
public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
private final JsonDeserializer<Venue> venueDeserializer;
|
||||
@@ -28,22 +39,21 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
this.leaderboardGroupDeserializer = leaderboardGroupDeserializer;
|
||||
}
|
||||
|
||||
public EventBase deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
UUID id = UUID.fromString((String) object.get(EventBaseJsonSerializer.FIELD_ID));
|
||||
String name = (String) object.get(EventBaseJsonSerializer.FIELD_NAME);
|
||||
String description = (String) object.get(EventBaseJsonSerializer.FIELD_DESCRIPTION);
|
||||
String officialWebsiteURLAsString = (String) object.get(EventBaseJsonSerializer.FIELD_OFFICIAL_WEBSITE_URL);
|
||||
String logoImageURLAsString = (String) object.get(EventBaseJsonSerializer.FIELD_LOGO_IMAGE_URL);
|
||||
Number startDate = (Number) object.get(EventBaseJsonSerializer.FIELD_START_DATE);
|
||||
Number endDate = (Number) object.get(EventBaseJsonSerializer.FIELD_END_DATE);
|
||||
public EventBase deserialize(JSONObject eventJson) throws JsonDeserializationException {
|
||||
UUID id = UUID.fromString((String) eventJson.get(EventBaseJsonSerializer.FIELD_ID));
|
||||
String name = (String) eventJson.get(EventBaseJsonSerializer.FIELD_NAME);
|
||||
String description = (String) eventJson.get(EventBaseJsonSerializer.FIELD_DESCRIPTION);
|
||||
String officialWebsiteURLAsString = (String) eventJson.get(EventBaseJsonSerializer.FIELD_OFFICIAL_WEBSITE_URL);
|
||||
Number startDate = (Number) eventJson.get(EventBaseJsonSerializer.FIELD_START_DATE);
|
||||
Number endDate = (Number) eventJson.get(EventBaseJsonSerializer.FIELD_END_DATE);
|
||||
final Venue venue;
|
||||
if (object.get(EventBaseJsonSerializer.FIELD_VENUE) != null) {
|
||||
JSONObject venueObject = Helpers.getNestedObjectSafe(object, EventBaseJsonSerializer.FIELD_VENUE);
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_VENUE) != null) {
|
||||
JSONObject venueObject = Helpers.getNestedObjectSafe(eventJson, EventBaseJsonSerializer.FIELD_VENUE);
|
||||
venue = venueDeserializer.deserialize(venueObject);
|
||||
} else {
|
||||
venue = null;
|
||||
}
|
||||
JSONArray leaderboardGroupsJson = (JSONArray) object.get(EventBaseJsonSerializer.FIELDS_LEADERBOARD_GROUPS);
|
||||
JSONArray leaderboardGroupsJson = (JSONArray) eventJson.get(EventBaseJsonSerializer.FIELDS_LEADERBOARD_GROUPS);
|
||||
List<LeaderboardGroupBase> leaderboardGroups = new ArrayList<LeaderboardGroupBase>();
|
||||
if (leaderboardGroupsJson != null) {
|
||||
for (Object lgJson : leaderboardGroupsJson) {
|
||||
@@ -60,40 +70,75 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
throw new JsonDeserializationException("Error deserializing official website URL for event "+name, e);
|
||||
}
|
||||
}
|
||||
JSONArray imagesJson = (JSONArray) eventJson.get(EventBaseJsonSerializer.FIELD_IMAGES);
|
||||
if (imagesJson != null) {
|
||||
for (Object imageJson : imagesJson) {
|
||||
ImageDescriptor imgaeDescriptor = loadImage((JSONObject) imageJson);
|
||||
if (imgaeDescriptor != null) {
|
||||
result.addImage(imgaeDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSONArray videosJson = (JSONArray) eventJson.get(EventBaseJsonSerializer.FIELD_VIDEOS);
|
||||
if (videosJson != null) {
|
||||
for (Object videoJson : videosJson) {
|
||||
VideoDescriptor videoDescriptor = loadVideo((JSONObject) videoJson);
|
||||
if (videoDescriptor != null) {
|
||||
result.addVideo(videoDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we read an event with data in the old image/video format we need migrate them
|
||||
if(Util.size(result.getImages()) == 0 && Util.size(result.getVideos()) == 0) {
|
||||
readImageAndVideoURLsFromLegacyServer(eventJson, result);
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void readImageAndVideoURLsFromLegacyServer(JSONObject eventJson, StrippedEventImpl event) throws JsonDeserializationException {
|
||||
URL logoImageURL = null;
|
||||
List<URL> imageURLs = new ArrayList<URL>();
|
||||
List<URL> sponsorImageURLs = new ArrayList<URL>();
|
||||
List<URL> videoURLs = new ArrayList<URL>();
|
||||
|
||||
String logoImageURLAsString = (String) eventJson.get(EventBaseJsonSerializer.FIELD_LOGO_IMAGE_URL);
|
||||
if (logoImageURLAsString != null) {
|
||||
try {
|
||||
result.setLogoImageURL(new URL(logoImageURLAsString));
|
||||
logoImageURL = new URL(logoImageURLAsString);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new JsonDeserializationException("Error deserializing logo image URL for event "+name, e);
|
||||
throw new JsonDeserializationException("Error deserializing logo image URL for event "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (object.get(EventBaseJsonSerializer.FIELD_IMAGE_URLS) != null) {
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_IMAGE_URLS) != null) {
|
||||
try {
|
||||
result.setImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventBaseJsonSerializer.FIELD_IMAGE_URLS)));
|
||||
imageURLs = getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, EventBaseJsonSerializer.FIELD_IMAGE_URLS));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new JsonDeserializationException("Error deserializing image URLs for event "+name, e);
|
||||
throw new JsonDeserializationException("Error deserializing image URLs for event "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (object.get(EventBaseJsonSerializer.FIELD_VIDEO_URLS) != null) {
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_VIDEO_URLS) != null) {
|
||||
try {
|
||||
result.setVideoURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventBaseJsonSerializer.FIELD_VIDEO_URLS)));
|
||||
videoURLs = getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, EventBaseJsonSerializer.FIELD_VIDEO_URLS));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new JsonDeserializationException("Error deserializing video URLs for event "+name, e);
|
||||
throw new JsonDeserializationException("Error deserializing video URLs for event "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (object.get(EventBaseJsonSerializer.FIELD_SPONSOR_IMAGE_URLS) != null) {
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_SPONSOR_IMAGE_URLS) != null) {
|
||||
try {
|
||||
result.setSponsorImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventBaseJsonSerializer.FIELD_SPONSOR_IMAGE_URLS)));
|
||||
sponsorImageURLs = getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, EventBaseJsonSerializer.FIELD_SPONSOR_IMAGE_URLS));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new JsonDeserializationException("Error deserializing sponsor image URLs for event "+name, e);
|
||||
throw new JsonDeserializationException("Error deserializing sponsor image URLs for event "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
JSONArray imageSizes = (JSONArray) object.get(EventBaseJsonSerializer.FIELD_IMAGE_SIZES);
|
||||
if (imageSizes != null) {
|
||||
for (Object imageURLAndSizeObject : imageSizes) {
|
||||
}
|
||||
// handle images sizes coming from an old server instance not having images and videos in the rich format
|
||||
Map<URL, ImageSize> imageSizes = new HashMap<URL, ImageSize>();;
|
||||
JSONArray imageSizesJson = (JSONArray) eventJson.get(EventBaseJsonSerializer.FIELD_IMAGE_SIZES);
|
||||
if (imageSizesJson != null) {
|
||||
for (Object imageURLAndSizeObject : imageSizesJson) {
|
||||
JSONObject imageURLAndSizeJson = (JSONObject) imageURLAndSizeObject;
|
||||
try {
|
||||
result.setImageSize(
|
||||
imageSizes.put(
|
||||
new URL((String) imageURLAndSizeJson.get(EventBaseJsonSerializer.FIELD_IMAGE_URL)),
|
||||
new ImageSizeImpl(
|
||||
((Number) imageURLAndSizeJson.get(EventBaseJsonSerializer.FIELD_IMAGE_WIDTH)).intValue(),
|
||||
@@ -103,10 +148,77 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
event.setMediaURLs(imageURLs, sponsorImageURLs, videoURLs, logoImageURL, imageSizes);
|
||||
}
|
||||
|
||||
private Iterable<URL> getURLsFromStrings(JSONArray strings) throws MalformedURLException {
|
||||
private ImageDescriptor loadImage(JSONObject imageJson) {
|
||||
ImageDescriptor image = null;
|
||||
URL imageURL = Helpers.getURLField(imageJson, EventBaseJsonSerializer.FIELD_SOURCE_URL);
|
||||
if (imageURL != null) {
|
||||
String title = (String) imageJson.get(EventBaseJsonSerializer.FIELD_TITLE);
|
||||
String subtitle = (String) imageJson.get(EventBaseJsonSerializer.FIELD_SUBTITLE);
|
||||
String copyright = (String) imageJson.get(EventBaseJsonSerializer.FIELD_COPYRIGHT);
|
||||
String localeRaw = (String) imageJson.get(EventBaseJsonSerializer.FIELD_LOCALE);
|
||||
Locale locale = localeRaw != null ? Locale.forLanguageTag(localeRaw) : null;
|
||||
Number imageWidth = (Number) imageJson.get(EventBaseJsonSerializer.FIELD_IMAGE_WIDTH_IN_PX);
|
||||
Number imageHeight = (Number) imageJson.get(EventBaseJsonSerializer.FIELD_IMAGE_HEIGHT_IN_PX);
|
||||
Number createdAtDateInMs = (Number) imageJson.get(EventBaseJsonSerializer.FIELD_CREATEDATDATE);
|
||||
TimePoint createdAtDate = createdAtDateInMs != null ? new MillisecondsTimePoint(createdAtDateInMs.longValue()) : null;
|
||||
JSONArray tags = (JSONArray) imageJson.get(EventBaseJsonSerializer.FIELD_TAGS);
|
||||
List<String> imageTags = new ArrayList<String>();
|
||||
if (tags != null) {
|
||||
for (Object tagObject : tags) {
|
||||
imageTags.add((String) tagObject);
|
||||
}
|
||||
}
|
||||
image = new ImageDescriptorImpl(imageURL, createdAtDate);
|
||||
image.setCopyright(copyright);
|
||||
image.setLocale(locale);
|
||||
image.setTitle(title);
|
||||
image.setSubtitle(subtitle);
|
||||
image.setTags(imageTags);
|
||||
if (imageWidth != null && imageHeight != null) {
|
||||
image.setSize(imageWidth.intValue(), imageHeight.intValue());
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
private VideoDescriptor loadVideo(JSONObject videoJson) {
|
||||
VideoDescriptor video = null;
|
||||
URL videoURL = Helpers.getURLField(videoJson, EventBaseJsonSerializer.FIELD_SOURCE_URL);
|
||||
if(videoURL != null) {
|
||||
String title = (String) videoJson.get(EventBaseJsonSerializer.FIELD_TITLE);
|
||||
String subtitle = (String) videoJson.get(EventBaseJsonSerializer.FIELD_SUBTITLE);
|
||||
String copyright = (String) videoJson.get(EventBaseJsonSerializer.FIELD_COPYRIGHT);
|
||||
String localeRaw = (String) videoJson.get(EventBaseJsonSerializer.FIELD_LOCALE);
|
||||
Locale locale = localeRaw != null ? Locale.forLanguageTag(localeRaw) : null;
|
||||
Object mimeTypeRaw = videoJson.get(EventBaseJsonSerializer.FIELD_MIMETYPE);
|
||||
MimeType mimeType = mimeTypeRaw == null ? null : MimeType.valueOf((String) mimeTypeRaw);
|
||||
Number createdAtDateInMs = (Number) videoJson.get(EventBaseJsonSerializer.FIELD_CREATEDATDATE);
|
||||
TimePoint createdAtDate = createdAtDateInMs != null ? new MillisecondsTimePoint(createdAtDateInMs.longValue()) : null;
|
||||
JSONArray tags = (JSONArray) videoJson.get(EventBaseJsonSerializer.FIELD_TAGS);
|
||||
Integer lengthInSeconds = (Integer) videoJson.get(EventBaseJsonSerializer.FIELD_VIDEO_LENGTH_IN_SECONDS);
|
||||
URL thumbnailURL = Helpers.getURLField(videoJson, EventBaseJsonSerializer.FIELD_VIDEO_THUMBNAIL_URL);
|
||||
List<String> videoTags = new ArrayList<String>();
|
||||
if (tags != null) {
|
||||
for (Object tagObject : tags) {
|
||||
videoTags.add((String) tagObject);
|
||||
}
|
||||
}
|
||||
video = new VideoDescriptorImpl(videoURL, mimeType, createdAtDate);
|
||||
video.setCopyright(copyright);
|
||||
video.setLocale(locale);
|
||||
video.setTitle(title);
|
||||
video.setSubtitle(subtitle);
|
||||
video.setTags(videoTags);
|
||||
video.setLengthInSeconds(lengthInSeconds);
|
||||
video.setThumbnailURL(thumbnailURL);
|
||||
}
|
||||
return video;
|
||||
}
|
||||
|
||||
private List<URL> getURLsFromStrings(JSONArray strings) throws MalformedURLException {
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
if (strings != null) {
|
||||
for (Object string : strings) {
|
||||
@@ -115,5 +227,4 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -1,6 +1,8 @@
|
||||
package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -48,6 +50,19 @@ public class Helpers {
|
||||
return (JSONArray) childObject;
|
||||
}
|
||||
|
||||
public static URL getURLField(JSONObject parent, String fieldName) {
|
||||
URL result = null;
|
||||
String urlAsString = (String) parent.get(fieldName);
|
||||
if (urlAsString != null) {
|
||||
try {
|
||||
result = new URL(urlAsString);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Error deserializing URL " + urlAsString);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Serializable tryUuidConversion(Serializable serializableId) {
|
||||
try {
|
||||
return UUID.fromString(serializableId.toString());
|
||||
|
||||
+78
-29
@@ -1,9 +1,6 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
@@ -12,11 +9,10 @@ import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
private static final Logger logger = Logger.getLogger(EventBaseJsonSerializer.class.getName());
|
||||
|
||||
public static final String FIELD_ID = "id";
|
||||
public static final String FIELD_NAME = "name";
|
||||
public static final String FIELD_DESCRIPTION = "description";
|
||||
@@ -31,9 +27,27 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
public static final String FIELD_IMAGE_URL = "imageURL";
|
||||
public static final String FIELD_IMAGE_WIDTH = "imageWidth";
|
||||
public static final String FIELD_IMAGE_HEIGHT = "imageHeight";
|
||||
public static final String FIELD_VIDEO_URL = "videoURL";
|
||||
public static final String FIELD_OFFICIAL_WEBSITE_URL = "officialWebsiteURL";
|
||||
public static final String FIELDS_LEADERBOARD_GROUPS = "leaderboardGroups";
|
||||
|
||||
public static final String FIELD_SOURCE_URL = "sourceURL";
|
||||
public static final String FIELD_TITLE = "title";
|
||||
public static final String FIELD_SUBTITLE = "subtitle";
|
||||
public static final String FIELD_MIMETYPE = "mimetype";
|
||||
public static final String FIELD_COPYRIGHT = "copyright";
|
||||
public static final String FIELD_CREATEDATDATE = "createdAtDate";
|
||||
public static final String FIELD_LOCALE = "locale";
|
||||
public static final String FIELD_TAGS = "tags";
|
||||
// specific image fields
|
||||
public static final String FIELD_IMAGES = "images";
|
||||
public static final String FIELD_IMAGE_WIDTH_IN_PX = "widthInPixel";
|
||||
public static final String FIELD_IMAGE_HEIGHT_IN_PX = "heightInPixel";
|
||||
// specific video fields
|
||||
public static final String FIELD_VIDEOS = "videos";
|
||||
public static final String FIELD_VIDEO_THUMBNAIL_URL = "thumbnailURL";
|
||||
public static final String FIELD_VIDEO_LENGTH_IN_SECONDS = "lengthInSeconds";
|
||||
|
||||
private final JsonSerializer<Venue> venueSerializer;
|
||||
private final JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer;
|
||||
|
||||
@@ -42,16 +56,17 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
this.venueSerializer = venueSerializer;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public JSONObject serialize(EventBase event) {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put(FIELD_ID, event.getId().toString());
|
||||
result.put(FIELD_NAME, event.getName());
|
||||
result.put(FIELD_DESCRIPTION, event.getDescription());
|
||||
result.put(FIELD_OFFICIAL_WEBSITE_URL, event.getOfficialWebsiteURL() != null ? event.getOfficialWebsiteURL().toString() : null);
|
||||
result.put(FIELD_LOGO_IMAGE_URL, event.getLogoImageURL() != null ? event.getLogoImageURL().toString() : null);
|
||||
result.put(FIELD_START_DATE, event.getStartDate() != null ? event.getStartDate().asMillis() : null);
|
||||
result.put(FIELD_END_DATE, event.getStartDate() != null ? event.getEndDate().asMillis() : null);
|
||||
result.put(FIELD_VENUE, venueSerializer.serialize(event.getVenue()));
|
||||
result.put(FIELD_LOGO_IMAGE_URL, event.getLogoImageURL() != null ? event.getLogoImageURL().toString() : null);
|
||||
result.put(FIELD_IMAGE_URLS, getURLsAsStringArray(event.getImageURLs()));
|
||||
result.put(FIELD_VIDEO_URLS, getURLsAsStringArray(event.getVideoURLs()));
|
||||
result.put(FIELD_SPONSOR_IMAGE_URLS, getURLsAsStringArray(event.getSponsorImageURLs()));
|
||||
@@ -62,37 +77,71 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
}
|
||||
JSONArray imageSizes = new JSONArray();
|
||||
result.put(FIELD_IMAGE_SIZES, imageSizes);
|
||||
for (URL imageURL : event.getImageURLs()) {
|
||||
addImageSize(imageURL, imageSizes, event);
|
||||
for (ImageDescriptor image : event.getImages()) {
|
||||
addImageSize(image, imageSizes);
|
||||
}
|
||||
if (event.getLogoImageURL() != null) {
|
||||
addImageSize(event.getLogoImageURL(), imageSizes, event);
|
||||
JSONArray jsonImages = new JSONArray();
|
||||
for(ImageDescriptor imageDescriptor: event.getImages()) {
|
||||
addImage(imageDescriptor, jsonImages);
|
||||
}
|
||||
for (URL sponsorImageURL : event.getSponsorImageURLs()) {
|
||||
addImageSize(sponsorImageURL, imageSizes, event);
|
||||
result.put(FIELD_IMAGES, jsonImages);
|
||||
JSONArray jsonVideos = new JSONArray();
|
||||
for(VideoDescriptor videoDescriptor: event.getVideos()) {
|
||||
addVideo(videoDescriptor, jsonVideos);
|
||||
}
|
||||
result.put(FIELD_VIDEOS, jsonVideos);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addImage(ImageDescriptor image, JSONArray imagesJson) {
|
||||
JSONObject imageJson = new JSONObject();
|
||||
imageJson.put(FIELD_SOURCE_URL, image.getURL().toString());
|
||||
imageJson.put(FIELD_LOCALE, image.getLocale() != null ? image.getLocale().toLanguageTag() : null);
|
||||
imageJson.put(FIELD_TITLE, image.getTitle());
|
||||
imageJson.put(FIELD_SUBTITLE, image.getSubtitle());
|
||||
imageJson.put(FIELD_MIMETYPE, image.getMimeType().name());
|
||||
imageJson.put(FIELD_COPYRIGHT, image.getCopyright());
|
||||
imageJson.put(FIELD_IMAGE_WIDTH_IN_PX, image.getWidthInPx());
|
||||
imageJson.put(FIELD_IMAGE_HEIGHT_IN_PX, image.getHeightInPx());
|
||||
imageJson.put(FIELD_CREATEDATDATE, image.getCreatedAtDate().asMillis());
|
||||
JSONArray tags = new JSONArray();
|
||||
for (String tag : image.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
imageJson.put(FIELD_TAGS, tags);
|
||||
imagesJson.add(imageJson);
|
||||
}
|
||||
|
||||
private void addVideo(VideoDescriptor video, JSONArray videosJson) {
|
||||
JSONObject videoJson = new JSONObject();
|
||||
videoJson.put(FIELD_SOURCE_URL, video.getURL().toString());
|
||||
videoJson.put(FIELD_LOCALE, video.getLocale() != null ? video.getLocale().toLanguageTag() : null);
|
||||
videoJson.put(FIELD_VIDEO_THUMBNAIL_URL, video.getThumbnailURL() != null ? video.getThumbnailURL().toString() : null);
|
||||
videoJson.put(FIELD_TITLE, video.getTitle());
|
||||
videoJson.put(FIELD_SUBTITLE, video.getSubtitle());
|
||||
videoJson.put(FIELD_MIMETYPE, video.getMimeType().name());
|
||||
videoJson.put(FIELD_COPYRIGHT, video.getCopyright());
|
||||
videoJson.put(FIELD_VIDEO_LENGTH_IN_SECONDS, video.getLengthInSeconds());
|
||||
videoJson.put(FIELD_CREATEDATDATE, video.getCreatedAtDate().asMillis());
|
||||
JSONArray tags = new JSONArray();
|
||||
for (String tag : video.getTags()) {
|
||||
tags.add(tag);
|
||||
}
|
||||
videoJson.put(FIELD_TAGS, tags);
|
||||
videosJson.add(videoJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* If <code>eventBase</code> knows the size of the image with URL <code>imageURL</code>, that size is serialized as
|
||||
* For backward compatibility the size of an image is also serialized as
|
||||
* JSON object to <code>imageSizes</code>
|
||||
*/
|
||||
private void addImageSize(URL imageURL, JSONArray imageSizes, EventBase eventBase) {
|
||||
ImageSize imageSize;
|
||||
try {
|
||||
imageSize = eventBase.getImageSize(imageURL);
|
||||
if (imageSize != null) {
|
||||
JSONObject imageSizeJson = new JSONObject();
|
||||
imageSizes.add(imageSizeJson);
|
||||
imageSizeJson.put(FIELD_IMAGE_URL, imageURL.toString());
|
||||
imageSizeJson.put(FIELD_IMAGE_WIDTH, imageSize.getWidth());
|
||||
imageSizeJson.put(FIELD_IMAGE_HEIGHT, imageSize.getHeight());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.FINE, "Couldn't retrieve image size for URL "+imageURL, e);
|
||||
} catch (ExecutionException e) {
|
||||
logger.log(Level.FINE, "Couldn't retrieve image size for URL "+imageURL, e);
|
||||
private void addImageSize(ImageDescriptor image, JSONArray imageSizes) {
|
||||
if(image.getHeightInPx() != null && image.getWidthInPx() != null) {
|
||||
JSONObject imageSizeJson = new JSONObject();
|
||||
imageSizes.add(imageSizeJson);
|
||||
imageSizeJson.put(FIELD_IMAGE_URL, image.getURL().toString());
|
||||
imageSizeJson.put(FIELD_IMAGE_WIDTH, image.getWidthInPx());
|
||||
imageSizeJson.put(FIELD_IMAGE_HEIGHT, image.getHeightInPx());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -32,6 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class EventDataJsonSerializerTest {
|
||||
protected final UUID expectedId = UUID.randomUUID();
|
||||
@@ -55,6 +57,7 @@ public class EventDataJsonSerializerTest {
|
||||
}
|
||||
|
||||
// see https://groups.google.com/forum/?fromgroups=#!topic/mockito/iMumB0_bpdo
|
||||
@SuppressWarnings("deprecation")
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Event and its basic attributes ...
|
||||
@@ -70,6 +73,8 @@ public class EventDataJsonSerializerTest {
|
||||
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getSponsorImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getImages()).thenReturn(Collections.<ImageDescriptor>emptySet());
|
||||
when(event.getVideos()).thenReturn(Collections.<VideoDescriptor>emptySet());
|
||||
// ... and the serializer itself.
|
||||
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
|
||||
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
|
||||
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
package com.sap.sailing.server.gateway.serialization.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.base.impl.VenueImpl;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
|
||||
public class EventDataJsonSerializerWithImagesAndVideosTest {
|
||||
private final UUID expectedId = UUID.randomUUID();
|
||||
private final String expectedName = "ab";
|
||||
private final Locale locale = Locale.GERMAN;
|
||||
private final TimePoint expectedStartDate = new MillisecondsTimePoint(new Date());
|
||||
private final TimePoint expectedEndDate = new MillisecondsTimePoint(new Date());
|
||||
private final Venue expectedVenue = new VenueImpl("Expected Venue");
|
||||
private final LeaderboardGroup expectedLeaderboardGroup = mock(LeaderboardGroup.class);
|
||||
private final URL imageURL;
|
||||
private final String copyright = "copyright by Alex";
|
||||
private final String imageTitle = "My image title";
|
||||
private final String imageSubtitle = "My image subtitle";
|
||||
private final Integer imageWidth = 500;
|
||||
private final Integer imageHeight = 300;
|
||||
|
||||
private final URL videoURL;
|
||||
private final URL videoThumbnailURL;
|
||||
private final Locale locale2 = Locale.CANADA_FRENCH;
|
||||
private final Integer videoLengthInSeconds = 2 * 60 * 60 * 1000; // 2h
|
||||
private final MimeType mimeType = MimeType.mp4;
|
||||
private final String copyright2 = "copyright by Don";
|
||||
private final String videoTitle = "My video title";
|
||||
private final String videoSubtitle = "My video subtitle";
|
||||
|
||||
private final TimePoint createdAt = MillisecondsTimePoint.now();
|
||||
private List<ImageDescriptor> images = new ArrayList<ImageDescriptor>();
|
||||
private List<VideoDescriptor> videos = new ArrayList<VideoDescriptor>();
|
||||
|
||||
private EventBaseJsonSerializer serializer;
|
||||
private EventBaseJsonDeserializer deserializer;
|
||||
private EventBase event;
|
||||
|
||||
public EventDataJsonSerializerWithImagesAndVideosTest() throws MalformedURLException {
|
||||
imageURL = new URL("http://some.host/with/some/file2.jpg");
|
||||
ImageDescriptor image1 = new ImageDescriptorImpl(imageURL, createdAt);
|
||||
image1.setCopyright(copyright);
|
||||
image1.setLocale(locale);
|
||||
image1.setSize(imageWidth, imageHeight);
|
||||
image1.setTitle(imageTitle);
|
||||
image1.setSubtitle(imageSubtitle);
|
||||
image1.addTag("Tag1");
|
||||
image1.addTag("Tag2");
|
||||
image1.addTag("Tag3");
|
||||
images.add(image1);
|
||||
|
||||
videoURL = new URL("http://some.host/with/some/video.mpg");
|
||||
videoThumbnailURL = new URL("http://some.host/with/some/video_thumbnail.jpg");
|
||||
|
||||
VideoDescriptor video1 = new VideoDescriptorImpl(videoURL, mimeType, createdAt);
|
||||
video1.setCopyright(copyright2);
|
||||
video1.setLocale(locale2);
|
||||
video1.setTitle(videoTitle);
|
||||
video1.setSubtitle(videoSubtitle);
|
||||
video1.setThumbnailURL(videoThumbnailURL);
|
||||
video1.setLengthInSeconds(videoLengthInSeconds);
|
||||
video1.addTag("Tag1");
|
||||
video1.addTag("Tag2");
|
||||
video1.addTag("Tag3");
|
||||
video1.addTag("Tag4");
|
||||
videos.add(video1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Event and its basic attributes ...
|
||||
event = mock(EventBase.class);
|
||||
when(event.getId()).thenReturn(expectedId);
|
||||
when(event.getName()).thenReturn(expectedName);
|
||||
when(event.getStartDate()).thenReturn(expectedStartDate);
|
||||
when(event.getEndDate()).thenReturn(expectedEndDate);
|
||||
when(event.getVenue()).thenReturn(expectedVenue);
|
||||
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getSponsorImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getImages()).thenReturn(images);
|
||||
when(event.getVideos()).thenReturn(videos);
|
||||
// ... and the serializer itself.
|
||||
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
|
||||
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
|
||||
|
||||
when(expectedLeaderboardGroup.getId()).thenReturn(UUID.randomUUID());
|
||||
when(expectedLeaderboardGroup.getName()).thenReturn("LG");
|
||||
when(expectedLeaderboardGroup.getDescription()).thenReturn("LG Description");
|
||||
when(expectedLeaderboardGroup.getDisplayName()).thenReturn("LG Display Name");
|
||||
when(expectedLeaderboardGroup.hasOverallLeaderboard()).thenReturn(false);
|
||||
doReturn(Collections.<LeaderboardGroup>singleton(expectedLeaderboardGroup)).when(event).getLeaderboardGroups();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageAndVideosAttributes() throws MalformedURLException {
|
||||
JSONObject result = serializer.serialize(event);
|
||||
JSONArray imagesJson = (JSONArray) result.get(EventBaseJsonSerializer.FIELD_IMAGES);
|
||||
JSONObject image1Json = (JSONObject) imagesJson.get(0);
|
||||
assertEquals(imageURL, new URL((String) image1Json.get(EventBaseJsonSerializer.FIELD_SOURCE_URL)));
|
||||
assertEquals(createdAt, new MillisecondsTimePoint(((Number) image1Json.get(EventBaseJsonSerializer.FIELD_CREATEDATDATE)).longValue()));
|
||||
assertEquals(copyright, (String) image1Json.get(EventBaseJsonSerializer.FIELD_COPYRIGHT));
|
||||
assertEquals(imageTitle, (String) image1Json.get(EventBaseJsonSerializer.FIELD_TITLE));
|
||||
assertEquals(imageSubtitle, (String) image1Json.get(EventBaseJsonSerializer.FIELD_SUBTITLE));
|
||||
assertEquals(imageWidth, (Integer) image1Json.get(EventBaseJsonSerializer.FIELD_IMAGE_WIDTH_IN_PX));
|
||||
assertEquals(imageHeight, (Integer) image1Json.get(EventBaseJsonSerializer.FIELD_IMAGE_HEIGHT_IN_PX));
|
||||
JSONArray imageTagsJson = (JSONArray) image1Json.get(EventBaseJsonSerializer.FIELD_TAGS);
|
||||
assertEquals(3, imageTagsJson.size());
|
||||
|
||||
JSONArray videosJson = (JSONArray) result.get(EventBaseJsonSerializer.FIELD_VIDEOS);
|
||||
JSONObject video1Json = (JSONObject) videosJson.get(0);
|
||||
assertEquals(videoURL, new URL((String) video1Json.get(EventBaseJsonSerializer.FIELD_SOURCE_URL)));
|
||||
assertEquals(createdAt, new MillisecondsTimePoint(((Number) video1Json.get(EventBaseJsonSerializer.FIELD_CREATEDATDATE)).longValue()));
|
||||
assertEquals(copyright2, (String) video1Json.get(EventBaseJsonSerializer.FIELD_COPYRIGHT));
|
||||
assertEquals(videoTitle, (String) video1Json.get(EventBaseJsonSerializer.FIELD_TITLE));
|
||||
assertEquals(videoSubtitle, (String) video1Json.get(EventBaseJsonSerializer.FIELD_SUBTITLE));
|
||||
assertEquals(videoThumbnailURL, new URL((String) video1Json.get(EventBaseJsonSerializer.FIELD_VIDEO_THUMBNAIL_URL)));
|
||||
assertEquals(videoLengthInSeconds, (Integer) video1Json.get(EventBaseJsonSerializer.FIELD_VIDEO_LENGTH_IN_SECONDS));
|
||||
JSONArray videoTagsJson = (JSONArray) video1Json.get(EventBaseJsonSerializer.FIELD_TAGS);
|
||||
assertEquals(4, videoTagsJson.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageAndVideosAfterDeserialization() throws JsonDeserializationException {
|
||||
final JSONObject result = serializer.serialize(event);
|
||||
final EventBase deserializedEvent = deserializer.deserialize(result);
|
||||
|
||||
ImageDescriptor image1 = deserializedEvent.getImages().iterator().next();
|
||||
assertEquals(createdAt, image1.getCreatedAtDate());
|
||||
assertEquals(imageURL, image1.getURL());
|
||||
assertEquals(locale, image1.getLocale());
|
||||
assertEquals(copyright, image1.getCopyright());
|
||||
assertEquals(imageTitle, image1.getTitle());
|
||||
assertEquals(imageSubtitle, image1.getSubtitle());
|
||||
assertEquals(imageWidth, image1.getWidthInPx());
|
||||
assertEquals(imageHeight, image1.getHeightInPx());
|
||||
assertEquals(3, Util.size(image1.getTags()));
|
||||
|
||||
VideoDescriptor video1 = deserializedEvent.getVideos().iterator().next();
|
||||
assertEquals(createdAt, video1.getCreatedAtDate());
|
||||
assertEquals(videoURL, video1.getURL());
|
||||
assertEquals(mimeType, video1.getMimeType());
|
||||
assertEquals(copyright2, video1.getCopyright());
|
||||
assertEquals(locale2, video1.getLocale());
|
||||
assertEquals(videoTitle, video1.getTitle());
|
||||
assertEquals(videoSubtitle, video1.getSubtitle());
|
||||
assertEquals(videoThumbnailURL, video1.getThumbnailURL());
|
||||
assertEquals(videoLengthInSeconds, video1.getLengthInSeconds());
|
||||
assertEquals(4, Util.size(video1.getTags()));
|
||||
}
|
||||
|
||||
}
|
||||
+13
-16
@@ -32,6 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class EventDataJsonSerializerWithNullValuesTest {
|
||||
protected final UUID expectedId = UUID.randomUUID();
|
||||
@@ -50,6 +52,7 @@ public class EventDataJsonSerializerWithNullValuesTest {
|
||||
protected EventBase event;
|
||||
|
||||
// see https://groups.google.com/forum/?fromgroups=#!topic/mockito/iMumB0_bpdo
|
||||
@SuppressWarnings("deprecation")
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Event and its basic attributes ...
|
||||
@@ -65,6 +68,8 @@ public class EventDataJsonSerializerWithNullValuesTest {
|
||||
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getSponsorImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getImages()).thenReturn(Collections.<ImageDescriptor>emptySet());
|
||||
when(event.getVideos()).thenReturn(Collections.<VideoDescriptor>emptySet());
|
||||
// ... and the serializer itself.
|
||||
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
|
||||
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
|
||||
@@ -79,31 +84,23 @@ public class EventDataJsonSerializerWithNullValuesTest {
|
||||
@Test
|
||||
public void testBasicAttributes() throws MalformedURLException {
|
||||
JSONObject result = serializer.serialize(event);
|
||||
assertEquals(
|
||||
expectedId,
|
||||
assertEquals(expectedId,
|
||||
UUID.fromString(result.get(EventBaseJsonSerializer.FIELD_ID).toString()));
|
||||
assertEquals(
|
||||
expectedName,
|
||||
assertEquals(expectedName,
|
||||
result.get(EventBaseJsonSerializer.FIELD_NAME));
|
||||
assertEquals(
|
||||
expectedDescription,
|
||||
assertEquals(expectedDescription,
|
||||
result.get(EventBaseJsonSerializer.FIELD_DESCRIPTION));
|
||||
assertEquals(
|
||||
expectedOfficialWebsiteURL,
|
||||
assertEquals(expectedOfficialWebsiteURL,
|
||||
result.get(EventBaseJsonSerializer.FIELD_OFFICIAL_WEBSITE_URL) == null ? null :
|
||||
new URL((String) result.get(EventBaseJsonSerializer.FIELD_OFFICIAL_WEBSITE_URL)));
|
||||
assertEquals(
|
||||
expectedLogoImageURL,
|
||||
assertEquals(expectedLogoImageURL,
|
||||
result.get(EventBaseJsonSerializer.FIELD_LOGO_IMAGE_URL) == null ? null :
|
||||
new URL((String) result.get(EventBaseJsonSerializer.FIELD_LOGO_IMAGE_URL)));
|
||||
assertEquals(
|
||||
expectedDescription,
|
||||
assertEquals(expectedDescription,
|
||||
result.get(EventBaseJsonSerializer.FIELD_DESCRIPTION));
|
||||
assertEquals(
|
||||
expectedStartDate,
|
||||
assertEquals(expectedStartDate,
|
||||
new MillisecondsTimePoint(((Number) result.get(EventBaseJsonSerializer.FIELD_START_DATE)).longValue()));
|
||||
assertEquals(
|
||||
expectedEndDate,
|
||||
assertEquals(expectedEndDate,
|
||||
new MillisecondsTimePoint(((Number) result.get(EventBaseJsonSerializer.FIELD_END_DATE)).longValue()));
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -31,6 +31,8 @@ import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class EventWithNullStartAndEndDataJsonSerializerTest {
|
||||
|
||||
@@ -55,6 +57,7 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
|
||||
expectedLogoImageURL = new URL("http://official.logo.com/logo.png");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Event and its basic attributes ...
|
||||
@@ -74,6 +77,8 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
|
||||
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getSponsorImageURLs()).thenReturn(Collections.<URL>emptySet());
|
||||
when(event.getImages()).thenReturn(Collections.<ImageDescriptor>emptySet());
|
||||
when(event.getVideos()).thenReturn(Collections.<VideoDescriptor>emptySet());
|
||||
doReturn(expectedLeaderboardGroups).when(event).getLeaderboardGroups();
|
||||
|
||||
// ... and the serializer itself.
|
||||
@@ -91,6 +96,7 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
|
||||
assertNull(result.get(EventBaseJsonSerializer.FIELD_END_DATE));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testBasicAttributesAfterDeserialization() throws JsonDeserializationException {
|
||||
final JSONObject result = serializer.serialize(event);
|
||||
|
||||
+8
-11
@@ -12,7 +12,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -127,7 +126,9 @@ import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.mongodb.MongoDBConfiguration;
|
||||
import com.sap.sse.mongodb.MongoDBService;
|
||||
|
||||
@@ -1326,12 +1327,10 @@ public class MasterDataImportTest {
|
||||
InterruptedException, ClassNotFoundException {
|
||||
RacingEventService sourceService = new RacingEventServiceImpl();
|
||||
|
||||
Iterable<URL> imageURLs = new HashSet<>();
|
||||
Iterable<URL> videoURLs = new HashSet<>();
|
||||
Iterable<URL> sponsorImageURLs = new HashSet<>();
|
||||
Event event = sourceService.createEventWithoutReplication("Test Event", /* eventDescription */ null,
|
||||
new MillisecondsTimePoint(0), new MillisecondsTimePoint(10), "testvenue", false, UUID.randomUUID(), imageURLs,
|
||||
videoURLs, sponsorImageURLs, /* logoImageURL */ null, /* officialWebsiteURL */ null);
|
||||
new MillisecondsTimePoint(0), new MillisecondsTimePoint(10), "testvenue", false, UUID.randomUUID(),
|
||||
/* officialWebsiteURL */ null, /* images */Collections.<ImageDescriptor> emptyList(),
|
||||
/* videos */Collections.<VideoDescriptor> emptyList());
|
||||
CourseArea defaultCourseArea = sourceService.addCourseArea(event.getId(), "ECHO", UUID.randomUUID());
|
||||
|
||||
Regatta regatta = sourceService.createRegatta(
|
||||
@@ -1393,12 +1392,10 @@ public class MasterDataImportTest {
|
||||
// Setup source service
|
||||
RacingEventService sourceService = new RacingEventServiceImpl();
|
||||
|
||||
Iterable<URL> imageURLs = new HashSet<>();
|
||||
Iterable<URL> videoURLs = new HashSet<>();
|
||||
Iterable<URL> sponsorImageURLs = new HashSet<>();
|
||||
Event event = sourceService.createEventWithoutReplication("Test Event", /* eventDescription */ null,
|
||||
new MillisecondsTimePoint(0), new MillisecondsTimePoint(10), "testvenue", false, UUID.randomUUID(), imageURLs,
|
||||
videoURLs, sponsorImageURLs, /* logoImageURL */ null, /* officialWebsiteURL */ null);
|
||||
new MillisecondsTimePoint(0), new MillisecondsTimePoint(10), "testvenue", false, UUID.randomUUID(),
|
||||
/* officialWebsiteURL */ null, /* images */Collections.<ImageDescriptor> emptyList(),
|
||||
/* videos */Collections.<VideoDescriptor> emptyList());
|
||||
CourseArea defaultCourseArea = sourceService.addCourseArea(event.getId(), "ECHO", UUID.randomUUID());
|
||||
|
||||
List<String> raceColumnNames = new ArrayList<String>();
|
||||
|
||||
+5
-7
@@ -5,7 +5,6 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
@@ -73,6 +72,8 @@ import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
|
||||
@@ -119,9 +120,7 @@ public class SearchServiceTest {
|
||||
cal.set(2014, 5, 8, 16, 00);
|
||||
final TimePoint pfingstbuschEndDate = new MillisecondsTimePoint(cal.getTime());
|
||||
pfingstbusch = server.apply(new CreateEvent("Pfingsbusch", /* eventDescription */ null, pfingstbuschStartDate, pfingstbuschEndDate, /* isPublic */
|
||||
"Kiel", true, UUID.randomUUID(), Collections.<URL>emptySet(),
|
||||
Collections.<URL>emptySet(),
|
||||
/* sponsorImageURLs */ Collections.<URL>emptySet(), /* logoImageURLAsString */ null, /* officialWebsiteURLAsString */ null));
|
||||
"Kiel", true, UUID.randomUUID(), /* officialWebsiteURLAsString */ null, /* images */Collections.<ImageDescriptor> emptyList(), /* videos */Collections.<VideoDescriptor> emptyList()));
|
||||
kiel = pfingstbusch.getVenue();
|
||||
final CourseAreaImpl kielAlpha = new CourseAreaImpl("Alpha", UUID.randomUUID());
|
||||
kiel.addCourseArea(kielAlpha);
|
||||
@@ -154,9 +153,8 @@ public class SearchServiceTest {
|
||||
cal.set(2014, 5, 8, 18, 00);
|
||||
final TimePoint aalEndDate = new MillisecondsTimePoint(cal.getTime());
|
||||
aalEvent = server.apply(new CreateEvent("Aalregatta", /* eventDescription */ null, aalStartDate, aalEndDate, /* isPublic */
|
||||
"Flensburg", true, UUID.randomUUID(), Collections.<URL>emptySet(),
|
||||
Collections.<URL>emptySet(), /* sponsorImageURLs */ Collections.<URL>emptySet(),
|
||||
/* logoimageURL */ null, /* officialWebsiteURLAsString */ null));
|
||||
"Flensburg", true, UUID.randomUUID(), /* officialWebsiteURLAsString */ null,
|
||||
/* images */Collections.<ImageDescriptor> emptyList(), /* videos */Collections.<VideoDescriptor> emptyList()));
|
||||
flensburg = aalEvent.getVenue();
|
||||
final CourseAreaImpl flensburgStandard = new CourseAreaImpl("Standard", UUID.randomUUID());
|
||||
flensburg.addCourseArea(flensburgStandard);
|
||||
|
||||
@@ -74,6 +74,8 @@ import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
import com.sap.sse.common.search.Searchable;
|
||||
@@ -369,7 +371,7 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
*/
|
||||
void updateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
|
||||
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL,
|
||||
URL logoImageURL, Iterable<URL> imageURLs, Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs);
|
||||
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos);
|
||||
|
||||
/**
|
||||
* Renames a sailing event. If a sailing event by the name <code>oldName</code> does not exist in {@link #getEvents()},
|
||||
@@ -464,7 +466,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
ConcurrentHashMap<String, Regatta> getPersistentRegattasForRaceIDs();
|
||||
|
||||
Event createEventWithoutReplication(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
|
||||
boolean isPublic, UUID id, Iterable<URL> imageURLs, Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs, URL logoImageURL, URL officialWebsiteURL);
|
||||
boolean isPublic, UUID id, URL officialWebsiteURL, Iterable<ImageDescriptor> images,
|
||||
Iterable<VideoDescriptor> videos);
|
||||
|
||||
void setRegattaForRace(Regatta regatta, String raceIdAsString);
|
||||
|
||||
|
||||
+13
-18
@@ -208,6 +208,8 @@ import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
import com.sap.sse.common.search.ResultImpl;
|
||||
@@ -2572,13 +2574,10 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
public Event addEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
|
||||
String venue, boolean isPublic, UUID id) {
|
||||
Event result = createEventWithoutReplication(eventName, eventDescription, startDate, endDate, venue, isPublic,
|
||||
id, /* imageURLs */Collections.<URL> emptyList(),
|
||||
/* videoURLs */Collections.<URL> emptyList(), /* sponsorImageURLs */Collections.<URL> emptyList(), /* logoImageURL */
|
||||
null, /* officialWebsiteURL */null);
|
||||
replicate(new CreateEvent(eventName, eventDescription, startDate, endDate, venue, isPublic, /* imageURLs */
|
||||
id, Collections.<URL> emptyList(),
|
||||
/* videoURLs */Collections.<URL> emptyList(), /* sponsorImageURLs */Collections.<URL> emptyList(),
|
||||
/* logoimageURL */null, /* officialWebsiteURLAsString */null));
|
||||
id, /* officialWebsiteURL */null, /* images */Collections.<ImageDescriptor> emptyList(),
|
||||
/* videos */Collections.<VideoDescriptor> emptyList());
|
||||
replicate(new CreateEvent(eventName, eventDescription, startDate, endDate, venue, isPublic, id,
|
||||
/* officialWebsiteURLAsString */null, /* images */Collections.<ImageDescriptor> emptyList(), /* videos */Collections.<VideoDescriptor> emptyList()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2589,16 +2588,14 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
|
||||
@Override
|
||||
public Event createEventWithoutReplication(String eventName, String eventDescription, TimePoint startDate,
|
||||
TimePoint endDate, String venue, boolean isPublic, UUID id, Iterable<URL> imageURLs,
|
||||
Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs, URL logoImageURL, URL officialWebsiteURL) {
|
||||
TimePoint endDate, String venue, boolean isPublic, UUID id, URL officialWebsiteURL, Iterable<ImageDescriptor> images,
|
||||
Iterable<VideoDescriptor> videos) {
|
||||
Event result = new EventImpl(eventName, startDate, endDate, venue, isPublic, id);
|
||||
addEvent(result);
|
||||
result.setDescription(eventDescription);
|
||||
result.setImageURLs(imageURLs);
|
||||
result.setVideoURLs(videoURLs);
|
||||
result.setSponsorImageURLs(sponsorImageURLs);
|
||||
result.setLogoImageURL(logoImageURL);
|
||||
result.setOfficialWebsiteURL(officialWebsiteURL);
|
||||
result.setImages(images);
|
||||
result.setVideos(videos);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2614,7 +2611,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
@Override
|
||||
public void updateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
|
||||
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL,
|
||||
URL logoImageURL, Iterable<URL> imageURLs, Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs) {
|
||||
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
|
||||
final Event event = eventsById.get(id);
|
||||
if (event == null) {
|
||||
throw new IllegalArgumentException("Sailing event with ID " + id + " does not exist.");
|
||||
@@ -2637,10 +2634,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
}
|
||||
event.setLeaderboardGroups(leaderboardGroups);
|
||||
event.setOfficialWebsiteURL(officialWebsiteURL);
|
||||
event.setLogoImageURL(logoImageURL);
|
||||
event.setImageURLs(imageURLs);
|
||||
event.setVideoURLs(videoURLs);
|
||||
event.setSponsorImageURLs(sponsorImageURLs);
|
||||
event.setImages(images);
|
||||
event.setVideos(videos);
|
||||
// TODO consider use diffutils to compute diff between old and new leaderboard groups list and apply the patch
|
||||
// to keep changes minimial
|
||||
mongoObjectFactory.storeEvent(event);
|
||||
|
||||
+8
-10
@@ -7,6 +7,8 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
/**
|
||||
* Creates an {@link Event} in the server, with a new venue and an empty course area list.
|
||||
@@ -23,14 +25,12 @@ public class CreateEvent extends AbstractEventOperation<Event> {
|
||||
private final boolean isPublic;
|
||||
private final String eventName;
|
||||
private final String eventDescription;
|
||||
private final Iterable<URL> videoURLs;
|
||||
private final Iterable<URL> imageURLs;
|
||||
private final Iterable<URL> sponsorImageURLs;
|
||||
private final URL logoImageURL;
|
||||
private final Iterable<ImageDescriptor> images;
|
||||
private final Iterable<VideoDescriptor> videos;
|
||||
private final URL officialWebsiteURL;
|
||||
|
||||
public CreateEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
|
||||
boolean isPublic, UUID id, Iterable<URL> imageURLs, Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs, URL logoImageURL, URL officialWebsiteURL) {
|
||||
boolean isPublic, UUID id, URL officialWebsiteURL, Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
|
||||
super(id);
|
||||
this.eventName = eventName;
|
||||
this.eventDescription = eventDescription;
|
||||
@@ -38,11 +38,9 @@ public class CreateEvent extends AbstractEventOperation<Event> {
|
||||
this.endDate = endDate;
|
||||
this.venue = venue;
|
||||
this.isPublic = isPublic;
|
||||
this.imageURLs = imageURLs;
|
||||
this.videoURLs = videoURLs;
|
||||
this.sponsorImageURLs = sponsorImageURLs;
|
||||
this.logoImageURL = logoImageURL;
|
||||
this.officialWebsiteURL = officialWebsiteURL;
|
||||
this.images = images;
|
||||
this.videos = videos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +62,7 @@ public class CreateEvent extends AbstractEventOperation<Event> {
|
||||
@Override
|
||||
public Event internalApplyTo(RacingEventService toState) {
|
||||
return toState.createEventWithoutReplication(getEventName(), eventDescription, startDate, endDate, venue, isPublic,
|
||||
getId(), imageURLs, videoURLs, sponsorImageURLs, logoImageURL, officialWebsiteURL);
|
||||
getId(), officialWebsiteURL, images, videos);
|
||||
}
|
||||
|
||||
}
|
||||
+9
-11
@@ -6,6 +6,8 @@ import java.util.UUID;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
|
||||
public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
private static final long serialVersionUID = -8271559266421161532L;
|
||||
@@ -17,14 +19,12 @@ public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
private final String eventName;
|
||||
private final String eventDescription;
|
||||
private final URL officialWebsiteURL;
|
||||
private final URL logoImageURL;
|
||||
private final Iterable<URL> imageURLs;
|
||||
private final Iterable<URL> videoURLs;
|
||||
private final Iterable<URL> sponsorImageURLs;
|
||||
private final Iterable<ImageDescriptor> images;
|
||||
private final Iterable<VideoDescriptor> videos;
|
||||
|
||||
public UpdateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
|
||||
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL logoImageURL,
|
||||
URL officialWebsiteURL, Iterable<URL> imageURLs, Iterable<URL> videoURLs, Iterable<URL> sponsorImageURLs) {
|
||||
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL,
|
||||
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
|
||||
super(id);
|
||||
this.eventName = eventName;
|
||||
this.eventDescription = eventDescription;
|
||||
@@ -34,10 +34,8 @@ public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
this.isPublic = isPublic;
|
||||
this.leaderboardGroupIds = leaderboardGroupIds;
|
||||
this.officialWebsiteURL = officialWebsiteURL;
|
||||
this.logoImageURL = logoImageURL;
|
||||
this.imageURLs = imageURLs;
|
||||
this.videoURLs = videoURLs;
|
||||
this.sponsorImageURLs = sponsorImageURLs;
|
||||
this.images = images;
|
||||
this.videos = videos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,7 +53,7 @@ public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) {
|
||||
toState.updateEvent(getId(), eventName, eventDescription, startDate, endDate, venueName, isPublic,
|
||||
leaderboardGroupIds, officialWebsiteURL, logoImageURL, imageURLs, videoURLs, sponsorImageURLs);
|
||||
leaderboardGroupIds, officialWebsiteURL, images, videos);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Common media data for media items
|
||||
*
|
||||
* @author pgtaboada
|
||||
*
|
||||
*/
|
||||
public class AbstractMediaDTO implements Serializable, Comparable<AbstractMediaDTO> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* TODO: would "caption" be a better name?
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* TODO: should we provide a subtitle?
|
||||
*/
|
||||
protected String subtitle;
|
||||
|
||||
/**
|
||||
* This information should be used for chronological ordering
|
||||
* TODO: Must not be null. We need to find a way to
|
||||
* migrate data!
|
||||
*/
|
||||
protected Date createdAtDate;
|
||||
|
||||
/**
|
||||
* TODO: initially I though of "author", but I am not sure if we need the author name. But we probably will need
|
||||
* some place to store copyright information...
|
||||
*/
|
||||
protected String copyright;
|
||||
|
||||
private MimeType mimeType;
|
||||
|
||||
/**
|
||||
* TODO: tags will give us some way to categorize medias. If we pass this information to the frontend, we need some
|
||||
* nice idea to show display this data. for now it should be something restricted to the backend domain modell
|
||||
*/
|
||||
private HashSet<String> tags = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* URL pointing to the media data.
|
||||
*/
|
||||
private String sourceRef;
|
||||
|
||||
/**
|
||||
* Default constructor required for GWT serialization.
|
||||
*/
|
||||
protected AbstractMediaDTO() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Media item with minimal set of information
|
||||
*
|
||||
* @param sourceRef
|
||||
* @param mimeType
|
||||
*/
|
||||
public AbstractMediaDTO(String sourceRef, MimeType mimeType, Date createdAtDate) {
|
||||
this.mimeType = mimeType;
|
||||
this.sourceRef = sourceRef;
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
public MimeType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public String getSourceRef() {
|
||||
return sourceRef;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public HashSet<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public String getSubtitle() {
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
public Date getCreatedAtDate() {
|
||||
return createdAtDate;
|
||||
}
|
||||
|
||||
public void setCreatedAtDate(Date createdAtDate) {
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
public String getCopyright() {
|
||||
return copyright;
|
||||
}
|
||||
|
||||
public void setCopyright(String copyright) {
|
||||
this.copyright = copyright;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(AbstractMediaDTO o) {
|
||||
return createdAtDate.compareTo(o.createdAtDate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* Common media data for media items
|
||||
*
|
||||
* @author pgtaboada
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractMediaDescriptor implements MediaDescriptor, Serializable {
|
||||
private static final long serialVersionUID = -6671425870632517274L;
|
||||
|
||||
protected String title;
|
||||
|
||||
protected String subtitle;
|
||||
|
||||
protected TimePoint createdAtDate;
|
||||
|
||||
protected String copyright;
|
||||
|
||||
protected MimeType mimeType;
|
||||
|
||||
protected Set<String> tags = new LinkedHashSet<String>();
|
||||
|
||||
protected URL url;
|
||||
|
||||
protected Locale locale;
|
||||
|
||||
/**
|
||||
* Media item with minimal set of information
|
||||
* @param url
|
||||
* @param mimeType
|
||||
*/
|
||||
public AbstractMediaDescriptor(URL url, MimeType mimeType, TimePoint createdAtDate) {
|
||||
this.mimeType = mimeType;
|
||||
this.url = url;
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimeType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTags(Iterable<String> tags) {
|
||||
this.tags.clear();
|
||||
if (tags != null) {
|
||||
Util.addAll(tags, this.tags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addTag(String tagName) {
|
||||
return tags.add(tagName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeTag(String tagName) {
|
||||
return tags.remove(tagName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubtitle() {
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getCreatedAtDate() {
|
||||
return createdAtDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreatedAtDate(TimePoint createdAtDate) {
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCopyright() {
|
||||
return copyright;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopyright(String copyright) {
|
||||
this.copyright = copyright;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTag(String tagName) {
|
||||
return tags.contains(tagName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
public interface ImageDescriptor extends MediaDescriptor {
|
||||
void setSize(Pair<Integer, Integer> size);
|
||||
void setSize(Integer widthInPx, Integer heightInPx);
|
||||
|
||||
Integer getWidthInPx();
|
||||
Integer getHeightInPx();
|
||||
|
||||
boolean hasSize();
|
||||
int getArea();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
|
||||
public class ImageDescriptorImpl extends AbstractMediaDescriptor implements ImageDescriptor {
|
||||
private static final long serialVersionUID = -702731462768602331L;
|
||||
|
||||
private Integer widthInPx;
|
||||
private Integer heightInPx;
|
||||
|
||||
/**
|
||||
* @param imageURL
|
||||
* @param size
|
||||
*/
|
||||
public ImageDescriptorImpl(URL imageURL, TimePoint createdAtDate) {
|
||||
super(imageURL, MimeType.image, createdAtDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getWidthInPx() {
|
||||
return widthInPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getHeightInPx() {
|
||||
return heightInPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(Pair<Integer, Integer> size) {
|
||||
if (size != null) {
|
||||
this.widthInPx = size.getA();
|
||||
this.heightInPx = size.getB();
|
||||
} else {
|
||||
this.widthInPx = null;
|
||||
this.heightInPx = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(Integer widthInPx, Integer heightInPx) {
|
||||
this.widthInPx = widthInPx;
|
||||
this.heightInPx = heightInPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSize() {
|
||||
return widthInPx != null && heightInPx != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
if(hasSize()) {
|
||||
return widthInPx * heightInPx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class ImageMetadataDTO extends AbstractMediaDTO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int widthInPx;
|
||||
private int heightInPx;
|
||||
|
||||
protected ImageMetadataDTO() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: should we use imagesize, or should we store height and width? For now, this is a convenience method...
|
||||
*
|
||||
* @param imageURL
|
||||
* @param size
|
||||
*/
|
||||
public ImageMetadataDTO(String imageURL, ImageSize size, Date createdAtDate) {
|
||||
super(imageURL, MimeType.image, createdAtDate);
|
||||
this.widthInPx = size.getWidth();
|
||||
this.heightInPx = size.getHeight();
|
||||
}
|
||||
|
||||
public ImageMetadataDTO(String imageURL, int heightInPx, int widthInPx, Date createdAtDate) {
|
||||
super(imageURL, MimeType.image, createdAtDate);
|
||||
this.widthInPx = widthInPx;
|
||||
this.heightInPx = heightInPx;
|
||||
}
|
||||
|
||||
public int getWidthInPx() {
|
||||
return widthInPx;
|
||||
}
|
||||
|
||||
public int getHeightInPx() {
|
||||
return heightInPx;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* A common media interface for all kinds of media like images or videos.
|
||||
*/
|
||||
public interface MediaDescriptor extends Serializable {
|
||||
MimeType getMimeType();
|
||||
URL getURL();
|
||||
|
||||
String getTitle();
|
||||
void setTitle(String title);
|
||||
|
||||
Iterable<String> getTags();
|
||||
void setTags(Iterable<String> tags);
|
||||
boolean addTag(String tagName);
|
||||
boolean removeTag(String tagName);
|
||||
boolean hasTag(String tagName);
|
||||
|
||||
String getSubtitle();
|
||||
void setSubtitle(String subtitle);
|
||||
|
||||
TimePoint getCreatedAtDate();
|
||||
void setCreatedAtDate(TimePoint createdAtDate);
|
||||
|
||||
String getCopyright();
|
||||
void setCopyright(String copyright);
|
||||
|
||||
Locale getLocale();
|
||||
void setLocale(Locale locale);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
public interface MediaTagConstants {
|
||||
static final String GALLERY = "Gallery";
|
||||
static final String STAGE = "Stage";
|
||||
static final String LOGO = "Logo";
|
||||
static final String TEASER = "Teaser";
|
||||
static final String SPONSOR = "Sponsor";
|
||||
static final String HIGHLIGHT = "Highlight";
|
||||
static final String LIVESTREAM = "Livestream";
|
||||
static final String FEATURED = "Featured";
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
public class MediaUtils {
|
||||
private static final Logger logger = Logger.getLogger(MediaUtils.class.getName());
|
||||
|
||||
/**
|
||||
* Youtube regex detection from:
|
||||
* http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url, mantish Mar 4
|
||||
* at 15:33
|
||||
*/
|
||||
private static final Pattern YOUTUBE_ID_REGEX = Pattern
|
||||
.compile("^.*(youtu.be/|v/|u/\\w/|embed/|watch\\?v=|\\&v=)([^#\\&\\?]+).*$");
|
||||
|
||||
private static final Pattern VIMEO_REGEX = Pattern.compile("^.*(vimeo\\.com\\/).*");
|
||||
|
||||
private static final Pattern MP4_REGEX = Pattern.compile(".*\\.mp4$");
|
||||
|
||||
/**
|
||||
* Detect mimetype for given url.
|
||||
*
|
||||
* @param url
|
||||
* the source pointing to the video mediafile
|
||||
* @return mimetype detected or MimeType.unknown
|
||||
*/
|
||||
public static MimeType detectMimeTypeFromUrl(String url) {
|
||||
|
||||
if (YOUTUBE_ID_REGEX.matcher(url).matches()) {
|
||||
return MimeType.youtube;
|
||||
} else if (VIMEO_REGEX.matcher(url).matches()) {
|
||||
return MimeType.vimeo;
|
||||
} else if (MP4_REGEX.matcher(url).matches()) {
|
||||
return MimeType.mp4;
|
||||
} else {
|
||||
return MimeType.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<Integer, Integer> getImageDimensions(URL imageURL) {
|
||||
Future<Pair<Integer, Integer>> imageSizeCalculator = getOrCreateImageSizeCalculator(imageURL);
|
||||
try {
|
||||
return imageSizeCalculator.get();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
private static Future<Pair<Integer, Integer>> getOrCreateImageSizeCalculator(final URL imageURL) {
|
||||
Future<Pair<Integer, Integer>> imageSizeFetcher = executor.submit(new Callable<Pair<Integer, Integer>>() {
|
||||
@Override
|
||||
public Pair<Integer, Integer> call() throws IOException {
|
||||
Pair<Integer, Integer> result = null;
|
||||
ImageInputStream in = null;
|
||||
try {
|
||||
URLConnection conn = imageURL.openConnection();
|
||||
in = ImageIO.createImageInputStream(conn.getInputStream());
|
||||
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
|
||||
if (readers.hasNext()) {
|
||||
ImageReader reader = readers.next();
|
||||
try {
|
||||
reader.setInput(in);
|
||||
result = new Pair<>(reader.getWidth(0), reader.getHeight(0));
|
||||
} finally {
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
logger.log(Level.SEVERE, "Stale image URL: "+imageURL, ioe);
|
||||
throw ioe;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return imageSizeFetcher;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public interface VideoDescriptor extends MediaDescriptor {
|
||||
Integer getLengthInSeconds();
|
||||
void setLengthInSeconds(Integer lengthInSeconds);
|
||||
|
||||
URL getThumbnailURL();
|
||||
void setThumbnailURL(URL thumbnailURL);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class VideoDescriptorImpl extends AbstractMediaDescriptor implements VideoDescriptor {
|
||||
private static final long serialVersionUID = 2651747912466590862L;
|
||||
|
||||
private Integer lengthInSeconds;
|
||||
|
||||
/**
|
||||
* URL to thumbnail image. This information works as override for youtube videos or as missing thumbnail
|
||||
* information for other formats. It can be either a link to thumbnail or even be a data/url contaning the base64
|
||||
* encoded image.
|
||||
*/
|
||||
private URL thumbnailURL;
|
||||
|
||||
public VideoDescriptorImpl(URL url, MimeType mimeType, TimePoint createdAtDate) {
|
||||
super(url, mimeType, createdAtDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getLengthInSeconds() {
|
||||
return lengthInSeconds;
|
||||
}
|
||||
|
||||
public void setLengthInSeconds(Integer lengthInSeconds) {
|
||||
this.lengthInSeconds = lengthInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getThumbnailURL() {
|
||||
return thumbnailURL;
|
||||
}
|
||||
|
||||
public void setThumbnailURL(URL thumbnailURL) {
|
||||
this.thumbnailURL = thumbnailURL;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class VideoMetadataDTO extends AbstractMediaDTO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* TODO: Do we really need video length? Should it be mandatory?
|
||||
*/
|
||||
private int lengthInSeconds;
|
||||
|
||||
/**
|
||||
* URL Reference to thumbnail image. This information works as override for youtube videos or as missing thumbnail
|
||||
* information for other formats. It can be either a link to thumbnail or even be a data/url contaning the base64
|
||||
* encoded image.
|
||||
*/
|
||||
private String thumbnailRef;
|
||||
|
||||
|
||||
protected VideoMetadataDTO() {
|
||||
}
|
||||
|
||||
|
||||
public VideoMetadataDTO(String url, MimeType mimeType, Date createdAtDate) {
|
||||
super(url, mimeType, createdAtDate);
|
||||
}
|
||||
|
||||
public int getLengthInSeconds() {
|
||||
return lengthInSeconds;
|
||||
}
|
||||
|
||||
public void setLengthInSeconds(int lengthInSeconds) {
|
||||
this.lengthInSeconds = lengthInSeconds;
|
||||
}
|
||||
|
||||
public void setThumbnailRef(String thumbnailRef) {
|
||||
this.thumbnailRef = thumbnailRef;
|
||||
}
|
||||
|
||||
public String getThumbnailRef() {
|
||||
return thumbnailRef;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
public interface WithImages {
|
||||
/**
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of image resources that can be
|
||||
* used to represent the event, e.g., on a web page.
|
||||
*
|
||||
* @return a non-<code>null</code> value which may be empty
|
||||
*/
|
||||
Iterable<ImageDescriptor> getImages();
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getImages() current contents of the image sequence by the images in
|
||||
* <code>images</code>.
|
||||
*
|
||||
* @param images
|
||||
* if <code>null</code>, the internal sequence of images is cleared but remains valid (non-
|
||||
* <code>null</code>)
|
||||
*/
|
||||
void setImages(Iterable<ImageDescriptor> images);
|
||||
|
||||
void addImage(ImageDescriptor image);
|
||||
|
||||
void removeImage(ImageDescriptor image);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface WithMedia extends WithImages, WithVideos {
|
||||
ImageDescriptor findImageWithTag(String tagName);
|
||||
List<ImageDescriptor> findImagesWithTag(String tagName);
|
||||
|
||||
VideoDescriptor findVideoWithTag(String tagName);
|
||||
List<VideoDescriptor> findVideosWithTag(String tagName);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.sap.sse.common.media;
|
||||
|
||||
public interface WithVideos {
|
||||
|
||||
/**
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of video resources that can be
|
||||
* used to represent the event, e.g., on a web page.
|
||||
*
|
||||
* @return a non-<code>null</code> value which may be empty
|
||||
*/
|
||||
Iterable<VideoDescriptor> getVideos();
|
||||
|
||||
/**
|
||||
* Replaces the {@link #getVideos() current contents of the video sequence by the videos in
|
||||
* <code>videos</code>.
|
||||
*
|
||||
* @param videos
|
||||
* if <code>null</code>, the internal sequence of videos is cleared but remains valid (non-
|
||||
* <code>null</code>)
|
||||
*/
|
||||
void setVideos(Iterable<VideoDescriptor> videos);
|
||||
|
||||
void addVideo(VideoDescriptor video);
|
||||
|
||||
void removeVideo(VideoDescriptor video);
|
||||
}
|
||||
+46
-1
@@ -5,6 +5,9 @@ import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.json.client.JSONArray;
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONParser;
|
||||
@@ -15,6 +18,7 @@ import com.google.gwt.user.client.ui.FileUpload;
|
||||
import com.google.gwt.user.client.ui.FormPanel;
|
||||
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
|
||||
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
|
||||
import com.google.gwt.user.client.ui.HasValue;
|
||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
@@ -29,7 +33,7 @@ import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class URLFieldWithFileUpload extends Composite {
|
||||
public class URLFieldWithFileUpload extends Composite implements HasValue<String> {
|
||||
private final TextBox urlTextBox;
|
||||
|
||||
private final FileUpload fileUploadField;
|
||||
@@ -37,6 +41,8 @@ public class URLFieldWithFileUpload extends Composite {
|
||||
private String uri;
|
||||
|
||||
private final Button removeButton;
|
||||
|
||||
private boolean valueChangeHandlerInitialized = false;
|
||||
|
||||
public URLFieldWithFileUpload(final StringMessages stringMessages) {
|
||||
final VerticalPanel mainPanel = new VerticalPanel();
|
||||
@@ -139,4 +145,43 @@ public class URLFieldWithFileUpload extends Composite {
|
||||
removeButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFocus(boolean focused) {
|
||||
urlTextBox.setFocus(focused);
|
||||
}
|
||||
|
||||
private HandlerRegistration addChangeHandler(ChangeHandler handler) {
|
||||
return addDomHandler(handler, ChangeEvent.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
|
||||
if (!valueChangeHandlerInitialized) {
|
||||
valueChangeHandlerInitialized = true;
|
||||
addChangeHandler(new ChangeHandler() {
|
||||
public void onChange(ChangeEvent event) {
|
||||
ValueChangeEvent.fire(URLFieldWithFileUpload.this, getValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
return addHandler(handler, ValueChangeEvent.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return getURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
setURL(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value, boolean fireEvents) {
|
||||
setValue(value);
|
||||
if (fireEvents) {
|
||||
ValueChangeEvent.fire(this, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ Export-Package: com.google.gwt.user.client.rpc.core.java.util,
|
||||
com.sap.sse.gwt.client.dialog,
|
||||
com.sap.sse.gwt.client.event,
|
||||
com.sap.sse.gwt.client.filestorage,
|
||||
com.sap.sse.gwt.client.media,
|
||||
com.sap.sse.gwt.client.mvp,
|
||||
com.sap.sse.gwt.client.panels,
|
||||
com.sap.sse.gwt.client.player,
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ import com.google.gwt.safehtml.shared.UriUtils;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.common.media.ImageMetadataDTO;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
|
||||
/**
|
||||
* Image carousel that uses the open source "slick carousel".
|
||||
@@ -53,7 +53,7 @@ import com.sap.sse.common.media.ImageMetadataDTO;
|
||||
*
|
||||
* Created by pgtaboada on 10.11.14.
|
||||
*/
|
||||
public class ImageCarousel<TYPE extends ImageMetadataDTO> extends Widget {
|
||||
public class ImageCarousel<TYPE extends ImageDTO> extends Widget {
|
||||
|
||||
private static SlickSliderUiBinder ourUiBinder = GWT.create(SlickSliderUiBinder.class);
|
||||
|
||||
@@ -316,4 +316,4 @@ public class ImageCarousel<TYPE extends ImageMetadataDTO> extends Widget {
|
||||
public void show(TYPE selectedImage, List<TYPE> imageList);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.sap.sse.gwt.client.media;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public abstract class AbstractMediaDTO implements IsSerializable {
|
||||
protected String title;
|
||||
|
||||
protected String subtitle;
|
||||
|
||||
protected Date createdAtDate;
|
||||
|
||||
protected String copyright;
|
||||
|
||||
protected MimeType mimeType;
|
||||
|
||||
protected List<String> tags = new ArrayList<String>();
|
||||
|
||||
protected String sourceRef;
|
||||
|
||||
protected String locale;
|
||||
|
||||
/** for GWT */
|
||||
protected AbstractMediaDTO() {
|
||||
}
|
||||
|
||||
public AbstractMediaDTO(String sourceRef, MimeType mimeType, Date createdAtDate) {
|
||||
this.sourceRef = sourceRef;
|
||||
this.mimeType = mimeType;
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getSubtitle() {
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
public Date getCreatedAtDate() {
|
||||
return createdAtDate;
|
||||
}
|
||||
|
||||
public void setCreatedAtDate(Date createdAtDate) {
|
||||
this.createdAtDate = createdAtDate;
|
||||
}
|
||||
|
||||
public String getCopyright() {
|
||||
return copyright;
|
||||
}
|
||||
|
||||
public void setCopyright(String copyright) {
|
||||
this.copyright = copyright;
|
||||
}
|
||||
|
||||
public MimeType getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(MimeType mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public boolean hasTag(String tagName) {
|
||||
return tags.contains(tagName);
|
||||
}
|
||||
|
||||
public void setTags(Iterable<String> tags) {
|
||||
for(String tag: tags) {
|
||||
this.tags.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
public String getSourceRef() {
|
||||
return sourceRef;
|
||||
}
|
||||
|
||||
public void setSourceRef(String sourceRef) {
|
||||
this.sourceRef = sourceRef;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.sap.sse.gwt.client.media;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public class ImageDTO extends AbstractMediaDTO {
|
||||
|
||||
/** for GWT */
|
||||
protected ImageDTO() {
|
||||
}
|
||||
|
||||
/** can be null if not known */
|
||||
private Integer widthInPx;
|
||||
private Integer heightInPx;
|
||||
|
||||
public ImageDTO(String imageRef, Date createdAtDate) {
|
||||
super(imageRef, MimeType.image, createdAtDate);
|
||||
}
|
||||
|
||||
public Integer getWidthInPx() {
|
||||
return widthInPx;
|
||||
}
|
||||
|
||||
public Integer getHeightInPx() {
|
||||
return heightInPx;
|
||||
}
|
||||
|
||||
public void setSizeInPx(Integer widthInPx, Integer heightInPx) {
|
||||
this.widthInPx = widthInPx;
|
||||
this.heightInPx = heightInPx;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.sap.sse.gwt.client.media;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
|
||||
public class VideoDTO extends AbstractMediaDTO {
|
||||
private Integer lengthInSeconds;
|
||||
private String thumbnailRef;
|
||||
|
||||
/** for GWT */
|
||||
protected VideoDTO() {
|
||||
}
|
||||
|
||||
public VideoDTO(String videoRef, MimeType mimeType, Date createdAtDate) {
|
||||
super(videoRef, mimeType, createdAtDate);
|
||||
}
|
||||
|
||||
public Integer getLengthInSeconds() {
|
||||
return lengthInSeconds;
|
||||
}
|
||||
|
||||
public void setLengthInSeconds(Integer lengthInSeconds) {
|
||||
this.lengthInSeconds = lengthInSeconds;
|
||||
}
|
||||
|
||||
public String getThumbnailRef() {
|
||||
return thumbnailRef;
|
||||
}
|
||||
|
||||
public void setThumbnailRef(String thumbnailRef) {
|
||||
this.thumbnailRef = thumbnailRef;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user