Merge branch 'design2015-mobile' of ssh://sapsailing.com/home/trac/git into design2015-mobile

# By Steffen Schaefer (4) and others
# Via Steffen Schaefer (3) and Christopher Ronnewinkel (D036654) (2)
* 'design2015-mobile' of ssh://sapsailing.com/home/trac/git:
  Fixed compiler error after merge
  Regattas are now sorted by default
  Regatta DTOs are now comparable to support deterministic sorting
  Event overview mobile - Adjusted expandable/collapsable regattas
  Event overview mobile - Improved MobileScetion widget
  Event overview mobile - Added utility methods to regatta status dto
  Changes to not use java.util.Locale.forLanguageTag as it isn't supported in Android API < 21
  scale "selected"-cross in simulation-legend;
This commit is contained in:
Papick Garcia Taboada committed 2015-06-17 16:49:04 +02:00
commit 0684aebcfc
15 files changed
+234 -212

No files matched your search

@@ -77,7 +77,7 @@ public class EventContext {
return regattaId;
}
if(eventDTO != null && (eventDTO.getType() == EventType.SINGLE_REGATTA || eventDTO.getType() == EventType.SERIES_EVENT)) {
return eventDTO.getRegattas().get(0).getId();
return eventDTO.getRegattas().iterator().next().getId();
}
return null;
}
@@ -7,7 +7,6 @@ import com.google.gwt.core.client.GWT;
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.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.home.mobile.partials.section.MobileSection;
@@ -21,15 +20,14 @@ import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
public class RegattaStatus extends Composite implements RefreshableWidget<RegattasAndLiveRacesDTO> {
private static final String TOGGLECONTAINERHIDDEN_STYLE = RegattaStatusResources.INSTANCE.css().togglecontainerhidden();
private static final String TOGGLEHIDDEN_STYLE = RegattaStatusResources.INSTANCE.css().togglecontainerhidden();
private static RegattaStatusUiBinder uiBinder = GWT.create(RegattaStatusUiBinder.class);
interface RegattaStatusUiBinder extends UiBinder<Widget, RegattaStatus> {
}
@UiField MobileSection itemContainerUi;
@UiField FlowPanel regattaContainerUi;
@UiField FlowPanel collapsableContainerUi;
@UiField MobileSection regattaContainerUi;
@UiField MobileSection collapsableContainerUi;
@UiField(provided = true) ToggleButton toggleButtonUi;
private final Presenter presenter;
@@ -39,7 +37,7 @@ public class RegattaStatus extends Composite implements RefreshableWidget<Regatt
toggleButtonUi = new ToggleButton(new ToggleButtonCommand() {
@Override
protected void execute(boolean expanded) {
collapsableContainerUi.setStyleName(TOGGLECONTAINERHIDDEN_STYLE, !expanded);
collapsableContainerUi.setStyleName(TOGGLEHIDDEN_STYLE, !expanded);
}
});
initWidget(uiBinder.createAndBindUi(this));
@@ -47,31 +45,24 @@ public class RegattaStatus extends Composite implements RefreshableWidget<Regatt
@Override
public void setData(RegattasAndLiveRacesDTO data, long nextUpdate, int updateNo) {
regattaContainerUi.clear();
collapsableContainerUi.clear();
regattaContainerUi.clearContent();
collapsableContainerUi.clearContent();
if (data.hasRegattasWithRaces()) {
for (Entry<RegattaMetadataDTO, Set<LiveRaceDTO>> pair : data.getRegattasWithRaces().entrySet()) {
RegattaStatusRegatta regattaWidget = addRegatta(regattaContainerUi, pair.getKey());
for (LiveRaceDTO race : pair.getValue()) {
regattaWidget.addRace(race);
}
regattaWidget.addRaces(pair.getValue());
}
for (RegattaMetadataDTO regatta : data.getRegattasWithoutRaces()) {
addRegatta(collapsableContainerUi, regatta);
}
} else {
for (RegattaMetadataDTO regatta : data.getRegattasWithoutRaces()) {
addRegatta(regattaContainerUi, regatta);
}
collapsableContainerUi.removeFromParent();
toggleButtonUi.removeFromParent();
}
toggleButtonUi.setStyleName(TOGGLEHIDDEN_STYLE, !data.hasRegattasWithRaces() || !data.hasRegattasWithoutRaces());
for (RegattaMetadataDTO regatta : data.getRegattasWithoutRaces()) {
addRegatta(data.hasRegattasWithRaces() ? collapsableContainerUi : regattaContainerUi, regatta);
}
}
private RegattaStatusRegatta addRegatta(FlowPanel container, RegattaMetadataDTO regatta) {
private RegattaStatusRegatta addRegatta(MobileSection container, RegattaMetadataDTO regatta) {
PlaceNavigation<?> placeNavigation = presenter.getRegattaLeaderboardNavigation(regatta.getId());
RegattaStatusRegatta regattaWidget = new RegattaStatusRegatta(regatta, placeNavigation);
container.add(regattaWidget);
container.addContent(regattaWidget);
return regattaWidget;
}
@@ -11,10 +11,10 @@
<mp:sectionHeader.SectionHeaderContent sectionTitle="{i18n.regattas}" />
</mp:header>
<mp:content>
<g:FlowPanel addStyleNames="{local_res.css.regattastatus_content}" ui:field="regattaContainerUi"/>
<mp:section.MobileSection addStyleNames="{local_res.css.regattastatus_content}" ui:field="regattaContainerUi"/>
</mp:content>
<mp:content>
<g:FlowPanel addStyleNames="{local_res.css.regattastatus_content} {local_res.css.togglecontainerhidden}"
<mp:section.MobileSection addStyleNames="{local_res.css.regattastatus_content} {local_res.css.togglecontainerhidden}"
ui:field="collapsableContainerUi" />
</mp:content>
</mp:section.MobileSection>
@@ -1,5 +1,7 @@
package com.sap.sailing.gwt.home.mobile.partials.regattaStatus;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
@@ -9,6 +11,7 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.common.client.BoatClassImageResolver;
import com.sap.sailing.gwt.common.client.BoatClassImageResources;
import com.sap.sailing.gwt.home.mobile.partials.section.IsMobileSection;
import com.sap.sailing.gwt.home.mobile.partials.section.MobileSection;
import com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderContent;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
@@ -16,7 +19,7 @@ import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRaceDTO;
import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
import com.sap.sailing.gwt.ui.shared.general.LabelType;
public class RegattaStatusRegatta extends Composite {
public class RegattaStatusRegatta extends Composite implements IsMobileSection {
private static RegattaStatusRegattaUiBinder uiBinder = GWT.create(RegattaStatusRegattaUiBinder.class);
@@ -31,8 +34,15 @@ public class RegattaStatusRegatta extends Composite {
initRegattaHeader(regatta, placeNavigation);
}
public void addRace(LiveRaceDTO race) {
itemContainerUi.addContent(new RegattaStatusRace(race));
@Override
public MobileSection getMobileSection() {
return itemContainerUi;
}
public void addRaces(Set<LiveRaceDTO> races) {
for (LiveRaceDTO race : races) {
itemContainerUi.addContent(new RegattaStatusRace(race));
}
headerUi.setLabelType(LabelType.LIVE);
}
@@ -0,0 +1,7 @@
package com.sap.sailing.gwt.home.mobile.partials.section;
public interface IsMobileSection {
MobileSection getMobileSection();
}
@@ -18,25 +18,18 @@ public class MobileSection extends Composite {
interface MyBinder extends UiBinder<Widget, MobileSection> {
}
@UiField
MobileSectionResources local_res;
@UiField
DivElement sectionHeaderHolderUi;
@UiField
DivElement sectionContentHolderUi;
@UiField
SimplePanel sectionHeaderUi;
@UiField
FlowPanel sectionContentUi;
@UiField MobileSectionResources local_res;
@UiField DivElement sectionHeaderHolderUi;
@UiField DivElement sectionContentHolderUi;
@UiField SimplePanel sectionHeaderUi;
@UiField FlowPanel sectionContentUi;
public MobileSection() {
MobileSectionResources.INSTANCE.css().ensureInjected();
SectionHeaderResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
@UiChild
public void addHeader(Widget theHeaderWidget) {
sectionHeaderUi.setWidget(theHeaderWidget);
@@ -44,6 +37,10 @@ public class MobileSection extends Composite {
@UiChild
public void addContent(Widget theContentWidget) {
if (theContentWidget instanceof IsMobileSection) {
IsMobileSection mobileSubSection = (IsMobileSection) theContentWidget;
mobileSubSection.getMobileSection().showAsSubSection();
}
if (theContentWidget instanceof MobileSection) {
MobileSection mobileSubSection = (MobileSection) theContentWidget;
mobileSubSection.showAsSubSection();
@@ -60,7 +57,6 @@ public class MobileSection extends Composite {
}
public void setEdgeToEdgeContent(boolean setIsEdgeToEdgeContent) {
if (setIsEdgeToEdgeContent) {
sectionContentHolderUi.addClassName(local_res.css().edgeToEdgeSectionContentHolder());
} else if (!setIsEdgeToEdgeContent) {
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.home.mobile.places.event;
import java.util.Collection;
import java.util.List;
import com.google.gwt.user.client.ui.Widget;
@@ -16,7 +17,7 @@ public interface EventView {
void setSailorInfos(String description, String buttonLabel, String url);
void setQuickFinderValues(List<RegattaMetadataDTO> regattaMetadatas);
void setQuickFinderValues(Collection<RegattaMetadataDTO> regattaMetadatas);
void setMediaForImpressions(int nrOfImages, int nrOfVideos, List<SailingImageDTO> images);
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.home.mobile.places.event;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
@@ -69,7 +70,7 @@ public class EventViewImpl extends Composite implements EventView {
}
@Override
public void setQuickFinderValues(List<RegattaMetadataDTO> regattaMetadatas) {
public void setQuickFinderValues(Collection<RegattaMetadataDTO> regattaMetadatas) {
quickFinderUi.addPlaceholderItem(MSG.resultsQuickfinder(), null);
for (RegattaMetadataDTO regattaMetadata : regattaMetadatas) {
quickFinderUi.addItemToGroup(regattaMetadata.getBoatCategory(), regattaMetadata.getDisplayName(), regattaMetadata.getId());
@@ -35,4 +35,8 @@ public class RegattasAndLiveRacesDTO implements DTO {
public boolean hasRegattasWithRaces() {
return !regattasWithRaces.isEmpty();
}
public boolean hasRegattasWithoutRaces() {
return !regattasWithoutRaces.isEmpty();
}
}
@@ -1,7 +1,9 @@
package com.sap.sailing.gwt.ui.shared.eventview;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
import com.sap.sailing.gwt.ui.shared.dispatch.Result;
import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO;
@@ -14,7 +16,7 @@ public class EventViewDTO extends EventMetadataDTO implements Result {
SINGLE_REGATTA, MULTI_REGATTA, SERIES_EVENT
}
private ArrayList<RegattaMetadataDTO> regattas = new ArrayList<>();
private TreeSet<RegattaMetadataDTO> regattas = new TreeSet<>();
private ArrayList<EventReferenceDTO> eventsOfSeries = new ArrayList<>();
private EventType type;
@@ -40,7 +42,7 @@ public class EventViewDTO extends EventMetadataDTO implements Result {
this.type = type;
}
public List<RegattaMetadataDTO> getRegattas() {
public Collection<RegattaMetadataDTO> getRegattas() {
return regattas;
}
@@ -31,6 +31,10 @@ public class RegattaReferenceDTO implements IsSerializable, Comparable<RegattaRe
@Override
public int compareTo(RegattaReferenceDTO o) {
return displayName.compareTo(o.displayName);
int compareByDisplayName = displayName.compareTo(o.displayName);
if(compareByDisplayName != 0) {
return compareByDisplayName;
}
return id.compareTo(o.id);
}
}
@@ -288,6 +288,7 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
protected void drawRectangleWithText(Context2d context2d, double x, double y, String color, String text, String time, double textmaxwidth, double timewidth, double xdelta, boolean visible) {
double offset = 3.0;
double crossOffset = 5.0;
context2d.setFont(textFont);
if (color != null) {
drawRectangle(context2d, x, y, color);
@@ -297,12 +298,12 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
context2d.setLineWidth(3.0);
context2d.setStrokeStyle("white");
context2d.beginPath();
context2d.moveTo(x + 4.0,y + 4.0);
context2d.lineTo(x + rectWidth - 4.0, y + rectHeight - 4.0);
context2d.moveTo(x + crossOffset,y + crossOffset);
context2d.lineTo(x + rectWidth - crossOffset, y + rectHeight - crossOffset);
context2d.stroke();
context2d.beginPath();
context2d.moveTo(x + 4.0, y + rectHeight - 4.0);
context2d.lineTo(x + rectWidth - 4.0,y + 4.0);
context2d.moveTo(x + crossOffset, y + rectHeight - crossOffset);
context2d.lineTo(x + rectWidth - crossOffset,y + crossOffset);
context2d.stroke();
context2d.setStrokeStyle("black");
}
@@ -159,7 +159,8 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
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;
// TODO use Locale.forLanguageTag(localeRaw) -> only possible with Android API Level 21
Locale locale = localeRaw != null ? new Locale(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);
@@ -192,7 +193,8 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
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;
// TODO use Locale.forLanguageTag(localeRaw) -> only possible with Android API Level 21
Locale locale = localeRaw != null ? new Locale(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);
@@ -1,155 +1,157 @@
package com.sap.sailing.server.gateway.serialization.impl;
import java.net.URL;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
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.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_ID = "id";
public static final String FIELD_NAME = "name";
public static final String FIELD_DESCRIPTION = "description";
public static final String FIELD_START_DATE = "startDate";
public static final String FIELD_END_DATE = "endDate";
public static final String FIELD_VENUE = "venue";
public static final String FIELD_IMAGE_URLS = "imageURLs";
public static final String FIELD_VIDEO_URLS = "videoURLs";
public static final String FIELD_SPONSOR_IMAGE_URLS = "sponsorImageURLs";
public static final String FIELD_LOGO_IMAGE_URL = "logoImageURL";
public static final String FIELD_IMAGE_SIZES = "imageSizes";
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;
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer) {
this.leaderboardGroupBaseSerializer = leaderboardGroupBaseSerializer;
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_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()));
JSONArray leaderboardGroups = new JSONArray();
result.put(FIELDS_LEADERBOARD_GROUPS, leaderboardGroups);
for (LeaderboardGroupBase lg : event.getLeaderboardGroups()) {
leaderboardGroups.add(leaderboardGroupBaseSerializer.serialize(lg));
}
JSONArray imageSizes = new JSONArray();
result.put(FIELD_IMAGE_SIZES, imageSizes);
for (ImageDescriptor image : event.getImages()) {
addImageSize(image, imageSizes);
}
JSONArray jsonImages = new JSONArray();
for(ImageDescriptor imageDescriptor: event.getImages()) {
addImage(imageDescriptor, jsonImages);
}
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);
}
/**
* For backward compatibility the size of an image is also serialized as
* JSON object to <code>imageSizes</code>
*/
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());
}
}
private JSONArray getURLsAsStringArray(Iterable<URL> urls) {
JSONArray jsonImageURLs = new JSONArray();
for (URL url : urls) {
jsonImageURLs.add(url.toString());
}
return jsonImageURLs;
}
}
package com.sap.sailing.server.gateway.serialization.impl;
import java.net.URL;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
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.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_ID = "id";
public static final String FIELD_NAME = "name";
public static final String FIELD_DESCRIPTION = "description";
public static final String FIELD_START_DATE = "startDate";
public static final String FIELD_END_DATE = "endDate";
public static final String FIELD_VENUE = "venue";
public static final String FIELD_IMAGE_URLS = "imageURLs";
public static final String FIELD_VIDEO_URLS = "videoURLs";
public static final String FIELD_SPONSOR_IMAGE_URLS = "sponsorImageURLs";
public static final String FIELD_LOGO_IMAGE_URL = "logoImageURL";
public static final String FIELD_IMAGE_SIZES = "imageSizes";
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;
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer) {
this.leaderboardGroupBaseSerializer = leaderboardGroupBaseSerializer;
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_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()));
JSONArray leaderboardGroups = new JSONArray();
result.put(FIELDS_LEADERBOARD_GROUPS, leaderboardGroups);
for (LeaderboardGroupBase lg : event.getLeaderboardGroups()) {
leaderboardGroups.add(leaderboardGroupBaseSerializer.serialize(lg));
}
JSONArray imageSizes = new JSONArray();
result.put(FIELD_IMAGE_SIZES, imageSizes);
for (ImageDescriptor image : event.getImages()) {
addImageSize(image, imageSizes);
}
JSONArray jsonImages = new JSONArray();
for(ImageDescriptor imageDescriptor: event.getImages()) {
addImage(imageDescriptor, jsonImages);
}
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());
// TODO use toLanguageTag() when deserializer can use Locale.forLanguageTag()
imageJson.put(FIELD_LOCALE, image.getLocale() != null ? image.getLocale().getLanguage() : 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());
// TODO use toLanguageTag() when deserializer can use Locale.forLanguageTag()
videoJson.put(FIELD_LOCALE, video.getLocale() != null ? video.getLocale().getLanguage() : 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);
}
/**
* For backward compatibility the size of an image is also serialized as
* JSON object to <code>imageSizes</code>
*/
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());
}
}
private JSONArray getURLsAsStringArray(Iterable<URL> urls) {
JSONArray jsonImageURLs = new JSONArray();
for (URL url : urls) {
jsonImageURLs.add(url.toString());
}
return jsonImageURLs;
}
}
@@ -59,7 +59,8 @@ public class EventDataJsonSerializerWithImagesAndVideosTest {
private final URL videoURL;
private final URL videoThumbnailURL;
private final Locale locale2 = Locale.CANADA_FRENCH;
private final Locale localeFr = Locale.FRENCH;
private final Locale localeFrCa = 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";
@@ -92,7 +93,7 @@ public class EventDataJsonSerializerWithImagesAndVideosTest {
VideoDescriptor video1 = new VideoDescriptorImpl(videoURL, mimeType, createdAt);
video1.setCopyright(copyright2);
video1.setLocale(locale2);
video1.setLocale(localeFrCa);
video1.setTitle(videoTitle);
video1.setSubtitle(videoSubtitle);
video1.setThumbnailURL(videoThumbnailURL);
@@ -180,12 +181,12 @@ public class EventDataJsonSerializerWithImagesAndVideosTest {
assertEquals(videoURL, video1.getURL());
assertEquals(mimeType, video1.getMimeType());
assertEquals(copyright2, video1.getCopyright());
assertEquals(locale2, video1.getLocale());
// Only the language part of the locale is being used
assertEquals(localeFr, video1.getLocale());
assertEquals(videoTitle, video1.getTitle());
assertEquals(videoSubtitle, video1.getSubtitle());
assertEquals(videoThumbnailURL, video1.getThumbnailURL());
assertEquals(videoLengthInSeconds, video1.getLengthInSeconds());
assertEquals(4, Util.size(video1.getTags()));
}
}