mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
reworked images and videos of event -> removed double maintenance of imageURLs, videoURLs, sponsorImageURLs -> they are now always calculated from images and videos
This commit is contained in:
1 parent
8125b4f3d4
commit
9decf43909
12 files changed
+143
-374
No files matched your search
@@ -43,5 +43,5 @@
|
||||
<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="-XstartOnFirstThread -Xmx2048m"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||
</launchConfiguration>
|
||||
+24
-104
@@ -185,7 +185,6 @@ import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
@@ -193,9 +192,6 @@ import com.sap.sse.common.impl.RGBColor;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
import com.sap.sse.common.media.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageDescriptorImpl;
|
||||
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;
|
||||
@@ -982,7 +978,10 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
try {
|
||||
for (DBObject object : eventCollection.find()) {
|
||||
Event event = loadEvent(object);
|
||||
migrateImagesAndVideosOfEvent(event);
|
||||
boolean hasMigratedSomething = loadLegacyImageAndVideoURLs(event, object);
|
||||
if(hasMigratedSomething) {
|
||||
new MongoObjectFactoryImpl(database).storeEvent(event);
|
||||
}
|
||||
result.add(event);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -1046,7 +1045,6 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
logger.severe("Error parsing official website URL "+officialWebSiteURLAsString+" for event "+name+". Ignoring this URL.");
|
||||
}
|
||||
}
|
||||
loadLegacyImageAndVideoURLs(result, eventDBObject);
|
||||
BasicDBList images = (BasicDBList) eventDBObject.get(FieldNames.EVENT_IMAGES.name());
|
||||
if (images != null) {
|
||||
for (Object imageObject : images) {
|
||||
@@ -2134,133 +2132,55 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates images and videos stored as pure URLs to the new richer media format
|
||||
* @param event the event to migrate
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void migrateImagesAndVideosOfEvent(Event event) {
|
||||
boolean changedAnything = false;
|
||||
|
||||
List<ImageDescriptor> newImages = new ArrayList<>();
|
||||
for (URL url : event.getImageURLs()) {
|
||||
if (!hasMedia(event.getImages(), url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, event.getStartDate());
|
||||
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);
|
||||
}
|
||||
newImages.add(image);
|
||||
changedAnything = true;
|
||||
}
|
||||
}
|
||||
for (URL url : event.getSponsorImageURLs()) {
|
||||
if (!hasMedia(event.getImages(), url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, event.getStartDate());
|
||||
image.addTag(MediaTagConstants.SPONSOR);
|
||||
newImages.add(image);
|
||||
changedAnything = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getLogoImageURL() != null && !hasMedia(event.getImages(), event.getLogoImageURL())) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(event.getLogoImageURL(), event.getStartDate());
|
||||
image.addTag(MediaTagConstants.LOGO);
|
||||
newImages.add(image);
|
||||
changedAnything = true;
|
||||
}
|
||||
|
||||
List<VideoDescriptor> newVideos = new ArrayList<VideoDescriptor>();
|
||||
for (URL url : event.getVideoURLs()) {
|
||||
if (!hasMedia(event.getVideos(), url)) {
|
||||
MimeType mimeType = MediaUtils.detectMimeTypeFromUrl(url.toString());
|
||||
VideoDescriptor video = new VideoDescriptorImpl(url, mimeType, event.getStartDate());
|
||||
newVideos.add(video);
|
||||
changedAnything = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changedAnything) {
|
||||
for (VideoDescriptor newVideo : newVideos) {
|
||||
event.addVideo(newVideo);
|
||||
}
|
||||
for (ImageDescriptor newImage : newImages) {
|
||||
event.addImage(newImage);
|
||||
}
|
||||
new MongoObjectFactoryImpl(database).storeEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy code to support conversion of old image and video URLs
|
||||
* @param event
|
||||
* @param eventDBObject
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void loadLegacyImageAndVideoURLs(Event event, DBObject eventDBObject) {
|
||||
private boolean loadLegacyImageAndVideoURLs(Event event, DBObject eventDBObject) {
|
||||
URL logoImageURL = null;
|
||||
List<URL> imageURLs = new ArrayList<URL>();
|
||||
List<URL> sponsorImageURLs = new ArrayList<URL>();
|
||||
List<URL> videoURLs = new ArrayList<URL>();
|
||||
|
||||
String logoImageURLAsString = (String) eventDBObject.get(FieldNames.EVENT_LOGO_IMAGE_URL.name());
|
||||
if (logoImageURLAsString != null) {
|
||||
try {
|
||||
event.setLogoImageURL(new URL(logoImageURLAsString));
|
||||
logoImageURL = new URL(logoImageURLAsString);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Error parsing logo image URL "+logoImageURLAsString+" for event "+event.getName()+". Ignoring this URL.");
|
||||
}
|
||||
}
|
||||
BasicDBList imageURLs = (BasicDBList) eventDBObject.get(FieldNames.EVENT_IMAGE_URLS.name());
|
||||
if (imageURLs != null) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
for (Object imageURL : imageURLs) {
|
||||
BasicDBList imageURLsJson = (BasicDBList) eventDBObject.get(FieldNames.EVENT_IMAGE_URLS.name());
|
||||
if (imageURLsJson != null) {
|
||||
for (Object imageURL : imageURLsJson) {
|
||||
try {
|
||||
urls.add(new URL((String) imageURL));
|
||||
imageURLs.add(new URL((String) imageURL));
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Error parsing image URL "+imageURL+" for event "+event.getName()+". Ignoring this image URL.");
|
||||
}
|
||||
}
|
||||
event.setImageURLs(urls);
|
||||
}
|
||||
BasicDBList videoURLs = (BasicDBList) eventDBObject.get(FieldNames.EVENT_VIDEO_URLS.name());
|
||||
if (videoURLs != null) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
for (Object videoURL : videoURLs) {
|
||||
BasicDBList videoURLsJson = (BasicDBList) eventDBObject.get(FieldNames.EVENT_VIDEO_URLS.name());
|
||||
if (videoURLsJson != null) {
|
||||
for (Object videoURL : videoURLsJson) {
|
||||
try {
|
||||
urls.add(new URL((String) videoURL));
|
||||
videoURLs.add(new URL((String) videoURL));
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Error parsing video URL "+videoURL+" for event "+event.getName()+". Ignoring this video URL.");
|
||||
}
|
||||
}
|
||||
event.setVideoURLs(urls);
|
||||
}
|
||||
BasicDBList sponsorImageURLs = (BasicDBList) eventDBObject.get(FieldNames.EVENT_SPONSOR_IMAGE_URLS.name());
|
||||
if (sponsorImageURLs != null) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
for (Object sponsorImageURL : sponsorImageURLs) {
|
||||
BasicDBList sponsorImageURLsJson = (BasicDBList) eventDBObject.get(FieldNames.EVENT_SPONSOR_IMAGE_URLS.name());
|
||||
if (sponsorImageURLsJson != null) {
|
||||
for (Object sponsorImageURL : sponsorImageURLsJson) {
|
||||
try {
|
||||
urls.add(new URL((String) sponsorImageURL));
|
||||
sponsorImageURLs.add(new URL((String) sponsorImageURL));
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Error parsing sponsor image URL "+sponsorImageURL+" for event "+event.getName()+". Ignoring this sponsor image URL.");
|
||||
}
|
||||
}
|
||||
event.setSponsorImageURLs(urls);
|
||||
}
|
||||
}
|
||||
|
||||
private ImageDescriptor migrateImageURLtoImage(URL url, TimePoint createdAt) {
|
||||
ImageDescriptorImpl image = new ImageDescriptorImpl(url, createdAt);
|
||||
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;
|
||||
return event.setMediaURLs(imageURLs, sponsorImageURLs, videoURLs, logoImageURL);
|
||||
}
|
||||
}
|
||||
+4
-45
@@ -1,13 +1,11 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -50,17 +48,6 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID, Wi
|
||||
*/
|
||||
Iterable<URL> getImageURLs();
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* 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
|
||||
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
|
||||
@@ -69,28 +56,12 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID, Wi
|
||||
*/
|
||||
Iterable<URL> getSponsorImageURLs();
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
void setLogoImageURL(URL logoImageURL);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
|
||||
@@ -100,17 +71,6 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID, Wi
|
||||
*/
|
||||
Iterable<URL> getVideoURLs();
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* 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
|
||||
@@ -121,9 +81,8 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID, Wi
|
||||
|
||||
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);
|
||||
}
|
||||
+94
-77
@@ -13,9 +13,15 @@ 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.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;
|
||||
@@ -27,10 +33,6 @@ 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;
|
||||
@@ -50,25 +52,12 @@ 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>();
|
||||
syncImageAndVideoURLsForBackwardCompatibility();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
if (imageURLs == null) {
|
||||
imageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
}
|
||||
if (videoURLs == null) {
|
||||
videoURLs = new ConcurrentLinkedQueue<URL>();
|
||||
}
|
||||
if (sponsorImageURLs == null) {
|
||||
sponsorImageURLs = new ConcurrentLinkedQueue<URL>();
|
||||
}
|
||||
if (images == null) {
|
||||
images = new ConcurrentLinkedQueue<ImageDescriptor>();
|
||||
}
|
||||
@@ -144,51 +133,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 (Util.size(image.getTags()) == 0 || image.hasTag(MediaTagConstants.GALLERY)) {
|
||||
result.add(image.getURL());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@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 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 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;
|
||||
List<ImageDescriptor> media = findMediaWithTag(images, MediaTagConstants.LOGO);
|
||||
if(media.size() > 0) {
|
||||
result = media.get(0).getURL();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -210,14 +189,12 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
public void addImage(ImageDescriptor image) {
|
||||
if (!images.contains(image)) {
|
||||
images.add(image);
|
||||
syncImageURLsFromImagesForBackwardCompatibility();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImage(ImageDescriptor image) {
|
||||
images.remove(image);
|
||||
syncImageURLsFromImagesForBackwardCompatibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -225,7 +202,6 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
this.images.clear();
|
||||
if (images != null) {
|
||||
Util.addAll(images, this.images);
|
||||
syncImageURLsFromImagesForBackwardCompatibility();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,14 +214,12 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
public void addVideo(VideoDescriptor video) {
|
||||
if (!videos.contains(video)) {
|
||||
videos.add(video);
|
||||
syncVideoURLsFromVideosForBackwardCompatibility();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVideo(VideoDescriptor video) {
|
||||
videos.remove(video);
|
||||
syncVideoURLsFromVideosForBackwardCompatibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,38 +227,81 @@ public abstract class EventBaseImpl implements EventBase {
|
||||
this.videos.clear();
|
||||
if (videos != null) {
|
||||
Util.addAll(videos, this.videos);
|
||||
syncVideoURLsFromVideosForBackwardCompatibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncImageURLsFromImagesForBackwardCompatibility() {
|
||||
List<URL> imageURLs = new ArrayList<>();
|
||||
List<URL> sponsorImageURLs = new ArrayList<>();
|
||||
URL logoImageURL = null;
|
||||
for (ImageDescriptor image : images) {
|
||||
if (image.hasTag(MediaTagConstants.SPONSOR)) {
|
||||
sponsorImageURLs.add(image.getURL());
|
||||
} else if (image.hasTag(MediaTagConstants.LOGO)) {
|
||||
logoImageURL = image.getURL();
|
||||
} else {
|
||||
imageURLs.add(image.getURL());
|
||||
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);
|
||||
}
|
||||
}
|
||||
setImageURLs(imageURLs);
|
||||
setSponsorImageURLs(sponsorImageURLs);
|
||||
setLogoImageURL(logoImageURL);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void syncVideoURLsFromVideosForBackwardCompatibility() {
|
||||
List<URL> videoURLs = new ArrayList<>();
|
||||
for (VideoDescriptor video : videos) {
|
||||
videoURLs.add(video.getURL());
|
||||
/** 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) {
|
||||
boolean changed = false;
|
||||
|
||||
for (URL url : imageURLs) {
|
||||
if (!hasMedia(images, url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, getStartDate());
|
||||
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;
|
||||
}
|
||||
}
|
||||
setVideoURLs(videoURLs);
|
||||
for (URL url : sponsorImageURLs) {
|
||||
if (!hasMedia(images, url)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(url, getStartDate());
|
||||
image.addTag(MediaTagConstants.SPONSOR);
|
||||
addImage(image);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (logoImageURL != null && !hasMedia(images, logoImageURL)) {
|
||||
ImageDescriptor image = migrateImageURLtoImage(logoImageURL, getStartDate());
|
||||
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 void syncImageAndVideoURLsForBackwardCompatibility() {
|
||||
syncImageURLsFromImagesForBackwardCompatibility();
|
||||
syncVideoURLsFromVideosForBackwardCompatibility();
|
||||
private ImageDescriptor migrateImageURLtoImage(URL url, TimePoint createdAt) {
|
||||
ImageDescriptorImpl image = new ImageDescriptorImpl(url, createdAt);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,8 @@
|
||||
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.ImageDescriptor;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.common.media.MediaUtils;
|
||||
|
||||
/**
|
||||
* An event is a group of {@link Regatta regattas} carried out at a common venue within a common time frame. For
|
||||
@@ -51,19 +46,4 @@ public interface Event extends EventBase {
|
||||
* 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.
|
||||
*
|
||||
* @deprecated Use {@link MediaUtils#getImageDimensions(URL)} or simply use the dimensions given by {@link ImageDescriptor}
|
||||
*/
|
||||
@Deprecated
|
||||
ImageSize getImageSize(URL imageURL) throws InterruptedException, ExecutionException;
|
||||
|
||||
}
|
||||
@@ -34,15 +34,11 @@ 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 +50,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 +57,6 @@ public class EventImpl extends EventBaseImpl implements Event {
|
||||
if (leaderboardGroups == null) {
|
||||
leaderboardGroups = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
this.imageSizeFetchers = new ConcurrentHashMap<>();
|
||||
this.executor = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,86 +98,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();
|
||||
}
|
||||
|
||||
private void refreshImageSizeFetcher(URL imageURL) {
|
||||
if (imageURL != null) {
|
||||
removeImageSizeFetcher(imageURL);
|
||||
getOrCreateImageSizeCalculator(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 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
-2
@@ -75,11 +75,11 @@ public class ImagesListComposite extends Composite {
|
||||
imagesControlsPanel.setSpacing(5);
|
||||
panel.add(imagesControlsPanel);
|
||||
|
||||
Button addPhotoBtn = new Button("Add photo");
|
||||
Button addPhotoBtn = new Button("Add gallery photo");
|
||||
addPhotoBtn.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
openCreateImageDialog(null);
|
||||
openCreateImageDialog(MediaTagConstants.GALLERY);
|
||||
}
|
||||
});
|
||||
imagesControlsPanel.add(addPhotoBtn);
|
||||
|
||||
+2
-1
@@ -10,7 +10,8 @@ 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 });
|
||||
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));
|
||||
|
||||
|
||||
+4
-2
@@ -92,6 +92,7 @@ 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;
|
||||
@@ -340,11 +341,12 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
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("Sponsor");
|
||||
image2.addTag(MediaTagConstants.SPONSOR);
|
||||
|
||||
VideoDescriptor video1 = new VideoDescriptorImpl(videoURL, MimeType.mp4, createdAt);
|
||||
event.addVideo(video1);
|
||||
@@ -354,9 +356,9 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
|
||||
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.getVideos()));
|
||||
assertEquals(1, Util.size(loadedEvent.getVideoURLs()));
|
||||
}
|
||||
|
||||
|
||||
+11
-16
@@ -22,12 +22,10 @@ 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.Util.Pair;
|
||||
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.MediaUtils;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.common.media.VideoDescriptor;
|
||||
import com.sap.sse.common.media.VideoDescriptorImpl;
|
||||
@@ -99,31 +97,36 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
}
|
||||
|
||||
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 {
|
||||
event.setLogoImageURL(new URL(logoImageURLAsString));
|
||||
logoImageURL = new URL(logoImageURLAsString);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new JsonDeserializationException("Error deserializing logo image URL for event "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_IMAGE_URLS) != null) {
|
||||
try {
|
||||
event.setImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, 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 "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_VIDEO_URLS) != null) {
|
||||
try {
|
||||
event.setVideoURLs(getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, 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 "+event.getName(), e);
|
||||
}
|
||||
}
|
||||
if (eventJson.get(EventBaseJsonSerializer.FIELD_SPONSOR_IMAGE_URLS) != null) {
|
||||
try {
|
||||
event.setSponsorImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(eventJson, 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 "+event.getName(), e);
|
||||
}
|
||||
@@ -145,6 +148,7 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
}
|
||||
}
|
||||
}
|
||||
event.setMediaURLs(imageURLs, sponsorImageURLs, videoURLs, logoImageURL);
|
||||
}
|
||||
|
||||
private ImageDescriptor loadImage(JSONObject imageJson) {
|
||||
@@ -214,16 +218,7 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
|
||||
return video;
|
||||
}
|
||||
|
||||
private ImageDescriptor migrateImageURLtoImage(URL url, TimePoint createdAt, ImageSize size) {
|
||||
ImageDescriptorImpl image = new ImageDescriptorImpl(url, createdAt);
|
||||
Pair<Integer, Integer> imageDimensions = MediaUtils.getImageDimensions(url);
|
||||
if (imageDimensions != null) {
|
||||
image.setSize(imageDimensions);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
private Iterable<URL> getURLsFromStrings(JSONArray strings) throws MalformedURLException {
|
||||
private List<URL> getURLsFromStrings(JSONArray strings) throws MalformedURLException {
|
||||
List<URL> result = new ArrayList<URL>();
|
||||
if (strings != null) {
|
||||
for (Object string : strings) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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";
|
||||
|
||||
Reference in new issue
Block a user