Java tutorial
/** * Copyright (C) 2012-2014 52North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as publishedby the Free * Software Foundation. * * If the program is linked with libraries which are licensed under one of the * following licenses, the combination of the program with the linked library is * not considered a "derivative work" of the program: * * - Apache License, version 2.0 * - Apache Software License, version 1.0 * - GNU Lesser General Public License, version 3 * - Mozilla Public License, versions 1.0, 1.1 and 2.0 * - Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed under * the aforementioned licenses, is permitted by the copyright holders if the * distribution is compliant with both the GNU General Public License version 2 * and the aforementioned licenses. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. */ package org.n52.client; import static org.n52.client.bus.EventBus.getMainEventBus; import static org.n52.client.ctrl.PropertiesManager.getPropertiesManager; import static org.n52.client.ctrl.RequestManager.hasUnfinishedRequests; import static org.n52.client.sos.i18n.SosStringsAccessor.i18n; import static org.n52.client.ui.Toaster.getToasterInstance; import static org.n52.client.util.ClientUtils.getDecodedParameters; import static org.n52.ext.link.sos.PermalinkParameter.BEGIN; import static org.n52.ext.link.sos.PermalinkParameter.END; import static org.n52.ext.link.sos.PermalinkParameter.FEATURES; import static org.n52.ext.link.sos.PermalinkParameter.OFFERINGS; import static org.n52.ext.link.sos.PermalinkParameter.PHENOMENONS; import static org.n52.ext.link.sos.PermalinkParameter.PROCEDURES; import static org.n52.ext.link.sos.PermalinkParameter.SERVICES; import static org.n52.ext.link.sos.PermalinkParameter.VERSIONS; import static org.n52.shared.Constants.DEFAULT_OVERVIEW_INTERVAL; import java.util.List; import java.util.Map; import org.eesgmbh.gimv.client.event.StateChangeEvent; import org.n52.client.bus.EventBus; import org.n52.client.bus.EventCallback; import org.n52.client.ctrl.PermalinkController; import org.n52.client.ctrl.PropertiesManager; import org.n52.client.ctrl.TimeManager; import org.n52.client.ses.ctrl.SesController; import org.n52.client.sos.ctrl.SOSController; import org.n52.client.sos.ctrl.SosDataManager; import org.n52.client.sos.event.DatesChangedEvent; import org.n52.client.sos.event.InitEvent; import org.n52.client.sos.event.data.GetFeatureEvent; import org.n52.client.sos.event.data.GetOfferingEvent; import org.n52.client.sos.event.data.GetPhenomenonsEvent; import org.n52.client.sos.event.data.GetProcedureEvent; import org.n52.client.sos.event.data.GetStationForTimeseriesEvent; import org.n52.client.sos.event.data.GetStationsWithinBBoxEvent; import org.n52.client.sos.event.data.NewSOSMetadataEvent; import org.n52.client.sos.event.data.OverviewIntervalChangedEvent; import org.n52.client.sos.event.data.OverviewIntervalChangedEvent.IntervalType; import org.n52.client.sos.event.data.RequestDataEvent; import org.n52.client.sos.event.data.StoreSOSMetadataEvent; import org.n52.client.sos.ui.StationSelector; import org.n52.client.ui.Toaster; import org.n52.client.ui.View; import org.n52.client.util.ClientUtils; import org.n52.ext.link.sos.PermalinkParameter; import org.n52.ext.link.sos.TimeRange; import org.n52.shared.serializable.pojos.TimeseriesRenderingOptions; import org.n52.shared.serializable.pojos.sos.Feature; import org.n52.shared.serializable.pojos.sos.Offering; import org.n52.shared.serializable.pojos.sos.Phenomenon; import org.n52.shared.serializable.pojos.sos.Procedure; import org.n52.shared.serializable.pojos.sos.SOSMetadata; import org.n52.shared.serializable.pojos.sos.SOSMetadataBuilder; import org.n52.shared.serializable.pojos.sos.SosService; import org.n52.shared.serializable.pojos.sos.SosTimeseries; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.http.client.URL; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; public final class Application implements EntryPoint { private static boolean HAS_STARTED = false; public static boolean isHasStarted() { return HAS_STARTED; } public static void setHasStarted(boolean hasStarted) { HAS_STARTED = hasStarted; } @Override public void onModuleLoad() { GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { public void onUncaughtException(Throwable e) { GWT.log("Uncaught Exception", e); } }); // TODO refactor startup to be more explicit getPropertiesManager(); // creates singleton } public static void continueStartup() { // init handlers before throwing events SosDataManager.getDataManager(); new SOSController(); if (ClientUtils.isSesEnabled()) { new SesController(); } View.getView(); Element element = Document.get().getElementById("loadingWrapper"); while (element.hasChildNodes()) { element.removeChild(element.getFirstChild()); } Application.finishStartup(); } public static void finishStartup() { try { String currentUrl = URL.decode(Window.Location.getHref()); if (hasQueryString(currentUrl) && !isGwtHostedModeParameterOnly()) { String[] services = getDecodedParameters(SERVICES); String[] versions = getDecodedParameters(VERSIONS); String[] features = getDecodedParameters(FEATURES); String[] offerings = getDecodedParameters(OFFERINGS); String[] procedures = getDecodedParameters(PROCEDURES); String[] phenomenons = getDecodedParameters(PHENOMENONS); String[] options = getDecodedParameters("options"); TimeRange timeRange = createTimeRange(); String locale = Window.Location.getParameter("locale"); if (isLocaleOnly(services, versions, offerings, features, procedures, phenomenons, locale)) { return; } if (!isAllParametersAvailable(services, versions, offerings, features, procedures, phenomenons)) { getToasterInstance().addErrorMessage(i18n.errorUrlParsing()); return; } if (timeRange.isSetStartAndEnd()) { fireNewTimeRangeEvent(timeRange); } PermalinkController permalinkController = new PermalinkController(); for (int i = 0; i < services.length; i++) { final String service = services[i]; final String version = versions[i]; final String offering = offerings[i]; final String procedure = procedures[i]; final String phenomenon = phenomenons[i]; final String feature = features[i]; SosTimeseries sosTimeseries = new SosTimeseries(); sosTimeseries.setFeature(new Feature(feature, service)); sosTimeseries.setOffering(new Offering(offering, service)); sosTimeseries.setPhenomenon(new Phenomenon(phenomenon, service)); sosTimeseries.setSosService(new SosService(service, version)); sosTimeseries.setProcedure(new Procedure(procedure, service)); GWT.log("Timeseries to load: " + sosTimeseries); TimeseriesRenderingOptions tsOptions = null; if (options != null && options.length > i) { tsOptions = createRenderingOptions(options[i]); GWT.log("with options: " + options[i]); permalinkController.addTimeseries(sosTimeseries, tsOptions); } else { permalinkController.addTimeseries(sosTimeseries); } SOSMetadataBuilder builder = new SOSMetadataBuilder().addServiceURL(service) .addServiceVersion(version); SOSMetadata sosMetadata = new SOSMetadata(builder); getMainEventBus().fireEvent(new StoreSOSMetadataEvent(sosMetadata)); getMainEventBus().fireEvent(new GetPhenomenonsEvent.Builder(service).build()); getMainEventBus().fireEvent(new GetFeatureEvent(service, feature)); getMainEventBus().fireEvent(new GetOfferingEvent(service, offering)); getMainEventBus().fireEvent(new GetProcedureEvent(service, procedure)); getMainEventBus().fireEvent(new GetStationForTimeseriesEvent(sosTimeseries)); getMainEventBus().fireEvent(new GetStationsWithinBBoxEvent(service, null)); getMainEventBus().fireEvent(new NewSOSMetadataEvent()); } } else { showStationSelectorWhenConfigured(); } } catch (Exception e) { if (!GWT.isProdMode()) { GWT.log("Error evaluating permalink!", e); } showStationSelectorWhenConfigured(); getToasterInstance().addErrorMessage(i18n.errorUrlParsing()); } finally { finalEvents(); } } private static TimeseriesRenderingOptions createRenderingOptions(String options) { if (options == null) { return new TimeseriesRenderingOptions(); } TimeseriesRenderingOptions tsOptions = new TimeseriesRenderingOptions(); JSONObject tsRenderingOptions = new JSONObject(parseUntrustedJson(options)); if (tsRenderingOptions.containsKey("color")) { JSONString color = tsRenderingOptions.get("color").isString(); tsOptions.setColor(color.stringValue()); } if (tsRenderingOptions.containsKey("lineWidth")) { JSONNumber lineWidth = tsRenderingOptions.get("lineWidth").isNumber(); tsOptions.setLineWidth((int) lineWidth.doubleValue()); } return tsOptions; } private native static JavaScriptObject parseUntrustedJson(String jsonString) /*-{ return $wnd.JSON.parse(jsonString); }-*/; private static boolean isGwtHostedModeParameterOnly() { Map<String, List<String>> parameters = Window.Location.getParameterMap(); boolean hasGwtCodesrvParameter = parameters.containsKey("gwt.codesvr"); return !GWT.isProdMode() && parameters.size() == 1 && hasGwtCodesrvParameter; } static TimeRange createTimeRange() { String begin = getDecodedParameter(BEGIN); String end = getDecodedParameter(END); TimeRange timeRange = TimeRange.createTimeRange(begin, end); return timeRange; } private static String getDecodedParameter(PermalinkParameter parameter) { return Window.Location.getParameter(parameter.nameLowerCase()); } private static void fireNewTimeRangeEvent(TimeRange timeRange) { try { DateTimeFormat formatter = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.ISO_8601); long begin = formatter.parseStrict(timeRange.getStart()).getTime(); long end = formatter.parseStrict(timeRange.getEnd()).getTime(); Toaster.getToasterInstance().addMessage("Begin: " + timeRange.getStart()); Toaster.getToasterInstance().addMessage("End: " + timeRange.getEnd()); EventBus.getMainEventBus().fireEvent(new DatesChangedEvent(begin, end, true)); } catch (Exception e) { if (!GWT.isProdMode()) { GWT.log("Unparsable TimeRange: " + timeRange, e); } } } private static void showStationSelectorWhenConfigured() { PropertiesManager properties = getPropertiesManager(); boolean showAtStartup = properties.getParameterAsBoolean("showStationSelectorAtStartup"); if (showAtStartup) { StationSelector.getInst().show(); } } private static boolean hasQueryString(String currentUrl) { return currentUrl.indexOf("?") > -1; } private static boolean isAllParametersAvailable(String[] serviceUrls, String[] versions, String[] offerings, String[] fois, String[] procedures, String[] phenomenons) { boolean serviceUrlAvailable = serviceUrls.length != 0; boolean versionAvailalbe = versions.length != 0; boolean offeringAvailable = offerings.length != 0; boolean featuresAvailable = fois.length != 0; boolean proceduresAvailable = procedures.length != 0; boolean phenomenonAvailable = phenomenons.length != 0; return serviceUrlAvailable && versionAvailalbe && offeringAvailable && featuresAvailable && proceduresAvailable && phenomenonAvailable; } private static boolean isLocaleOnly(String[] services, String[] versions, String[] offerings, String[] features, String[] procedures, String[] phenomenons, String locale) { boolean serviceUrlsEmpty = services.length == 0; boolean versionEmpty = versions.length == 0; boolean offeringEmpty = offerings.length == 0; boolean featuresEmpty = features.length == 0; boolean proceduresEmpty = procedures.length == 0; boolean phenomenonEmpty = phenomenons.length == 0; boolean localeAvailable = locale != null; return serviceUrlsEmpty && versionEmpty && offeringEmpty && featuresEmpty && proceduresEmpty && phenomenonEmpty && localeAvailable; } private static void finalEvents() { // check for time intervals bigger than the default overview interval (in days) PropertiesManager propertiesMgr = getPropertiesManager(); int days = propertiesMgr.getParamaterAsInt(DEFAULT_OVERVIEW_INTERVAL, 5); TimeManager timeMgr = TimeManager.getInst(); long timeInterval = timeMgr.daysToMillis(days); long currentInterval = timeMgr.getEnd() - timeMgr.getBegin(); if (timeInterval <= currentInterval) { timeInterval += timeMgr.getOverviewOffset(timeMgr.getBegin(), timeMgr.getEnd()); } getMainEventBus().fireEvent(new OverviewIntervalChangedEvent(timeInterval, IntervalType.DAY)); getMainEventBus().fireEvent(new InitEvent(), new EventCallback() { public void onEventFired() { EventBus.getOverviewChartEventBus().fireEvent(StateChangeEvent.createMove()); final Timer t = new Timer() { @Override public void run() { if (hasUnfinishedRequests()) { this.schedule(200); } else { HAS_STARTED = false; getMainEventBus().fireEvent(new RequestDataEvent()); } } }; t.schedule(200); } }); } }