summaryrefslogtreecommitdiff
path: root/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi
diff options
context:
space:
mode:
Diffstat (limited to 'test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi')
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/pocmain/TrafficIncidentsServicePocMain.java686
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ATrafficInfoClient.java101
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/BooleanExpressionsFrame.java76
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/CategoryDefinitionsWindow.java186
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/IconDefinitionWindow.java158
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ImagePanel.java37
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficIncidentsPainter.java209
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoListDisplay.java2165
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoMapView.java265
-rwxr-xr-xtest/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/WarningClient.java240
10 files changed, 4123 insertions, 0 deletions
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/pocmain/TrafficIncidentsServicePocMain.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/pocmain/TrafficIncidentsServicePocMain.java
new file mode 100755
index 0000000..0867f4c
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/pocmain/TrafficIncidentsServicePocMain.java
@@ -0,0 +1,686 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.pocmain;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+
+import openlr.map.MapDatabase;
+import openlr.map.teleatlas.sqlite.impl.MapDatabaseImpl;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.genivi.booleanexpr.ClassAttribute;
+import org.genivi.booleanexpr.ComparisonOperator;
+import org.genivi.booleanexpr.ComparisonPredicate;
+import org.genivi.booleanexpr.DownCastPredicate;
+import org.genivi.booleanexpr.DyadicExpression;
+import org.genivi.booleanexpr.DyadicLogicalOperator;
+import org.genivi.booleanexpr.FilterexprFactory;
+import org.genivi.booleanexpr.ListOperator;
+import org.genivi.booleanexpr.MultiplicityPredicate;
+import org.genivi.booleanexpr.SignedIntegerLiteral;
+import org.genivi.common.CommonFactory;
+import org.genivi.common.LocalizedString;
+import org.genivi.common.Version;
+import org.genivi.iconset.ColorType;
+import org.genivi.iconset.IconData;
+import org.genivi.iconset.IconDefinition;
+import org.genivi.iconset.IconDescriptor;
+import org.genivi.iconset.IconDimension;
+import org.genivi.iconset.IconInfo;
+import org.genivi.iconset.IconSet;
+import org.genivi.iconset.IconSize;
+import org.genivi.iconset.IconsetFactory;
+import org.genivi.locref.LocationReferenceType;
+import org.genivi.locref.decoder.openlr.OpenLRDecoder;
+import org.genivi.locref.refimpl.LocationReferenceDecodingHandlerRefImpl;
+import org.genivi.tpegtecfeed.refimpl.TpegTecFeedRefImpl;
+import org.genivi.trafficincidentsservice.CategoryDefinition;
+import org.genivi.trafficincidentsservice.DefaultTrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TrafficIncidentFeedListener;
+import org.genivi.trafficincidentsservice.trafficincidentsserviceFactory;
+import org.genivi.trafficincidentsservice.refimpl.TrafficIncidentsService;
+import org.genivi.trafficincidentsservice.textgenerator.basictextgenerator.BasicTextGenerator;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.trafficincidentPackage;
+import org.genivi.trafficincidentsservice.trafficincidenttables.CauseCode;
+import org.genivi.trafficincidentsservice.trafficincidenttables.EffectCode;
+import org.genivi.trafficincidentsservice.trafficincidenttables.VisibilityReduced;
+import org.genivi.trafficinfo.demo.logging.EclipseConsoleFormatter;
+import org.genivi.trafficinfo.tpeg.clientside.broadcast.fwk.impl.TpegSfwRefImpl;
+import org.genivi.trafficinfo.tpeg.clientside.broadcastadaptionlayer.refimpl.BroadcastAdaptationLayerImplementation;
+import org.genivi.trafficinfo.tpeg.serverside.broadcast.fwk.impl.BroadcastFrameworkImplementation;
+import org.genivi.trafficinfo.tpeg.tecservice.testsetplayer.TestPlayerTecService;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.ATrafficInfoClient;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.CategoryDefinitionsWindow;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.IconDefinitionWindow;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.TrafficInfoListDisplay;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.TrafficInfoMapView;
+import org.genivi.trafficinfo.trafficincidentsexampleclients.WarningClient;
+
+
+
+/**
+ * This class demonstrates the usage of the functionality of the TrafficIncidentsService.
+ * - Logging is performed via the Java package java.util.logging.
+ * - Three different applications (clients of the TrafficIncidentsService) can be started:
+ * - ATrafficInfoClient: uses polling to get the Traffic Incidents, outputs textual information via Logging.
+ *
+ */
+public class TrafficIncidentsServicePocMain {
+ private final static String MAP_PATH = "resources/tomtom_utrecht_2008_04.db3";
+ private final static Logger LOGGER = Logger.getLogger(TrafficIncidentsServicePocMain.class.getName());
+ private final static CommonFactory COMMON_FACTORY = CommonFactory.eINSTANCE;
+ private final static IconsetFactory iconsetFactory = IconsetFactory.eINSTANCE;
+ private final static trafficincidentsserviceFactory TRAFFIC_INCIDENTS_SVC_FACTORY = trafficincidentsserviceFactory.eINSTANCE;
+ private final static FilterexprFactory FILTER_EXPR_FACTORY = FilterexprFactory.eINSTANCE;
+ private final static trafficincidentPackage tip = trafficincidentPackage.eINSTANCE;
+
+ // settings to control what to run and what not
+ private final static Level logLevel = Level.SEVERE;
+ private final static boolean useIconFiles = false;
+ private final static boolean runIconDefinitionWindow = false;
+ private final static boolean runCategoryDefinitionsWindow = false;
+ private final static boolean runATrafficInfoClient = false;
+ private final static boolean runTrafficInfoMapView = true;
+ private final static boolean runTrafficInfoListDisplay = true;
+ private final static boolean runWarningClient = true;
+
+ private EList<Integer> iconSetIds = null;
+ private EList<Integer> categoryIds = null;
+ private EList<IconSet> iconSets = null;
+ private EList<IconDefinition> iconDefinitions = null;
+ private EList<CategoryDefinition> categoryDefinitions = null;
+ private MapDatabase mapDataBase;
+ private TrafficIncidentsService trafficIncidentsService;
+ private ATrafficInfoClient trafficIncidentsClient;
+
+ TrafficIncidentsServicePocMain() {
+
+ logSetup();
+
+ // Show that a client can be started without having a Traffic Information Provider.
+ if (runATrafficInfoClient) {
+ trafficIncidentsClient = new ATrafficInfoClient();
+ trafficIncidentsClient.start();
+ }
+
+
+ // Create a Location Reference Decoding Handler to be used by the Traffic Incidents Service
+ LocationReferenceDecodingHandlerRefImpl locationReferenceDecodingHandlerRefImpl = new LocationReferenceDecodingHandlerRefImpl();
+
+ // Open a map database to be used by the location decoders
+ mapDataBase = new MapDatabaseImpl(MAP_PATH);
+
+ // Create an OpenLR decoder and register it on the LocationReferenceDecodingHandlerRefImpl
+ OpenLRDecoder openLRDecoder = new OpenLRDecoder(mapDataBase);
+ locationReferenceDecodingHandlerRefImpl.addDecoder((Byte) (byte) LocationReferenceType.OPEN_LR.getValue(), openLRDecoder);
+
+ // Create the Traffic Incidents Service
+ trafficIncidentsService = new TrafficIncidentsService(locationReferenceDecodingHandlerRefImpl, new BasicTextGenerator());
+ customizeTrafficIncidentsService(trafficIncidentsService);
+
+ // Make this provider known to the client
+ if (runATrafficInfoClient) {
+ trafficIncidentsClient.setTrafficIncidentsService(trafficIncidentsService);
+ }
+
+ /*
+ * Initialise server side broadcast setup, and a services:
+ * TPEG-TEC Service and Time Service.
+ */
+
+ // Create and start Server Side framework
+ BroadcastFrameworkImplementation serverSideBroadcastFramework = new BroadcastFrameworkImplementation();
+ serverSideBroadcastFramework.start();
+
+ @SuppressWarnings("unused")
+ TestPlayerTecService tecService = new TestPlayerTecService(serverSideBroadcastFramework);
+
+ /*
+ * Initialize client side TPEG framework for broadcast reception, and a Time Application.
+ */
+
+ // Create client side TPEG framework.
+ TpegSfwRefImpl clientSideTpegFrameworkImplementationBroadcast = new TpegSfwRefImpl();
+ @SuppressWarnings("unused")
+ BroadcastAdaptationLayerImplementation broadcastAdaptationLayerImplementation = new BroadcastAdaptationLayerImplementation("some tuner", clientSideTpegFrameworkImplementationBroadcast);
+
+ // Create TPEG-TEC Feed (TEC Application in TISA terms)
+ new TpegTecFeedRefImpl(clientSideTpegFrameworkImplementationBroadcast, trafficIncidentsService);
+
+ // Register dummy feed for extra status information.
+ TrafficIncidentFeedListener dummyTrafficIncidentsUpdatesListener = new MyTrafficIncidentsUpdatesListener();
+ trafficIncidentsService.registerFeed(dummyTrafficIncidentsUpdatesListener , "GENIVI", "RDS-TMC", "TMC bridge");
+
+
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ LOGGER.info("Main end");
+ }
+
+ private void customizeTrafficIncidentsService(
+ TrafficIncidentsService trafficIncidentsService) {
+
+ TrafficIncidentsListener reserveIconSetIdsReplyListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void reserveIconSetIdsReply(EList<Integer> iconSetIds) {
+ setIconSetIds(iconSetIds);
+ }
+ };
+
+ trafficIncidentsService.reserveIconSetIds(reserveIconSetIdsReplyListener, 10);
+ while (iconSetIds == null) {
+ LOGGER.info("Waiting for iconSetIds");
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ LOGGER.info("iconSetIds received");
+
+ // Create the icon set definitions.
+ iconSets = new BasicEList<IconSet>();
+ iconSets.add(createIconSet(iconSetIds.get(0), ColorType.GRAY_8, IconDimension.D2D, true, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(1), ColorType.RGB888, IconDimension.D2D, true, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(2), ColorType.GRAY_8, IconDimension.D2D, false, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(3), ColorType.RGB888, IconDimension.D2D, false, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(4), ColorType.RGB888, IconDimension.D25D, true, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(5), ColorType.RGB888, IconDimension.D25D, false, 28, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(6), ColorType.GRAY_8, IconDimension.D2D, true, 44, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(7), ColorType.RGB888, IconDimension.D2D, true, 44, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(8), ColorType.GRAY_8, IconDimension.D2D, false, 44, 32, useIconFiles));
+ iconSets.add(createIconSet(iconSetIds.get(9), ColorType.RGB888, IconDimension.D2D, false, 44, 32, useIconFiles));
+
+ iconDefinitions = createIconDefinitions(iconSets);
+
+ trafficIncidentsService.addIconDefinitions(null, iconDefinitions);
+ trafficIncidentsService.addIconSetDefinitions(null, iconSets);
+
+ TrafficIncidentsListener reserveCategoryIdsReplyListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void reserveCategoryIdsReply(EList<Integer> categoryIds) {
+ setCategoryIds(categoryIds);
+ }
+ };
+
+ trafficIncidentsService.reserveCategoryIds(reserveCategoryIdsReplyListener, 3);
+ while (categoryIds == null) {
+ LOGGER.info("Waiting for categoryIds");
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ LOGGER.info("categoryIds received");
+
+ categoryDefinitions = new BasicEList<CategoryDefinition>();
+ categoryDefinitions.add(createCategory1(categoryIds.get(0)));
+ categoryDefinitions.add(createCategory2(categoryIds.get(1)));
+ categoryDefinitions.add(createCategory3(categoryIds.get(2)));
+
+ trafficIncidentsService.addCategoryDefinitions(null, categoryDefinitions);
+ }
+
+ private void setIconSetIds(EList<Integer> iconSetIds) {
+ this.iconSetIds = iconSetIds;
+ }
+
+ private void setCategoryIds(EList<Integer> categoryIds) {
+ this.categoryIds = categoryIds;
+ }
+
+ private IconSet createIconSet(int iconSetId, ColorType colorType,
+ IconDimension iconDimension, boolean dayTimeIcon, int themeId,
+ int size, boolean useIconFiles) {
+ IconSet iconSet = iconsetFactory.createIconSet();
+ iconSet.setIconSetId(iconSetId);
+ iconSet.setColorType(colorType);
+ iconSet.setDimension(iconDimension);
+ iconSet.setDayTimeIcon(dayTimeIcon);
+ iconSet.setThemeId(themeId);
+ iconSet.setMediumType("image/png");
+ IconSize iconSize = iconsetFactory.createIconSize();
+ iconSize.setWidth(size);
+ iconSize.setHeight(size);
+ iconSet.setSize(iconSize);
+ for (int iconId = 1; iconId <= 6; iconId++) {
+ IconDescriptor iconDescriptor = iconsetFactory.createIconDescriptor();
+ if (useIconFiles) {
+ iconDescriptor.setUrl(constructIconFileName(iconSet, iconId));
+ }
+ iconDescriptor.setIconId(iconId);
+ iconSet.getIconDescriptors().add(iconDescriptor);
+ }
+
+ return iconSet;
+ }
+
+ private String constructIconFileName(IconSet iconSet, int iconId) {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("icons");
+ buf.append(File.separator);
+
+ buf.append("icon_setId");
+ buf.append(iconSet.getIconSetId());
+ buf.append("_");
+ buf.append(iconSet.getColorType().getName());
+ buf.append("_");
+ buf.append(iconSet.getDimension().getName());
+ buf.append("_");
+ if (iconSet.isDayTimeIcon()) {
+ buf.append("day");
+ } else {
+ buf.append("night");
+ }
+ buf.append("_themeId");
+ buf.append(iconSet.getThemeId());
+ buf.append("_");
+ buf.append(iconSet.getSize().getWidth());
+ buf.append("x");
+ buf.append(iconSet.getSize().getHeight());
+ buf.append("_iconId");
+ buf.append(iconId);
+ buf.append(".png");
+
+ return buf.toString();
+ }
+
+ private EList<IconDefinition> createIconDefinitions(EList<IconSet> iconSets) {
+ EList<IconDefinition> iconDefinitions = new BasicEList<IconDefinition>();
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ iconDescriptor.getIconId();
+ iconDescriptor.getUrl();
+ BufferedImage image = createIcon(iconSet.getIconSetId(), iconSet.getColorType(), iconSet.getDimension(),
+ iconSet.isDayTimeIcon(), iconSet.getThemeId(), iconSet.getSize(), iconDescriptor.getIconId());
+ IconDefinition iconDefinition = iconsetFactory.createIconDefinition();
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ iconDefinition.setIconInfo(iconInfo);
+
+ if (iconDescriptor.isSetUrl()) {
+ File output = new File(iconDescriptor.getUrl());
+ try {
+ ImageIO.write(image, "png", output);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ImageIO.write(image, "png", outputStream);
+ IconData iconData = iconsetFactory.createIconData();
+ byte[] bytes = outputStream.toByteArray();
+ iconData.setData(bytes);
+ iconDefinition.setIconData(iconData);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ iconDefinitions.add(iconDefinition);
+
+ }
+ }
+
+ return iconDefinitions;
+ }
+
+ private Color getColor(ColorType colorType, int iconId, boolean dayTimeIcon) {
+ Color color = null;
+
+ switch (colorType) {
+ case BLACK_AND_WHITE:
+ case GRAY_4:
+ case GRAY_8:
+ int componentValue = 255 - (28 * iconId);
+ if (!dayTimeIcon) {
+ componentValue = 255 - componentValue;
+ }
+ color = new Color(componentValue, componentValue, componentValue);
+ break;
+
+ case RGB555:
+ case RGB565:
+ case RGB888:
+ int red = 42 * (iconId - 1);
+ int green = 125;
+ int blue = 42 * (6 - iconId);
+ if (!dayTimeIcon) {
+ red = 255 - red;
+ green = 255 - green;
+ blue = 255 - blue;
+ }
+ color = new Color(red, green, blue);
+ }
+
+ return color;
+ }
+
+ private BufferedImage createIcon(int iconSetId, ColorType colorType,
+ IconDimension iconDimension, boolean dayTimeIcon, int themeId,
+ IconSize iconSize, int iconId) {
+ BufferedImage bi = new BufferedImage(iconSize.getWidth(), iconSize.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics g = bi.getGraphics();
+
+ g.setColor(getColor(colorType, iconId, dayTimeIcon));
+
+ if (themeId == 44) {
+ g.fillOval(0, 0, iconSize.getWidth() - 1, iconSize.getHeight() - 1);
+ } else {
+ g.fill3DRect(0, 0, iconSize.getWidth() - 1, iconSize.getHeight() - 1, true);
+ }
+
+ if (iconDimension == IconDimension.D25D) {
+ g.setColor(Color.GRAY);
+ g.drawString(iconSetId + "/" + iconId, 10, 18);
+ g.drawString(iconSetId + "/" + iconId, 9, 19);
+ g.drawString(iconSetId + "/" + iconId, 8, 20);
+ }
+
+ if (dayTimeIcon) {
+ g.setColor(Color.BLACK);
+ } else {
+ g.setColor(Color.WHITE);
+ }
+ g.drawString(iconSetId + "/" + iconId, 7, 21);
+
+ return bi;
+ }
+
+ private CategoryDefinition createCategory1(int categoryId) {
+ CategoryDefinition categoryDefinition = TRAFFIC_INCIDENTS_SVC_FACTORY.createCategoryDefinition();
+
+ categoryDefinition.setCategoryId(categoryId);
+
+ LocalizedString[] localizedNames = new LocalizedString[2];
+ LocalizedString localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("nld");
+ localizedCategoryName.setString("file");
+ localizedNames[0] = localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("eng");
+ localizedCategoryName.setString("stationary traffic");
+ localizedNames[1] = localizedCategoryName;
+ categoryDefinition.setLocalizedNames(localizedNames);
+
+ // Comparison Predicate: effectCode == STATIONARY_TRAFFIC
+ ComparisonPredicate effectIsStationaryTraffic = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute effectCode = FILTER_EXPR_FACTORY.createClassAttribute();
+ effectCode.setAttributeName(tip.getTrafficIncident_EffectCode().getName());
+ effectIsStationaryTraffic.setAttribute(effectCode);
+ effectIsStationaryTraffic.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral stationaryTrafficEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ stationaryTrafficEnumValue.setValue(EffectCode.STATIONARY_TRAFFIC.getValue());
+ effectIsStationaryTraffic.setLiteral(stationaryTrafficEnumValue);
+
+ categoryDefinition.setExpression(effectIsStationaryTraffic.toString());
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ if (iconDescriptor.getIconId() == 1) {
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ categoryDefinition.getIconsList().add(iconInfo);
+ }
+ }
+ }
+
+ return categoryDefinition;
+ }
+
+ private CategoryDefinition createCategory2(int categoryId) {
+ CategoryDefinition categoryDefinition = TRAFFIC_INCIDENTS_SVC_FACTORY.createCategoryDefinition();
+
+ categoryDefinition.setCategoryId(categoryId);
+
+ LocalizedString[] localizedNames = new LocalizedString[2];
+ LocalizedString localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("nld");
+ localizedCategoryName.setString("druk verkeer - laagstaande zon");
+ localizedNames[0] = localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("eng");
+ localizedCategoryName.setString("heavy traffic - low sunglare");
+ localizedNames[1] = localizedCategoryName;
+ categoryDefinition.setLocalizedNames(localizedNames);
+
+ // Comparison Predicate: effectCode == HEAVY_TRAFFIC
+ ComparisonPredicate effectIsHeavyTraffic = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute effectCode = FILTER_EXPR_FACTORY.createClassAttribute();
+ effectCode.setAttributeName(tip.getTrafficIncident_EffectCode().getName());
+ effectIsHeavyTraffic.setAttribute(effectCode);
+ effectIsHeavyTraffic.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral heavyTrafficEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ heavyTrafficEnumValue.setValue(EffectCode.HEAVY_TRAFFIC.getValue());
+ effectIsHeavyTraffic.setLiteral(heavyTrafficEnumValue);
+
+
+ // Comparison Predicate: mainCause == VISIBILITY_REDUCED
+ ComparisonPredicate mainCauseIsVisibilityReduced = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute mainCause = FILTER_EXPR_FACTORY.createClassAttribute();
+ mainCause.setAttributeName(tip.getCause_MainCause().getName());
+ mainCauseIsVisibilityReduced.setAttribute(mainCause);
+ mainCauseIsVisibilityReduced.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral visibilityReducedEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ visibilityReducedEnumValue.setValue(CauseCode.VISIBILITY_REDUCED.getValue());
+ mainCauseIsVisibilityReduced.setLiteral(visibilityReducedEnumValue);
+
+ // Comparison Predicate: subCause == LOW_SUNGLARE
+ ComparisonPredicate subCauseIsLowSunglare = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute subCause = FILTER_EXPR_FACTORY.createClassAttribute();
+ subCause.setAttributeName(tip.getDirectCause_SubCause().getName());
+ subCauseIsLowSunglare.setAttribute(subCause);
+ subCauseIsLowSunglare.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral lowSunglareEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ lowSunglareEnumValue.setValue(VisibilityReduced.VISIBILITY_REDUCED_DUE_TO_LOW_SUN_GLARE.getValue());
+ subCauseIsLowSunglare.setLiteral(lowSunglareEnumValue);
+
+ // Dyadic Expression: (mainCause == VISIBILITY_REDUCED) && (subCause == LOW_SUNGLARE)
+ DyadicExpression causeExpression = FILTER_EXPR_FACTORY.createDyadicExpression();
+ causeExpression.setLeftHandTerm(mainCauseIsVisibilityReduced);
+ causeExpression.setLogicalOperator(DyadicLogicalOperator.AND);
+ causeExpression.setRightHandTerm(subCauseIsLowSunglare);
+
+ // Downcast: to DirectCause where (mainCause == VISIBILITY_REDUCED) && (subCause == LOW_SUNGLARE)
+ DownCastPredicate directCauseDownCast = FILTER_EXPR_FACTORY.createDownCastPredicate();
+ directCauseDownCast.setClassName(tip.getDirectCause().getName());
+ directCauseDownCast.setExpression(causeExpression);
+
+ // Multiplicity Predicate: ANY cause instanceof DirectCause where (mainCause == VISIBILITY_REDUCED) && (subCause == LOW_SUNGLARE)
+ MultiplicityPredicate anyCausePredicate = FILTER_EXPR_FACTORY.createMultiplicityPredicate();
+ anyCausePredicate.setListOperator(ListOperator.ANY);
+ ClassAttribute causes = FILTER_EXPR_FACTORY.createClassAttribute();
+ causes.setAttributeName(tip.getTrafficIncident_Causes().getName());
+ anyCausePredicate.setAttribute(causes);
+ anyCausePredicate.setExpression(directCauseDownCast);
+
+
+ // Dyadic Expression: (effectCode == HAEVY_TRAFFIC) AND (ANY cause instanceof DirectCause where (mainCause == VISIBILITY_REDUCED) && (subCause == LOW_SUNGLARE))
+ DyadicExpression expression = FILTER_EXPR_FACTORY.createDyadicExpression();
+ expression.setLeftHandTerm(effectIsHeavyTraffic);
+ expression.setLogicalOperator(DyadicLogicalOperator.AND);
+ expression.setRightHandTerm(anyCausePredicate);
+
+ categoryDefinition.setExpression(expression.toString());
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ if (iconDescriptor.getIconId() == 2) {
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ categoryDefinition.getIconsList().add(iconInfo);
+ }
+ }
+ }
+
+ return categoryDefinition;
+ }
+
+ private CategoryDefinition createCategory3(int categoryId) {
+ CategoryDefinition categoryDefinition = TRAFFIC_INCIDENTS_SVC_FACTORY.createCategoryDefinition();
+
+ categoryDefinition.setCategoryId(categoryId);
+
+ LocalizedString[] localizedNames = new LocalizedString[2];
+ LocalizedString localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("nld");
+ localizedCategoryName.setString("beperkt zicht");
+ localizedNames[0] = localizedCategoryName;
+ localizedCategoryName = COMMON_FACTORY.createLocalizedString();
+ localizedCategoryName.setLanguageCode("eng");
+ localizedCategoryName.setString("visibility reduced");
+ localizedNames[1] = localizedCategoryName;
+ categoryDefinition.setLocalizedNames(localizedNames);
+
+
+ // Comparison Predicate: mainCause == VISIBILITY_REDUCED
+ ComparisonPredicate mainCauseIsVisibilityReduced = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute mainCause = FILTER_EXPR_FACTORY.createClassAttribute();
+ mainCause.setAttributeName(tip.getCause_MainCause().getName());
+ mainCauseIsVisibilityReduced.setAttribute(mainCause);
+ mainCauseIsVisibilityReduced.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral visibilityReducedEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ visibilityReducedEnumValue.setValue(CauseCode.VISIBILITY_REDUCED.getValue());
+ mainCauseIsVisibilityReduced.setLiteral(visibilityReducedEnumValue);
+
+ // Multiplicity Predicate: ANY cause where (mainCause == VISIBILITY_REDUCED)
+ MultiplicityPredicate anyCausePredicate = FILTER_EXPR_FACTORY.createMultiplicityPredicate();
+ anyCausePredicate.setListOperator(ListOperator.ANY);
+ ClassAttribute causes = FILTER_EXPR_FACTORY.createClassAttribute();
+ causes.setAttributeName(tip.getTrafficIncident_Causes().getName());
+ anyCausePredicate.setAttribute(causes);
+ anyCausePredicate.setExpression(mainCauseIsVisibilityReduced);
+
+ categoryDefinition.setExpression(anyCausePredicate.toString());
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ if (iconDescriptor.getIconId() == 3) {
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ categoryDefinition.getIconsList().add(iconInfo);
+ }
+ }
+ }
+
+ return categoryDefinition;
+ }
+
+ /**
+ * Create the GUI and show it. For thread safety,
+ * this method should be invoked from the
+ * event-dispatching thread.
+ */
+ private void createAndShowGUI() {
+ // Map view
+ if (runTrafficInfoMapView) {
+ @SuppressWarnings("unused")
+ TrafficInfoMapView trafficInfoMapView = new TrafficInfoMapView(mapDataBase, trafficIncidentsService);
+ }
+
+ // Traffic incidentIds list display
+ if (runTrafficInfoListDisplay) {
+ TrafficInfoListDisplay trafficIncidentsListDisplay = new TrafficInfoListDisplay(trafficIncidentsService);
+ trafficIncidentsListDisplay.setVisible(true);
+ }
+
+ // Warning Client
+ if (runWarningClient) {
+ @SuppressWarnings("unused")
+ WarningClient warningClient = new WarningClient(trafficIncidentsService);
+ }
+
+ if (runIconDefinitionWindow) {
+ IconDefinitionWindow iconDefinitionWindow = new IconDefinitionWindow(iconDefinitions, iconSets, useIconFiles);
+ iconDefinitionWindow.setVisible(true);
+ }
+
+ if (runCategoryDefinitionsWindow) {
+ CategoryDefinitionsWindow categoryDefinitionsWindow = new CategoryDefinitionsWindow(categoryDefinitions, iconDefinitions, iconSets, useIconFiles);
+ categoryDefinitionsWindow.setVisible(true);
+ }
+ }
+
+ private void logSetup() {
+ // Create Logger
+ Logger logger = Logger.getLogger("");
+ logger.setLevel(logLevel);
+
+ Handler consoleHandler = null;
+ for (Handler handler: logger.getHandlers()) {
+ if (handler.getClass().getName().equals("java.util.logging.ConsoleHandler")) {
+ consoleHandler = handler;
+ break;
+ }
+ }
+ consoleHandler.setFormatter(new EclipseConsoleFormatter());
+ consoleHandler.setLevel(Level.INFO);
+ }
+
+ public static void main(String[] args) {
+ @SuppressWarnings("unused")
+ TrafficIncidentsServicePocMain trafficIncidentsServicePocMain = new TrafficIncidentsServicePocMain();
+ }
+
+ class MyTrafficIncidentsUpdatesListener extends EObjectImpl implements TrafficIncidentFeedListener {
+
+ @Override
+ public void getVersionReply(Version version) {
+ // No action
+ }
+
+ @Override
+ public void getLanguageReply(String languageCode, String countryCode) {
+ // No action
+ }
+
+ @Override
+ public void registerFeedReply(int feedId) {
+ // No action
+ }
+
+ @Override
+ public void addLanguageListenerReply() {
+ // No action
+ }
+
+ @Override
+ public void removeLanguageListenerReply() {
+ // No action
+ }
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ATrafficInfoClient.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ATrafficInfoClient.java
new file mode 100755
index 0000000..24533d6
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ATrafficInfoClient.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.util.logging.Logger;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.genivi.trafficincidentsservice.DefaultTrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TextDetailLevel;
+import org.genivi.trafficincidentsservice.TrafficIncidents;
+import org.genivi.trafficincidentsservice.TrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.trafficincidenttables.WarningLevel;
+
+/**
+ * This class is a very simple Traffic Incidents Service client.
+ * Every 3 seconds:
+ * - It requests the Ids of all the current Traffic Incidents
+ * - For these Ids it requests the full texts
+ * - It prints the Ids and the texts to System.out.
+ */
+public class ATrafficInfoClient extends Thread {
+ private final static Logger LOGGER = Logger.getLogger(ATrafficInfoClient.class.getName());
+
+ private TrafficIncidents trafficInfo = null;
+ private EList<Integer> incidentIds;
+ private TrafficIncidentsListener trafficIncidentsListener;
+
+ public ATrafficInfoClient() {
+ LOGGER.info("Creating ATrafficInfoClient");
+
+ trafficIncidentsListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getTrafficIncidentIdsReply(EList<Integer> incidentIds) {
+ LOGGER.info("getTrafficIncidentIdsReply called.");
+ getAndShowTrafficInfoStep2(incidentIds);
+ }
+
+
+ @Override
+ public void getTextsReply(EList<String> texts) {
+ LOGGER.info("getTextsReply called.");
+ getAndShowTrafficInfoStep3(texts);
+ }
+ };
+ }
+
+ public TrafficIncidents getTrafficInfo() {
+ return trafficInfo;
+ }
+
+ public void setTrafficIncidentsService(TrafficIncidents trafficInfo) {
+ this.trafficInfo = trafficInfo;
+ }
+
+ public void run() {
+ for ( ; ; ) {
+ if (trafficInfo != null) {
+ getAndShowTrafficInfoStep1();
+ } else {
+ System.out.println("ATrafficInfoClient: No traffic info provider");
+ }
+
+ try {
+ sleep(1000 * 3);
+ } catch (InterruptedException e) {
+ System.out.println("ATrafficInfoClient woke up too early");
+ }
+ }
+ }
+
+
+ private void getAndShowTrafficInfoStep1() {
+ LOGGER.info("Polling; calling getTrafficIncidentIds()");
+ trafficInfo.getTrafficIncidentIds(trafficIncidentsListener, new BasicEList<WarningLevel>(), new BasicEList<Integer>());
+ }
+
+ private void getAndShowTrafficInfoStep2(EList<Integer> incidentIds) {
+ this.incidentIds = incidentIds;
+ LOGGER.info("Getting the texts for the Traffic Incidents by calling getTexts().");
+ trafficInfo.getTexts(trafficIncidentsListener, incidentIds, TextDetailLevel.FULL);
+ }
+
+ private void getAndShowTrafficInfoStep3(EList<String> messageTexts) {
+ System.out.println("Current Traffic Incidents:");
+ System.out.print("Ids:");
+ for (Integer incidentId: incidentIds) {
+ System.out.print(" " + incidentId.toString());
+ }
+ System.out.println();
+ for (String messageText: messageTexts) {
+ System.out.println(messageText);
+ }
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/BooleanExpressionsFrame.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/BooleanExpressionsFrame.java
new file mode 100755
index 0000000..370505e
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/BooleanExpressionsFrame.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.util.logging.Logger;
+
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+
+@SuppressWarnings("serial")
+public class BooleanExpressionsFrame extends JFrame {
+ private final static Logger LOGGER = Logger.getLogger(TrafficInfoMapView.class.getName());
+
+ public BooleanExpressionsFrame(String[] descriptions, String[] expressions) {
+ init(descriptions, expressions);
+
+ pack();
+ }
+
+ private void init(String[] descriptions, String[] expressions) {
+ JPanel mainPanel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(mainPanel, BoxLayout.Y_AXIS);
+ mainPanel.setLayout(boxLayout);
+
+ for (int i = 0; i < descriptions.length; i++) {
+ mainPanel.add(createExpressionPanel(descriptions[i], expressions[i]));
+ }
+
+ JScrollPane scrollPane = new JScrollPane(mainPanel);
+
+ setContentPane(scrollPane);
+
+ setPreferredSize(new Dimension(850, 900));
+ }
+
+ private Component createExpressionPanel(String description, String expression) {
+ LOGGER.info("=> description = " + description + ", expression = " + expression);
+ JPanel panel = new JPanel();
+
+ JLabel descriptionLabel = new JLabel(description);
+ JPanel labelPanel = new JPanel();
+ labelPanel.add(descriptionLabel);
+ Dimension currentSize = labelPanel.getPreferredSize();
+ Dimension labelPanelSize = new Dimension(200, (int) currentSize.getHeight());
+ labelPanel.setSize(labelPanelSize);
+ labelPanel.setMinimumSize(labelPanelSize);
+ labelPanel.setMaximumSize(labelPanelSize);
+ labelPanel.setPreferredSize(labelPanelSize);
+ panel.add(labelPanel);
+
+ JTextPane expressionPane = new JTextPane();
+ expressionPane.setText(expression);
+ expressionPane.setEditable(false);
+ currentSize = expressionPane.getPreferredSize();
+ Dimension expressionPaneSize = new Dimension(600, (int) currentSize.getHeight());
+ expressionPane.setSize(expressionPaneSize);
+ expressionPane.setMinimumSize(expressionPaneSize);
+ expressionPane.setMaximumSize(expressionPaneSize);
+ expressionPane.setPreferredSize(expressionPaneSize);
+ panel.add(expressionPane);
+
+ return panel;
+ }
+
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/CategoryDefinitionsWindow.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/CategoryDefinitionsWindow.java
new file mode 100755
index 0000000..bb99493
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/CategoryDefinitionsWindow.java
@@ -0,0 +1,186 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import org.eclipse.emf.common.util.EList;
+import org.genivi.common.LocalizedString;
+import org.genivi.iconset.IconData;
+import org.genivi.iconset.IconDefinition;
+import org.genivi.iconset.IconDescriptor;
+import org.genivi.iconset.IconInfo;
+import org.genivi.iconset.IconSet;
+import org.genivi.iconset.IconsetFactory;
+import org.genivi.trafficincidentsservice.CategoryDefinition;
+
+@SuppressWarnings("serial")
+public class CategoryDefinitionsWindow extends JFrame {
+ private static final String NEW_LINE = System.getProperty("line.separator");
+ private static final IconsetFactory ICON_SET_FACTORY = IconsetFactory.eINSTANCE;
+
+ private boolean useIconFiles = false;
+ private Map<IconInfo, IconDefinition> iconDefinitionsMap = new HashMap<>();
+ private Map<IconInfo, IconDescriptor> iconDescriptorsMap = new HashMap<>();
+
+ public CategoryDefinitionsWindow(
+ EList<CategoryDefinition> categoryDefinitions,
+ EList<IconDefinition> iconDefinitions, EList<IconSet> iconSets, boolean useIconFiles) {
+ this.useIconFiles = useIconFiles;
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ IconInfo iconInfo = ICON_SET_FACTORY.createIconInfo();
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconDescriptorsMap.put(iconInfo, iconDescriptor);
+ }
+ }
+
+ if (!useIconFiles) {
+ for (IconDefinition iconDefinition: iconDefinitions) {
+ iconDefinitionsMap.put(iconDefinition.getIconInfo(), iconDefinition);
+ }
+ }
+
+ JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ for (CategoryDefinition categoryDefinition: categoryDefinitions) {
+ panel.add(createCategoryDefinitionPanel(categoryDefinition));
+ }
+
+ getContentPane().add(panel, BorderLayout.CENTER);
+ pack();
+ }
+
+ private Component createCategoryDefinitionPanel(
+ CategoryDefinition categoryDefinition) {
+ JPanel panel = new JPanel();
+ panel.setBorder(BorderFactory.createLoweredBevelBorder());
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ panel.add(createTextPanel(categoryDefinition));
+ panel.add(createIconsPanel(categoryDefinition));
+
+ return panel;
+ }
+
+ private Component createTextPanel(CategoryDefinition categoryDefinition) {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("categoryId: ");
+ buf.append(categoryDefinition.getCategoryId());
+ buf.append(NEW_LINE);
+
+ buf.append("expression: ");
+ buf.append(categoryDefinition.getExpression());
+ buf.append(NEW_LINE);
+
+ buf.append("Localized names: ");
+ for (LocalizedString localizedName: categoryDefinition.getLocalizedNames()) {
+ buf.append(NEW_LINE);
+ buf.append(" languageCode: ");
+ buf.append(localizedName.getLanguageCode());
+ buf.append(NEW_LINE);
+ buf.append(" countryCode: ");
+ buf.append(localizedName.getCountryCode());
+ buf.append(NEW_LINE);
+ buf.append(" name: ");
+ buf.append(localizedName.getString());
+ buf.append(NEW_LINE);
+ }
+
+ buf.append(NEW_LINE);
+ buf.append("icons:");
+
+
+ JTextArea textArea = new JTextArea(buf.toString());
+ textArea.setEditable(false);
+ textArea.setAlignmentX(Component.LEFT_ALIGNMENT);
+ return textArea;
+ }
+
+ private Component createIconsPanel(CategoryDefinition categoryDefinition) {
+ JPanel panel = new JPanel();
+
+ for (IconInfo iconInfo: categoryDefinition.getIcons()) {
+ panel.add(createIconPanel(iconInfo));
+ }
+
+ panel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ return panel;
+ }
+
+ private Component createIconPanel(IconInfo iconInfo) {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new BorderLayout());
+ BufferedImage image = null;
+ if (useIconFiles) {
+ IconDescriptor iconDescriptor = iconDescriptorsMap.get(iconInfo);
+ File imageFile = new File(iconDescriptor.getUrl());
+ try {
+ image = ImageIO.read(imageFile);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ IconDefinition iconDefinition = iconDefinitionsMap.get(iconInfo);
+ IconData iconData = iconDefinition.getIconData();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(iconData.getData());
+ try {
+ image = ImageIO.read(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ panel.add(new JLabel(new ImageIcon(image)), BorderLayout.CENTER);
+
+ panel.add(createIconInfoTextPanel(iconInfo), BorderLayout.SOUTH);
+
+ return panel;
+ }
+
+ private Component createIconInfoTextPanel(IconInfo iconInfo) {
+ JPanel panel = new JPanel();
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("iconSetId: ");
+ buf.append(iconInfo.getIconSetId());
+ buf.append(NEW_LINE);
+
+ buf.append("iconId: ");
+ buf.append(iconInfo.getIconId());
+
+ JTextArea textArea = new JTextArea(buf.toString());
+ textArea.setEditable(false);
+
+ panel.add(textArea);
+
+ return panel;
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/IconDefinitionWindow.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/IconDefinitionWindow.java
new file mode 100755
index 0000000..e40e916
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/IconDefinitionWindow.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import org.eclipse.emf.common.util.EList;
+import org.genivi.iconset.IconData;
+import org.genivi.iconset.IconDefinition;
+import org.genivi.iconset.IconDescriptor;
+import org.genivi.iconset.IconInfo;
+import org.genivi.iconset.IconSet;
+import org.genivi.iconset.IconsetFactory;
+
+@SuppressWarnings("serial")
+public class IconDefinitionWindow extends JFrame {
+ private static final String NEW_LINE = System.getProperty("line.separator");
+ private static final IconsetFactory iconsetFactory = IconsetFactory.eINSTANCE;
+
+ private boolean useIconFiles = false;
+ private Map<IconInfo, IconDefinition> iconDefinitionsMap = new HashMap<IconInfo, IconDefinition>();
+
+ public IconDefinitionWindow(EList<IconDefinition> iconDefinitions, EList<IconSet> iconSets, boolean useIconFiles) {
+ this.useIconFiles = useIconFiles;
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ if (!useIconFiles) {
+ for (IconDefinition iconDefinition: iconDefinitions) {
+ iconDefinitionsMap.put(iconDefinition.getIconInfo(), iconDefinition);
+ }
+ }
+
+ JPanel panel = new JPanel();
+
+ panel.add(creatIconThemePanel(iconSets, 28));
+ panel.add(creatIconThemePanel(iconSets, 44));
+
+ setContentPane(panel);
+ pack();
+ }
+
+ private Component creatIconThemePanel(EList<IconSet> iconSets, int themeId) {
+ JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ for (IconSet iconSet: iconSets) {
+ if (iconSet.getThemeId() == themeId) {
+ panel.add(createIconSetPanel(iconSet));
+ }
+ }
+
+ return panel;
+ }
+
+ private Component createIconSetPanel(IconSet iconSet) {
+ JPanel panel = new JPanel();
+ panel.add(createMetaDataPanel(iconSet));
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ panel.add(createIconPreviewPanel(iconSet, iconDescriptor));
+ }
+ return panel;
+ }
+
+ private Component createIconPreviewPanel(IconSet iconSet,
+ IconDescriptor iconDescriptor) {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new BorderLayout());
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSet.getIconSetId());
+ iconInfo.setIconId(iconDescriptor.getIconId());
+ BufferedImage image = null;
+ if (useIconFiles) {
+ File imageFile = new File(iconDescriptor.getUrl());
+ try {
+ image = ImageIO.read(imageFile);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ IconDefinition iconDefinition = iconDefinitionsMap.get(iconInfo);
+ IconData iconData = iconDefinition.getIconData();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(iconData.getData());
+ try {
+ image = ImageIO.read(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ panel.add(new ImagePanel(image), BorderLayout.CENTER);
+
+ JLabel label = new JLabel("icon " + iconDescriptor.getIconId());
+ panel.add(label, BorderLayout.SOUTH);
+
+ return panel;
+ }
+
+ private Component createMetaDataPanel(IconSet iconSet) {
+ JPanel panel = new JPanel();
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("iconSetId: ");
+ buf.append(iconSet.getIconSetId());
+ buf.append(NEW_LINE);
+
+ buf.append("colorType: ");
+ buf.append(iconSet.getColorType().getName());
+ buf.append(NEW_LINE);
+
+ buf.append("dimension: ");
+ buf.append(iconSet.getDimension().getName());
+ buf.append(NEW_LINE);
+
+ buf.append("daytime/nighttime: ");
+ if (iconSet.isDayTimeIcon()) {
+ buf.append("daytime");
+ } else {
+ buf.append("nighttime");
+ }
+ buf.append(NEW_LINE);
+
+ buf.append("themeId: ");
+ buf.append(iconSet.getThemeId());
+ buf.append(NEW_LINE);
+
+ buf.append("size: ");
+ buf.append(iconSet.getSize().getWidth());
+ buf.append(" x ");
+ buf.append(iconSet.getSize().getHeight());
+ buf.append(NEW_LINE);
+
+ JTextArea textArea = new JTextArea(buf.toString());
+ textArea.setEditable(false);
+
+ return panel.add(textArea);
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ImagePanel.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ImagePanel.java
new file mode 100755
index 0000000..46996f2
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/ImagePanel.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+
+@SuppressWarnings("serial")
+public class ImagePanel extends JPanel {
+
+ private Image img;
+
+ public ImagePanel(String imageFileName) {
+ this(new ImageIcon(imageFileName).getImage());
+ }
+
+ public ImagePanel(Image img) {
+ this.img = img;
+ Dimension dimension = new Dimension(img.getWidth(null), img.getHeight(null));
+ setSize(dimension);
+ setPreferredSize(dimension);
+ }
+
+ public void paintComponent(Graphics g) {
+ g.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), this);
+ }
+} \ No newline at end of file
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficIncidentsPainter.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficIncidentsPainter.java
new file mode 100755
index 0000000..6626c2a
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficIncidentsPainter.java
@@ -0,0 +1,209 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+import java.util.logging.Logger;
+
+import openlr.map.Line;
+import openlr.map.MapDatabase;
+import openlr.map.Node;
+
+import org.eclipse.emf.common.util.EList;
+import org.genivi.common.Coordinate;
+import org.genivi.common.RectangularArea;
+import org.genivi.location.LinearLocation;
+import org.genivi.location.LinearLocationInfo;
+import org.genivi.location.Location;
+import org.genivi.location.LocationInfo;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.TrafficIncident;
+import org.jdesktop.swingx.JXMapViewer;
+import org.jdesktop.swingx.mapviewer.GeoPosition;
+import org.jdesktop.swingx.painter.AbstractPainter;
+
+
+/**
+ * Painter that only can draw on to JXMapViewers.
+ * Based on code from rbair.
+ */
+public class TrafficIncidentsPainter<T extends JXMapViewer> extends AbstractPainter<T> {
+ private final static Logger LOGGER = Logger.getLogger(TrafficIncidentsPainter.class.getName());
+
+ private MapDatabase mapDataBase;
+ private EList<TrafficIncident> incidents;
+ private boolean drawBoundingBox = false;
+ private boolean useCoordinates = false; // If true, the location from getLocation() is used, else the coordinates from LocatinInfo are used.
+ private EList<RectangularArea> areas = null; // If not null, areas are drawn
+
+ /**
+ * Creates a new instance of WaypointPainter
+ */
+ public TrafficIncidentsPainter(MapDatabase mapDataBase) {
+ this.mapDataBase = mapDataBase;
+
+ setAntialiasing(true);
+ setCacheable(false);
+ }
+
+ public EList<TrafficIncident> getIncidents() {
+ return incidents;
+ }
+
+ public void setIncidents(EList<TrafficIncident> incidents) {
+ this.incidents = incidents;
+ }
+
+ public void setUseCoordinates(boolean useCoordinates) {
+ this.useCoordinates = useCoordinates;
+ }
+
+ public void setDrawBoundingBox(boolean drawBoundingBox) {
+ this.drawBoundingBox = drawBoundingBox;
+ }
+
+ public void setAreas(EList<RectangularArea> areas) {
+ this.areas = areas;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param g
+ * @param map
+ * @param width
+ * @param height
+ */
+ @Override
+ protected void doPaint(Graphics2D g, T map, int width, int height) {
+ LOGGER.fine("=>");
+ if (areas != null) {
+ for (RectangularArea area: areas) {
+ drawRectangle(g, map, area);
+ }
+ }
+
+ if (incidents == null) {
+ LOGGER.fine("<= No Traffic Incidents.");
+ return;
+ }
+
+ LOGGER.fine("Number of Traffic Incidents = " + incidents.size());
+ for (TrafficIncident incident: incidents) {
+ paintIncident(g, map, width, height, incident);
+ }
+ LOGGER.fine("<=");
+ }
+
+ private void paintIncident(Graphics2D g, T map, int width, int height, TrafficIncident incident) {
+ LOGGER.fine("=>");
+ if (useCoordinates) {
+ paintLocation(g, map, incident.getLocation());
+ } else {
+ paintLocationInfo(g, map, incident.getLocationInfo());
+ }
+
+ if (drawBoundingBox && incident.getLocationBoundingBox() != null) {
+ drawRectangle(g, map, incident.getLocationBoundingBox());
+ }
+ LOGGER.fine("<=");
+ }
+
+ private void paintLocation(Graphics2D g, T map, Location location) {
+ LOGGER.fine("=>");
+ if (location instanceof LinearLocation) {
+ LOGGER.fine("location is LinearLocation");
+ LinearLocation linearLocation = (LinearLocation) location;
+ List<Long> segments = linearLocation.getSegments();
+
+ for (long segment: segments) {
+ Line line = mapDataBase.getLine(segment);
+ Node startNode = line.getStartNode();
+ Node endNode = line.getEndNode();
+ paintLine(g, map, startNode.getLongitudeDeg(), startNode.getLatitudeDeg(), endNode.getLongitudeDeg(), endNode.getLatitudeDeg(), Color.BLUE, 3f);
+ }
+ } else {
+ LOGGER.fine("location is not a linearLocation, this type is not supported");
+ }
+ LOGGER.fine("<=");
+ }
+
+ private void paintLocationInfo(Graphics2D g, T map, LocationInfo locationInfo) {
+ LOGGER.fine("=>");
+ if (locationInfo instanceof LinearLocationInfo) {
+ LinearLocationInfo linearLocationInfo = (LinearLocationInfo) locationInfo;
+ EList<Coordinate> coordinates = linearLocationInfo.getCoordinates();
+ LOGGER.fine("linear location, size = " + coordinates.size());
+
+ for (int i = 1; i < coordinates.size(); i++) {
+ Coordinate startCoordinate = coordinates.get(i - 1);
+ Coordinate endCoordinate = coordinates.get(i);
+ paintLine(g, map, startCoordinate.getLongitude(), startCoordinate.getLatitude(), endCoordinate.getLongitude(), endCoordinate.getLatitude(), Color.RED, 3f);
+ }
+ } else {
+ LOGGER.fine("location is not a linearLocation, this type is not supported");
+ }
+ LOGGER.fine("=>");
+ }
+
+ private void drawRectangle(Graphics2D g, T map, RectangularArea locationBoundingBox) {
+ Coordinate bottomLeft = locationBoundingBox.getBottomLeft();
+ Coordinate topRight = locationBoundingBox.getTopRight();
+ paintLine(g, map, bottomLeft.getLongitude(), topRight.getLatitude(), topRight.getLongitude(), topRight.getLatitude(), Color.BLACK, 1f);
+ paintLine(g, map, topRight.getLongitude(), topRight.getLatitude(), topRight.getLongitude(), bottomLeft.getLatitude(), Color.BLACK, 1f);
+ paintLine(g, map, topRight.getLongitude(), bottomLeft.getLatitude(), bottomLeft.getLongitude(), bottomLeft.getLatitude(), Color.BLACK, 1f);
+ paintLine(g, map, bottomLeft.getLongitude(), bottomLeft.getLatitude(), bottomLeft.getLongitude(), topRight.getLatitude(), Color.BLACK, 1f);
+ }
+
+ private void paintLine(Graphics2D g, T map, double longitude1,
+ double latitude1, double longitude2, double latitude2,
+ Color color, Float lineWidth) {
+ LOGGER.fine("=> coordinates: (" + longitude1 + ", " + latitude1 + ") (" + longitude2 + ", " + latitude2 + ")");
+
+ // figure out whether the line is within this map viewport
+ // so, get the bounds
+ Rectangle viewportBounds = map.getViewportBounds();
+ int zoom = map.getZoom();
+ Dimension sizeInTiles = map.getTileFactory().getMapSize(zoom);
+ int tileSize = map.getTileFactory().getTileSize(zoom);
+ Dimension sizeInPixels = new Dimension(sizeInTiles.width*tileSize, sizeInTiles.height*tileSize);
+
+ double vpx = viewportBounds.getX();
+ // normalize the left edge of the viewport to be positive
+ while(vpx < 0) {
+ vpx += sizeInPixels.getWidth();
+ }
+ // normalize the left edge of the viewport to no wrap around the world
+ while(vpx > sizeInPixels.getWidth()) {
+ vpx -= sizeInPixels.getWidth();
+ }
+
+ // create two new viewports next to eachother
+ Rectangle2D vp2 = new Rectangle2D.Double(vpx,
+ viewportBounds.getY(),viewportBounds.getWidth(),viewportBounds.getHeight());
+
+ GeoPosition startNodeGeoPosition = new GeoPosition(latitude1, longitude1);
+ Point2D point0 = map.getTileFactory().geoToPixel(startNodeGeoPosition, map.getZoom());
+ GeoPosition endNodeGeoPosition = new GeoPosition(latitude2, longitude2);
+ Point2D point1 = map.getTileFactory().geoToPixel(endNodeGeoPosition, map.getZoom());
+ int x0 = (int)(point0.getX() - vp2.getX());
+ int y0 = (int)(point0.getY() - vp2.getY());
+ int x1 = (int)(point1.getX() - vp2.getX());
+ int y1 = (int)(point1.getY() - vp2.getY());
+ g.setStroke(new BasicStroke(lineWidth));
+ g.setColor(color);
+ g.drawLine(x0, y0, x1, y1);
+
+ LOGGER.fine("<=");
+ }
+} \ No newline at end of file
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoListDisplay.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoListDisplay.java
new file mode 100755
index 0000000..07cfd59
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoListDisplay.java
@@ -0,0 +1,2165 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.EtchedBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableModel;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.genivi.booleanexpr.BooleanExpression;
+import org.genivi.booleanexpr.ClassAttribute;
+import org.genivi.booleanexpr.ComparisonOperator;
+import org.genivi.booleanexpr.ComparisonPredicate;
+import org.genivi.booleanexpr.DyadicExpression;
+import org.genivi.booleanexpr.DyadicLogicalOperator;
+import org.genivi.booleanexpr.FilterexprFactory;
+import org.genivi.booleanexpr.IsSetPredicate;
+import org.genivi.booleanexpr.ListOperator;
+import org.genivi.booleanexpr.MetaOperator;
+import org.genivi.booleanexpr.MultiplicityPredicate;
+import org.genivi.booleanexpr.SignedIntegerLiteral;
+import org.genivi.booleanexpr.util.FilterExprUtil;
+import org.genivi.common.LocalizedString;
+import org.genivi.common.Version;
+import org.genivi.iconset.ColorType;
+import org.genivi.iconset.IconData;
+import org.genivi.iconset.IconDefinition;
+import org.genivi.iconset.IconDescriptor;
+import org.genivi.iconset.IconDimension;
+import org.genivi.iconset.IconInfo;
+import org.genivi.iconset.IconSet;
+import org.genivi.iconset.IconsetFactory;
+import org.genivi.location.AreaLocation;
+import org.genivi.location.AreaLocationInfo;
+import org.genivi.location.LinearLocation;
+import org.genivi.location.LinearLocationInfo;
+import org.genivi.location.Location;
+import org.genivi.location.LocationInfo;
+import org.genivi.location.PointLocation;
+import org.genivi.location.PointLocationInfo;
+import org.genivi.trafficincidentsservice.CategoryDefinition;
+import org.genivi.trafficincidentsservice.DefaultTrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.FeedInformation;
+import org.genivi.trafficincidentsservice.LengthUnit;
+import org.genivi.trafficincidentsservice.TextDetailLevel;
+import org.genivi.trafficincidentsservice.TrafficIncidentFeedStatus;
+import org.genivi.trafficincidentsservice.TrafficIncidentField;
+import org.genivi.trafficincidentsservice.TrafficIncidents;
+import org.genivi.trafficincidentsservice.TrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TrafficIncidentsStatus;
+import org.genivi.trafficincidentsservice.WeightUnit;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.Advice;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.Applicability;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.Cause;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.DirectCause;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.LaneRestrictions;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.LinkedCause;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.TrafficIncident;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.trafficincidentPackage;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.VehicleRelatedRestriction;
+import org.genivi.trafficincidentsservice.trafficincidenttables.RestrictionType;
+import org.genivi.trafficincidentsservice.trafficincidenttables.VehicleType;
+import org.genivi.trafficincidentsservice.trafficincidenttables.WarningLevel;
+
+
+@SuppressWarnings("serial")
+public class TrafficInfoListDisplay extends JFrame {
+ private final static Logger LOGGER = Logger.getLogger(TrafficInfoMapView.class.getName());
+ private static final String TITLE_BODY = "Traffic Incidents List Display (TrafficIncidentsService version: ";
+ private static final String NEW_LINE = System.getProperty("line.separator");
+ private static final SimpleDateFormat DF = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+ private final static FilterexprFactory FILTER_EXPR_FACTORY = FilterexprFactory.eINSTANCE;
+ private final static trafficincidentPackage tip = trafficincidentPackage.eINSTANCE;
+ private static final String NO_COUNTRY = "<none>";
+ private static String[] SUPPORTED_LANGUAGES = {
+ "nld", "eng", "fra", "deu"
+ };
+ private static String[] SUPPORTED_COUNTRIES = {
+ NO_COUNTRY, "nld", "gbr", "usa", "fra", "deu"
+ };
+ private static String[] FEED_INFO_TABLE_COLUMN_NAMES = {
+ "Data Provider", "Protocol", "Communication Channel", "Feed Status", "Traffic Incidents Status"
+ };
+ private static Object[][] UNKOWN_FEED_INFO = {
+ {"-", "-", "-", "-", "-"}
+ };
+ private static final long AXLE_LOAD_NORMAL = 4;
+ private static final long AXLE_LOAD_EXTRA = 3;
+
+ private final static IconsetFactory iconsetFactory = IconsetFactory.eINSTANCE;
+ private static List<TrafficIncidentField> trafficIncidentFields = new ArrayList<TrafficIncidentField>();
+
+ private TrafficIncidents trafficIncidentsService;
+
+ private boolean versionInfoObtained = false;
+ private boolean iconSetsObtained = false;
+ private boolean iconDefinitionsObtained = false;
+ private boolean categoryDefinitionsObtained = false;
+
+ private EList<IconSet> iconSets; // Descriptions of the icon sets available in the system. These are obtained from the TrafficIncidentsService.
+ private EList<Integer> iconThemes; // Icon themes available in iconSets.
+ private EList<ColorType> iconColorTypes; // Color types available in iconSets.
+ private EList<IconDimension> iconDimensions; // Icon dimensions available in iconSets.
+ private boolean dayTimeSupported = false; // Indicates whether there are daytime icons in iconSets.
+ private boolean nightTimeSupported = false; // Indicates whether there are night time icons in iconSets.
+ private EList<Integer> iconSetsPriorityOrder; // Priority order for the icon to be used.
+ private Map<IconInfo, BufferedImage> iconImages = new HashMap<IconInfo, BufferedImage>(); // Images of all icons.
+ private Map<Integer, CategoryDefinition> categoryDefinitionsMap = new HashMap<Integer, CategoryDefinition>();
+ private EList<Integer> currentCategoryIds = new BasicEList<Integer>();
+ private JCheckBox holdCheckBox;
+ private JCheckBox applicabilityCheckBox;
+ private JCheckBox extraTonsCheckBox;
+ private JTextArea fullTextArea;
+ private JTextArea summaryTextArea;
+ private JPanel fieldsTextPanel;
+ private Version trafficIncidentsVersion = null;
+ private Date lastUpdateDate = null;
+ private TrafficIncidentsListener primaryUpdateListener;
+ private TrafficIncidentsListener updateListener = null;
+ private TrafficIncidentsListener fullTextListener;
+ private TrafficIncidentsListener summaryTextListener;
+ private TrafficIncidentsListener fieldsListener;
+ private JCheckBox allCategoriesCheckBox;
+ private JList<ListCategoryDefinition> categoriesSelectionList;
+ private JComboBox<String> languageSelectionBox;
+ private JComboBox<String> languageCountrySelectionBox;
+ private JComboBox<Integer> iconThemeSelectionBox;
+ private JComboBox<ColorType> iconColorTypeSelectionBox;
+ private JComboBox<IconDimension> iconDimensionSelectionBox;
+ private JCheckBox nightTimeCheckbox;
+ private JLabel iconSetPriorityOrderLabel;
+ private JPanel statusPanel;
+ private JLabel trafficIncidentFeedStatusLabel;
+ private JLabel trafficIncidentsStatusLabel;
+ DefaultTableModel feedInfoTableModel;
+ private String currentLanguage;
+ private String currentLanguageCountry;
+ private JComboBox<LengthUnit> lengthUnitSelectionBox;
+ private JComboBox<WeightUnit> weightUnitSelectionBox;
+ private JTextField dateFormatTextField;
+ private JTextField timeFormatTextField;
+
+ static {
+ for (TrafficIncidentField trafficIncidentField: TrafficIncidentField.values()) {
+ trafficIncidentFields.add(trafficIncidentField);
+ }
+ }
+
+ public TrafficInfoListDisplay(TrafficIncidents trafficIncidents) {
+ super(TITLE_BODY + "<no version info available>");
+ LOGGER.setLevel(Level.SEVERE);
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ this.trafficIncidentsService = trafficIncidents;
+
+ primaryUpdateListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getVersionReply(Version trafficIncidentsVersion) {
+ LOGGER.info("getVersionReply() called.");
+ setTrafficIncidentsVersion(trafficIncidentsVersion);
+
+ updateTitle();
+
+ versionInfoObtained = true;
+
+ // Only start the real work after we obtained the necessary information.
+ if (readyToGo() && (updateListener == null)) {
+ updateListener = this;
+ updateApplicabilitySetting();
+
+ trafficIncidentsService.addUpdateListener(this, new BasicEList<WarningLevel>(), currentCategoryIds, this);
+ }
+ }
+
+ @Override
+ public void updates(EList<Integer> unchangedTrafficIncidentIds, EList<Integer> changedTrafficIncidentIds, EList<Integer> newTrafficIncidentIds, EList<Integer> deletedTrafficIncidentIds) {
+ LOGGER.info("updates() called. unchangedTrafficIncidentIds = " + unchangedTrafficIncidentIds + ", changedTrafficIncidentIds = " + changedTrafficIncidentIds + ", newTrafficIncidentIds = " + newTrafficIncidentIds + ", deletedTrafficIncidentIds = " + deletedTrafficIncidentIds);
+
+ EList<Integer> incidentIds = new BasicEList<>(unchangedTrafficIncidentIds);
+ incidentIds.addAll(changedTrafficIncidentIds);
+ incidentIds.addAll(newTrafficIncidentIds);
+
+ LOGGER.info("New list of incidents = " + incidentIds);
+ updateFullTextPaneStep1(incidentIds);
+ updateSummaryTextPaneStep1(incidentIds);
+ updateFieldsTextPaneStep1(incidentIds);
+ lastUpdateDate = new Date();
+ updateTitle();
+ }
+
+ @Override
+ public void getLanguageReply(String languageCode, String countryCode) {
+ LOGGER.info("getLanguageReply() called.");
+ updateSelectedLanguage(languageCode, countryCode);
+ }
+
+ @Override
+ public void trafficIncidentsStatus(
+ TrafficIncidentFeedStatus trafficIncidentFeedStatus,
+ TrafficIncidentsStatus trafficIncidentsStatus) {
+ LOGGER.info("trafficIncidentsStatus() called.");
+ updateStatusInfo(trafficIncidentFeedStatus, trafficIncidentsStatus);
+ }
+
+ @Override
+ public void feedInformation(EList<FeedInformation> feedsInformation) {
+ LOGGER.info("feedInformation() called.");
+ updateFeedInfo(feedsInformation);
+ }
+
+ @Override
+ public void getIconSetsReply(EList<IconSet> iconSets) {
+ LOGGER.info("getIconSetsReply() called.");
+ boolean obtainIconsFromTrafficIncidentsService = handleIconSets(iconSets);
+ if (obtainIconsFromTrafficIncidentsService) {
+ LOGGER.info("Calling getIconDefinitions()");
+ trafficIncidentsService.getIconDefinitions(this, new BasicEList<IconInfo>());
+ } else {
+ iconDefinitionsObtained = true;
+ }
+
+ iconSetsObtained = true;
+
+ // Only start the real work after we obtained the necessary information.
+ if (readyToGo() && (updateListener == null)) {
+ updateListener = this;
+ updateApplicabilitySetting();
+
+ trafficIncidentsService.addUpdateListener(this, new BasicEList<WarningLevel>(), new BasicEList<Integer>(), this);
+ }
+ }
+
+ @Override
+ public void getIconDefinitionsReply(EList<IconDefinition> iconDefinitions) {
+ LOGGER.info("getIconDefinitionsReply() called.");
+ handleIconDefinitions(iconDefinitions);
+ iconDefinitionsObtained = true;
+
+ // Only start the real work after we obtained the necessary information.
+ if (readyToGo() && (updateListener == null)) {
+ updateListener = this;
+ updateApplicabilitySetting();
+
+ trafficIncidentsService.addUpdateListener(this, new BasicEList<WarningLevel>(), new BasicEList<Integer>(), this);
+ }
+ }
+
+ @Override
+ public void getCategoryDefinitionsReply(EList<CategoryDefinition> categoryDefinitions) {
+ LOGGER.info("getCategoryDefinitionsReply() called.");
+ handleCategoryDefinitions(categoryDefinitions);
+ categoryDefinitionsObtained = true;
+
+ // Only start the real work after we obtained the necessary information.
+ if (readyToGo() && (updateListener == null)) {
+ updateListener = this;
+ updateApplicabilitySetting();
+
+ trafficIncidentsService.addUpdateListener(this, new BasicEList<WarningLevel>(), new BasicEList<Integer>(), this);
+ }
+ }
+
+ @Override
+ public void addUpdateListenerReply() {
+ LOGGER.info("addUpdateListenerReply() called.");
+ // no action
+ }
+
+ @Override
+ public void removeUpdateListenerReply() {
+ LOGGER.info("Installing new updateListener");
+ trafficIncidentsService.addUpdateListener(this, new BasicEList<WarningLevel>(), currentCategoryIds, this);
+ }
+ };
+
+ fullTextListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getTextsReply(EList<String> texts) {
+ LOGGER.info("getTextsReply() for Full Text called.");
+ updateFullTextPaneStep2(texts);
+ }
+ };
+
+ summaryTextListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getTextsReply(EList<String> texts) {
+ LOGGER.info("getTextsReply() for Summary called.");
+ updateSummaryTextPaneStep2(texts);
+ }
+ };
+
+ fieldsListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getTrafficIncidentsReply(EList<TrafficIncident> trafficIncidents) {
+ LOGGER.info("getTrafficIncidentsReply() called.");
+ updateFieldsTextPaneStep2(trafficIncidents);
+ }
+
+ };
+
+ init();
+
+ pack();
+
+ updateTitle();
+
+ LOGGER.info("Calling getVersion()");
+ trafficIncidents.getVersion(primaryUpdateListener);
+ LOGGER.info("Calling getLanguage()");
+ trafficIncidents.getLanguage(primaryUpdateListener);
+ LOGGER.info("Calling getIconSets()");
+ trafficIncidents.getIconSets(primaryUpdateListener);
+ LOGGER.info("Calling getCategoryDefinitions()");
+ trafficIncidents.getCategoryDefinitions(primaryUpdateListener);
+ LOGGER.info("Calling addTrafficIncidentsStatusListener()");
+ trafficIncidents.addTrafficIncidentsStatusListener(null, primaryUpdateListener);
+ LOGGER.info("Calling addFeedInformationListener()");
+ trafficIncidents.addFeedInformationListener(null, primaryUpdateListener);
+ }
+
+ protected void handleCategoryDefinitions(EList<CategoryDefinition> categoryDefinitions) {
+ for (CategoryDefinition categoryDefinition: categoryDefinitions) {
+ categoryDefinitionsMap.put(categoryDefinition.getCategoryId(), categoryDefinition);
+ }
+
+ updateCategoriesSelectionBox();
+ }
+
+ private void updateCategoriesSelectionBox() {
+ DefaultListModel<ListCategoryDefinition> listModel = new DefaultListModel<>();
+ for (CategoryDefinition categoryDefinition: categoryDefinitionsMap.values()) {
+ listModel.addElement(new ListCategoryDefinition(categoryDefinition));
+ }
+ categoriesSelectionList.setSelectionInterval(0, listModel.getSize());
+ categoriesSelectionList.setModel(listModel);
+ }
+
+ private boolean readyToGo() {
+ LOGGER.info("In readyToGo: versionInfoObtained = " + versionInfoObtained + ", iconSetsObtained = " + iconSetsObtained + ", iconDefinitionsObtained = " + iconDefinitionsObtained + ", categoryDefinitionsObtained = " + categoryDefinitionsObtained);
+ if (versionInfoObtained && iconSetsObtained &&
+ iconDefinitionsObtained && categoryDefinitionsObtained) {
+ LOGGER.info("Ready to GO!");
+ } else {
+ LOGGER.info("Not yet ready to go");
+ }
+ return versionInfoObtained && iconSetsObtained &&
+ iconDefinitionsObtained && categoryDefinitionsObtained;
+ }
+
+ protected boolean handleIconSets(EList<IconSet> iconSets) {
+ this.iconSets = iconSets;
+
+ boolean obtainIconsFromTrafficIncidentsService = false;
+
+ for (IconSet iconSet: iconSets) {
+ for (IconDescriptor iconDescriptor: iconSet.getIconDescriptors()) {
+ if (iconDescriptor.isSetUrl()) {
+ readIconFromFile(iconSet.getIconSetId(), iconDescriptor);
+ } else {
+ obtainIconsFromTrafficIncidentsService = true;
+ }
+ }
+ }
+
+ updateIconSetControls();
+
+ return obtainIconsFromTrafficIncidentsService;
+ }
+
+ private void updateIconSetControls() {
+ determineIconThemes();
+ updateIconThemeSelectionBox();
+ determineIconColorTypes();
+ updateIconColorTypeSelectionBox();
+ determineIconDimensions();
+ updateIconDimensionSelectionBox();
+ determineDayNightSupport();
+ updateNightTimeCheckbox();
+
+ determineIconSetsOrder();
+ }
+
+ private void determineIconThemes() {
+ iconThemes = new BasicEList<Integer>();
+
+ for (IconSet iconSet: iconSets) {
+ Integer themeId = iconSet.getThemeId();
+ if (!iconThemes.contains(themeId)) {
+ iconThemes.add(themeId);
+ }
+ }
+ }
+
+ private void updateIconThemeSelectionBox() {
+ iconThemeSelectionBox.removeAllItems();
+
+ for (Integer themeId: iconThemes) {
+ iconThemeSelectionBox.addItem(themeId);
+ }
+
+ iconThemeSelectionBox.setSelectedIndex(0);
+ }
+
+ private void determineIconColorTypes() {
+ iconColorTypes = new BasicEList<ColorType>();
+
+ for (IconSet iconSet: iconSets) {
+ ColorType colorType = iconSet.getColorType();
+ if (!iconColorTypes.contains(colorType)) {
+ iconColorTypes.add(colorType);
+ }
+ }
+ }
+
+ private void updateIconColorTypeSelectionBox() {
+ iconColorTypeSelectionBox.removeAllItems();
+
+ for (ColorType colorType: iconColorTypes) {
+ iconColorTypeSelectionBox.addItem(colorType);
+ }
+
+ iconColorTypeSelectionBox.setSelectedIndex(0);
+ }
+
+ private void determineIconDimensions() {
+ iconDimensions = new BasicEList<IconDimension>();
+
+ for (IconSet iconSet: iconSets) {
+ IconDimension iconDimension = iconSet.getDimension();
+ if (!iconDimensions.contains(iconDimension)) {
+ iconDimensions.add(iconDimension);
+ }
+ }
+ }
+
+ private void updateIconDimensionSelectionBox() {
+ iconDimensionSelectionBox.removeAllItems();
+
+ for (IconDimension iconDimension: iconDimensions) {
+ iconDimensionSelectionBox.addItem(iconDimension);
+ }
+
+ iconDimensionSelectionBox.setSelectedIndex(0);
+ }
+
+ private void determineDayNightSupport() {
+ dayTimeSupported = false;
+ nightTimeSupported = false;
+
+ for (IconSet iconSet: iconSets) {
+ boolean isDayTimeIcon = iconSet.isDayTimeIcon();
+ if (isDayTimeIcon) {
+ dayTimeSupported = true;
+ } else {
+ nightTimeSupported = true;
+ }
+ }
+ }
+
+ private void updateNightTimeCheckbox() {
+ if (dayTimeSupported && nightTimeSupported) {
+ nightTimeCheckbox.setEnabled(true);
+ nightTimeCheckbox.setSelected(false);
+ } else {
+ nightTimeCheckbox.setEnabled(true);
+ if (dayTimeSupported) {
+ nightTimeCheckbox.setSelected(false);
+ } else {
+ nightTimeCheckbox.setSelected(true);
+ }
+ }
+ }
+
+ private void determineIconSetsOrder() {
+ // Get latest values from controls
+ Integer preferredIconThemeId = (Integer) iconThemeSelectionBox.getSelectedItem();
+ ColorType preferredIconColorType = (ColorType) iconColorTypeSelectionBox.getSelectedItem();
+ IconDimension preferredIconDimension = (IconDimension) iconDimensionSelectionBox.getSelectedItem();
+ boolean dayTimePreferred = !nightTimeCheckbox.isSelected();
+
+
+ iconSetsPriorityOrder = new BasicEList<Integer>();
+
+ // Add icons: Start with specifying all properties, ..., end with all don't cares.
+ iconSetOrderAddSets(preferredIconThemeId, preferredIconColorType,
+ preferredIconDimension, dayTimePreferred);
+ iconSetOrderAddSets(preferredIconThemeId, preferredIconColorType,
+ preferredIconDimension, null);
+ iconSetOrderAddSets(preferredIconThemeId, preferredIconColorType,
+ null, null);
+ iconSetOrderAddSets(null, preferredIconColorType,
+ null, null);
+ iconSetOrderAddSets(null, null,
+ null, null);
+
+ updateIconSetPriorityOrderLabel();
+ }
+
+ private void iconSetOrderAddSets(Integer themeId, ColorType colorType,
+ IconDimension iconDimension, Boolean isDayTimeIcon) {
+ EList<IconSet> iconSetsToAdd = getIconSets(themeId, colorType, iconDimension, isDayTimeIcon);
+
+ for (IconSet iconSet: iconSetsToAdd) {
+ Integer iconSetId = iconSet.getIconSetId();
+ if (!iconSetsPriorityOrder.contains(iconSetId)) {
+ iconSetsPriorityOrder.add(iconSetId);
+ }
+ }
+ }
+
+ private EList<IconSet> getIconSets(Integer themeId, ColorType colorType,
+ IconDimension iconDimension, Boolean isDayTimeIcon) {
+ EList<IconSet> filteredIconSets = new BasicEList<IconSet>();
+
+ for (IconSet iconSet: iconSets) {
+ if (((themeId == null) || (iconSet.getThemeId() == themeId)) &&
+ ((colorType == null) || (iconSet.getColorType() == colorType)) &&
+ ((iconDimension == null) || (iconSet.getDimension() == iconDimension)) &&
+ ((isDayTimeIcon == null) || (iconSet.isDayTimeIcon() == isDayTimeIcon))) {
+ filteredIconSets.add(iconSet);
+ }
+ }
+ return filteredIconSets;
+ }
+
+ private void updateIconSetPriorityOrderLabel() {
+ StringBuilder buf = new StringBuilder();
+ boolean first = true;
+
+ for (Integer iconSetId: iconSetsPriorityOrder) {
+ if (!first) {
+ buf.append(", ");
+ } else {
+ first = false;
+ }
+ buf.append(iconSetId);
+ }
+
+ iconSetPriorityOrderLabel.setText(buf.toString());
+ }
+
+ private void readIconFromFile(int iconSetId, IconDescriptor iconDescriptor) {
+ IconInfo iconInfo = iconsetFactory.createIconInfo();
+ iconInfo.setIconSetId(iconSetId);
+ iconInfo.setIconId(iconDescriptor.getIconId());
+
+ File input = new File(iconDescriptor.getUrl());
+ try {
+ BufferedImage image = ImageIO.read(input);
+ iconImages.put(iconInfo, image);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void handleIconDefinitions(EList<IconDefinition> iconDefinitions) {
+ for (IconDefinition iconDefinition: iconDefinitions) {
+ IconData iconData = iconDefinition.getIconData();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(iconData.getData());
+ try {
+ BufferedImage image = ImageIO.read(inputStream);
+ iconImages.put(iconDefinition.getIconInfo(), image);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void setTrafficIncidentsVersion(Version trafficIncidentsVersion) {
+ this.trafficIncidentsVersion = trafficIncidentsVersion;
+ }
+
+
+ private void init() {
+ Container contentPane = getContentPane();
+
+ // create control pane on the top.
+ contentPane.add(createStatusAndControlPanel(), BorderLayout.NORTH);
+
+ // create the 3 message text panels.
+ JPanel incidentsPanel = new JPanel();
+ incidentsPanel.setLayout(new BorderLayout());
+ incidentsPanel.add(createFullTextPanel(), BorderLayout.NORTH);
+ incidentsPanel.add(createSummaryTextPanel(), BorderLayout.CENTER);
+ incidentsPanel.add(createFieldsTextPanel(), BorderLayout.SOUTH);
+ contentPane.add(incidentsPanel, BorderLayout.CENTER);
+
+ // call the update methods to get the text for 'no messages' in the panels.
+ updateFullTextPaneStep1(null);
+ updateSummaryTextPaneStep1(null);
+ updateFieldsTextPaneStep1(null);
+ }
+
+ private JPanel createStatusAndControlPanel() {
+ JPanel panel = new JPanel();
+ panel.add(createCategoriesSelectionPanel());
+
+ JPanel statusAndControlPanel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(statusAndControlPanel, BoxLayout.Y_AXIS);
+ statusAndControlPanel.setLayout(boxLayout);
+
+ statusAndControlPanel.add(createStatusPanel());
+ statusAndControlPanel.add(createIconSetSelectionPanel());
+ statusAndControlPanel.add(createUnitControlPanel());
+
+ panel.add(statusAndControlPanel);
+
+ return panel;
+ }
+
+ private JPanel createStatusPanel() {
+ JPanel panel = new JPanel();
+
+ panel.add(createHoldApplicabilityAndTrafficIncidentsStatusPanel());
+ panel.add(createFeedInfoPanel());
+
+ return panel;
+ }
+
+ private Component createHoldApplicabilityAndTrafficIncidentsStatusPanel() {
+ JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ panel.add(createHoldAndApplicabilityPanel());
+ panel.add(createTrafficIncidentsStatusPanel());
+
+ return panel;
+ }
+
+ private Component createHoldAndApplicabilityPanel() {
+ JPanel panel = new JPanel();
+
+ holdCheckBox = new JCheckBox("hold");
+ panel.add(holdCheckBox);
+
+ applicabilityCheckBox = new JCheckBox("applicability");
+ applicabilityCheckBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateApplicabilitySetting();
+ }
+
+ });
+ panel.add(applicabilityCheckBox);
+ extraTonsCheckBox = new JCheckBox("Add " + AXLE_LOAD_EXTRA + "t to " + AXLE_LOAD_NORMAL + "t");
+ extraTonsCheckBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateApplicabilitySetting();
+ }
+
+ });
+ panel.add(extraTonsCheckBox);
+
+
+
+ return panel;
+ }
+
+ protected void updateApplicabilitySetting() {
+ String expressionString;
+
+ if (applicabilityCheckBox.isSelected()) {
+ BooleanExpression applicabilityFilterExpression;
+
+ if (extraTonsCheckBox.isSelected()) {
+ applicabilityFilterExpression = createApplicabilityExpression(1000 * (AXLE_LOAD_NORMAL + AXLE_LOAD_EXTRA));
+ } else {
+ applicabilityFilterExpression = createApplicabilityExpression(1000 * AXLE_LOAD_NORMAL);
+ }
+ expressionString = applicabilityFilterExpression.toString();
+ LOGGER.info("expressionString = " + expressionString);
+ } else {
+ expressionString = "";
+ }
+
+ LOGGER.info("Filter expression: " + expressionString);
+ trafficIncidentsService.setApplicability(null, expressionString);
+ applicabilityCheckBox.setToolTipText("Test" + NEW_LINE + "ok" + NEW_LINE + "last");
+ }
+
+ private Component createUnitControlPanel() {
+ JPanel panel = new JPanel();
+
+ panel.add(createLanguageSelectionsPanel());
+ panel.add(createLengthUnitPanel());
+ panel.add(createWeightUnitPanel());
+ panel.add(createDateFormatPanel());
+ panel.add(createTimeFormatPanel());
+
+ return panel;
+ }
+
+ private Component createLengthUnitPanel() {
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("Length unit:");
+ panel.add(label);
+
+ lengthUnitSelectionBox = new JComboBox<>(LengthUnit.values());
+ Dimension lengthUnitSelectionBoxDimension = new Dimension(75, 26);
+ lengthUnitSelectionBox.setSize(lengthUnitSelectionBoxDimension);
+ lengthUnitSelectionBox.setMaximumSize(lengthUnitSelectionBoxDimension);
+ lengthUnitSelectionBox.setPreferredSize(lengthUnitSelectionBoxDimension);
+ lengthUnitSelectionBox.setSelectedIndex(-1);
+ lengthUnitSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateLengthUnit();
+ }
+
+ });
+ panel.add(lengthUnitSelectionBox);
+
+ return panel;
+ }
+
+ private void updateLengthUnit() {
+ LengthUnit lengthUnit = (LengthUnit) lengthUnitSelectionBox.getSelectedItem();
+ LOGGER.info("Setting length unit to: " + lengthUnit);
+ trafficIncidentsService.setLengthUnit(null, lengthUnit);
+ }
+
+ private Component createWeightUnitPanel() {
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("Weight unit:");
+ panel.add(label);
+
+ weightUnitSelectionBox = new JComboBox<>(WeightUnit.values());
+ Dimension weightUnitSelectionBoxDimension = new Dimension(75, 26);
+ weightUnitSelectionBox.setSize(weightUnitSelectionBoxDimension);
+ weightUnitSelectionBox.setMaximumSize(weightUnitSelectionBoxDimension);
+ weightUnitSelectionBox.setPreferredSize(weightUnitSelectionBoxDimension);
+ weightUnitSelectionBox.setSelectedIndex(-1);
+ weightUnitSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateWeightUnit();
+ }
+
+ });
+ panel.add(weightUnitSelectionBox);
+
+ return panel;
+ }
+
+ private void updateWeightUnit() {
+ WeightUnit weightUnit = (WeightUnit) weightUnitSelectionBox.getSelectedItem();
+ LOGGER.info("Setting weight unit to: " + weightUnit);
+ trafficIncidentsService.setWeightUnit(null, weightUnit);
+ }
+
+ private Component createDateFormatPanel() {
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("Date format:");
+ panel.add(label);
+
+ dateFormatTextField = new JTextField(6);
+ dateFormatTextField.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateDateFormat();
+ }
+
+ });
+ panel.add(dateFormatTextField);
+
+ return panel;
+ }
+
+ private void updateDateFormat() {
+ String dateFormat = dateFormatTextField.getText();
+ LOGGER.info("Setting date format to: " + dateFormat);
+ trafficIncidentsService.setDateFormat(null, dateFormat);
+ }
+
+ private Component createTimeFormatPanel() {
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("Time format:");
+ panel.add(label);
+
+ timeFormatTextField = new JTextField(6);
+ timeFormatTextField.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ updateTimeFormat();
+ }
+
+ });
+ panel.add(timeFormatTextField);
+
+ return panel;
+ }
+
+ private void updateTimeFormat() {
+ String timeFormat = timeFormatTextField.getText();
+ LOGGER.info("Setting time format to: " + timeFormat);
+ trafficIncidentsService.setTimeFormat(null, timeFormat);
+ }
+
+
+ private JPanel createCategoriesSelectionPanel() {
+ JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ JButton showExpressionsPanel = new JButton("Boolean Expressions");
+ showExpressionsPanel.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ showExpressionsPanel();
+ }
+
+ });
+ panel.add(showExpressionsPanel);
+
+ JLabel label = new JLabel("Categories:");
+ panel.add(label);
+
+ allCategoriesCheckBox = new JCheckBox("All categories");
+ allCategoriesCheckBox.setSelected(true);
+ allCategoriesCheckBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if (allCategoriesCheckBox.isSelected()) {
+ categoriesSelectionList.setEnabled(false);
+ } else {
+ categoriesSelectionList.setEnabled(true);
+ }
+ handleCategorySelectionChanged();
+ }
+
+ });
+ panel.add(allCategoriesCheckBox);
+
+ categoriesSelectionList = new JList<>();
+ categoriesSelectionList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ categoriesSelectionList.setVisibleRowCount(-1);
+ categoriesSelectionList.setEnabled(false);
+ categoriesSelectionList.addListSelectionListener(new ListSelectionListener() {
+
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ handleCategorySelectionChanged();
+ }
+ });
+ JScrollPane listScroller = new JScrollPane(categoriesSelectionList);
+ listScroller.setPreferredSize(new Dimension(100, 80));
+ panel.add(listScroller);
+
+ return panel;
+ }
+
+ protected void showExpressionsPanel() {
+ String[] descriptions = new String[5];
+ String[] expressions = new String[5];
+
+ descriptions[0] = "applicability 3t";
+ expressions[0] = createApplicabilityExpression(1000 * AXLE_LOAD_NORMAL).format("", " ");
+
+ descriptions[1] = "applicability 7t";
+ expressions[1] = createApplicabilityExpression(1000 * (AXLE_LOAD_NORMAL + AXLE_LOAD_EXTRA)).format("", " ");
+
+ int index = 2;
+ for (CategoryDefinition categoryDefinition: categoryDefinitionsMap.values()) {
+ descriptions[index] = categoryDefinition.getLocalizedNames(1).getString();
+ String expressionString = categoryDefinition.getExpression();
+ BooleanExpression expression = FilterExprUtil.parseFilterExpression(expressionString);
+ expressions[index] = expression.format("", " ");
+ index++;
+ }
+
+ BooleanExpressionsFrame booleanExpressionsFrame = new BooleanExpressionsFrame(descriptions, expressions);
+ booleanExpressionsFrame.setVisible(true);
+ }
+
+ protected void handleCategorySelectionChanged() {
+ LOGGER.info("=>");
+ EList<Integer> selectedCategoryIds = new BasicEList<Integer>();
+
+ if (allCategoriesCheckBox.isSelected()) {
+ // selectedCategoryIds stays empty.
+ LOGGER.info("allCategoriesCheckBox is selected, so empty category list");
+ } else {
+ int[] selectedIndices = categoriesSelectionList.getSelectedIndices();
+ for (int i = 0; i < selectedIndices.length; i++) {
+ ListCategoryDefinition listCategoryDefinition = categoriesSelectionList.getModel().getElementAt(selectedIndices[i]);
+ LOGGER.info("Adding selected category Id: " + listCategoryDefinition.getCategoryDefinition().getCategoryId());
+ selectedCategoryIds.add(listCategoryDefinition.getCategoryDefinition().getCategoryId());
+ }
+ }
+
+ if (!selectedCategoryIds.equals(currentCategoryIds)) {
+ currentCategoryIds = selectedCategoryIds;
+ LOGGER.info("Going to remove updateListener: " + updateListener);
+ trafficIncidentsService.removeUpdateListener(primaryUpdateListener, updateListener);
+ }
+
+ LOGGER.info("<=");
+ }
+
+ private JPanel createLanguageSelectionsPanel() {
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("UI Language:");
+ panel.add(label);
+
+ languageSelectionBox = new JComboBox<>(SUPPORTED_LANGUAGES);
+ languageSelectionBox.setSelectedIndex(-1);
+ languageSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ LOGGER.info("languageSelectionBox: actionPerformed");
+ String selectedLanguage = (String) languageSelectionBox.getSelectedItem();
+ LOGGER.info("languageSelectionBox: actionPerformed, currentLanguage = " + currentLanguage + ", selectedLanguage = " + selectedLanguage);
+
+ if (!selectedLanguage.equals(currentLanguage)) {
+ currentLanguage = selectedLanguage;
+ LOGGER.info("Calling setLanguage()");
+ trafficIncidentsService.setLanguage(null, currentLanguage, currentLanguageCountry);
+ } else {
+ LOGGER.info("Same language selected, no action");
+ }
+
+ }
+
+ });
+ panel.add(languageSelectionBox);
+
+ languageCountrySelectionBox = new JComboBox<>(SUPPORTED_COUNTRIES);
+ languageCountrySelectionBox.setSelectedIndex(-1);
+ languageCountrySelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ LOGGER.info("languageCountrySelectionBox: actionPerformed");
+ String selectedLanguageCountry = (String) languageCountrySelectionBox.getSelectedItem();
+ if (selectedLanguageCountry.equals(NO_COUNTRY)) {
+ selectedLanguageCountry = null;
+ }
+ LOGGER.info("languageCountrySelectionBox: actionPerformed, currentLanguageCountry = " + currentLanguageCountry + ", selectedLanguageCountry = " + selectedLanguageCountry);
+
+ if (!isRequestedLanguageCountry(selectedLanguageCountry)) {
+ currentLanguageCountry = selectedLanguageCountry;
+ LOGGER.info("Calling setLanguage()");
+ trafficIncidentsService.setLanguage(null, currentLanguage, currentLanguageCountry);
+ } else {
+ LOGGER.info("Same country selected, no action");
+ }
+
+ }
+
+ });
+ panel.add(languageCountrySelectionBox);
+
+ return panel;
+ }
+
+ private JPanel createIconSetSelectionPanel() {
+ // Theme
+ JPanel panel = new JPanel();
+
+ JLabel label = new JLabel("Theme:");
+ panel.add(label);
+
+ iconThemeSelectionBox = new JComboBox<>();
+ iconThemeSelectionBox.setSelectedIndex(-1);
+ iconThemeSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ determineIconSetsOrder();
+ }
+
+ });
+ panel.add(iconThemeSelectionBox);
+
+ // Color type
+ label = new JLabel("Color type:");
+ panel.add(label);
+
+ iconColorTypeSelectionBox = new JComboBox<>();
+ iconColorTypeSelectionBox.setSelectedIndex(-1);
+ iconColorTypeSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ determineIconSetsOrder();
+ }
+
+ });
+ panel.add(iconColorTypeSelectionBox);
+
+
+ // Icon dimension
+ label = new JLabel("Dimension:");
+ panel.add(label);
+
+ iconDimensionSelectionBox = new JComboBox<>();
+ iconDimensionSelectionBox.setSelectedIndex(-1);
+ iconDimensionSelectionBox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ determineIconSetsOrder();
+ }
+
+ });
+ panel.add(iconDimensionSelectionBox);
+
+ // Night time
+ nightTimeCheckbox = new JCheckBox("Night time");
+ nightTimeCheckbox.addActionListener(new ActionListener(){
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ determineIconSetsOrder();
+ }
+
+ });
+ panel.add(nightTimeCheckbox);
+
+
+ // Calculated priority order
+ label = new JLabel("IconSet priority order:");
+ panel.add(label);
+
+ iconSetPriorityOrderLabel = new JLabel("No icon sets available");
+ panel.add(iconSetPriorityOrderLabel);
+
+ return panel;
+ }
+
+ private JPanel createTrafficIncidentsStatusPanel() {
+ statusPanel = new JPanel();
+
+ GridLayout layout = new GridLayout(2, 2);
+ statusPanel.setLayout(layout);
+ statusPanel.setForeground(Color.ORANGE);
+
+ JLabel label;
+
+ label = new JLabel("Feed status: ");
+ statusPanel.add(label);
+
+ trafficIncidentFeedStatusLabel = new JLabel("INIT");
+ statusPanel.add(trafficIncidentFeedStatusLabel);
+
+ label = new JLabel("Traffic Incidents status: ");
+ statusPanel.add(label);
+
+ trafficIncidentsStatusLabel = new JLabel("init");
+ statusPanel.add(trafficIncidentsStatusLabel);
+
+ return statusPanel;
+ }
+
+ private JPanel createFeedInfoPanel() {
+ JPanel feedInfoTablePanel = new JPanel();
+ feedInfoTableModel = new DefaultTableModel(UNKOWN_FEED_INFO, FEED_INFO_TABLE_COLUMN_NAMES);
+ JTable table = new JTable(feedInfoTableModel);
+ table.setPreferredScrollableViewportSize(new Dimension(600, 40));
+ table.setFillsViewportHeight(true);
+
+ //Create the scroll pane and add the table to it.
+ JScrollPane scrollPane = new JScrollPane(table);
+
+ //Add the scroll pane to this panel.
+ feedInfoTablePanel.add(scrollPane);
+
+ return feedInfoTablePanel;
+ }
+
+ /**
+ * Create a panel for the Full message texts.
+ */
+ private JPanel createFullTextPanel() {
+ JPanel panel = new JPanel();
+
+ panel.setBorder(BorderFactory.createTitledBorder("Full text"));
+
+ fullTextArea = new JTextArea(8, 100);
+ fullTextArea.setLineWrap(true);
+ fullTextArea.setEditable(false);
+ JScrollPane scrollPane = new JScrollPane(fullTextArea);
+ panel.add(scrollPane, BorderLayout.CENTER);
+
+ return panel;
+ }
+
+ /**
+ * Create a panel for the Summary messages texts.
+ */
+ private JPanel createSummaryTextPanel() {
+ JPanel panel = new JPanel();
+
+ panel.setBorder(BorderFactory.createTitledBorder("Summary text"));
+
+ summaryTextArea = new JTextArea(6, 100);
+ summaryTextArea.setLineWrap(true);
+ summaryTextArea.setEditable(false);
+ JScrollPane scrollPane = new JScrollPane(summaryTextArea);
+ panel.add(scrollPane, BorderLayout.CENTER);
+
+ return panel;
+ }
+
+ /**
+ * Create a panel for the texts created from the fields in a
+ * Traffic Incident.
+ */
+ private JPanel createFieldsTextPanel() {
+ fieldsTextPanel = new JPanel();
+ fieldsTextPanel.setBorder(BorderFactory.createTitledBorder("Fields text"));
+ return fieldsTextPanel;
+ }
+
+ /**
+ * First step in updating the Full text panel:
+ * - display a default text if there are no incidents
+ * - otherwise send a request for the texts, with fullTextListener as listener.
+ */
+ private void updateFullTextPaneStep1(EList<Integer> incidentIds) {
+ LOGGER.info("=>");
+ if (incidentIds == null || incidentIds.size() == 0) {
+ LOGGER.info("<= No Traffic Incidents.");
+ if (holdCheckBox.isSelected()) {
+ return;
+ }
+
+ fullTextArea.setText("Nothing to report");
+ return;
+ }
+
+ trafficIncidentsService.getTexts(fullTextListener, incidentIds, TextDetailLevel.FULL);
+ LOGGER.info("<= Traffic Incidents.");
+ }
+
+ /**
+ * Second step in updating the Full text panel:
+ * - display the received texts.
+ */
+ private void updateFullTextPaneStep2(EList<String> texts) {
+ if (holdCheckBox.isSelected()) {
+ return;
+ }
+
+ StringBuilder buf = new StringBuilder();
+
+ boolean first = true;
+ for (String text: texts) {
+ if (!first) {
+ buf.append(NEW_LINE);
+ buf.append(NEW_LINE);
+ } else {
+ first = false;
+ }
+ buf.append(text);
+ }
+
+ fullTextArea.setText(buf.toString());
+
+ this.repaint();
+ }
+
+
+ /**
+ * First step in updating the Summary text panel:
+ * - display a default text if there are no incidents
+ * - otherwise send a request for the texts, with summaryTextListener as listener.
+ */
+ private void updateSummaryTextPaneStep1(EList<Integer> incidentIds) {
+ if (incidentIds == null || incidentIds.size() == 0) {
+ if (holdCheckBox.isSelected()) {
+ return;
+ }
+
+ summaryTextArea.setText("Nothing to report");
+ return;
+ }
+
+ trafficIncidentsService.getTexts(summaryTextListener, incidentIds, TextDetailLevel.SUMMARY);
+ }
+
+
+ /**
+ * Second step in updating the Summary text panel:
+ * - display the received texts.
+ */
+ private void updateSummaryTextPaneStep2(EList<String> texts) {
+ if (holdCheckBox.isSelected()) {
+ return;
+ }
+
+ StringBuilder buf = new StringBuilder();
+
+ boolean first = true;
+ for (String text: texts) {
+ if (!first) {
+ buf.append(NEW_LINE);
+ buf.append(NEW_LINE);
+ } else {
+ first = false;
+ }
+ buf.append(text);
+ }
+
+ summaryTextArea.setText(buf.toString());
+
+ repaint();
+ }
+
+
+ /**
+ * First step in updating the Fields text panel:
+ * - display a default text if there are no incidents
+ * - otherwise send a request for the Traffic Incidents, with fieldsListener as listener.
+ */
+ private void updateFieldsTextPaneStep1(EList<Integer> incidentIds) {
+ if ((incidentIds == null) || (incidentIds.size() == 0)) {
+ updateFieldsTextPaneStep2(null);
+ return;
+ }
+
+ trafficIncidentsService.getTrafficIncidents(fieldsListener, incidentIds, true);
+ }
+
+
+ /**
+ * Second step in updating the Summary text panel:
+ * - display the information per field for each incident.
+ */
+ private void updateFieldsTextPaneStep2(EList<TrafficIncident> incidents) {
+ if (holdCheckBox.isSelected()) {
+ return;
+ }
+
+ fieldsTextPanel.removeAll();
+
+ JPanel incidentsPanel = new JPanel();
+
+ if (incidents != null) {
+ LOGGER.info("incidents list in not null, number of incidents = " + incidents.size());
+ BoxLayout boxLayout = new BoxLayout(incidentsPanel, BoxLayout.Y_AXIS);
+ incidentsPanel.setLayout(boxLayout);
+ for (TrafficIncident incident: incidents) {
+ incidentsPanel.add(createIncidentPanel(incident));
+ }
+ } else {
+ incidentsPanel.add(new JLabel("Nothing to report"));
+ }
+ JScrollPane scrollPane = new JScrollPane(incidentsPanel);
+ Dimension dimension = new Dimension(1000, 400);
+ scrollPane.setPreferredSize(dimension);
+ fieldsTextPanel.add(scrollPane);
+
+ fieldsTextPanel.revalidate();
+ fieldsTextPanel.repaint();
+ }
+
+ private JPanel createIncidentPanel(TrafficIncident incident) {
+ LOGGER.info("Creating panel for incident with Id: " + incident.getTrafficIncidentId());
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
+
+ panel.add(createTextFieldsPanel(incident), BorderLayout.CENTER);
+ EList<Integer> categoryIds;
+ categoryIds = incident.getCategoryIds();
+ panel.add(createCategoriesPanel(categoryIds), BorderLayout.WEST);
+
+ return panel;
+ }
+
+ private Component createTextFieldsPanel(TrafficIncident incident) {
+ StringBuilder buf = new StringBuilder();
+ generateFieldsText(buf, incident);
+ JTextArea textArea = new JTextArea(buf.toString());
+ textArea.setEditable(false);
+
+ return textArea;
+ }
+
+ private Component createCategoriesPanel(EList<Integer> categoryIds) {
+ JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ if (categoryIds.size() != 0) {
+ for (int categoryId: categoryIds) {
+ panel.add(createCategoryPanel(categoryId));
+ }
+ } else {
+ panel.add(createCategoryPanel(-1));
+ }
+
+ return panel;
+ }
+
+ private Component createCategoryPanel(int categoryId) {
+ JPanel panel = new JPanel();
+ Dimension dimension = new Dimension(200, 50);
+ panel.setMaximumSize(dimension);
+ panel.setPreferredSize(dimension);
+
+ panel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
+
+ panel.setLayout(new BorderLayout());
+
+ if (categoryId != -1) {
+ CategoryDefinition categoryDefinition = categoryDefinitionsMap.get(categoryId);
+
+ // Add icon as CENTER
+ // Create a map with icons related to the category, the set we have to chose from.
+ Map<Integer, IconInfo> categoryIcons = new HashMap<Integer, IconInfo>();
+ for (IconInfo iconInfo: categoryDefinition.getIcons()) {
+ LOGGER.fine("Adding iconInfo to categoryIcons: iconSetId = " + iconInfo.getIconSetId() + ", iconId = " + iconInfo.getIconId());
+ categoryIcons.put(iconInfo.getIconSetId(), iconInfo);
+ }
+
+ // In priority order, check which one is available for the category.
+ IconInfo iconInfo = null;
+ for (Integer iconSetId: iconSetsPriorityOrder) {
+ LOGGER.fine("Looking for iconSetId: " + iconSetId);
+ if (categoryIcons.containsKey(iconSetId)) {
+ LOGGER.fine("Found it!");
+ iconInfo = categoryIcons.get(iconSetId);
+ break;
+ }
+ }
+ if (iconInfo != null) {
+ LOGGER.info("iconInfo: iconSetId = " + iconInfo.getIconSetId() + ", iconId = " + iconInfo.getIconId());
+ } else {
+ LOGGER.info("iconInfo: iconSetId = null!");
+ }
+ BufferedImage image = iconImages.get(iconInfo);
+ panel.add(new ImagePanel(image), BorderLayout.CENTER);
+
+ // Add category name as SOUTH
+ // First search for language and country, then for language, then take first name
+ String categoryName = null;
+ for (LocalizedString localizedString: categoryDefinition.getLocalizedNames()) {
+ if (isRequestedLocale(localizedString.getLanguageCode(), localizedString.getCountryCode())) {
+ categoryName = localizedString.getString();
+ LOGGER.info("Category name found for current language and country");
+ break;
+ }
+ }
+ if (categoryName == null) {
+ for (LocalizedString localizedString: categoryDefinition.getLocalizedNames()) {
+ if (isRequestedLanguage(localizedString.getLanguageCode())) {
+ categoryName = localizedString.getString();
+ LOGGER.info("Category name found for current language");
+ break;
+ }
+ }
+ }
+ if (categoryName == null) {
+ categoryName = categoryDefinition.getLocalizedNames(0).getString();
+ }
+ panel.add(new JLabel(categoryName), BorderLayout.SOUTH);
+ } else {
+ panel.add(new JLabel("No category"), BorderLayout.SOUTH);
+ }
+
+ return panel;
+ }
+
+ private boolean isRequestedLocale(String languageCode, String countryCode) {
+ return isRequestedLanguage(languageCode) && isRequestedLanguageCountry(countryCode);
+ }
+
+ private boolean isRequestedLanguage(String languageCode) {
+ boolean returnValue = ((languageCode == null && currentLanguage == null) ||
+ ((languageCode != null) && (currentLanguage != null) &&
+ languageCode.equals(currentLanguage)));
+ LOGGER.info("<=" + returnValue);
+ return returnValue;
+ }
+
+ private boolean isRequestedLanguageCountry(String languageCountryCode) {
+ boolean returnValue = ((languageCountryCode == null && currentLanguageCountry == null) ||
+ ((languageCountryCode != null) && (currentLanguageCountry != null) &&
+ languageCountryCode.equals(currentLanguageCountry)));
+ LOGGER.info("<=" + returnValue);
+ return returnValue;
+ }
+
+ /**
+ * Generate text field information for a single incident.
+ */
+ private void generateFieldsText(StringBuilder buf, TrafficIncident trafficIncident) {
+ LOGGER.info("Creating Fields Text for incident with Id: " + trafficIncident.getTrafficIncidentId());
+
+ buf.append("General Information");
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tEffect: ");
+ String effect = trafficIncident.getEffectText();
+ if (effect != null) {
+ buf.append(effect);
+ } else {
+ buf.append("---");
+ }
+ buf.append(" (effectCode = ");
+ if (trafficIncident.isSetEffectCode()) {
+ buf.append(trafficIncident.getEffectCode());
+ buf.append(" = ");
+ buf.append(trafficIncident.getEffectCode().getValue());
+ } else {
+ buf.append("---");
+ }
+ buf.append(")");
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tValidity Period: ");
+ if (trafficIncident.isSetStartTime()) {
+ buf.append(" from ");
+ buf.append(DF.format(trafficIncident.getStartTime()));
+ }
+ if (trafficIncident.isSetStopTime()) {
+ buf.append(" till ");
+ buf.append(DF.format(trafficIncident.getStopTime()));
+ }
+ buf.append(NEW_LINE);
+
+ buf.append("\tTendency: ");
+ String tendency = trafficIncident.getTendencyText();
+ if (tendency != null) {
+ buf.append(tendency);
+ } else {
+ buf.append("---");
+ }
+ buf.append(" (tendency = ");
+ if (trafficIncident.isSetTendency()) {
+ buf.append(trafficIncident.getTendency());
+ buf.append(" = ");
+ buf.append(trafficIncident.getTendency().getValue());
+ } else {
+ buf.append("---");
+ }
+ buf.append(")");
+ buf.append(NEW_LINE);
+
+ buf.append("\tLength Affected: ");
+ if (trafficIncident.isSetLengthAffected()) {
+ buf.append(String.valueOf(trafficIncident.getLengthAffected()));
+ buf.append(" meters");
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tAverage Speed: ");
+ if (trafficIncident.isSetAverageSpeedAbsolute()) {
+ buf.append(String.valueOf(trafficIncident.getAverageSpeedAbsolute()));
+ buf.append(" m/s");
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tDelay: ");
+ if (trafficIncident.isSetDelay()) {
+ buf.append(String.valueOf(trafficIncident.getDelay()));
+ buf.append(" minutes");
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tSpeed Limit: ");
+ if (trafficIncident.isSetSegmentSpeedLimit()) {
+ buf.append(String.valueOf(trafficIncident.getSegmentSpeedLimit()));
+ buf.append(" m/s");
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("\tExpected Speed: ");
+ if (trafficIncident.isSetExpectedSpeedAbsolute()) {
+ buf.append(String.valueOf(trafficIncident.getExpectedSpeedAbsolute()));
+ buf.append(" m/s");
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("Location: ");
+ if (trafficIncident.isSetLocation()) {
+ Location location = trafficIncident.getLocation();
+ if (location instanceof PointLocation) {
+ buf.append("point location");
+ } else if (location instanceof LinearLocation) {
+ buf.append("linear location");
+ LinearLocation linearLocation = (LinearLocation) location;
+ buf.append(", positive offet = ");
+ buf.append(linearLocation.getPositiveOffset());
+ buf.append(", negative offset = ");
+ buf.append(linearLocation.getNegativeOffset());
+ buf.append(", segments");
+ for (Long segment: linearLocation.getSegments()) {
+ buf.append(": ");
+ buf.append(segment);
+ }
+ } else if (location instanceof AreaLocation) {
+ buf.append("area location");
+ }
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("Location Info: ");
+ if (trafficIncident.isSetLocationInfo()) {
+ LocationInfo locationInfo = trafficIncident.getLocationInfo();
+ if (locationInfo instanceof PointLocationInfo) {
+ buf.append("(point location) ");
+ buf.append(locationInfo.getName());
+ } else if (locationInfo instanceof LinearLocationInfo) {
+ LinearLocationInfo linearLocationInfo = (LinearLocationInfo) locationInfo;
+ buf.append("(linear location) ");
+ buf.append(linearLocationInfo.getName());
+ buf.append(": ");
+ if (linearLocationInfo.getFromLocationParentName() != null &&
+ linearLocationInfo.getToLocationParentName() != null) {
+ buf.append(linearLocationInfo.getFromLocationParentName());
+ buf.append(" => ");
+ buf.append(linearLocationInfo.getToLocationParentName());
+ buf.append(" ");
+ }
+ buf.append("section: ");
+ buf.append(linearLocationInfo.getFromLocationName());
+ buf.append(" - ");
+ buf.append(linearLocationInfo.getToLocationName());
+ } else if (locationInfo instanceof AreaLocationInfo) {
+ buf.append("(area location) ");
+ buf.append(locationInfo.getName());
+ }
+ } else {
+ buf.append("---");
+ }
+
+ buf.append(NEW_LINE);
+
+ buf.append("Cause texts");
+ buf.append(NEW_LINE);
+
+ List<String> causes = trafficIncident.getCauseTexts();
+ for (String cause: causes) {
+ buf.append("\tCause: ");
+ buf.append(cause);
+ buf.append(NEW_LINE);
+ }
+
+ buf.append("Cause model data");
+ buf.append(NEW_LINE);
+ for (Cause cause: trafficIncident.getCauses()) {
+ buf.append("mainCause = " + cause.getMainCause() + " = " + cause.getMainCause().getValue());
+ if (cause instanceof DirectCause) {
+ buf.append(", direct cause, ");
+ DirectCause directCause = (DirectCause) cause;
+ buf.append(", warning level = " + directCause.getWarningLevel() + " = " + directCause.getWarningLevel().getValue());
+ if (directCause.isUnverifiedInformation()) {
+ buf.append(", unverified information");
+ } else {
+ buf.append(", verified information");
+ }
+ buf.append(", sub cause = ");
+ if (directCause.isSetSubCause()) {
+ buf.append(directCause.getSubCause());
+ } else {
+ buf.append("---");
+ }
+ buf.append(", length affected = ");
+ if (directCause.isSetLengthAffected()) {
+ buf.append(directCause.getLengthAffected());
+ } else {
+ buf.append("---");
+ }
+ buf.append(", lane restrictions: ");
+ if (directCause.isSetLaneRestrictions()) {
+ LaneRestrictions laneRestrictions = directCause.getLaneRestrictions();
+ buf.append("type = " + laneRestrictions.getLaneRestrictionType() + " = " + laneRestrictions.getLaneRestrictionType().getValue());
+ buf.append("; number of lanes = " + laneRestrictions.getNumberOfLanes());
+ } else {
+ buf.append("---");
+ }
+ buf.append(", free text = " );
+ if (directCause.isSetFreeText()) {
+ buf.append(directCause.getFreeText());
+ } else {
+ buf.append("---");
+ }
+ } else if (cause instanceof LinkedCause) {
+ buf.append(", linked cause, ");
+ LinkedCause linkedCause = (LinkedCause) cause;
+ buf.append(" trafficIncidentId = ");
+ buf.append(linkedCause.getCauseTrafficIncidentId());
+ }
+ buf.append(NEW_LINE);
+ }
+
+ buf.append("Advices");
+ buf.append(NEW_LINE);
+
+ buf.append("Advice model data");
+ buf.append(NEW_LINE);
+ for (Advice advice: trafficIncident.getAdvices()) {
+ buf.append("mainAdvice = " + advice.getMainAdvice() + " = " + advice.getMainAdvice().getValue());
+ buf.append(", sub advice = ");
+ if (advice.isSetSubAdvice()) {
+ buf.append(advice.getSubAdvice());
+ } else {
+ buf.append("---");
+ }
+ buf.append(", free text = " );
+ if (advice.isSetFreeText()) {
+ buf.append(advice.getFreeText());
+ } else {
+ buf.append(" ---");
+ }
+ buf.append(", applicability =" );
+ if (advice.isSetApplicability()) {
+ bufAppendApplicability(buf, advice.getApplicability());
+ } else {
+ buf.append(" ---");
+ }
+ buf.append(NEW_LINE);
+ }
+
+
+ List<String> advices = trafficIncident.getAdviceTexts();
+ for (String advice: advices) {
+ buf.append("\tAdvice: ");
+ buf.append(advice);
+ buf.append(NEW_LINE);
+ }
+
+
+ buf.append("Applicability");
+ buf.append(NEW_LINE);
+
+ List<String> applicabilityList = trafficIncident.getApplicabilityTexts();
+ for (String applicability: applicabilityList) {
+ buf.append("\tApplicability: ");
+ buf.append(applicability);
+ buf.append(NEW_LINE);
+ }
+
+ buf.append("Applicability from data model");
+ if (trafficIncident.isSetApplicability()) {
+ bufAppendApplicability(buf, trafficIncident.getApplicability());
+ } else {
+ buf.append(" ---");
+ }
+ buf.append(NEW_LINE);
+ }
+
+ private void bufAppendApplicability(StringBuilder buf, List<Applicability> applicabilities) {
+ for (Applicability applicability: applicabilities) {
+ buf.append(" vehicle type = ");
+ buf.append(applicability.getVehicleType());
+ buf.append(" = ");
+ buf.append(applicability.getVehicleType().getValue());
+
+ buf.append("; vehicle related restrictions: ");
+ if (applicability.isSetVehicleRelatedRestrictions()) {
+ bufAppendVehicleRelatedRestrictions(buf, applicability.getVehicleRelatedRestrictions());
+ } else {
+ buf.append("---");
+ }
+ }
+ }
+
+ private void bufAppendVehicleRelatedRestrictions(StringBuilder buf, List<VehicleRelatedRestriction> vehicleRelatedRestrictions) {
+ for (VehicleRelatedRestriction restriction: vehicleRelatedRestrictions) {
+ buf.append("restriction type = ");
+ buf.append(restriction.getRestrictionType());
+ buf.append(" = ");
+ buf.append(restriction.getRestrictionType().getValue());
+ buf.append("; restriction type = ");
+ buf.append(restriction.getRestrictionValue());
+ }
+
+ }
+
+ /**
+ * Update the title of the Frame.
+ */
+ private void updateTitle() {
+ // Create and display title, using the version received from trafficIncidentsService.
+ StringBuilder title = new StringBuilder();
+ title.append(TITLE_BODY);
+
+ if (trafficIncidentsVersion != null) {
+ title.append(String.valueOf(trafficIncidentsVersion.getMajor()));
+ title.append(".");
+ title.append(String.valueOf(trafficIncidentsVersion.getMinor()));
+ title.append(".");
+ title.append(String.valueOf(trafficIncidentsVersion.getMicro()));
+ title.append(" ");
+ title.append(trafficIncidentsVersion.getDate());
+ } else {
+ title.append("<no version info available>");
+ }
+
+ title.append(", last updated: ");
+ if (lastUpdateDate != null) {
+ title.append(DF.format(lastUpdateDate));
+ } else {
+ title.append("<nothing received yet>");
+ }
+ title.append(")");
+ setTitle(title.toString());
+ }
+
+ private void updateSelectedLanguage(String languageCode, String languageCountryCode) {
+ currentLanguage = languageCode;
+ currentLanguageCountry = languageCountryCode;
+
+ String selectedLanguage = (String) languageSelectionBox.getSelectedItem();
+ if (selectedLanguage != null) {
+ if (!selectedLanguage.equals(currentLanguage)) {
+ languageSelectionBox.setSelectedItem(currentLanguage);
+ }
+ } else {
+ languageSelectionBox.setSelectedItem(currentLanguage);
+ }
+
+ String selectedLanguageCountry = (String) languageCountrySelectionBox.getSelectedItem();
+ if (selectedLanguageCountry != null) {
+ if (!selectedLanguageCountry.equals(currentLanguageCountry)) {
+ if (currentLanguageCountry != null) {
+ languageCountrySelectionBox.setSelectedItem(currentLanguageCountry);
+ } else {
+ languageCountrySelectionBox.setSelectedItem(NO_COUNTRY);
+ }
+ }
+ } else {
+ if (currentLanguageCountry != null) {
+ languageCountrySelectionBox.setSelectedItem(currentLanguageCountry);
+ } else {
+ languageCountrySelectionBox.setSelectedItem(NO_COUNTRY);
+ }
+ }
+ }
+
+ private void updateStatusInfo(TrafficIncidentFeedStatus trafficIncidentFeedStatus, TrafficIncidentsStatus trafficIncidentsStatus) {
+ trafficIncidentFeedStatusLabel.setText(trafficIncidentFeedStatus.getName());
+ trafficIncidentsStatusLabel.setText(trafficIncidentsStatus.getName());
+
+ Color backgroundColor = null;
+ if (trafficIncidentFeedStatus == TrafficIncidentFeedStatus.UNAVAILABLE) {
+ backgroundColor = Color.LIGHT_GRAY;
+ } else {
+ switch (trafficIncidentsStatus) {
+ case AVAILABLE:
+ backgroundColor = Color.GREEN;
+ break;
+
+ case PARTLY_AVAILABLE:
+ backgroundColor = Color.ORANGE;
+ break;
+
+ case UNAVAILABLE:
+ backgroundColor = Color.RED;
+ break;
+ }
+ }
+ statusPanel.setBackground(backgroundColor);
+ }
+
+ protected void updateFeedInfo(EList<FeedInformation> feedsInformation) {
+ feedInfoTableModel.setRowCount(feedsInformation.size());
+ int row = 0;
+ for (FeedInformation feedInformation: feedsInformation) {
+ if (feedInformation.getDataProviderName() != null) {
+ feedInfoTableModel.setValueAt(feedInformation.getDataProviderName(), row, 0);
+ } else {
+ feedInfoTableModel.setValueAt("-", row, 0);
+ }
+ if (feedInformation.getProtocolName() != null) {
+ feedInfoTableModel.setValueAt(feedInformation.getProtocolName(), row, 1);
+ } else {
+ feedInfoTableModel.setValueAt("-", row, 1);
+ }
+ if (feedInformation.getCommunicationChannelName() != null) {
+ feedInfoTableModel.setValueAt(feedInformation.getCommunicationChannelName(), row, 2);
+ } else {
+ feedInfoTableModel.setValueAt("-", row, 2);
+ }
+ if (feedInformation.getFeedStatus() != null) {
+ feedInfoTableModel.setValueAt(feedInformation.getFeedStatus().getName(), row, 3);
+ } else {
+ feedInfoTableModel.setValueAt("-", row, 3);
+ }
+ if (feedInformation.getTrafficIncidentsStatus() != null) {
+ feedInfoTableModel.setValueAt(feedInformation.getTrafficIncidentsStatus().getName(), row, 4);
+ } else {
+ feedInfoTableModel.setValueAt("-", row, 4);
+ }
+ row++;
+ }
+ }
+
+ /**
+ * When does the statement isApplicable() evaluate to true?
+ *
+ * If there is no Applicability, it is applicable to all cars.
+ * If there is one Applicability, it is applicable to cars matching the Applicability.
+ * If there is more than one Applicability this should be interpreted as:
+ * - for cars matching Applicability-1
+ * - and for cars matching Applicability-2
+ * - and ....
+ * - and for cars matching Applicability-n.
+ *
+ * In a logical expression this is:
+ * - there is no Applicability
+ * - OR
+ * - vehicle parameters match Applicability-1
+ * - OR vehicle parameters match Applicability-2
+ * - OR ..
+ * - OR vehicle parameters match Applicability-n.
+ *
+ * Or isApplicable() is true if:
+ * - there is no Applicability
+ * - OR ANY Applicability matches the vehicle parameters
+ *
+ * An Applicability matches the vehicle parameters:
+ * - if Applicability contains a vehicleType AND
+ * vehicleType matches the carVehicleType
+ * - AND the VehicleRelatedRestrictions match
+ *
+ * VehicleRelatedRestrictions match if:
+ * - if there are no VehicleRelatedRestrictions
+ * - OR each VehicleRelatedRestriction matches the related car parameter
+ *
+ * How to handle unknown car parameters?
+ * E.g. what if the car type or weight is unknown.
+ * In this case the application has to chose between:
+ * - false positives
+ * Incidents which aren't applicable are treated as applicable.
+ * This is achieved by defining the test related to an unknown parameter to always be true.
+ * - false negatives
+ * Incidents which are applicable aren't treated as applicable.
+ * This is achieved by defining the test related to an unknown parameter to always be false.
+ * It is advised to go for false positives.
+ *
+ * This description shows that it will be simpler to define the isNotApplicable expression (so the expression for the incidents
+ * to be filtered out).
+ *
+ * When does the statement isNotApplicable() evaluate to true?
+ *
+ * isNotApplicable() is true if:
+ * - there is at least one Applicability
+ * - AND all Applicabilities don't match the vehicle parameters.
+ *
+ * An Applicability doesn't match the vehicle parameters:
+ * - if Applicability contains a vehicleType AND
+ * vehicleType doesn't match the carVehicleType
+ * - OR the VehicleRelatedRestrictions don't match
+ *
+ * VehicleRelatedRestrictions don't match if:
+ * - any VehicleRelatedRestriction doesn't match the related car parameter
+ *
+ * Using false positives this changes to:
+ *
+ * An Applicability doesn't match the vehicle parameters:
+ * - if carVehicleType is known AND
+ * Applicability contains a vehicleType AND
+ * vehicleType doesn't match the carVehicleType
+ * - OR the VehicleRelatedRestrictions don't match
+ *
+ * VehicleRelatedRestrictions don't match if:
+ * - any VehicleRelatedRestriction related to a known car parameter doesn't match this parameter
+ *
+ *
+ * This method creates an ApplicabilityExpression for:
+ * - Vehicle type: LORRY
+ * - AXLE_LOAD: 7000 kg (7 tonnes)
+ * - False positives for all other parameters.
+ *
+ * ApplicabilityExpression := applicabilitySpecified AND ALL ApplicabilityDoesntMatchTheVehicleParameters
+ * ApplicabilityExpression := ALL ApplicabilityDoesntMatchTheVehicleParameters
+ * ApplicabilityDoesntMatchTheVehicleParameters := VehicleTypeDoesntMatch OR VehicleRelatedRestrictionsDontMatch
+ * VehicleTypeDoesntMatch := vehicleTypeIsSet AND vehicleType != LORRY
+ * VehicleRelatedRestrictionsDontMatch := ANY VehicleRelatedRestrictionDoesntMatch
+ * VehicleRelatedRestrictionDoesntMatch := AxleLoadNotLessThan7t OR AxleLoadNotGreaterThan7t
+ * AxleLoadNotLessThan7t := restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000
+ * AxleLoadNotGreaterThan7t := restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000
+ * @param axleLoad
+ *
+ * @return
+ */
+ private BooleanExpression createApplicabilityExpression(long axleLoad) {
+ ClassAttribute restrictionType;
+
+ // AxleLoadGreaterThan7t := restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000
+ // Comparison Predicate: restrictionType == AXLE_LOAD_GREATER_THAN
+ ComparisonPredicate restrictionTypeIsAxleLoadGreaterThan = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ restrictionType = FILTER_EXPR_FACTORY.createClassAttribute();
+ restrictionType.setAttributeName(tip.getVehicleRelatedRestriction_RestrictionType().getName());
+ restrictionTypeIsAxleLoadGreaterThan.setAttribute(restrictionType);
+ restrictionTypeIsAxleLoadGreaterThan.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral restrictionTypeGreaterThanEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ restrictionTypeGreaterThanEnumValue.setValue(RestrictionType.AXLE_LOAD_GREATER_THAN.getValue());
+ restrictionTypeIsAxleLoadGreaterThan.setLiteral(restrictionTypeGreaterThanEnumValue);
+
+ // Comparison Predicate: restrictionValue > 7000
+ ComparisonPredicate restrictionValueGreaterThan7t = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ ClassAttribute restrictionValue = FILTER_EXPR_FACTORY.createClassAttribute();
+ restrictionValue.setAttributeName(tip.getVehicleRelatedRestriction_RestrictionValue().getName());
+ restrictionValueGreaterThan7t.setAttribute(restrictionValue);
+ restrictionValueGreaterThan7t.setComparisonOperator(ComparisonOperator.GREATER_THEN);
+ SignedIntegerLiteral literal7t = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ literal7t.setValue(axleLoad);
+ restrictionValueGreaterThan7t.setLiteral(literal7t);
+
+ // Dyadic Expression: restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000
+ DyadicExpression axleLoadGreaterThan7t = FILTER_EXPR_FACTORY.createDyadicExpression();
+ axleLoadGreaterThan7t.setLeftHandTerm(restrictionTypeIsAxleLoadGreaterThan);
+ axleLoadGreaterThan7t.setLogicalOperator(DyadicLogicalOperator.AND);
+ axleLoadGreaterThan7t.setRightHandTerm(restrictionValueGreaterThan7t);
+
+
+ // AxleLoadNotLessThan7t := restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000
+ // Comparison Predicate: restrictionType == AXLE_LOAD_LESS_THAN
+ ComparisonPredicate restrictionTypeIsAxleLoadLessThan = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ restrictionType = FILTER_EXPR_FACTORY.createClassAttribute();
+ restrictionType.setAttributeName(tip.getVehicleRelatedRestriction_RestrictionType().getName());
+ restrictionTypeIsAxleLoadLessThan.setAttribute(restrictionType);
+ restrictionTypeIsAxleLoadLessThan.setComparisonOperator(ComparisonOperator.EQUAL);
+ SignedIntegerLiteral restrictionTypeEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ restrictionTypeEnumValue.setValue(RestrictionType.AXLE_LOAD_LESS_THAN.getValue());
+ restrictionTypeIsAxleLoadLessThan.setLiteral(restrictionTypeEnumValue);
+
+ // Comparison Predicate: restrictionValue < 7000
+ ComparisonPredicate restrictionValueLessThan7t = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ restrictionValue = FILTER_EXPR_FACTORY.createClassAttribute();
+ restrictionValue.setAttributeName(tip.getVehicleRelatedRestriction_RestrictionValue().getName());
+ restrictionValueLessThan7t.setAttribute(restrictionValue);
+ restrictionValueLessThan7t.setComparisonOperator(ComparisonOperator.LESS_THAN);
+ literal7t = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ literal7t.setValue(axleLoad);
+ restrictionValueLessThan7t.setLiteral(literal7t);
+
+ // Dyadic Expression: restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000
+ DyadicExpression axleLoadLessThan7t = FILTER_EXPR_FACTORY.createDyadicExpression();
+ axleLoadLessThan7t.setLeftHandTerm(restrictionTypeIsAxleLoadLessThan);
+ axleLoadLessThan7t.setLogicalOperator(DyadicLogicalOperator.AND);
+ axleLoadLessThan7t.setRightHandTerm(restrictionValueLessThan7t);
+
+ // VehicleRelatedRestrictionDoesntMatch := AxleLoadLessThan7t OR AxleLoadGreaterThan7t
+ // Dyadic Expression: ((restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000) ||
+ // (restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000))
+ DyadicExpression axleLoadLessThan7tOrAxleLoadGreaterThan7t = FILTER_EXPR_FACTORY.createDyadicExpression();
+ axleLoadLessThan7tOrAxleLoadGreaterThan7t.setLeftHandTerm(axleLoadLessThan7t);
+ axleLoadLessThan7tOrAxleLoadGreaterThan7t.setLogicalOperator(DyadicLogicalOperator.OR);
+ axleLoadLessThan7tOrAxleLoadGreaterThan7t.setRightHandTerm(axleLoadGreaterThan7t);
+
+
+ // Sub Class Predicate: Applicability: (isSet(vehicle type) AND vehicle type != LORRY) ||
+ // (restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000) ||
+ // (restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000)
+
+ // VehicleRelatedRestrictionsDontMatch := ANY VehicleRelatedRestrictionDoesntMatch
+ MultiplicityPredicate vehicleRelatedRestrictionsDontMatch = FILTER_EXPR_FACTORY.createMultiplicityPredicate();
+ vehicleRelatedRestrictionsDontMatch.setListOperator(ListOperator.ANY);
+ ClassAttribute vehicleRelatedRestrictions = FILTER_EXPR_FACTORY.createClassAttribute();
+ vehicleRelatedRestrictions.setAttributeName(tip.getApplicability_VehicleRelatedRestrictions().getName());
+ vehicleRelatedRestrictionsDontMatch.setAttribute(vehicleRelatedRestrictions);
+ vehicleRelatedRestrictionsDontMatch.setExpression(axleLoadLessThan7tOrAxleLoadGreaterThan7t);
+
+ ClassAttribute vehicleType;
+ // VehicleTypeDoesntMatch := isSet(vehicle type) AND vehicleType != LORRY
+
+ // Is Set Predicate: isSet(vehicle type)
+ vehicleType = FILTER_EXPR_FACTORY.createClassAttribute();
+ vehicleType.setAttributeName(tip.getApplicability_VehicleType().getName());
+ IsSetPredicate vehicleTypeIsSet = FILTER_EXPR_FACTORY.createIsSetPredicate();
+ vehicleTypeIsSet.setAttribute(vehicleType);
+
+ // Comparison Predicate: vehicle type != LORRY
+ ComparisonPredicate vehicleTypeNotLorry = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ vehicleType = FILTER_EXPR_FACTORY.createClassAttribute();
+ vehicleType.setAttributeName(tip.getApplicability_VehicleType().getName());
+ vehicleTypeNotLorry.setAttribute(vehicleType);
+ vehicleTypeNotLorry.setComparisonOperator(ComparisonOperator.NOT_EQUAL);
+ SignedIntegerLiteral lorryEnumValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ lorryEnumValue.setValue(VehicleType.LORRY.getValue());
+ vehicleTypeNotLorry.setLiteral(lorryEnumValue);
+
+ // Dyadic Expression: isSet(vehicle type) AND vehicle type != LORRY
+ DyadicExpression vehicleTypeIsSetAndNotLorry = FILTER_EXPR_FACTORY.createDyadicExpression();
+ vehicleTypeIsSetAndNotLorry.setLeftHandTerm(vehicleTypeIsSet);
+ vehicleTypeIsSetAndNotLorry.setLogicalOperator(DyadicLogicalOperator.AND);
+ vehicleTypeIsSetAndNotLorry.setRightHandTerm(vehicleTypeNotLorry);
+
+
+
+ // ApplicabilityDoesntMatchTheVehicleParameters := VehicleTypeDoesntMatch OR VehicleRelatedRestrictionsDontMatch
+ // Dyadic Expression: (isSet(vehicle type) AND vehicle type != LORRY) ||
+ // ((restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000) ||
+ // (restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000))
+ DyadicExpression notLorryAndAxleLoad = FILTER_EXPR_FACTORY.createDyadicExpression();
+ notLorryAndAxleLoad.setLeftHandTerm(vehicleTypeIsSetAndNotLorry);
+ notLorryAndAxleLoad.setLogicalOperator(DyadicLogicalOperator.OR);
+ notLorryAndAxleLoad.setRightHandTerm(vehicleRelatedRestrictionsDontMatch);
+
+ // Sub Class Predicate: Applicability: (isSet(vehicle type) AND vehicle type != LORRY) ||
+ // (restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000) ||
+ // (restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000)
+
+ ClassAttribute applicabilityAttribute;
+
+ // ApplicabilityExpression := ALL ApplicabilityDoesntMatchTheVehicleParameters
+ // Multiplicity Predicate: ALL (Applicability: (isSet(vehicle type) AND vehicle type != LORRY) ||
+ // (restrictionType == AXLE_LOAD_LESS_THAN AND restrictionValue < 7000) ||
+ // (restrictionType == AXLE_LOAD_GREATER_THAN AND restrictionValue > 7000))
+ MultiplicityPredicate allApplicabilityNotLorryAndAxleLoad = FILTER_EXPR_FACTORY.createMultiplicityPredicate();
+ allApplicabilityNotLorryAndAxleLoad.setListOperator(ListOperator.ALL);
+ applicabilityAttribute = FILTER_EXPR_FACTORY.createClassAttribute();
+ applicabilityAttribute.setAttributeName(tip.getTrafficIncident_Applicability().getName());
+ allApplicabilityNotLorryAndAxleLoad.setAttribute(applicabilityAttribute);
+ allApplicabilityNotLorryAndAxleLoad.setExpression(notLorryAndAxleLoad);
+
+ // ApplicabilitySpecified := COUNT(applicability) > 0
+ // Multiplicity Predicate: LIST (COUNT > 0)
+
+ applicabilityAttribute = FILTER_EXPR_FACTORY.createClassAttribute();
+ applicabilityAttribute.setAttributeName(tip.getTrafficIncident_Applicability().getName());
+ applicabilityAttribute.setMetaOperator(MetaOperator.SIZE);
+
+ ComparisonPredicate applicabilityListSizeGreaterThan0 = FILTER_EXPR_FACTORY.createComparisonPredicate();
+ applicabilityListSizeGreaterThan0.setAttribute(applicabilityAttribute);
+ applicabilityListSizeGreaterThan0.setComparisonOperator(ComparisonOperator.GREATER_THEN);
+ SignedIntegerLiteral zeroValue = FILTER_EXPR_FACTORY.createSignedIntegerLiteral();
+ zeroValue.setValue(0l);
+ applicabilityListSizeGreaterThan0.setLiteral(zeroValue);
+
+ DyadicExpression isNotApplicable = FILTER_EXPR_FACTORY.createDyadicExpression();
+ isNotApplicable.setLeftHandTerm(applicabilityListSizeGreaterThan0);
+ isNotApplicable.setLogicalOperator(DyadicLogicalOperator.AND);
+ isNotApplicable.setRightHandTerm(allApplicabilityNotLorryAndAxleLoad);
+
+ return isNotApplicable;
+ }
+
+ private class ListCategoryDefinition {
+ CategoryDefinition categoryDefinition;
+
+ public ListCategoryDefinition(CategoryDefinition categoryDefinition) {
+ this.categoryDefinition = categoryDefinition;
+ }
+
+ public CategoryDefinition getCategoryDefinition() {
+ return categoryDefinition;
+ }
+
+ public String toString() {
+ LOGGER.fine("toString => currentLanguage = " + currentLanguage);
+ String categoryName = null;
+
+ for (LocalizedString localizedString: categoryDefinition.getLocalizedNames()) {
+ if (localizedString.getLanguageCode().equals(currentLanguage) &&
+ (localizedString.getCountryCode() == null ||
+ localizedString.getCountryCode().equals(currentLanguageCountry))) {
+ categoryName = localizedString.getString();
+ LOGGER.fine("Category name found for current language and country");
+ break;
+ }
+ }
+
+ if (categoryName == null) {
+ for (LocalizedString localizedString: categoryDefinition.getLocalizedNames()) {
+ if (localizedString.getLanguageCode().equals(currentLanguage)) {
+ categoryName = localizedString.getString();
+ LOGGER.fine("Category name found for current language");
+ break;
+ }
+ }
+ }
+
+ if (categoryName == null) {
+ LOGGER.fine("Using default (first) language.");
+ categoryName = categoryDefinition.getLocalizedNames(0).getString();
+ }
+
+ LOGGER.fine("toString <=");
+ return categoryName;
+ }
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoMapView.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoMapView.java
new file mode 100755
index 0000000..373ece2
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/TrafficInfoMapView.java
@@ -0,0 +1,265 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+import openlr.map.MapDatabase;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.genivi.common.CommonFactory;
+import org.genivi.common.Coordinate;
+import org.genivi.common.RectangularArea;
+import org.genivi.trafficincidentsservice.DefaultTrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TrafficIncidents;
+import org.genivi.trafficincidentsservice.TrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.TrafficIncident;
+import org.genivi.trafficincidentsservice.trafficincidenttables.WarningLevel;
+import org.jdesktop.swingx.JXMapViewer;
+import org.jdesktop.swingx.mapviewer.GeoPosition;
+
+
+public class TrafficInfoMapView extends Thread {
+ private final static Logger LOGGER = Logger.getLogger(TrafficInfoMapView.class.getName());
+ private static final String WINDOW_TITLE = "GENIVI Traffic Information Map View";
+ private static final CommonFactory COMMON_FACTORY = CommonFactory.eINSTANCE;
+ private static EList<RectangularArea> areas;
+
+ private static final String locationString = "location";
+ private static final String locationInfoString = "locationInfo";
+
+ private JFrame frame;
+ private MapDatabase mapDataBase;
+ private TrafficIncidents trafficIncidentsService = null;
+ private TrafficIncidentsListener trafficIncidentsListener;
+ private org.jdesktop.swingx.JXMapKit jXMapKit;
+ private JRadioButton locationButton;
+ private JRadioButton locationInfoButton;
+ private ButtonGroup buttonGroup;
+ private JCheckBox boundingBoxCheckBox;
+ private JCheckBox areaFilterCheckBox;
+ private JCheckBox showFilterAreasCheckBox;
+
+ static {
+ areas = new BasicEList<RectangularArea>();
+
+ RectangularArea area = COMMON_FACTORY.createRectangularArea();
+ Coordinate bottomLeft = COMMON_FACTORY.createCoordinate();
+ bottomLeft.setAltitude(0);
+ bottomLeft.setLongitude(5.06d);
+ bottomLeft.setLatitude(52.08d);
+ Coordinate topRight = COMMON_FACTORY.createCoordinate();
+ topRight.setAltitude(0);
+ topRight.setLongitude(5.10d);
+ topRight.setLatitude(52.11d);
+ area.setBottomLeft(bottomLeft);
+ area.setTopRight(topRight);
+ areas.add(area);
+
+ area = COMMON_FACTORY.createRectangularArea();
+ bottomLeft = COMMON_FACTORY.createCoordinate();
+ bottomLeft.setAltitude(0);
+ bottomLeft.setLongitude(5.07d);
+ bottomLeft.setLatitude(52.07d);
+ topRight = COMMON_FACTORY.createCoordinate();
+ topRight.setAltitude(0);
+ topRight.setLongitude(5.15d);
+ topRight.setLatitude(52.09d);
+ area.setBottomLeft(bottomLeft);
+ area.setTopRight(topRight);
+ areas.add(area);
+ }
+
+ public TrafficInfoMapView(MapDatabase mapDataBase, TrafficIncidents trafficIncidentsService) {
+ LOGGER.setLevel(Level.SEVERE);
+ LOGGER.info("Creating TrafficInfoMapView");
+ this.mapDataBase = mapDataBase;
+ this.trafficIncidentsService = trafficIncidentsService;
+
+ trafficIncidentsListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void getTrafficIncidentIdsReply(EList<Integer> incidentIds) {
+ LOGGER.info("getTrafficIncidentIdsReply called.");
+ getAndShowTrafficInfoStep2(incidentIds);
+ }
+
+ @Override
+ public void getTrafficIncidentsReply(EList<TrafficIncident> trafficIncidents) {
+ LOGGER.info("getTrafficIncidentsReply called.");
+ getAndShowTrafficInfoStep3(trafficIncidents);
+ }
+ };
+
+ frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setTitle(WINDOW_TITLE);
+
+ jXMapKit = new org.jdesktop.swingx.JXMapKit();
+ jXMapKit.setDefaultProvider(org.jdesktop.swingx.JXMapKit.DefaultProviders.OpenStreetMaps);
+ jXMapKit.setDataProviderCreditShown(true);
+ jXMapKit.setPreferredSize(new Dimension(600, 500));
+ jXMapKit.setZoom(3);
+ jXMapKit.setAddressLocationShown(false);
+ jXMapKit.setAddressLocation(new GeoPosition(52.095,5.088));
+ frame.getContentPane().add(jXMapKit);
+
+ frame.getContentPane().add(createControlPanel(), BorderLayout.NORTH);
+
+ //Display the window.
+ frame.pack();
+ frame.setVisible(true);
+ getAndShowTrafficInfoStep3(null);
+ start();
+ }
+
+ private JPanel createControlPanel() {
+ JPanel panel = new JPanel();
+ panel.add(createLocationControlPanel());
+ panel.add(createBoundingBoxPanel());
+ panel.add(createFilterPanel());
+
+ return panel;
+ }
+
+ private JPanel createLocationControlPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(BorderFactory.createEtchedBorder());
+
+ JLabel label = new JLabel("draw location from: ");
+ panel.add(label);
+
+ locationButton = new JRadioButton(locationString);
+ locationButton.setSelected(true);
+ panel.add(locationButton);
+ locationInfoButton = new JRadioButton(locationInfoString);
+ panel.add(locationInfoButton);
+
+ buttonGroup = new ButtonGroup();
+ buttonGroup.add(locationButton);
+ buttonGroup.add(locationInfoButton);
+
+ return panel;
+ }
+
+
+ private JPanel createBoundingBoxPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(BorderFactory.createEtchedBorder());
+
+ boundingBoxCheckBox = new JCheckBox("bounding box");
+ panel.add(boundingBoxCheckBox);
+
+ return panel;
+ }
+
+ private JPanel createFilterPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(BorderFactory.createEtchedBorder());
+
+ areaFilterCheckBox = new JCheckBox("area filter");
+ panel.add(areaFilterCheckBox);
+
+ showFilterAreasCheckBox = new JCheckBox("show filter areas");
+ panel.add(showFilterAreasCheckBox);
+
+ return panel;
+ }
+
+ public void run() {
+ for ( ; ; ) {
+ if (trafficIncidentsService != null) {
+ getAndShowTrafficInfoStep1();
+ } else {
+ System.out.println("TrafficInfoMapView: No Traffic Incidents Service");
+ }
+
+ try {
+ sleep(1000 * 3);
+ } catch (InterruptedException e) {
+ System.out.println("TrafficInfoMapView woke up too early");
+ }
+ }
+ }
+
+ private void getAndShowTrafficInfoStep1() {
+ LOGGER.info("Polling; calling getTrafficIncidentIds()");
+ if (areaFilterCheckBox.isSelected()) {
+ trafficIncidentsService.getTrafficIncidentIdsInAreas(trafficIncidentsListener, new BasicEList<WarningLevel>(), new BasicEList<Integer>(), areas);
+ } else {
+ trafficIncidentsService.getTrafficIncidentIds(trafficIncidentsListener, new BasicEList<WarningLevel>(), new BasicEList<Integer>());
+ }
+ }
+
+ private void getAndShowTrafficInfoStep2(EList<Integer> incidentIds) {
+ if (incidentIds != null && incidentIds.size() > 0) {
+ LOGGER.info("There are incidents, calling getTrafficIncidents().");
+ trafficIncidentsService.getTrafficIncidents(trafficIncidentsListener, incidentIds, false);
+ } else {
+ LOGGER.info("No incidents.");
+ getAndShowTrafficInfoStep3(null);
+ }
+ }
+
+ public void getAndShowTrafficInfoStep3(EList<TrafficIncident> incidents) {
+ TrafficIncidentsPainter<JXMapViewer> painter = new TrafficIncidentsPainter<JXMapViewer>(mapDataBase);
+
+ painter.setIncidents(incidents);
+ boolean useCoordinates;
+ if (locationButton.isSelected()) {
+ LOGGER.info("useCoordinates = true");
+ useCoordinates = true;
+ } else {
+ LOGGER.info("useCoordinates = false");
+ useCoordinates = false;
+ }
+
+ painter.setUseCoordinates(useCoordinates);
+
+ painter.setDrawBoundingBox(boundingBoxCheckBox.isSelected());
+
+ if (showFilterAreasCheckBox.isSelected()) {
+ painter.setAreas(areas);
+ }
+
+ jXMapKit.getMainMap().setOverlayPainter(painter);
+ }
+
+ /**
+ * Create the GUI and show it. For thread safety,
+ * this method should be invoked from the
+ * event-dispatching thread.
+ */
+ private static void createAndShowGUI() {
+ TrafficInfoMapView trafficInfoMapView = new TrafficInfoMapView(null, null);
+
+ trafficInfoMapView.getAndShowTrafficInfoStep3(null);
+ }
+
+ public static void main(String[] args) {
+ //Schedule a job for the event-dispatching thread:
+ //creating and showing this application's GUI.
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ }
+}
diff --git a/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/WarningClient.java b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/WarningClient.java
new file mode 100755
index 0000000..5d23095
--- /dev/null
+++ b/test/traffic-incidents-service/hmi/org.genivi.trafficinfo.trafficincidentsexampleclients/src/main/java/org/genivi/trafficinfo/trafficincidentsexampleclients/WarningClient.java
@@ -0,0 +1,240 @@
+/**
+ * Copyright (C) 2013 TomTom International B.V.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.genivi.trafficinfo.trafficincidentsexampleclients;
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.genivi.location.LinearLocationInfo;
+import org.genivi.trafficincidentsservice.DefaultTrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.TrafficIncidentField;
+import org.genivi.trafficincidentsservice.TrafficIncidents;
+import org.genivi.trafficincidentsservice.TrafficIncidentsListener;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.Cause;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.DirectCause;
+import org.genivi.trafficincidentsservice.trafficincidents.trafficincident.TrafficIncident;
+import org.genivi.trafficincidentsservice.trafficincidenttables.WarningLevel;
+
+@SuppressWarnings("serial")
+public class WarningClient extends JFrame{
+ private final static Logger LOGGER = Logger.getLogger(TrafficInfoMapView.class.getName());
+ private static final String TITLE = "Traffic Incident Warning";
+ private static final BasicEList<WarningLevel> severities = new BasicEList<WarningLevel>();
+ private static final BasicEList<TrafficIncidentField> trafficIncidentFields = new BasicEList<TrafficIncidentField>();
+
+ private TrafficIncidents trafficIncidentsService;
+ private TrafficIncidentsListener trafficIncidentsListener;
+ private JPanel warningPanel;
+
+ static {
+ severities.add(WarningLevel.DANGER_LEVEL_1);
+ severities.add(WarningLevel.DANGER_LEVEL_2);
+ severities.add(WarningLevel.DANGER_LEVEL_3);
+ trafficIncidentFields.add(TrafficIncidentField.CAUSES);
+ trafficIncidentFields.add(TrafficIncidentField.LOCATION_INFO);
+ trafficIncidentFields.add(TrafficIncidentField.CAUSE_TEXTS);
+ }
+
+ public WarningClient(TrafficIncidents trafficIncidents) {
+ super(TITLE);
+
+ LOGGER.setLevel(Level.SEVERE);
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ this.trafficIncidentsService = trafficIncidents;
+
+ trafficIncidentsListener = new DefaultTrafficIncidentsListener() {
+
+ @Override
+ public void updates(EList<Integer> unchangedTrafficIncidentIds, EList<Integer> changedTrafficIncidentIds, EList<Integer> newTrafficIncidentIds, EList<Integer> deletedTrafficIncidentIds) {
+ LOGGER.info("updates() called.");
+
+ EList<Integer> incidentIds = new BasicEList<>(unchangedTrafficIncidentIds);
+ incidentIds.addAll(changedTrafficIncidentIds);
+ incidentIds.addAll(newTrafficIncidentIds);
+
+ // Update text pane with the new information.
+ handleTrafficIncidentIdsReply(incidentIds);
+ }
+
+ @Override
+ public void getTrafficIncidentsReply(EList<TrafficIncident> trafficIncidents) {
+ LOGGER.info("getTrafficIncidentsReply() called.");
+ updateWarningPanel(trafficIncidents);
+ }
+
+ @Override
+ public void addUpdateListenerReply() {
+ // No action.
+ LOGGER.info("Call to addUpdateListenerReply ignored.");
+ }
+ };
+
+ Container contentPane = getContentPane();
+ contentPane.add(createTextPanel());
+ pack();
+
+ trafficIncidentsService.addUpdateListener(trafficIncidentsListener, severities, new BasicEList<Integer>(), trafficIncidentsListener);
+ }
+
+
+ /**
+ * Create a panel for the Full message texts.
+ */
+ private JPanel createTextPanel() {
+ warningPanel = new JPanel();
+ warningPanel.setLayout(new FlowLayout());
+ Dimension warningPanelSize = new Dimension(1000, 500);
+ warningPanel.setMinimumSize(warningPanelSize);
+ warningPanel.setPreferredSize(warningPanelSize);
+
+ return warningPanel;
+ }
+
+
+ /**
+ * First step in updating the text panel:
+ * - hide the Frame if there are no incidents.
+ * - otherwise send a request for the texts, with textListener as listener.
+ */
+ private void handleTrafficIncidentIdsReply(EList<Integer> incidentIds) {
+ LOGGER.info("=>");
+ if (incidentIds == null || incidentIds.size() == 0) {
+ LOGGER.info("<= No Traffic Incidents.");
+ warningPanel.removeAll();
+ setVisible(false);
+ return;
+ }
+
+ trafficIncidentsService.getTrafficIncidentsFields(trafficIncidentsListener, incidentIds, trafficIncidentFields);
+ LOGGER.info("<= Traffic Incidents.");
+ }
+
+ /**
+ * Second step in updating the Full text panel:
+ * - display the received texts.
+ */
+ private void updateWarningPanel(EList<TrafficIncident> trafficIncidents) {
+ LOGGER.info("=>");
+ warningPanel.removeAll();
+
+ for (TrafficIncident trafficIncident: trafficIncidents) {
+ StringBuffer buf = new StringBuffer();
+
+ EList<Cause> causes = trafficIncident.getCauses();
+ EList<String> causeTexts = trafficIncident.getCauseTexts();
+
+ if (causes.size() != causeTexts.size()) {
+ throw new RuntimeException("Unequal sizes of causes and cause texts");
+ }
+
+ for (int i = 0; i < causes.size(); i++) {
+ // Only if it is a DirectCause there can be a WarningLevel, so it may have to be shown.
+ Cause cause = causes.get(i);
+ if (cause instanceof DirectCause) {
+ DirectCause directCause = (DirectCause) cause;
+ WarningLevel warningLevel = null;
+ if (directCause.isSetWarningLevel()) {
+ warningLevel = directCause.getWarningLevel();
+ }
+ if (warningLevel != null && severities.contains(warningLevel)) {
+ buf.setLength(0);
+ generateLocationText(buf, trafficIncident);
+ buf.append(" ");
+
+ String causeText = causeTexts.get(i);
+ buf.append(causeText);
+ warningPanel.add(createWarningPanel(buf.toString(), warningLevel));
+ }
+ }
+ }
+ }
+
+ this.repaint();
+ setVisible(true);
+ LOGGER.info("<= visible");
+ }
+
+ private void generateLocationText(StringBuffer buf, TrafficIncident trafficIncident) {
+
+ if (trafficIncident.isSetLocationInfo()) {
+ LinearLocationInfo linearLocationInfo = (LinearLocationInfo) trafficIncident.getLocationInfo();
+ buf.append("on the ");
+ buf.append(linearLocationInfo.getName());
+ buf.append(" from ");
+ buf.append(linearLocationInfo.getFromLocationParentName());
+ buf.append(" to ");
+ buf.append(linearLocationInfo.getFromLocationName());
+ buf.append(" between ");
+ buf.append(linearLocationInfo.getToLocationName());
+ buf.append(" and ");
+ buf.append(linearLocationInfo.getToLocationParentName());
+ }
+ }
+
+ private JPanel createWarningPanel(String text, WarningLevel warningLevel) {
+ JPanel panel = new JPanel();
+
+ String title;
+ if (warningLevel != null) {
+ title = warningLevel.getName();
+ } else {
+ title = "No warning level available in the Traffic Incident";
+ }
+
+ panel.setBorder(BorderFactory.createTitledBorder(title));
+
+ JTextArea textArea = new JTextArea(6, 80);
+ textArea.setLineWrap(true);
+ textArea.setEditable(false);
+ textArea.setText(text);
+ JScrollPane scrollPane = new JScrollPane(textArea);
+
+ Color backgroundColor = null;
+ if (warningLevel != null) {
+ switch (warningLevel) {
+ case DANGER_LEVEL_1:
+ backgroundColor = Color.YELLOW;
+ break;
+
+ case DANGER_LEVEL_2:
+ backgroundColor = Color.ORANGE;
+ break;
+
+ case DANGER_LEVEL_3:
+ backgroundColor = Color.RED;
+ break;
+
+ default:
+ // should not occur, no specific background color.
+ break;
+ }
+ }
+
+ if (backgroundColor != null) {
+ panel.setBackground(backgroundColor);
+ }
+
+ panel.add(scrollPane);
+
+ return panel;
+ }
+}