# HG changeset patch # User Thomas Arendsen Hein # Date 1348827247 -7200 # Node ID 2b745b5e731c4837b09ebd31dee308c353e49358 # Parent 27d3d009399339604bd03eb58bd048780acf3b08# Parent 5391c329168c2c5167891ef11278297f01f69508 merged flys-backend/0.1 diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/ChangeLog Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,473 @@ +2011-03-30 Ingo Weinzierl + + * doc/conf/artifacts/winfo.xml: Renamed an output mode in the WINFO + artifact configuration. + +2011-03-29 Ingo Weinzierl + + * src/main/resources/messages_de_DE.properties, + src/main/resources/messages_de.properties: Changed a german string. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/CalculationSelect.java: + Modified the available calculation modes and its order in the DESCRIBE + document. + + * src/main/resources/messages.properties, + src/main/resources/messages_de_DE.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: Adapted the names of + calculation modes. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java: + Added the hash code of an artifact to the artifact part of the + collection's DESCRIBE document. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Changed + the background color of discharge curves to white. + +2011-03-28 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java: + Cache the scale, too. Otherwise two calls to getValues() with + different arguments will result in the same output. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java: + Introduced a 'scale' parameter in the getValues() method. + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Filled + the out() operation with code that draws a discharge table of one or + more gauges specified by the given range in entered in a previous state. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/ChartExportHelper.java: + New. A helper class to exports charts. + + * pom.xml: Added dependencies to iText, Batik and JFreeChart. + +2011-03-28 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/importer/PegelGltParser.java: + Fixed swap of operands. + +2011-03-28 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/model/GaugesFactory.java: + New. Load gauges for a river and filter them for given + ranges. + +2011-03-25 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java: + Store data in a double [][] instead of interleaved double [] + to be compatible with org.jfree.data.xy.DefaultXYDataset. + +2011-03-25 Ingo Weinzierl + + * TODO: Removed 'i18n' and 'step-back' TODOs and added an issue to remove + the Backend reference from FLYSArtifactCollection. + +2011-03-25 Ingo Weinzierl + + * src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java: + Added missing artifact namespace of an attribute in the DESCRIBE + document. + +2011-03-24 Ingo Weinzierl + + * src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java: + New. This ArtifactCollection overrides the DefaultArtifactCollection to + implement FLYS specific describe() and out() operations. + + * doc/conf/conf.xml: Use the FLYSArtifactCollection instead of the + DefaultArtifactCollection for this application. + +2011-03-24 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java: + New. Fetches values of discharge tables in form of packed + w/q double arrays for given gauges. + + * src/main/java/de/intevation/flys/artifacts/model/RiverFactory.java: + Removed needless import. + +2011-03-24 Ingo Weinzierl + + * src/main/resources/messages_de_DE.properties: Added a german resource + bundle to avoid exceptions in the flys artifacts. Sometimes, the + Resources class is not able to find a 'de_DE' bundle and throws an + exception. This is really strange, because it should use the 'de' bundle + in that case, but it doesn't. + +2011-03-23 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Added + some code to append the output modes of previous states to the DESCRIBE + document. + + TODO: Determine if the current state is already filled with data and + append its output modes as well! + +2011-03-22 Ingo Weinzierl + + * doc/conf/artifacts/winfo.xml: Enhanced the location_distance state with + an output mode 'discharge_table'. + +2011-03-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + Write human readable strings as label attribute into the DESCRIBE + output. Those labels are used to be displayed in the GUI. + +2011-03-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/CalculationSelect.java: + Added some further calculation types. + + * src/main/resources/messages.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: Added i18n strings for the + calculation types + +2011-03-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: + Implemented the step-back part of the advance() operation. + +2011-03-21 Ingo Weinzierl + + * src/main/resources/messages_de.properties: Fixed a german umlaut. + +2011-03-18 Ingo Weinzierl + + * doc/conf/artifacts/winfo.xml: Added new states for entering a + location/distance and w/q. + + * src/main/resources/messages.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: New string for the + location/distance and w/q input states. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/WQSelect.java: + New. A state for the W/Q input of the WINFO parameterization. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + Append an attribute 'uiprovider' to the dynamic UI node. + + * src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java: + New. A state for the location/distance selection of the WINFO + parameterization. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + Added a new method getUIProvider() that might be overriden by concreted + subclasses that should be rendered with a specific UIProvider. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: + The static UI part is created by the previous states now. This makes it + possible to group the data objects (which is necessary to group the + objects in the ui). + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + Added a describeStatic() method that creates a node that contains the + data of that state. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/services/RiverService.java: + Removed TODO: the document contains the rivers provided by the backend + now. + +2011-03-17 Sascha L. Teichmann + + * pom.xml: Added dependency to flys backend. + + * src/main/java/de/intevation/flys/artifacts/model/River.java: + Removed. We are using the backend model now. + + * src/main/java/de/intevation/flys/artifacts/model/RiverFactory.java: + Fetches the rivers from the backend. + + * src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java: + Import fixes. + +2011-03-15 Sascha L. Teichmann + + * doc/conf/conf.xml: Added section for database backend configuration. + +2011-03-15 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java: + Fixed build error coming from different import of XMLUtils. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + Appended the missing label node that contains the human readable name of + the data item. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java, + src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + I18N of strings for the DESCRIBE document. + + * src/main/resources/messages.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: I18N strings for the + calculcation mode state. + +2011-03-14 Ingo Weinzierl + + * doc/conf/artifacts/winfo.xml: Modified the winfo states. + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Adapted + the artifact regarding the changes of the last commit. The states + describe() method creates the dynamic UI node - the artifact needs to + apply this node. + + * src/main/java/de/intevation/flys/artifacts/states/CalculationSelect.java: + New. The state for choosing the calculation mode. + + * src/main/resources/messages.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: Added i18n strings for the + calculation mode state. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java: + New. This is the base state for the FLYS application. It provides a + method that creates the dynamic ui node for the DESCRIBE. + + * src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java, + src/main/java/de/intevation/flys/artifacts/states/GaugeSelect.java: Both + classes extend the abstract base class DefaultState. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/resources/Resources.java: + New. This class retrieves the i18n strings from a ResourceBundle. + + * src/main/resources/messages.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: Resource files for german and + english translation. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Appended + the data that have been inserted in former states into the static node + of the DESCRIBE. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: The + operations feed() and advance() return the description of the artifact + using the describe() operation. This avoids additional server round trips + in the client - the clients gets to know about the new state of the + artifact immediately. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: + Implemented a part (step forward) of the advance operation. + + * TODO: Implement Step-Back in advance operation. + +2011-03-09 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: + Implemented the abstract method getName(). It returns the constant + 'winfo' string. + + * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: + Implemented the feed action. The data of an incoming feed() operation is + stored in StateData objects that are saved in a map in the artifact. + + NOTE: There is no input validation and no i18n of error messages (see + TODO). + +2011-03-09 Ingo Weinzierl + + * TODO: This file contains some open points that need to be done. + +2011-03-09 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: New. This + artifact serves as the default artifact for the FLYS application. + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: This + artifact now inherits from FLYSArtifact. Furthermore, there is one big + change: we don't store the State objects itself in the artifact, but + just the identifier of those. This makes the artifact smaller and more + compatible agains previous versions of the software. + +2011-03-08 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/services/RiverService.java: + New. This service will retrieve a list of provided rivers. + + * doc/conf/conf.xml: Added a configuration for the RiverService. + +2011-03-07 Ingo Weinzierl + + * doc/conf/conf.xml: Added a section user-factory and collection-factory in + the factories part of the configuration. + +2011-03-01 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java: + Replaced the 'special' attribute from DESCRIBE with a 'uiprovider' + attribute. + +2011-02-08 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: The + RiverSelect state is called to create the UI part of the describe + document. + + * src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java: + Implemented the dynamic UI part of describe(). The static part is not + inserted into the describe document at the moment. We need a reference to + the previous states for this. + +2011-02-08 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/model/RiverFactory.java, + src/main/java/de/intevation/flys/artifacts/model/River.java: New. A model + class that represents a river and its factory to create concrete river + instances. + NOTE: Currently, this is just a mockup. The factory just returns two + static rivers "Mosel" and "Saar" without a connection to a backend. + +2011-02-07 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/StateFactory.java: The + input data of a state is initialized with empty StateData objects after + the State has been created. + + * doc/conf/artifacts/winfo.xml: Renamed the input data nodes of the states + which now fits better to the class name of the implementation. + +2011-02-07 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: The + describe document returned by this artifact now contains the current state + and the reachable states. + +2011-02-07 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java: + The transitions are put into the TransitionEngine with the ID of the state + - not longer with the artifact name. On this way, we are able to fetch + just the transitions for a specific state, instead of all the transitions + of an artifact. + +2011-02-04 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Describe() + returns the artifact's uuid and hash value. The whole implementation of + describe() is still outstanding. + +2011-02-04 Ingo Weinzierl + + * doc/conf/artifacts/winfo.xml: Removed useless config stuff. + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Removed + useless methods, and improved the init process - the first state is set as + the current state for this artifact. + + * src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java, + src/main/java/de/intevation/flys/artifacts/states/GaugeSelect.java: New. + The states are used in the first two steps of the WINFOArtifact. + Currently, they just implement stubs of the necessary methods setup() and + describe(). + +2011-02-04 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/State.java, + src/main/java/de/intevation/flys/artifacts/transitions/TransitionEngine.java, + src/main/java/de/intevation/flys/artifacts/transitions/Transition.java: + Removed. These classes are placed in the artifact-database now. + + * src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java, + src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java: + Adapted imports of Transition. + + * src/main/java/de/intevation/flys/artifacts/states/StateFactory.java: New. + This factory should be used to create concrete State objects. + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java: Added + a constant key to store the StateEngine in the context. + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java: + New method that initializes the states at application start. + +2011-02-03 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/states/State.java: New. The + interface description of a state. + + * src/main/java/de/intevation/flys/artifacts/transitions/Transition.java, + src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java: + New. The interface description and a default implementation of a + transition. + + * src/main/java/de/intevation/flys/artifacts/transitions/TransitionEngine.java: + New. The TransitionEngine stores all transitions for each artifact and + should be used to determine, if an artifact can advance from one state to + another. + + * src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java: + New. Transitions should be created by using this class. + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java: New. + The Flys context. It currently defines keys to store important components + in the context. + + * src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java: + New. The context factory initializes the basic components of the + application. Currently, the TransitionEngine is created and all artifacts + with its transitions are read from the global configuration and stored in + the FLYSContext. + + * pom.xml: Added a dependency to the 'artifacts-common' package. + + * doc/conf/artifacts/winfo.xml: Corrected the classname of the + DefaultTransition. + + * doc/conf/conf.xml: Added FLYSContextFactory as context-factory. + +2011-02-02 Ingo Weinzierl + + * doc/conf/conf.xml: An initial configuration file for the FLYS artifact + server. + + * doc/conf/artifacts/winfo.xml: An initial transition configuration of an + WINFO artifact. + + * src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: A stub of + an artifact for a WINFO parameterization. + + * pom.xml: Set the source code version to 1.5. + +2011-02-01 Sascha L. Teichmann + + * src/**, pom.xml: Added initial maven project. + * ChangeLog: new. diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/TODO Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,4 @@ +- Validation of the input values of an incoming feed() call +- Remove the reference to Backend from FLYSArtifactCollection. Use the + methods of ArtifactDatabase (context.getDatabase()) to do the + necessary work. diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/doc/conf/artifacts/winfo.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/doc/conf/artifacts/winfo.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/doc/conf/conf.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/doc/conf/conf.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,61 @@ + + YOUR_SECRET + + de.intevation.flys.artifacts.context.FLYSContextFactory + + de.intevation.artifactdatabase.DefaultArtifactCollectionFactory + + + + de.intevation.artifactdatabase.DefaultArtifactFactory + + + de.intevation.artifactdatabase.DefaultUserFactory + + + de.intevation.artifactdatabase.DefaultServiceFactory + + + + + + + + + + + 8181 + localhost + + + + 60000 + + + + SA + + jdbc:h2:${artifacts.config.dir}/../artifactdb/artifacts.db + + + + diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/pom.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,79 @@ + + 4.0.0 + + de.intevation.flys.artifacts + flys-artifacts + 1.0-SNAPSHOT + jar + + flys-artifacts + http://maven.apache.org + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.5 + 1.5 + + + + + + + + jfree + jfreechart + 1.0.13 + + + junit + junit + 3.8.1 + test + + + de.intevation.bsh.artifact-database + artifact-database + 1.0-SNAPSHOT + + + de.intevation.artifacts.common + artifacts-common + 1.0-SNAPSHOT + + + de.intevation.flys + flys-backend + 1.0-SNAPSHOT + + + jfree + jfreechart + 1.0.13 + + + org.apache.xmlgraphics + batik-dom + 1.7 + + + org.apache.xmlgraphics + batik-svggen + 1.7 + + + com.lowagie + itext + 2.1.7 + + + diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/App.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/App.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +package de.intevation.flys.artifacts; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,437 @@ +package de.intevation.flys.artifacts; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.DefaultArtifact; +import de.intevation.artifactdatabase.data.DefaultStateData; +import de.intevation.artifactdatabase.data.StateData; +import de.intevation.artifactdatabase.state.State; +import de.intevation.artifactdatabase.state.StateEngine; +import de.intevation.artifactdatabase.transition.TransitionEngine; + +import de.intevation.flys.artifacts.context.FLYSContext; + + +/** + * The defaul FLYS artifact. + * + * @author Ingo Weinzierl + */ +public abstract class FLYSArtifact extends DefaultArtifact { + + /** The logger that is used in this artifact.*/ + private static Logger logger = Logger.getLogger(FLYSArtifact.class); + + + /** The XPath that points to the input data elements of the FEED document.*/ + public static final String XPATH_FEED_INPUT = + "/art:action/art:data/art:input"; + + /** The XPath that points to the name of the target state of ADVANCE.*/ + public static final String XPATH_ADVANCE_TARGET = + "/art:action/art:target/@art:name"; + + /** The constant string that shows that an operation was successful.*/ + public static final String OPERATION_SUCCESSFUL = "SUCCESS"; + + /** The constant string that shows that an operation failed.*/ + public static final String OPERATION_FAILED = "FAILURE"; + + + /** The identifier of the current state. */ + protected String currentStateId; + + /** The identifiers of previous states on a stack.*/ + protected Vector previousStateIds; + + /** The name of the artifact.*/ + protected String name; + + /** The data that have been inserted into this artifact.*/ + protected Map data; + + + /** + * The default constructor that creates an empty FLYSArtifact. + */ + public FLYSArtifact() { + data = new HashMap(); + previousStateIds = new Vector(); + } + + + /** + * Returns the name of the concrete artifact. + * + * @return the name of the concrete artifact. + */ + public abstract String getName(); + + + /** + * Returns the FLYSContext from context object. + * + * @param context The CallContext or the FLYSContext. + * + * @return the FLYSContext. + */ + protected FLYSContext getFlysContext(Object context) { + return context instanceof FLYSContext + ? (FLYSContext) context + : (FLYSContext) ((CallContext) context).globalContext(); + } + + + /** + * Initialize the artifact and insert new data if data contains + * information necessary for this artifact. + * + * @param identifier The UUID. + * @param factory The factory that is used to create this artifact. + * @param context The CallContext. + * @param data Some optional data. + */ + @Override + public void setup( + String identifier, + ArtifactFactory factory, + Object context, + Document data) + { + logger.debug("Setup this artifact with the uuid: " + identifier); + + super.setup(identifier, factory, context, data); + + FLYSContext flysContext = (FLYSContext) context; + StateEngine engine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + String name = getName(); + + logger.debug("Set initial state for artifact '" + name + "'"); + List states = engine.getStates(name); + + setCurrentState(states.get(0)); + } + + + /** + * Insert new data included in input into the current state. + * + * @param target XML document that contains new data. + * @param context The CallContext. + * + * @return a document that contains a SUCCESS or FAILURE message. + */ + @Override + public Document feed(Document target, CallContext context) { + logger.info("FLYSArtifact.feed()"); + + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element result = creator.create("result"); + doc.appendChild(result); + + try { + saveData(target, XPATH_FEED_INPUT); + return describe(target, context); + } + catch (IllegalArgumentException iae) { + creator.addAttr(result, "type", OPERATION_FAILED, true); + + // TODO I18N this message - getMessage() returns a lookup string, no + // human readable error message + result.setTextContent(iae.getMessage()); + } + + return doc; + } + + + /** + * This method handles request for changing the current state of an + * artifact. It is possible to step forward or backward. + * + * @param target The incoming ADVANCE document. + * @param context The CallContext. + * + * @return a document that contains a SUCCESS or FAILURE message. + */ + public Document advance(Document target, CallContext context) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element result = ec.create("result"); + + String targetState = XMLUtils.xpathString( + target, XPATH_ADVANCE_TARGET, ArtifactNamespaceContext.INSTANCE); + + logger.info("FLYSArtifact.advance() to '" + targetState + "'"); + + if (isStateReachable(targetState, context)) { + logger.info("Advance: Step forward"); + + Vector prev = getPreviousStateIds(); + prev.add(getCurrentStateId()); + + setCurrentStateId(targetState); + + return describe(target, context); + } + else if (isPreviousState(targetState, context)) { + logger.info("Advance: Step back to"); + + Vector prevs = getPreviousStateIds(); + int targetIdx = prevs.indexOf(targetState); + int start = prevs.size() - 1; + + for (int i = start; i >= targetIdx; i--) { + String prev = prevs.get(i); + logger.debug("Remove state id '" + prev + "'"); + prevs.remove(prev); + } + + setCurrentStateId(targetState); + + return describe(target, context); + } + + logger.warn("Advance: Cannot advance to '" + targetState + "'"); + ec.addAttr(result, "type", OPERATION_FAILED, true); + + doc.appendChild(result); + + return doc; + } + + + /** + * Returns the identifier of the current state. + * + * @return the identifier of the current state. + */ + protected String getCurrentStateId() { + return currentStateId; + } + + + /** + * Sets the identifier of the current state. + * + * @param id the identifier of a state. + */ + protected void setCurrentStateId(String id) { + currentStateId = id; + } + + + /** + * Set the current state of this artifact. NOTEWe don't store the + * State object itself - which is not necessary - but its identifier. So + * this method will just call the setCurrentStateId() method with the + * identifier of state. + * + * @param state The new current state. + */ + protected void setCurrentState(State state) { + setCurrentStateId(state.getID()); + } + + + /** + * Returns the current state of the artifact. + * + * @return the current State of the artifact. + */ + protected State getCurrentState(Object context) { + FLYSContext flysContext = getFlysContext(context); + StateEngine engine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + return engine.getState(getCurrentStateId()); + } + + + /** + * Returns the vector of previous state identifiers. + * + * @return the vector of previous state identifiers. + */ + protected Vector getPreviousStateIds() { + return previousStateIds; + } + + + /** + * Adds a new StateData item to the data pool of this artifact. + * + * @param name the name of the data object. + * @param data the data object itself. + */ + protected void addData(String name, StateData data) { + this.data.put(name, data); + } + + + /** + * This method returns a specific StateData object that is stored in the + * data pool of this artifact. + * + * @param name The name of the data object. + * + * @return the StateData object if existing, otherwise null. + */ + protected StateData getData(String name) { + return data.get(name); + } + + + /** + * This method stores the data that is contained in the FEED document. + * + * @param feed The FEED document. + * @param xpath The XPath that points to the data nodes. + */ + public void saveData(Document feed, String xpath) + throws IllegalArgumentException + { + if (feed == null || xpath == null || xpath.length() == 0) { + throw new IllegalArgumentException("feed.no.input.data"); + } + + NodeList nodes = (NodeList) XMLUtils.xpath( + feed, + xpath, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (nodes == null || nodes.getLength() == 0) { + throw new IllegalArgumentException("feed.no.input.data"); + } + + int count = nodes.getLength(); + logger.debug("Try to save " + count + " data items."); + + for (int i = 0; i < count; i++) { + Node node = nodes.item(i); + + String name = XMLUtils.xpathString( + node, "@art:name", ArtifactNamespaceContext.INSTANCE); + String value = XMLUtils.xpathString( + node, "@art:value", ArtifactNamespaceContext.INSTANCE); + + if (name != null && value != null) { + logger.debug("Save data item for '" + name + "' : " + value); + + // TODO ADD INPUT VALIDATION! + addData(name, new DefaultStateData(name, null, null, value)); + } + } + } + + + /** + * This method fills a state object with the data that have been inserted to + * this artifact. This is necessary to use the isStateReachable() method, + * because the Transitions need to know about the inserted data. + * + * @param state The state that needs to be filled with data. + * + * @return the filled state. + */ + protected State fillState(State state) { + Map stateData = state.getData(); + + if (stateData == null) { + return state; + } + + Set keys = stateData.keySet(); + + for (String key: keys) { + StateData tmp = getData(key); + + if (tmp != null) { + StateData data = stateData.get(key); + data.setValue(tmp.getValue()); + } + } + + return state; + } + + + /** + * Determines if the state with the identifier stateId is reachable + * from the current state. The determination itself takes place in the + * TransitionEngine. + * + * @param stateId The identifier of a state. + * @param context The context object. + * + * @return true, if the state specified by stateId is reacahble, + * otherwise false. + */ + protected boolean isStateReachable(String stateId, Object context) { + logger.debug("Determine if the state '" + stateId + "' is reachable."); + + FLYSContext flysContext = getFlysContext(context); + + State currentState = fillState(getCurrentState(context)); + StateEngine sEngine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + TransitionEngine tEngine = (TransitionEngine) flysContext.get( + FLYSContext.TRANSITION_ENGINE_KEY); + + return tEngine.isStateReachable(stateId, currentState, sEngine); + } + + + /** + * Determines if the state with the identifier stateId is a previous + * state of the current state. + * + * @param stateId The target state identifier. + * @param context The context object. + */ + protected boolean isPreviousState(String stateId, Object context) { + logger.debug("Determine if the state '" + stateId + "' is old."); + + Vector prevs = getPreviousStateIds(); + if (prevs.contains(stateId)) { + return true; + } + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,286 @@ +package de.intevation.flys.artifacts; + +import java.awt.Color; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import org.apache.log4j.Logger; + +import org.jfree.data.xy.DefaultXYDataset; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; + +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; + +import de.intevation.artifactdatabase.ProtocolUtils; +import de.intevation.artifactdatabase.state.Output; +import de.intevation.artifactdatabase.state.State; +import de.intevation.artifactdatabase.state.StateEngine; +import de.intevation.artifactdatabase.transition.TransitionEngine; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.flys.model.Gauge; + +import de.intevation.flys.artifacts.model.DischargeTables; +import de.intevation.flys.artifacts.model.GaugesFactory; +import de.intevation.flys.artifacts.states.DefaultState; +import de.intevation.flys.artifacts.context.FLYSContext; +import de.intevation.flys.exports.ChartExportHelper; + + +/** + * The default WINFO artifact. + * + * @author Ingo Weinzierl + */ +public class WINFOArtifact extends FLYSArtifact { + + /** The logger for this class */ + private static Logger logger = Logger.getLogger(WINFOArtifact.class); + + + /** The name of the artifact.*/ + public static final String ARTIFACT_NAME = "winfo"; + + /** XPath */ + public static final String XPATH_STATIC_UI ="/art:result/art:ui/art:static"; + + + /** + * The default constructor. + */ + public WINFOArtifact() { + } + + + /** + * This method returns a description of this artifact. + * + * @param data Some data. + * @param context The CallContext. + * + * @return the description of this artifact. + */ + public Document describe(Document data, CallContext context) { + logger.debug("Describe: the current state is: " + getCurrentStateId()); + + FLYSContext flysContext = null; + if (context instanceof FLYSContext) { + flysContext = (FLYSContext) context; + } + else { + flysContext = (FLYSContext) context.globalContext(); + } + + StateEngine stateEngine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + TransitionEngine transitionEngine = (TransitionEngine) flysContext.get( + FLYSContext.TRANSITION_ENGINE_KEY); + + List reachable = transitionEngine.getReachableStates( + getCurrentState(context), stateEngine); + + Document description = XMLUtils.newDocument(); + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + description, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element root = ProtocolUtils.createRootNode(creator); + description.appendChild(root); + + State current = getCurrentState(context); + + ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash()); + ProtocolUtils.appendState(creator, root, current); + ProtocolUtils.appendReachableStates(creator, root, reachable); + + Element ui = ProtocolUtils.createArtNode( + creator, "ui", null, null); + + Element staticUI = ProtocolUtils.createArtNode( + creator, "static", null, null); + + Element outs = ProtocolUtils.createArtNode( + creator, "outputmodes", null, null); + appendOutputModes(description, outs, context, identifier()); + + appendStaticUI(description, staticUI, context, identifier()); + + Element dynamic = current.describe( + description, + root, + context, + identifier()); + + if (dynamic != null) { + ui.appendChild(dynamic); + } + + ui.appendChild(staticUI); + + root.appendChild(ui); + root.appendChild(outs); + + return description; + } + + + @Override + public void out( + Document format, + OutputStream out, + CallContext context) + throws IOException + { + logger.info("WINFOArtifact.out"); + String river = (String) getData("river").getValue(); + String from = (String) getData("ld_from").getValue(); + String to = (String) getData("ld_to").getValue(); + + double f = Double.parseDouble(from); + double t = Double.parseDouble(to); + + List ranges = new ArrayList(); + ranges.add(new double [] { f, t }); + + List gauges = GaugesFactory.getGauges(river); + List filtered = GaugesFactory.filterRanges(gauges, ranges); + + if (logger.isDebugEnabled()) { + int numGauges = gauges != null ? gauges.size() : 0; + int numFiltered = filtered != null ? filtered.size() : 0; + + logger.debug("++++++++++++++++++++"); + logger.debug("Search gauges for river: " + river); + logger.debug("-> ... from range: " + from); + logger.debug("-> ... to range: " + to); + logger.debug("-> Found " + numGauges + " gauges in total."); + logger.debug("-> Found " + numFiltered + " gauges after filtering."); + logger.debug("++++++++++++++++++++"); + } + + String[] gaugeNames = new String[filtered.size()]; + int idx = 0; + for (Gauge gauge: filtered) { + gaugeNames[idx++] = gauge.getName(); + } + + DischargeTables dt = new DischargeTables(river, gaugeNames); + Map gaugeValues = dt.getValues(100d); + + DefaultXYDataset dataset = new DefaultXYDataset(); + + for (String gauge: gaugeNames) { + double[][] values = gaugeValues.get(gauge); + dataset.addSeries(gauge, values); + } + + JFreeChart chart = ChartFactory.createXYLineChart( + "Abflusskurven (" + river + ")", + "Q", "W", + dataset, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + ChartExportHelper.exportImage( + out, + chart, + "png", + 600, 400); + } + + + /** + * Returns the name of the concrete artifact. + * + * @return the name of the concrete artifact. + */ + public String getName() { + return ARTIFACT_NAME; + } + + + protected void appendOutputModes( + Document doc, + Element outs, + CallContext context, + String uuid) + { + Vector stateIds = getPreviousStateIds(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + FLYSContext flysContext = getFlysContext(context); + StateEngine engine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + for (String stateId: stateIds) { + logger.debug("Append output modes for state: " + stateId); + State state = engine.getState(stateId); + + List list = state.getOutputs(); + if (list == null || list.size() == 0) { + continue; + } + + ProtocolUtils.appendOutputModes(creator, outs, list); + } + + // TODO If the current state is already filled with data, the output is + // available as well! So we need some code to append the outputs of the + // current already filled state. + } + + + /** + * This method appends the static data - that has already been inserted by + * the user - to the static node of the DESCRIBE document. + * + * @param doc The document. + * @param ui The root node. + * @param context The CallContext. + * @param uuid The identifier of the artifact. + */ + protected void appendStaticUI( + Document doc, + Node ui, + CallContext context, + String uuid) + { + Vector stateIds = getPreviousStateIds(); + + FLYSContext flysContext = getFlysContext(context); + StateEngine engine = (StateEngine) flysContext.get( + FLYSContext.STATE_ENGINE_KEY); + + for (String stateId: stateIds) { + logger.debug("Append static data for state: " + stateId); + DefaultState state = (DefaultState) engine.getState(stateId); + ui.appendChild(state.describeStatic(doc, ui, context, uuid)); + } + + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,44 @@ +package de.intevation.flys.artifacts.context; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +import de.intevation.artifactdatabase.DefaultArtifactContext; + + +/** + * This class is used to store application wide information in a global context. + * + * @author Ingo Weinzierl + */ +public class FLYSContext extends DefaultArtifactContext { + + /** The logger used in this class */ + private static Logger logger = Logger.getLogger(FLYSContext.class); + + /** The key that is used to store the TransitionEngine in the context */ + public static final String TRANSITION_ENGINE_KEY = + "artifact.transition.engine"; + + /** The key that is used to store the StateEngine in the context */ + public static final String STATE_ENGINE_KEY = + "artifact.state.engine"; + + + /** + * The default constructor. + */ + public FLYSContext() { + super(); + } + + + /** + * A constructor with a config document. + */ + public FLYSContext(Document config) { + super(config); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,190 @@ +package de.intevation.flys.artifacts.context; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import de.intevation.artifacts.ArtifactContextFactory; + +import de.intevation.artifacts.common.utils.XMLUtils; +import de.intevation.artifacts.common.utils.Config; + +import de.intevation.artifactdatabase.state.State; +import de.intevation.artifactdatabase.state.StateEngine; +import de.intevation.artifactdatabase.transition.Transition; +import de.intevation.artifactdatabase.transition.TransitionEngine; + +import de.intevation.flys.artifacts.states.StateFactory; +import de.intevation.flys.artifacts.transitions.TransitionFactory; + + +/** + * The ArtifactContextFactory is used to initialize basic components and put + * them into the global context of the application. + * + * @author Ingo Weinzierl + */ +public class FLYSContextFactory implements ArtifactContextFactory { + + /** The logger that is used in this class */ + private static Logger logger = Logger.getLogger(FLYSContextFactory.class); + + /** The XPath to the artifacts configured in the configuration. */ + public static final String XPATH_ARTIFACTS = + "/artifact-database/artifacts/artifact"; + + /** The XPath to the name of the artifact. */ + public static final String XPATH_ARTIFACT_NAME = "/artifact/@name"; + + /** The XPath to the xlink ref in an artifact configuration. */ + public static final String XPATH_XLINK = "xlink:href"; + + /** The XPath to the transitions configured in the artifact config. */ + public static final String XPATH_TRANSITIONS = + "/artifact/states/transition"; + + /** The XPath to the states configured in the artifact config. */ + public static final String XPATH_STATES = + "/artifact/states/state"; + + /** + * Creates a new FLYSArtifactContext object and initialize all + * components required by the application. + * + * @param config The artifact server configuration. + * @return a FLYSArtifactContext. + */ + public Object createArtifactContext(Document config) { + FLYSContext context = new FLYSContext(config); + + configureTransitions(config, context); + configureStates(config, context); + + return context; + } + + + /** + * This method initializes the transition configuration. + * + * @param config the config document. + * @param context the FLYSContext. + */ + protected void configureTransitions(Document config, FLYSContext context) { + TransitionEngine engine = new TransitionEngine(); + + Document[] artifacts = getArtifactConfigurations(config); + logger.info("Found " + artifacts.length + " artifacts in the config."); + + for (Document doc: artifacts) { + List transitions = new ArrayList(); + + String artName = (String) XMLUtils.xpath( + doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); + + NodeList list = (NodeList) XMLUtils.xpath( + doc, XPATH_TRANSITIONS, XPathConstants.NODESET); + + if (list == null) { + logger.warn("The artifact has no transitions configured."); + continue; + } + + int trans = list.getLength(); + + logger.info( + "Artifact '" + artName + "' has " + trans + " transitions."); + + for (int i = 0; i < trans; i++) { + Transition t = TransitionFactory.createTransition(list.item(i)); + String s = t.getFrom(); + engine.addTransition(s, t); + } + } + + context.put(FLYSContext.TRANSITION_ENGINE_KEY, engine); + } + + + /** + * This method returns all artifact documents defined in + * config.
NOTE: The artifact configurations need to be + * stored in own files referenced by an xlink. + * + * @param config The global configuration. + * + * @return an array of Artifact configurations. + */ + protected Document[] getArtifactConfigurations(Document config) { + NodeList artifacts = (NodeList) XMLUtils.xpath( + config, XPATH_ARTIFACTS, XPathConstants.NODESET); + + int count = artifacts.getLength(); + + Document[] artifactDocs = new Document[count]; + + for (int i = 0; i < count; i++) { + Element tmp = (Element) artifacts.item(i); + + String xlink = tmp.getAttribute(XPATH_XLINK); + xlink = Config.replaceConfigDir(xlink); + + File artifactFile = new File(xlink); + artifactDocs[i] = XMLUtils.parseDocument(artifactFile); + } + + return artifactDocs; + } + + + /** + * This method initializes the transition configuration. + * + * @param config the config document. + * @param context the FLYSContext. + */ + protected void configureStates(Document config, FLYSContext context) { + StateEngine engine = new StateEngine(); + + Document[] artifacts = getArtifactConfigurations(config); + logger.info("Found " + artifacts.length + " artifacts in the config."); + + for (Document doc: artifacts) { + List states = new ArrayList(); + + String artName = (String) XMLUtils.xpath( + doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); + + NodeList stateList = (NodeList) XMLUtils.xpath( + doc, XPATH_STATES, XPathConstants.NODESET); + + if (stateList == null) { + logger.warn("The artifact has no states configured."); + continue; + } + + int count = stateList.getLength(); + + logger.info( + "Artifact '" + artName + "' has " + count + " states."); + + for (int i = 0; i < count; i++) { + states.add(StateFactory.createState( + stateList.item(i))); + } + + engine.addStates(artName, states); + } + + context.put(FLYSContext.STATE_ENGINE_KEY, engine); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,110 @@ +package de.intevation.flys.artifacts.model; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Arrays; + +import java.io.Serializable; + +import org.hibernate.SessionFactory; +import org.hibernate.Session; +import org.hibernate.Query; + +import org.apache.log4j.Logger; + +import de.intevation.flys.backend.SessionFactoryProvider; + +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.DischargeTable; +import de.intevation.flys.model.DischargeTableValue; + +public class DischargeTables +implements Serializable +{ + private static Logger log = Logger.getLogger(DischargeTables.class); + + protected List gaugeNames; + + protected String riverName; + + protected double scale; + + protected Map values; + + public DischargeTables() { + } + + public DischargeTables(String riverName, String [] gaugeNames) { + this(riverName, Arrays.asList(gaugeNames)); + } + + public DischargeTables(String riverName, List gaugeNames) { + scale = Double.NaN; + this.riverName = riverName; + this.gaugeNames = gaugeNames; + } + + public Map getValues(double scale) { + if (values == null || scale != this.scale) { + values = loadValues(scale); + this.scale = scale; + } + return values; + } + + protected Map loadValues(double scale) { + Map values = new HashMap(); + + SessionFactory sf = SessionFactoryProvider.getSessionFactory(); + Session session = sf.openSession(); + + try { + Query gaugeQuery = session.createQuery( + "from Gauge where name=:gauge and river.name=:river"); + gaugeQuery.setParameter("river", riverName); + + for (String gaugeName: gaugeNames) { + gaugeQuery.setParameter("gauge", gaugeName); + List gauges = gaugeQuery.list(); + if (gauges.isEmpty()) { + log.warn( + "no gauge '"+gaugeName+"' at river '"+riverName+"'"); + continue; + } + Gauge gauge = gauges.get(0); + + List tables = gauge.getDischargeTables(); + + if (tables.isEmpty()) { + log.warn( + "no discharge table for gauge '" + gaugeName + "'"); + continue; + } + + // TODO: Filter by time interval + DischargeTable table = tables.get(0); + + List dtvs = + table.getDischargeTableValues(); + + double [][] vs = new double[2][dtvs.size()]; + + int idx = 0; + for (DischargeTableValue dtv: dtvs) { + vs[0][idx] = dtv.getQ().doubleValue() * scale; + vs[1][idx] = dtv.getW().doubleValue() * scale; + ++idx; + } + + values.put(gaugeName, vs); + } + + return values; + } + finally { + session.close(); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugesFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugesFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.flys.artifacts.model; + +import java.util.List; +import java.util.ArrayList; + +import de.intevation.flys.backend.SessionFactoryProvider; + +import de.intevation.flys.model.River; +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.Range; + +import org.hibernate.SessionFactory; +import org.hibernate.Session; +import org.hibernate.Query; + +public class GaugesFactory +{ + public static List getGauges(River river) { + return getGauges(river.getName()); + } + + public static List getGauges(String river) { + SessionFactory sf = SessionFactoryProvider.getSessionFactory(); + Session session = sf.openSession(); + try { + Query query = session.createQuery( + "from Gauge where river.name=:name"); + query.setParameter("name", river); + return query.list(); + } + finally { + session.close(); + } + } + + public static List filterRanges( + List gauges, + List ranges + ) { + // XXX: Inefficent! + ArrayList rs = new ArrayList(); + for (double [] range: ranges) { + double a = range[0]; + double b = range[1]; + rs.add(new Range(Math.min(a, b), Math.max(a, b), null)); + } + return filter(gauges, rs); + } + + public static List filter(List gauges, List ranges) { + // TODO: Make it an HQL filter! + ArrayList out = new ArrayList(); + for (Gauge gauge: gauges) { + Range range = gauge.getRange(); + for (Range cmp: ranges) { + if (range.intersects(cmp)) { + out.add(gauge); + break; + } + } + } + return out; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RiverFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RiverFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,40 @@ +package de.intevation.flys.artifacts.model; + + +import java.util.List; + +import de.intevation.flys.model.River; + +import de.intevation.flys.backend.SessionFactoryProvider; + +import org.hibernate.SessionFactory; +import org.hibernate.Session; + +/** + * @author Ingo Weinzierl + */ +public class RiverFactory { + + /** We don't need to instantiate concrete objects of this class. */ + private RiverFactory() { + } + + + /** + * Returns all rivers that were found in the backend. + * + * @return all rivers. + */ + public static List getRivers() { + SessionFactory sf = SessionFactoryProvider.getSessionFactory(); + Session session = sf.openSession(); + try { + return (List)session + .createQuery("from River order by name").list(); + } + finally { + session.close(); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/resources/Resources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/resources/Resources.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,106 @@ +package de.intevation.flys.artifacts.resources; + +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.apache.log4j.Logger; + +import de.intevation.artifacts.CallMeta; + +/** + * This class provides methods for i18n. + * + * @author Ingo Weinzierl + */ +public class Resources { + + /** The logger that is used in this class.*/ + private static Logger logger = Logger.getLogger(Resources.class); + + /** The singleton instance.*/ + private static Resources INSTANCE; + + /** The locales supported by this server.*/ + protected Locale[] locales; + + /** + * No instance of this class is necessary. + */ + private Resources() { + } + + + /** + * Returns the locales supported by this server. + * + * @return the supported locales. + */ + public Locale[] getLocales() { + if (locales == null) { + readLocales(); + } + + return locales; + } + + + /** + * Read the locales configured for this server. + */ + protected void readLocales() { + // TODO IMPLEMENT ME + + locales = new Locale[2]; + locales[0] = Locale.GERMANY; + locales[1] = Locale.ENGLISH; + } + + + /** + * This method returns the translated value for key or def if + * key is not existing in the resource bundle. + * + * @param meta The CallMeta object of the request that contains the + * preferred locale. + * @param key The key that should be translated. + * @param def A default value that is returned, if key was not found. + * + * @return the translated message. + */ + public static String getMsg(CallMeta meta, String key, String def) { + if (INSTANCE == null) { + INSTANCE = new Resources(); + } + + Locale[] locales = INSTANCE.getLocales(); + Locale locale = meta.getPreferredLocale(locales); + + return getMsg(locale, key, def); + } + + + /** + * This method returns the translated value for key or def if + * key is not existing in the resource bundle. + * + * @param locale The locale. + * @param key The key that should be translated. + * @param def A default value that is returned, if key was not found. + * + * @return the translated message. + */ + public static String getMsg(Locale locale, String key, String def) { + ResourceBundle bundle = ResourceBundle.getBundle("messages", locale); + + try { + return bundle.getString(key); + } + catch (MissingResourceException mre) { + logger.warn("No message found for key: " + key); + + return def; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/RiverService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/RiverService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,71 @@ +package de.intevation.flys.artifacts.services; + +import java.util.List; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import de.intevation.artifacts.CallMeta; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.DefaultService; + +import de.intevation.flys.model.River; + +import de.intevation.flys.artifacts.model.RiverFactory; + + +/** + * This service provides information about the supported rivers by this + * application. + * + * @author Ingo Weinzierl + */ +public class RiverService extends DefaultService { + + /** The logger used in this service.*/ + private static Logger logger = Logger.getLogger(RiverService.class); + + + /** + * The default constructor. + */ + public RiverService() { + } + + + public Document process( + Document data, + Object globalContext, + CallMeta callMeta) + { + logger.debug("RiverService.process"); + + Document result = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + result, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + List allRivers = RiverFactory.getRivers(); + + Element rivers = ec.create("rivers"); + + for (River river: allRivers) { + Element r = ec.create("river"); + ec.addAttr(r, "name", river.getName(), true); + + rivers.appendChild(r); + } + + result.appendChild(rivers); + + return result; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/CalculationSelect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/CalculationSelect.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,92 @@ +package de.intevation.flys.artifacts.states; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Element; + +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.ProtocolUtils; + +import de.intevation.flys.artifacts.resources.Resources; + +/** + * @author Ingo Weinzierl + */ +public class CalculationSelect extends DefaultState { + + /** The logger that is used in this class.*/ + private static Logger logger = Logger.getLogger(CalculationSelect.class); + + + /** Constant value for the reference line calculation.*/ + public static final String CALCULATION_SURFACE_CURVE = + "calc.surface.curve"; + + /** Constant value for the differences calculation.*/ + public static final String CALCULATION_DURATION_CURVE = + "calc.duration.curve"; + + /** Constant value for the flood map calculation.*/ + public static final String CALCULATION_FLOOD_MAP = + "calc.flood.map"; + + /** Constant value for the profile calculation.*/ + public static final String CALCULATION_DISCHARGE_LONGITUDINAL_CURVE = + "calc.discharge.longitudinal.section"; + + /** Constant value for the state discharge curve calculation.*/ + public static final String CALCULATION_DISCHARGE_CURVE = + "calc.discharge.curve"; + + /** An array that holds all available calculation modes.*/ + public static final String[] CALCULATIONS = { + CALCULATION_SURFACE_CURVE, + CALCULATION_FLOOD_MAP, + CALCULATION_DISCHARGE_CURVE, + CALCULATION_DURATION_CURVE, + CALCULATION_DISCHARGE_LONGITUDINAL_CURVE }; + + + protected Element[] createItems( + XMLUtils.ElementCreator cr, + String name, + CallContext context) + { + CallMeta meta = context.getMeta(); + Element[] calcs = new Element[CALCULATIONS.length]; + + int i = 0; + + for (String calc: CALCULATIONS) { + calcs[i++] = createItem( + cr, new String[] { + Resources.getMsg(meta, calc, calc), + calc + }); + } + + return calcs; + } + + + protected Element createItem(XMLUtils.ElementCreator cr, Object obj) { + Element item = ProtocolUtils.createArtNode(cr, "item", null, null); + Element label = ProtocolUtils.createArtNode(cr, "label", null, null); + Element value = ProtocolUtils.createArtNode(cr, "value", null, null); + + String[] arr = (String[]) obj; + + label.setTextContent(arr[0]); + value.setTextContent(arr[1]); + + item.appendChild(label); + item.appendChild(value); + + return item; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DefaultState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DefaultState.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,187 @@ +package de.intevation.flys.artifacts.states; + +import java.util.Collection; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.ProtocolUtils; +import de.intevation.artifactdatabase.data.StateData; +import de.intevation.artifactdatabase.state.AbstractState; + +import de.intevation.flys.artifacts.resources.Resources; + + +/** + * @author Ingo Weinzierl + */ +public abstract class DefaultState extends AbstractState { + + /** The logger that is used in this class.*/ + private static Logger logger = Logger.getLogger(DefaultState.class); + + + public Element describeStatic( + Document document, + Node root, + CallContext context, + String uuid) + { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + CallMeta meta = context.getMeta(); + + String label = Resources.getMsg(meta, getID(), getID()); + Element ui = ProtocolUtils.createArtNode( + creator, "state", + new String[] { "name", "uiprovider", "label" }, + new String[] { getID(), getUIProvider(), label }); + + Map theData = getData(); + if (theData == null) { + return ui; + } + + Collection dataItems = theData.values(); + + for (StateData data: dataItems) { + String name = data.getName(); + String value = (String) data.getValue(); + + logger.debug("Append element '" + name + "' (" + value + ")"); + + Element dataElement = creator.create("data"); + creator.addAttr(dataElement, "name", name, true); + creator.addAttr(dataElement, "type", data.getType(), true); + + Element itemElement = creator.create("item"); + creator.addAttr(itemElement, "value", value, true); + creator.addAttr( + itemElement, + "label", + Resources.getMsg(meta, value, value), + true); + + dataElement.appendChild(itemElement); + ui.appendChild(dataElement); + } + + return ui; + } + + + public Element describe( + Document document, + Node root, + CallContext context, + String uuid) + { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element ui = null; + String uiprovider = getUIProvider(); + if (uiprovider != null) { + ui = ProtocolUtils.createArtNode( + creator, "dynamic", + new String[] { "uiprovider" }, + new String[] { uiprovider }); + } + else { + ui = ProtocolUtils.createArtNode(creator, "dynamic", null, null); + } + + Map theData = getData(); + if (theData == null) { + return ui; + } + + Collection dataItems = theData.values(); + + for (StateData data: dataItems) { + String name = data.getName(); + Element select = createData(creator, data, context); + + Element choices = ProtocolUtils.createArtNode( + creator, "choices", null, null); + + select.appendChild(choices); + ui.appendChild(select); + + Element[] items = createItems(creator, name, context); + for (Element item: items) { + choices.appendChild(item); + } + } + + return ui; + } + + + /** + * This method creates the root node that contains the list of selectable + * items. + * + * @param cr The ElementCreator. + * @param name The name of the amount of data. + * + * @return the root node of the item list. + */ + protected Element createData( + XMLUtils.ElementCreator cr, + StateData data, + CallContext context) + { + Element select = ProtocolUtils.createArtNode( + cr, "select", null, null); + cr.addAttr(select, "name", data.getName(), true); + + Element label = ProtocolUtils.createArtNode( + cr, "label", null, null); + + select.appendChild(label); + + label.setTextContent(Resources.getMsg( + context.getMeta(), + getID(), + getID())); + + return select; + } + + + /** + * This method creates a list of items. These items represent the amount of + * input data that is possible for this state. + * + * @param cr The ElementCreator. + * @param name The name of the amount of data. + * + * @return a list of items. + */ + protected abstract Element[] createItems( + XMLUtils.ElementCreator cr, + String name, + CallContext context); + + + protected String getUIProvider() { + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/GaugeSelect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/GaugeSelect.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.flys.artifacts.states; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifacts.CallContext; + +import de.intevation.artifactdatabase.state.AbstractState; + + +/** + * @author Ingo Weinzierl + */ +public class GaugeSelect extends AbstractState { + + /** The logger used in this class. */ + private static Logger logger = Logger.getLogger(GaugeSelect.class); + + /** + * The default constructor that initializes an empty GaugeState object. + */ + public GaugeSelect() { + super(null, null); + } + + + public void setup(Node config) { + super.setup(config); + } + + + public Element describe( + Document document, + Node root, + CallContext context, + String uuid) + { + // TODO Implement me + logger.error("Currently not implemented."); + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,105 @@ +package de.intevation.flys.artifacts.states; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Element; + +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.ProtocolUtils; +import de.intevation.artifactdatabase.data.StateData; + +import de.intevation.flys.artifacts.resources.Resources; + +/** + * @author Ingo Weinzierl + */ +public class LocationDistanceSelect extends DefaultState { + + /** The logger used in this class.*/ + private static Logger logger = Logger.getLogger(LocationDistanceSelect.class); + + + /** The default step width.*/ + public static final String DEFAULT_STEP = "100"; + + /** + * The default constructor that initializes an empty State object. + */ + public LocationDistanceSelect() { + } + + protected Element createData( + XMLUtils.ElementCreator cr, + StateData data, + CallContext context) + { + Element select = ProtocolUtils.createArtNode( + cr, "select", null, null); + + cr.addAttr(select, "name", data.getName(), true); + + Element label = ProtocolUtils.createArtNode( + cr, "label", null, null); + + Element choices = ProtocolUtils.createArtNode( + cr, "choices", null, null); + + label.setTextContent(Resources.getMsg( + context.getMeta(), + data.getName(), + data.getName())); + + select.appendChild(label); + + return select; + } + + + protected Element[] createItems( + XMLUtils.ElementCreator cr, + String name, + CallContext context) + { + // TODO Insert correct min/max values! + + if (name.equals("ld_from")) { + Element min = createItem(cr, new String[] {"min", "1"}); + return new Element[] { min }; + } + else if (name.equals("ld_to")) { + Element max = createItem(cr, new String[] {"max", "10"}); + return new Element[] { max }; + } + else { + Element step = createItem(cr, new String[] {"step", DEFAULT_STEP}); + return new Element[] { step }; + } + + } + + + protected Element createItem(XMLUtils.ElementCreator cr, Object obj) { + Element item = ProtocolUtils.createArtNode(cr, "item", null, null); + Element label = ProtocolUtils.createArtNode(cr, "label", null, null); + Element value = ProtocolUtils.createArtNode(cr, "value", null, null); + + String[] arr = (String[]) obj; + + label.setTextContent(arr[0]); + value.setTextContent(arr[1]); + + item.appendChild(label); + item.appendChild(value); + + return item; + } + + + protected String getUIProvider() { + return "location_distance_panel"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,115 @@ +package de.intevation.flys.artifacts.states; + +import java.util.List; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.ProtocolUtils; +import de.intevation.artifactdatabase.data.StateData; + +import de.intevation.flys.model.River; + +import de.intevation.flys.artifacts.model.RiverFactory; + +import de.intevation.flys.artifacts.resources.Resources; + + +/** + * @author Ingo Weinzierl + */ +public class RiverSelect extends DefaultState { + + /** The logger used in this class. */ + private static Logger logger = Logger.getLogger(RiverSelect.class); + + /** + * The default constructor that initializes an empty State object. + */ + public RiverSelect() { + } + + + /** + * Initialize the state based on the state node in the configuration. + * + * @param config The state configuration node. + */ + public void setup(Node config) { + super.setup(config); + } + + + protected Element createData( + XMLUtils.ElementCreator cr, + StateData data, + CallContext context) + { + Element select = ProtocolUtils.createArtNode( + cr, "select", + new String[] { "uiprovider" }, + new String[] { "select_with_map" }); + cr.addAttr(select, "name", data.getName()); + + Element label = ProtocolUtils.createArtNode( + cr, "label", null, null); + + Element choices = ProtocolUtils.createArtNode( + cr, "choices", null, null); + + label.setTextContent(Resources.getMsg( + context.getMeta(), + getID(), + getID())); + + return select; + } + + + protected Element[] createItems( + XMLUtils.ElementCreator cr, + String name, + CallContext context) + { + List rivers = RiverFactory.getRivers(); + Element[] items = new Element[rivers.size()]; + + int idx = 0; + for (River river: rivers) { + items[idx++] = createRiverItem(cr, river); + } + + return items; + } + + + /** + * This method creates a node that represents a river item. This node + * contains the label and the value that describe the river. + * + * @param cr The ElementCreator. + * @param river The river. + * + * @return the element that contains the information about the river. + */ + protected Element createRiverItem(XMLUtils.ElementCreator cr, River river) { + Element item = ProtocolUtils.createArtNode(cr, "item", null, null); + Element label = ProtocolUtils.createArtNode(cr, "label", null, null); + Element value = ProtocolUtils.createArtNode(cr, "value", null, null); + + label.setTextContent(river.getName()); + value.setTextContent(river.getName()); + + item.appendChild(label); + item.appendChild(value); + + return item; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StateFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StateFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.flys.artifacts.states; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifactdatabase.data.DefaultStateData; +import de.intevation.artifactdatabase.state.State; + +import de.intevation.artifacts.common.utils.XMLUtils; + + +/** + * @author Ingo Weinzierl + */ +public class StateFactory { + + /** The logger used in this class */ + private static Logger logger = Logger.getLogger(StateFactory.class); + + /** The XPath to the classname of the state */ + public static final String XPATH_STATE = "@state"; + + /** The XPath to the data items of the state relative to the state node. */ + public static final String XPATH_DATA = "data"; + + /** The XPath to the data name relative to the data node.*/ + public static final String XPATH_DATA_NAME = "@name"; + + /** The XPath to the data type relative to the data node.*/ + public static final String XPATH_DATA_TYPE = "@type"; + + /** The XPath to the data description relative to the data node.*/ + public static final String XPATH_DATA_DESCRIPTION = "@description"; + + + /** + * Creates a new State based on the configured class provided by + * stateConf. + * + * @param stateConf The configuration of the state. + * + * @return a State. + */ + public static State createState(Node stateConf) { + String clazz = (String) XMLUtils.xpath( + stateConf, XPATH_STATE, XPathConstants.STRING); + + State state = null; + + try { + logger.debug("Create a new State for class: " + clazz); + state = (State) Class.forName(clazz).newInstance(); + state.setup(stateConf); + + initializeStateData(state, stateConf); + } + catch (InstantiationException ie) { + logger.error(ie, ie); + } + catch (IllegalAccessException iae) { + logger.error(iae, iae); + } + catch (ClassNotFoundException cnfe) { + logger.error(cnfe, cnfe); + } + + return state; + } + + + /** + * This method extracts the configured input data of a state and adds new + * StateData objects to the State. + * + * @param state The state. + * @param stateConf The state configuration node. + */ + protected static void initializeStateData(State state, Node stateConf) { + NodeList dataList = (NodeList) XMLUtils.xpath( + stateConf, XPATH_DATA, XPathConstants.NODESET); + + if (dataList == null || dataList.getLength() == 0) { + logger.debug("The state has no input data configured."); + + return; + } + + int items = dataList.getLength(); + + logger.debug("The state has " + items + " data items configured."); + + for (int i = 0; i < items; i++) { + Node data = dataList.item(i); + + String name = (String) XMLUtils.xpath( + data, XPATH_DATA_NAME, XPathConstants.STRING); + String type = (String) XMLUtils.xpath( + data, XPATH_DATA_TYPE, XPathConstants.STRING); + String desc = (String) XMLUtils.xpath( + data, XPATH_DATA_DESCRIPTION, XPathConstants.STRING); + + if (name == null || name.equals("")) { + logger.warn("No name for data item at pos " + i + " found."); + continue; + } + + if (type == null || type.equals("")) { + logger.warn("No type for data item at pos " + i + " found."); + logger.warn("Default type 'string' used."); + type = "string"; + } + + state.addData(name, new DefaultStateData(name, type, desc)); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQSelect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQSelect.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,110 @@ +package de.intevation.flys.artifacts.states; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Element; + +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.ProtocolUtils; +import de.intevation.artifactdatabase.data.StateData; + +import de.intevation.flys.artifacts.resources.Resources; + +/** + * @author Ingo Weinzierl + */ +public class WQSelect extends DefaultState { + + /** The logger used in this class.*/ + private static Logger logger = Logger.getLogger(WQSelect.class); + + + /** The default step width for Qs.*/ + public static final String DEFAULT_STEP_Q = "50"; + + /** The default step width for Qs.*/ + public static final String DEFAULT_STEP_W = "30"; + + /** + * The default constructor that initializes an empty State object. + */ + public WQSelect() { + } + + protected Element createData( + XMLUtils.ElementCreator cr, + StateData data, + CallContext context) + { + Element select = ProtocolUtils.createArtNode( + cr, "select", null, null); + + cr.addAttr(select, "name", data.getName(), true); + + Element label = ProtocolUtils.createArtNode( + cr, "label", null, null); + + Element choices = ProtocolUtils.createArtNode( + cr, "choices", null, null); + + label.setTextContent(Resources.getMsg( + context.getMeta(), + data.getName(), + data.getName())); + + select.appendChild(label); + + return select; + } + + + protected Element[] createItems( + XMLUtils.ElementCreator cr, + String name, + CallContext context) + { + // TODO Insert correct min/max values! + + if (name.equals("wq_from")) { + Element minW = createItem(cr, new String[] {"minW", "250"}); + Element minQ = createItem(cr, new String[] {"minQ", "5.5"}); + return new Element[] { minW, minQ }; + } + else if (name.equals("wq_to")) { + Element maxW = createItem(cr, new String[] {"maxW", "850"}); + Element maxQ = createItem(cr, new String[] {"maxQ", "1530"}); + return new Element[] { maxW, maxQ }; + } + else { + Element stepW = createItem(cr, new String[] {"stepW", DEFAULT_STEP_W}); + Element stepQ = createItem(cr, new String[] {"stepQ", DEFAULT_STEP_Q}); + return new Element[] { stepW, stepQ }; + } + } + + + protected Element createItem(XMLUtils.ElementCreator cr, Object obj) { + Element item = ProtocolUtils.createArtNode(cr, "item", null, null); + Element label = ProtocolUtils.createArtNode(cr, "label", null, null); + Element value = ProtocolUtils.createArtNode(cr, "value", null, null); + + String[] arr = (String[]) obj; + + label.setTextContent(arr[0]); + value.setTextContent(arr[1]); + + item.appendChild(label); + item.appendChild(value); + + return item; + } + + + protected String getUIProvider() { + return "wq_panel"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,90 @@ +package de.intevation.flys.artifacts.transitions; + +import de.intevation.artifactdatabase.state.State; +import de.intevation.artifactdatabase.transition.Transition; + +/** + * The default implementation of a Transition. + * + * @author Ingo Weinzierl + */ +public class DefaultTransition implements Transition { + + /** The ID of the current state */ + protected String from; + + /** The ID of the target state */ + protected String to; + + + /** + * The default constructor. + */ + public DefaultTransition() { + } + + + /** + * The default constructor. + * + * @param from The current state. + * @param to The target state. + */ + public DefaultTransition(String from, String to) { + this.from = from; + this.to = to; + } + + + /** + * Returns the current state ID. + * + * @return the current state ID. + */ + public String getFrom() { + return from; + } + + + /** + * Returns the target state ID. + * + * @return the target state ID. + */ + public String getTo() { + return to; + } + + + /** + * Set the current state ID. + * + * @param to the current state ID. + */ + public void setFrom(String from) { + this.from = from; + } + + + /** + * Set the target state ID. + * + * @param to the target state ID. + */ + public void setTo(String to) { + this.to = to; + } + + + /** + * This method always returns true. + * + * @param state The target state. + * + * @return true. + */ + public boolean isValid(State state) { + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,70 @@ +package de.intevation.flys.artifacts.transitions; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + +import de.intevation.artifactdatabase.transition.Transition; + +import de.intevation.artifacts.common.utils.XMLUtils; + + +/** + * @author Ingo Weinzierl + */ +public class TransitionFactory { + + /** The logger used in this class */ + private static Logger logger = Logger.getLogger(TransitionFactory.class); + + /** The XPath to the classname of the transition */ + public static final String XPATH_TRANSITION = "@transition"; + + /** The XPath to the current state ID */ + public static final String XPATH_CURRENT_STATE = "from/@state"; + + /** The XPath to the target state ID */ + public static final String XPATH_TARGET_STATE = "to/@state"; + + + /** + * Creates a new Transition based on the configured class provided by + * transitionConf. + * + * @param transitionConf The configuration of the transition. + * + * @return a Transition. + */ + public static Transition createTransition(Node transitionConf) { + String clazz = (String) XMLUtils.xpath( + transitionConf, XPATH_TRANSITION, XPathConstants.STRING); + + Transition transition = null; + + try { + transition = (Transition) Class.forName(clazz).newInstance(); + + String from = (String) XMLUtils.xpath( + transitionConf, XPATH_CURRENT_STATE, XPathConstants.STRING); + String to = (String) XMLUtils.xpath( + transitionConf, XPATH_TARGET_STATE, XPathConstants.STRING); + + transition.setFrom(from); + transition.setTo(to); + } + catch (InstantiationException ie) { + logger.error(ie, ie); + } + catch (IllegalAccessException iae) { + logger.error(iae, iae); + } + catch (ClassNotFoundException cnfe) { + logger.error(cnfe, cnfe); + } + + return transition; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,117 @@ +package de.intevation.flys.collections; + +import java.util.Date; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CollectionItem; + +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifactdatabase.DefaultArtifactCollection; +import de.intevation.artifactdatabase.Backend; +import de.intevation.artifactdatabase.Backend.PersistentArtifact; + + +/** + * @author Ingo Weinzierl + */ +public class FLYSArtifactCollection extends DefaultArtifactCollection { + + /** The logger used in this class.*/ + private static Logger log = Logger.getLogger(FLYSArtifactCollection.class); + + + /** Constant XPath that points to the outputmodes of an artifact.*/ + public static final String XPATH_ARTIFACT_OUTPUTMODES = + "/art:result/art:outputmodes"; + + + @Override + public Document describe(CallContext context) { + log.debug("FLYSArtifactCollection.describe: " + identifier); + + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Date creationTime = getCreationTime(); + String creation = creationTime != null + ? Long.toString(creationTime.getTime()) + : ""; + + Element collection = ec.create("artifact-collection"); + Element artifacts = ec.create("artifacts"); + + ec.addAttr(collection, "name", getName(), true); + ec.addAttr(collection, "uuid", identifier(), true); + ec.addAttr(collection, "creation", creation, true); + + collection.appendChild(artifacts); + doc.appendChild(collection); + + Document attribute = getAttribute(); + if (attribute != null) { + Node child = attribute.getFirstChild(); + collection.appendChild(doc.importNode(child, true)); + } + + Backend backend = Backend.getInstance(); + CollectionItem[] items = backend.listCollectionArtifacts(identifier()); + + for (CollectionItem item: items) { + artifacts.appendChild( + buildArtifactNode(item, backend, context, ec)); + } + + return doc; + } + + + protected Element buildArtifactNode( + CollectionItem item, + Backend backend, + CallContext context, + XMLUtils.ElementCreator ec) + { + String uuid = item.getArtifactIdentifier(); + + log.debug("Append artifact '"+ uuid +"' to collection description"); + + PersistentArtifact pArtifact = backend.getArtifact(uuid); + Artifact artifact = pArtifact.getArtifact(); + + Element ci = ec.create("artifact"); + ec.addAttr(ci, "uuid", uuid, true); + ec.addAttr(ci, "hash", artifact.hash(), true); + + // XXX I am not sure if it works well every time with an empty document + // in the describe operation of an artifact. + Document description = artifact.describe(null, context); + Node outputModes = (Node) XMLUtils.xpath( + description, + XPATH_ARTIFACT_OUTPUTMODES, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + + if (outputModes != null) { + Document doc = ci.getOwnerDocument(); + ci.appendChild(doc.importNode(outputModes, true)); + } + + return ci; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/java/de/intevation/flys/exports/ChartExportHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartExportHelper.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.flys.exports; + +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.PageSize; +import com.lowagie.text.Rectangle; + +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfTemplate; +import com.lowagie.text.pdf.PdfWriter; + +import java.awt.Graphics2D; +import java.awt.Transparency; + +import java.awt.geom.Rectangle2D.Double; + +import java.awt.geom.Rectangle2D; + +import java.awt.image.BufferedImage; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import javax.imageio.ImageIO; + +import org.apache.batik.svggen.SVGGraphics2D; +import org.apache.batik.svggen.SVGGraphics2DIOException; + +import org.apache.log4j.Logger; + +import org.jfree.chart.JFreeChart; + +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.utils.XMLUtils; + + +/** + * This class is a helper class which supports some methods to export charts + * into specific formats. + * + * @author Ingo Weinzierl + */ +public class ChartExportHelper { + + /** + * Constant field to define A4 as default page size. + */ + private static final String DEFAULT_PAGE_SIZE = "A4"; + + /** + * Constant field to define UTF-8 as default encoding. + */ + private static final String DEFAULT_ENCODING = "UTF-8"; + + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(ChartExportHelper.class); + + + /** + * A method to export a JFreeChart as image to an + * OutputStream with a given format, width and height. + * + * @param out OutputStream + * @param chart JFreeChart object to be exported. + * @param format Format (e.g. png, gif, jpg) + * @param width Width, the image used to be + * @param height Height, the image used to be + * + * @throws IOException if writing image to OutputStream failed. + */ + public static void exportImage( + OutputStream out, + JFreeChart chart, + String format, + int width, + int height + ) + throws IOException + { + log.info("export chart as png"); + + ImageIO.write( + chart.createBufferedImage( + width, height, Transparency.BITMASK, null + ), + format, + out + ); + } + + + /** + * A method to export a JFreeChart as SVG to an + * OutputStream. + * + * @param out OutputStream + * @param chart JFreeChart to be exported + * @param encoding Encoding, defaults to {@link #DEFAULT_ENCODING} if null + * @param width Width the svg used to be + * @param height Height the svg used to be + */ + public static void exportSVG( + OutputStream out, + JFreeChart chart, + String encoding, + int width, + int height + ) { + log.info("export chart as svg"); + + if (encoding == null) + encoding = DEFAULT_ENCODING; + + org.w3c.dom.Document document = XMLUtils.newDocument(); + SVGGraphics2D graphics = new SVGGraphics2D(document); + + chart.draw(graphics, new Rectangle2D.Double(0.0D, 0.0D,width,height)); + + try { + graphics.stream(new OutputStreamWriter(out, encoding)); + } + catch (SVGGraphics2DIOException svge) { + log.error("Error while writing svg export to output stream.", svge); + } + catch (UnsupportedEncodingException uee) { + log.error("Unsupported encoding: " + encoding, uee); + } + } + + + /** + * A method to export a JFreeChart as PDF to an + * OutputStream. + * + * @param out OutputStream + * @param chart JFreeChart + * @param pageFormat String to specify a page format, {@link + * #DEFAULT_PAGE_SIZE} is used if no pageFormat is given + * @param landscape If this is true, the pdf is delivered in landscape + * format + * @param marginLeft Space to left border + * @param marginRight Space to right border + * @param marginTop Space to upper border + * @param marginBottom Space to lower border + */ + public static void exportPDF( + OutputStream out, + JFreeChart chart, + String pageFormat, + float marginLeft, + float marginRight, + float marginTop, + float marginBottom, + CallContext context + ) { + log.info("export chart as pdf."); + + if (pageFormat == null) + pageFormat = DEFAULT_PAGE_SIZE; + + // max size of the chart + Rectangle page = PageSize.getRectangle(pageFormat); + float pageWidth = page.getWidth(); + float pageHeight = page.getHeight(); + + // the chart width + int chartWidth = (Integer) context.getContextValue("chart.width"); + int chartHeight = (Integer) context.getContextValue("chart.height"); + + boolean landscape = chartWidth > chartHeight ? true : false; + + float width = 0; + float height = 0; + if (landscape) { + width = pageHeight; + height = pageWidth; + } + else { + width = pageWidth; + height = pageHeight; + } + + float spaceX = width - marginLeft - marginRight; + if (chartWidth > spaceX) { + log.warn("Width of the chart is too big for pdf -> resize it now."); + double ratio = ((double)spaceX) / chartWidth; + chartWidth *= ratio; + chartHeight *= ratio; + log.debug("Resized chart to " + chartWidth + "x" + chartHeight); + } + + float spaceY = height - marginTop - marginBottom; + if (chartHeight > spaceY) { + log.warn("Height of the chart is too big for pdf -> resize it now."); + double ratio = ((double)spaceY) / chartHeight; + chartWidth *= ratio; + chartHeight *= ratio; + log.debug("Resized chart to " + chartWidth + "x" + chartHeight); + } + + Document document = null; + if (landscape) { + document = new Document(page.rotate()); + log.debug("Create landscape pdf."); + } + else + document = new Document(page); + + try { + PdfWriter writer = PdfWriter.getInstance(document, out); + + document.addSubject(chart.getTitle().getText()); + document.addCreationDate(); + document.open(); + + PdfContentByte content = writer.getDirectContent(); + + PdfTemplate template = content.createTemplate(width, height); + Graphics2D graphics = template.createGraphics(width, height); + + double[] origin = getCenteredAnchor( + marginLeft, marginRight, marginBottom, marginTop, + width, height, + chartWidth, chartHeight); + + Rectangle2D area = new Rectangle2D.Double( + origin[0], origin[1], chartWidth, chartHeight); + + chart.draw(graphics, area); + graphics.dispose(); + content.addTemplate(template, 0f, 0f); + } + catch (DocumentException de) { + log.error("Error while exporting chart to pdf.", de); + } + finally { + document.close(); + } + } + + + /** + * This method returns the anchor of the chart so that the chart is centered + * according to the given parameters. + * + * @param mLeft Left margin + * @param mRight Right margin + * @param mBottom Bottom margin + * @param mTop Top margin + * @param width The complete width of the drawing area. + * @param height The complete height of the drawing area. + * @param chartWidth The width of the chart. + * @param chartHeight The height of the chart. + * + * @return an array that contains the anchor for a chart with the given + * parameters. The first value is the x point, the second value is the y + * point. + */ + public static double[] getCenteredAnchor( + double mLeft, double mRight, double mBottom, double mTop, + double width, double height, + double chartWidth, double chartHeight + ) { + if (log.isDebugEnabled()) { + log.debug("Calculate centered origin..."); + log.debug("-> PDF width : " + width); + log.debug("-> PDF height : " + height); + log.debug("-> Chart width : " + chartWidth); + log.debug("-> Chart height : " + chartHeight); + log.debug("-> margin left : " + mLeft); + log.debug("-> margin right : " + mRight); + log.debug("-> margin bottom: " + mBottom); + log.debug("-> margin top : " + mTop); + } + + double[] origin = new double[2]; + + double centerX = width / 2; + double centerY = height / 2; + + origin[0] = centerX - chartWidth / 2; + origin[1] = centerY - chartHeight / 2; + + origin[0] = origin[0] >= mLeft ? origin[0] : mLeft; + origin[1] = origin[1] >= mTop ? origin[1] : mTop; + + if (log.isDebugEnabled()) { + log.debug("==> centered left origin: " + origin[0]); + log.debug("==> centered top origin: " + origin[1]); + } + + return origin; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/resources/messages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/resources/messages.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +state.winfo.river = River +state.winfo.calculation_mode = Calculation Mode +state.winfo.location_distance = Location or distance selection +state.winfo.wq = Input for W/Q data + +calc.surface.curve = Water Level/Surface Curve +calc.flood.map = Flood Plain +calc.discharge.curve = State Discharge Curve/Stage Discharge Relation +calc.duration.curve = Duration Curve +calc.discharge.longitudinal.section = TODO (W bei...) + +river = River +calculation_mode = Calculation Mode diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/resources/messages_de.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/resources/messages_de.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +state.winfo.river = Gew\u00e4sser +state.winfo.calculation_mode = Berechnungsart +state.winfo.location_distance = Wahl des Berechnungsortes/strecke +state.winfo.wq = Eingabe f\u00fcr W/Q Daten + +calc.surface.curve = Wasserstand/Wasserspiegellage +calc.flood.map = \u00dcberschwemmungsfl\u00e4che +calc.discharge.curve = Abflusskurve/Abflusstafel +calc.duration.curve = Dauerlinie +calc.discharge.longitudinal.section = W bei ungleichm\u00e4\u00dfigem Abflussl\u00e4ngsschnitt + +river = Fluss +calculation_mode = Berechnungsart diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/resources/messages_de_DE.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/resources/messages_de_DE.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +state.winfo.river = Gew\u00e4sser +state.winfo.calculation_mode = Berechnungsart +state.winfo.location_distance = Wahl des Berechnungsortes/strecke +state.winfo.wq = Eingabe f\u00fcr W/Q Daten + +calc.surface.curve = Wasserstand/Wasserspiegellage +calc.flood.map = \u00dcberschwemmungsfl\u00e4che +calc.discharge.curve = Abflusskurve/Abflusstafel +calc.duration.curve = Dauerlinie +calc.discharge.longitudinal.section = W bei ungleichm\u00e4\u00dfigem Abflussl\u00e4ngsschnitt + +river = Fluss +calculation_mode = Berechnungsart diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/main/resources/messages_en.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/resources/messages_en.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +state.winfo.river = River +state.winfo.calculation_mode = Calculation Mode +state.winfo.location_distance = Location or distance selection +state.winfo.wq = Input for W/Q data + +calc.surface.curve = Water Level/Surface Curve +calc.flood.map = Flood Plain +calc.discharge.curve = State Discharge Curve/Stage Discharge Relation +calc.duration.curve = Duration Curve +calc.discharge.longitudinal.section = TODO (W bei...) + +river = River +calculation_mode = Calculation Mode diff -r 5391c329168c -r 2b745b5e731c flys-artifacts/src/test/java/de/intevation/flys/artifacts/AppTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/test/java/de/intevation/flys/artifacts/AppTest.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.flys.artifacts; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff -r 5391c329168c -r 2b745b5e731c flys-client/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/.classpath Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,11 @@ + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/.project --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/.project Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,15 @@ + + + FLYS + FLYS project + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.jdt.core.javanature + + diff -r 5391c329168c -r 2b745b5e731c flys-client/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/ChangeLog Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,1230 @@ +2011-03-30 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Removed some comments that have been commited by mistaken. + +2011-03-30 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Derives the ConstantsWithLookup interface now. This makes it possible to + fetch i18n string using a getString(String key) lookup method. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Removed '@DefaultMessage' annotations - they are not available for + ConstantsWithLookup, added a further i18n string and fixed another one. + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Some modifications related to the changes above. + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Removed the hard coded title determination based on the selected module. + Now, the getString() of FLYSMessages is used to determine the human + readable string. + +2011-03-30 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java, + src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java, + src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java, + src/main/java/de/intevation/flys/client/client/FLYS.java, + src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java, + src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java: + Removed useless imports. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYS.java: The + CollectionView no longer gets an empty collection when it is created. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java: + The CollectionViews are no longer stored in a Map but in a List. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Bugfix: We just create a new collection a single time - if no one is + existing. If the output modes of the artifact that is used for the + parameterization changes, we fetch the new DESCRIBE document of the + collection using the new DescribeCollectionService. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java, + src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java: + New. This service is used to fetch the DESCRIBE document of a specific + collection and returns a Collection object that contains the information of + that document. The code to parse the DESCRIBE has been moved here from + the AddArtifactServiceImpl which now derives the + DescribeCollectionServiceImpl. + + * src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java: + This service is derived from DescribeCollectionServiceImpl now, because + the methods to parse the DESCRIBE document are moved to that service. + + * src/main/webapp/WEB-INF/web.xml: Registered the + DescribeCollectionService. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Replaced the german title of the project list 'Berechnungen' with + 'Projekte'. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYS.java: Registered the + ProjectList as CollectionChangeHandler of each created CollectionView. + + * src/main/java/de/intevation/flys/client/client/ui/ProjectList.java: + Implements the CollectionChangeHandler to update the list of user + collections after a collection changed (or has been created). + + * src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java, + src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java: + Modified the output of the 'name' and 'date' fields. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Added a format for datetime strings. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java, + src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java: + New. This service returns a list of Collections owned by a specified + user. + + * src/main/webapp/WEB-INF/web.xml: Registered the UserCollectionsService. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java, + src/main/java/de/intevation/flys/client/shared/model/Collection.java: + Added methods to retrieve the creation time. + +2011-03-29 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Fixed code + in ProjectList toggle method. + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: Fixed + the WQInputPanel label to have the correct size. + +2011-03-29 Raimund Renkert + + * src/main/webapp/FLYS.html: Added style information to avoid the smartgwt + theme margin. + +2011-03-29 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Changed some german strings. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Changed tab title. + +2011-03-29 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: Set + label width to have a tabled style for WINFO selections. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Resized window to fit the content size. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + The ParameterList is a Tab now and can set its title itself. So, the + title will change after the module is chosen. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Removed code to insert the ParameterList into a new Tab. This is no longer + needed, because the ParameterList is a Tab itself. + +2011-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Modified the string that points to the 'back button' image. + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + Modified the URL that points to the 'back button' image. Now, the + base URL is taken into account as well. The button will be shown + everywhere now (in every installation)! + +2011-03-29 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: Set + label width to have a tabled style for WINFO selections. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Resized window to fit the content size. + +2011-03-29 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Fixed + toggle method. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java: + A CollectionItem has a hash() method now. The value comes from the + Collection's DESCRIBE document. + + * src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java: + The hash value of a collection item is parsed from DESCRIBE document. + + * src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java: + Appended the hash value of the artifact to the URL of the chart image. + This bypasses the browser cache of a previous chart image. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + A parameterization change will always remove all output tabs before + updating the output tab panel. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Modified existing string and added a new one. + + * src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + Added a further radio button for a plugin and changed the alignment of + the radio button to vertical. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java: + Removed the "TODO: ThemeEditor" label. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Removed the date string from title bar. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/UIProvider.java, + src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + A UIProvider might now have a panel that can be used to render helper + widgets. E.g. the river selection will render its river map into this + panel. It is injected and can be placed somewhere around the + application. + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Injected the right panel of the parameter panel into the UIProvider. + Helper widgets are rendered into this panel now! + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java, + src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + Some layout improvements (heights, position of elements and so far). + +2011-03-28 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: The project + list button toggles the project list now. + +2011-03-28 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + Replaced next button image with smartgwt button. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Removed + button path, added text for new button. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties: + Removed image path, added english text for button. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Removed image path, added german text for button. + +2011-03-28 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added text + for FLYSFooter. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Added german text for footer label. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java: New. A + new ui element at the bottom of the page. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: Added footer + element to FLYS webpage. + +2011-03-28 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/ProjectList.java: + Customized ProjectList style. + * src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: Set + background color and size constraints. + + * src/main/webapp/FLYS.css: Added background style. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java: + The right side of this panel displays an image now. This image + represents a chart that is generated by an artifact. The request is made + up in the ChartOutputServiceImpl. + + * src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java: + New. This service creates the request to retrieve chart images and + writes the response to the output stream. + + NOTE: This service is not asynchron! It is derived directly from + HttpServlet. + + * src/main/webapp/WEB-INF/web.xml: Registered the ChartOutputService. + +2011-03-25 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Limited the area for CollectionView to the size of FLYSWorkspace. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: Fixed + a typo. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java: + An OutputTab with two panels. The left one is not implemented yet + (ThemeEditor). The right one will display an image. + + * src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: The + content pane is set in the constructor. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + New output tabs will use the ChartOutputTab. + + NOTE: We should move the code that constructs the concrete output tabs + into a factory class that decides which OutputTab has to be used. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + The tab bar is extended with output tabs if the artifact used for the + parameterization reaches a state with output modes. + + * src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: A + base class that might be used to derive concrete output tabs for charts, + maps and so on. + +2011-03-28 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java, + src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Moved parameterization specific code from CollectionView to + ParameterList. + +2011-03-26 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java, + src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Moved ParameterList specific code into the ParameterList. + +2011-03-25 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java, + src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java, + src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java: + Changed the return type to 'Collection' - returned a UUID (String) + before. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + The artifact is put into the collection (or new collection) if we reach + a step in the parameterization in that an artifact has reachable + outputs. Furthermore, some adjustments related to the changes of the + return type in the CreateCollectionService. + +2011-03-25 Ingo Weinzierl + + * src/main/webapp/WEB-INF/web.xml: Made the AddArtifactService accessible. + +2011-03-25 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java, + src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java: + New. This service adds an existing artifact to an existing collection. + The return value of this service is a Collection that is filled with + CollectionItems and OutputModes. + +2011-03-25 Raimund Renkert + + * src/main/java/de/intevation/flys/client/FLYS.gwt.xml: Changed theme to + smartgwt Enterprise Blue. + +2011-03-25 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/Facet.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultFacet.java: + New. An interface and its default implementation that provide methods + to get information about facets. Currently, the only information that is + supported is the name of the facet. + + * src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java: + New. An interface and its default implementation that provide methods to + get information about the available output modes and its facets of + artifacts -> a CollectionItem is related to an artifact - both have the + same identifier. + + * src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java, + src/main/java/de/intevation/flys/client/shared/model/Collection.java: + The Collection no longer stores references to artifacts, but to + CollectionItems. I have changed this, because the artifact contains a + lot more information we need for the Collections. So, I decided to + create CollectionItems that are related to artiacts but just know about + the possible outputmodes and facets. + +2011-03-24 Raimund Renkert + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Set styles + for label. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java: Fixed the + method to calculate the image width and resized the BfG logo. + + * src/main/webapp/FLYS.css: Introduced styles for fonts and BfG colorscheme. + +2011-03-23 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + Extract the output modes from DESCRIBE document and fill the + ArtifactDescription with those objects. + +2011-03-23 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java: + Added a method to retrieve the available output modes of the artifact. + + * src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java: + Implemented the method to retrieve the available output modes and + enhanced the default constructor with a parameter for output modes. + +2011-03-23 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/OutputMode.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java: + New. An interface and its default implementation that describes + available output modes of artifacts. + +2011-03-21 Ingo Weinzierl + + * src/main/webapp/images/next.xcf: Moved to images/next.xcf to avoid that + this file is included in the WAR archive of the web application. + + * images/next.xcf: Moved from src/main/webapp/images/next.xcf. + +2011-03-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + Parse the selected values as human readable strings from the static UI + part. + + * src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Display human readable values in the static UI part. + +2011-03-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/event/HasStepBackHandlers.java, + src/main/java/de/intevation/flys/client/client/event/StepBackHandler.java, + src/main/java/de/intevation/flys/client/client/event/StepBackEvent.java: + New. These classes are used to realize a notification mechanism to + listen to the step-back part of the advance() operation. UI elements + should fire a StepBackEvent if the user tries to step back to a previous + state. + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + The UIProvider implements the HasStepBackHandlers interface and fires + StepBackEvents if the 'back' button has been clicked. + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Listens to StepBackEvents. If such an event is received, we gonna remove + all old state items from the list and revert the view. Afterwards, the + artifact description is used to redraw the whole view. + + NOTE: I think we should just remove those items that belong to states + between the current state and the target state. This would avoid a + complete refresh of the ParameterPanel. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Listens to StepBackEvents. If such an event is received, the advance() + operation is triggerd with the current artifact and the new target + state identifier to step back to that state. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java, + src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java: + The methods that validates a FormItem will skip StaticTextItem + validation. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + Added a mechanism to validate and save user input before returning the + data entered in the fields. + Reason: the BlurEvent - after that we gonne validate and save the input + stuff - is not fired when the focus is still in one of the text fields + and we click the 'next' button immediately. A nullpointer exception + would be the result (which is avoided with the mechanism). + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Added localized strings that point to the source of the 'back' button. + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + Added a new method that creates the 'back' button and returns it. + + TODO: Fire an event that triggers the ADVANCE action. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Append the 'back' button in the panel with the 'old' parameters. + + * src/main/webapp/images/back.png, + src/main/webapp/images/back_en.png, + src/main/webapp/images/back_de.png: New. Images für the 'back' button in + the parameterization. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + localized strings that point to the images of the 'next' button. + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + There is a method that creates the 'next' button, adds the UIProvider as + ClickHandler and returns the button. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/ParameterList.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java, + src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + The 'next' button is created in the AbstractUIProvider. So, we have a + central place to adjust the look of this button. + + * src/main/webapp/images/next.xcf, + src/main/webapp/images/next.png, + src/main/webapp/images/next_en.png, + src/main/webapp/images/next_de.png: Images for the 'next' button in the + parameterization. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + Read min/max values and define those values as default values for the + distance modes. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java: + Read min/max values and define those values as default values for the + distance mode. + +2011-03-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + When a state is reached with no further user input, the 'current' + property of the ParameterList is set to 'null' and no dynamic panel is + shown. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Fixed a typo. + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + The widgets displayed in the static panel are created using the + UIProvider defined in the DataList. + + * src/main/java/de/intevation/flys/client/client/ui/UIProvider.java: There + is a new method createOld() that is used to create the static + representation of a DataList. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Implemented the createOld() method. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DataList.java: + Added a constructor to create a DataList with a label. + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + Read the label of the static state data objects and create the DataList + objects with this attribute. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DataList.java: This + data structure manages a list of Data objects. A DataList is the list of + Data objects that a single State can have. So, this class has methods to + retrieve the name of the state it belongs to, the list of Data objects, + the recommended UIProvider and a label. + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java, + src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java, + src/main/java/de/intevation/flys/client/shared/model/Data.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultData.java, + src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java, + src/main/java/de/intevation/flys/client/client/ui/ParameterList.java, + src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java, + src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java, + src/main/java/de/intevation/flys/client/client/ui/UIProvider.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java, + src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + Necessary refactoring to introduce the DataList data structure to manage + the list of Data objects a single State provides. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Added a bit more space between the values that have been entered in + former states and the current input panel. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/UserServiceImpl.java, + src/main/java/de/intevation/flys/client/shared/model/Data.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultData.java, + src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java, + src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Removed needless imported. + + * src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + The SelectProvider extends the AbstractUIProvider now. Now, each + concrete UIProvider is an instance of the AbstractUIProvider that + handles some basic events. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + The Single-W panel is displayed initially when the WQInputPanel is + rendered. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + Implemented some methods to retrieve the data that have been entered by + the user. The getData() method retrieves data now! + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java: + Implemented some methods to retrieve the data that have been entered by + the user. The getData() method retrieves data now! + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + Defined the 'WINFO' plugin as default plugin. The initial view will + display a preselcted winfo radio button. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java: + Added the missing 'next' button. + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + Added the ClickHandler to the 'next' button. + +2011-03-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java: + The 'uiprovider' attribute 'wq_panel' will return a WQInputPanel + provider. + +2011-03-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java: + Some refactoring. This class now uses the DoubleRangePanel and + DoubleArrayPanel for the two different input modes as well. + +2011-03-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings used in the WQInputPanel. + + * src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java: + New. This panel contains three input fields that enables the user to + enter a start and end value and a step width. Furthermore, there are + methods to validate the fields and to retrieve its values. + + * src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java: + New. This panel contains a single input field that enables the user to + enter a list of double values. There is a method to validate the input + and a method to retrieve the list of entered double values. + + * src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: + New. This panel allows the user to enter W or Q values for single or + range input in one single state. + +2011-03-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings used in the LocationDistancePanel. + + * src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java: + New. This abstract class implements the UIProvider and the + HasStepForwardHandlers interface and its necessary methods. These two + things are required by each concrete UIProvider, so this class should be + the base class for further concrete UIProviders. + + * src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java: + New. A UIProvider that enables the user to enter locations or a + distance. + + * src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java: + States with a uiprovider attribute set to 'location_distance_panel' use + the LocationDistancePanel for user input. + +2011-03-15 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Clear the panel that displays the current input widget before adding a + new one to this panel. + +2011-03-15 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + a i18n string for a new calculation. + + * src/main/java/de/intevation/flys/client/client/FLYSImages.java, + src/main/java/de/intevation/flys/client/client/images/gewkarte.png: New + image: the map that shows the relevant rivers. + + * src/main/java/de/intevation/flys/client/client/ui/MapSelection.java: + Added the river map to the right panel of that widget. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Implemented the step forward mechanism. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java, + src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + Save the name of the data item. We need the name for feed(). + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: + Before adding further old data items, we gonna check if the item is + already existing in the list. If it exists, the item is not added. + +2011-03-14 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Read i18n strings from DESCRIBE document and display them in the UI. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Integrated the mechnism to listen on paramer changes. The CollectionView + is both: a HasParameterChangeHandler and a ParameterChangeHandler. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Bugfix: Removed static string from gui. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + Parse the static data from DESCRIBE document and put it into the + ArtifactDescription. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/event/HasParameterChangeHandler.java, + src/main/java/de/intevation/flys/client/client/event/ParameterChangeHandler.java, + src/main/java/de/intevation/flys/client/client/event/ParameterChangeEvent.java: + New. Interfaces and classes used for a listener mechanism to notify + listeners when the parameterization of a Collection/Artifact has + changed. + +2011-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/StepForwardService.java, + src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java: + New. This service bundles the artifact operations feed() and advance() + into a single service. + + * src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/AdvanceService.java, + src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java: + New. This service provides a method that triggers the advance() operation + of the artifact server. + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + Added code to parse the reachable states from DESCRIBE. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Make use of the 'forward' service after choosing the module and the river. + + * src/main/webapp/WEB-INF/web.xml: Registered the new services 'forward' and + 'advance'. + +2011-03-09 Ingo Weinzierl + + * src/test/java/de/intevation/flys/client/FLYSJUnit.gwt.xml, + src/main/java/de/intevation/flys/client/client/GreetingServiceAsync.java, + src/main/java/de/intevation/flys/client/client/GreetingService.java: + Removed the GreetingService from out application - this service has been + added initially by creating this repository. + +2011-03-09 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings for the module and river selection. + + * src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java: + New. A wrapper for the module and river selection. Both information can + be chosen in just one step. + + * src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: + Some layout improvements. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Makes use of the ModuleSelection if no artifact is existing in a new + CollectionView. Users may now choose the desired plugin and the river in + one single step. + +2011-03-09 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/RiverService.java, + src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java: + New. A service that retrieves a list of supported rivers by the artifact + server. + + * src/main/java/de/intevation/flys/client/shared/model/River.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultRiver.java: + New. A model class and its default implementation to store rivers. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: At application + start, the provided rivers by the artifact server are fetched using the + RiverService. The rivers are queriable via a getRivers() method. + + * src/main/webapp/WEB-INF/web.xml: Registered the RiverService. + +2011-03-08 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings used in the menu panel. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: Added a method + to retrieve the project list. + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Added + further buttons (labels with ClickHandler) to switch the language, + logout the current user or open an info panel. + +2011-03-08 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/images/flys_logo.gif, + src/main/java/de/intevation/flys/client/client/images/bfg_logo.gif: New. + A logo of the BfG and a logo of the application FLYS. Both copied from + desktop FLYS. + + * src/main/java/de/intevation/flys/client/client/FLYSImages.java: New. + This interface grants access to the images used in this application. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: + Added the fullname of FLYS. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java: New. + This class displays the header containing a FLYS and a BfG logo. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: Integrated the + FLYSHeader into the layout at the bottom of the application. + + * src/main/webapp/FLYS.html: Set the title of the application to + "FLYS-3.0". + +2011-03-07 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java, + src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java, + src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java: + New. A service that might be used to create new collections in the + artifact server. + + * src/main/webapp/WEB-INF/web.xml: Registered the service to create new + collections. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Added the service to create new collections. Currently, this service is + not used. + +2011-03-07 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DefaultUser.java, + src/main/java/de/intevation/flys/client/shared/model/User.java: A user + interface and its default implementation. + + * src/main/java/de/intevation/flys/client/client/services/UserService.java, + src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java, + * src/main/java/de/intevation/flys/client/server/UserServiceImpl.java: This + service will currently return the first user that is returned by the + artifact server. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: The FLYS + instance stores the user that is logged in, because we need to make use of + this user in many services. + + * src/main/java/de/intevation/flys/client/client/ui/ProjectList.java, + src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Make use + of the User of this package - the User of the common package is not used + any longer. + +2011-03-02 Sascha L. Teichmann + + * pom.xml: Added missing SmartGWT repository. + +2011-02-22 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: A UI + widget that stores and displays the data of former states and the current + data. The widget displaying of the current data is created by the + UIProvider that is stored in the Data object. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: We + are able to create new WINFO artifacts. After the artifact has been + created, the first 'state' is rendered in a 'WINFO tab' using the + ParameterList. + +2011-02-22 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + The 'uiprovider' attribute is parsed from DESCRIBE document and stored at + the Data object. + + * src/main/java/de/intevation/flys/client/shared/model/Data.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultData.java: + Implemented code to store the UIProvider (as string!) for the Data object. + +2011-02-22 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/event/StepForwardEvent.java: + An event that is thrown after the user has selected or entered data in the + UI and triggers the feed & advance operations via UI button. + + * src/main/java/de/intevation/flys/client/client/event/HasStepForwardHandlers.java: + This interface is used by classes that provide that step forward + mechanism. + + * src/main/java/de/intevation/flys/client/client/event/StepForwardHandler.java: + This interface is used by classes that want to listen to + StepForwardEvents. + +2011-02-22 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/UIProvider.java, + src/main/java/de/intevation/flys/client/client/ui/MapSelection.java, + src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: The + interface description and two implementations of a UIProvider. A + UIProvider is used to create widgets for the user input. The UIProvider + that is used in the current state depends on the data type in the describe + document and a 'uiprovider' flag that might be configured there. + + * src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java: + The factory that is used to create new instances of UIProvider. + +2011-02-21 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + This view implements the HasCollectionChangeHandlers interface - + CollectionChangeHandler can register to this class and retrieve + notifications when the collection of this view changes. + +2011-02-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/event/CollectionChangeHandler.java, + src/main/java/de/intevation/flys/client/client/event/CollectionChangeEvent.java, + src/main/java/de/intevation/flys/client/client/event/HasCollectionChangeHandlers.java: + New. These interfaces and classes should be used to listen to changes in + Collections. + +2011-02-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java, + src/main/java/de/intevation/flys/client/shared/model/Collection.java: + Enhanced the Collection and its default implementation with new methods + to add new Artifacts, retrieve Artifacts and get the number of artifacts + managed by the Collection. + +2011-02-18 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java: + New. This factory is used to create an ArtifactDescription based on an + DESCRIBE document returned by the artifact server. + + * src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java: A + new DefaultArtifact with an ArtifactDescription that contains the dynamic + UI part is returned by the create() method now. + +2011-02-17 Ingo Weinzierl + + * pom.xml: This client uses the artifacts http-client for the communication + between client and server now. + + * src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java: + New. An instance of the ArtitactCreator interface of the http-client. It + uses the document returned by the artifact server to create an artifact + instance. + + NOTE: The artifact creation needs to be implemented! This is currently + just a stub to make the other things work. + + * src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/ArtifactService.java: + The method signature of create() changed: the server url is required now. + + * src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java: + Make use of the HttpClient and the FLYSArtifactCreator to create + artifacts. + + * src/main/java/de/intevation/flys/client/client/FLYS.java, + src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Added the server url to the create() call of the ArtifactService. + +2011-02-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + This view will now display radio buttons to choose between the module + 'WINFO', 'MINFO', 'Map' and 'Fix-Analyse'. A button is shown to create an + artifact of the selected module. + + NOTE: The next step here is to use the returning artifact with its + description and display widgets based on these information. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + i18n strings for the CollectionView's 'next' button. + +2011-02-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java, + src/main/java/de/intevation/flys/client/shared/model/DataItem.java, + src/main/java/de/intevation/flys/client/shared/model/Data.java: The + interfaces implement the Serializable interface now. + + * src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultDataItem.java, + src/main/java/de/intevation/flys/client/shared/model/DefaultData.java: + New. Default implementions of the interfaces above. These classes + implements constructors and the necessary methods of the interface + descriptions only! + +2011-02-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java, + src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java, + src/main/java/de/intevation/flys/client/client/services/ArtifactService.java: + New. Interface descriptions and the server implementation of an artifact + service that provides basic methods for working with artifacts. + + NOTE: The implementation is currently just a stub. The artifact creation + needs to be implemented. + + * src/main/webapp/WEB-INF/web.xml: Added a servlet for the artifact + interface. + +2011-02-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/Artifact.java: + Implements the serializable interface which is necessary to be able to + use this object in the GWT client code. + + * src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java: + New. A simple default implementation of an artifact. + +2011-02-16 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/FLYS.gwt.xml: Added the + Resources and XML modules of GWT. + + * src/main/java/de/intevation/flys/client/client/config.xml: An xml file + that will contain the client configuration. + + * src/main/java/de/intevation/flys/client/client/Config.java: New. This + class should be used to handle the client configuration and provides + methods for retrieving information about the configuration. + + * src/main/java/de/intevation/flys/client/client/FLYSResources.java: The + configuration (Config) is initialized at the startup. + +2011-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/Artifact.java: New. + The interface description of an artifact used in this client. There are + several methods that provide information about the artifact itself and its + representation. + + * src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java: + New. The ArtifactDescription provides information about the current + representation of an artifact. + + * src/main/java/de/intevation/flys/client/shared/model/DataItem.java, + src/main/java/de/intevation/flys/client/shared/model/Data.java: New. The + interfaces are used to handle user input. + +2011-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + strings for the plugins. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + Display radio buttons if the collection is new and no plugin (winfo, + minfo, map, fix analyse) has been chosen. + +2011-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: New + strings for the CollectionViews. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java: New. + This is the workspace for FLYS. It contains the windows for each + collection of the user. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: + New. This window will display a collection. Currently, it has just a + title, but no content. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: Displays + the FLYSWorkspace. + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Added a + button to open new collections. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: The + FLYSWorkspace is created here. FLYS stores a reference to it and puts the + workspace into the FLYSView. Furthermore, there is a new method that + creates new Collections. + + NOTE: Currently, there is no communication with the artifact server, + because Collections aren't implemented yet! + +2011-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java, + src/main/java/de/intevation/flys/client/shared/model/Collection.java: + Added a new method that returns the UUID of the collection. + +2011-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/client/ui/ProjectList.java: The + ProjectList stores a reference to the current user and provides a list + with his existing projects. + + NOTE: There are created two Collections and two CollectionRecords for the + mockup. This code needs to be removed after a service to fetch the user + collections has been implemented. + + * src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java: + This grid will show a list of collections with its last modification date, + their uuid and two buttons to publish and delete the collection. + + NOTE: The buttons have no effect yet. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: The FLYS class + has a reference to the ProjectList. If a logged in user was found, the + ProjectList is initialized and added to the FLYSView. + + * src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: There is + a new method to set the ProjectList. Furthermore, all UI components are + put into a HLayout now. On this way, we are able to open/close the + ProjectList. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages.java, + src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties: + Added strings for the project list. + +2011-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java, + src/main/java/de/intevation/flys/client/shared/model/Collection.java: The + interface and its default implementation of a Collection. + NOTE: I think both classes will change pretty much, but they have been + necessary for the ProjectList mockup. + +2011-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/client/FLYS.gwt.xml: The artifact-common + package is available in the GWT code now. + + * pom.xml: Made the artifact-common package available. + + * src/main/java/de/intevation/flys/client/server/UserServiceImpl.java, + src/main/java/de/intevation/flys/client/client/services/UserService.java, + src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java: + A service definition that retrieves user information. Currently, this + service defines a single method that returns the user that is currently + logged in. + + * src/main/webapp/WEB-INF/web.xml: Added a servlet definition that provides + the UserService. + + * src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties, + src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added + I18N string for a guest user. + + * src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: There are + new methods to set the current user and to update the menu with its name. + + * src/main/java/de/intevation/flys/client/client/FLYS.java: After creating + the necessary components, the current user is queried by the UserService + and displayed in the menu bar. diff -r 5391c329168c -r 2b745b5e731c flys-client/FLYS.launch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/FLYS.launch Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/FLYSTest-dev.launch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/FLYSTest-dev.launch Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/FLYSTest-prod.launch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/FLYSTest-prod.launch Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/README.txt Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,84 @@ +--- Generated by GWT WebAppCreator --- + +Congratulations, you've successfully generated a starter project! What next? + +-- Option A: Import your project into Eclipse (recommended) -- + +If you use Eclipse, you can simply import the generated project into Eclipse. +We've tested against Eclipse 3.4 and 3.5. Later versions will likely also +work, earlier versions may not. + +If the directory containing this file does not have a .classpath or .project +file, generate them by running 'ant eclipse.generate' + +In Eclipse, go to the File menu and choose: + + File -> Import... -> Existing Projects into Workspace + + Browse to the directory containing this file, + select "FLYS". + + Be sure to uncheck "Copy projects into workspace" if it is checked. + + Click Finish. + +You can now browse the project in Eclipse. + +To launch your web app in GWT development mode, go to the Run menu and choose: + + Run -> Open Debug Dialog... + + Under Java Application, you should find a launch configuration + named "FLYS". Select and click "Debug". + + You can now use the built-in debugger to debug your web app in development mode. + +If you supplied the junit path when invoking webAppCreator, you should see +launch configurations for running your tests in development and production +mode. + +-- Option B: Build from the command line with Ant -- + +If you prefer to work from the command line, you can use Ant to build your +project. (http://ant.apache.org/) Ant uses the generated 'build.xml' file +which describes exactly how to build your project. This file has been tested +to work against Ant 1.7.1. The following assumes 'ant' is on your command +line path. + +To run development mode, just type 'ant devmode'. + +To compile your project for deployment, just type 'ant'. + +To compile and also bundle into a .war file, type 'ant war'. + +If you supplied the junit path when invoking webAppCreator, you can type 'ant +test' to run tests in development and production mode. + +For a full listing of other targets, type 'ant -p'. + +-- Option C: Using another IDE -- + +GWT projects can be run in other IDEs as well, but will require some manual +setup. If you go this route, be sure to: + +* Have your IDE build .class files into 'war/WEB-INF/classes'. +* Add gwt-user.jar and gwt-dev.jar to your project build path. +* When creating a launch configuration, add a classpath entry for your 'src' + folder (this is somewhat unusual but GWT needs access to your source files). + +If you get stuck, try to mimic what the Ant 'build.xml' would do. + +-- Option D: Using Maven -- + +If you have generated your project with the option '-maven', you have a 'pom.xml' +file ready to use. Assuming you have 'maven2' installed in your system, 'mvn' is +in your path, and you have access to maven repositories, you should be able to run: + +mvn clean # delete temporary stuff +mvn test # run all the tests (gwt and junit) +mvn gwt:run # run development mode +mvn gwt:compile # compile to javascript +mvn package # generate a .war package ready to deploy + +For more information about other available goals, read maven and gwt-maven-plugin +documentation (http://maven.apache.org, http://mojo.codehaus.org/gwt-maven-plugin) diff -r 5391c329168c -r 2b745b5e731c flys-client/images/next.xcf Binary file flys-client/images/next.xcf has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/pom.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,161 @@ + + + + + 4.0.0 + de.intevation.flys.client + FLYS + war + 1.0-SNAPSHOT + de.intevation.flys.client.FLYS + + + + 2.1.1 + + 1.5 + 1.5 + + + + + com.google.gwt + gwt-servlet + ${gwtVersion} + runtime + + + com.google.gwt + gwt-user + ${gwtVersion} + provided + + + com.google.gwt + gwt-dev + ${gwtVersion} + test + + + com.smartgwt + smartgwt + 2.4 + + + de.intevation.artifacts.common + artifacts-common + 1.0-SNAPSHOT + + + de.intevation.artifacts.httpclient + http-client + 1.0-SNAPSHOT + + + junit + junit + 4.4 + test + + + + + + target/www/WEB-INF/classes + + + + + + org.codehaus.mojo + gwt-maven-plugin + + + + prepare-package + + compile + + + + + + + FLYS.html + + target/www + + true + + + + + + maven-surefire-plugin + + + ${project.build.sourceDirectory} + ${project.build.testSourceDirectory} + + false + always + + + + + gwt.args + -out target/www + + + + + + + + maven-resources-plugin + + + compile + + copy-resources + + + target/www + + + src/main/webapp + + + + + + + + + + maven-clean-plugin + + + src/main/webapp/flys + src/main/webapp/WEB-INF/classes + tomcat + www-test + .gwt-tmp + + + + + + + + + com.smartgwt + SmartGWT + http://www.smartclient.com/maven2 + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/FLYS.gwt.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/FLYS.gwt.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/Config.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/Config.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,72 @@ +package de.intevation.flys.client.client; + +import com.google.gwt.xml.client.Document; +import com.google.gwt.xml.client.Node; + + +/** + * A class that is used to handle the global configuration of this client. You + * can retrieve an instance of this class using the getInstance + * methods. NOTE: the configuration is initialized using {@link + * getInstance(Document)} the first time. + * + * @author Ingo Weinzierl + */ +public class Config { + + /** The instance of the configuration. */ + protected static Config INSTANCE; + + /** The xml document that contains the configuration options.*/ + protected Document config; + + + /** + * Get an instance by using {@link getInstance(Document)} or {@link + * getInstance()}. + */ + private Config(Document config) { + this.config = config; + } + + + /** + * Returns an instance of this class and initializes the configuration of + * this has not been done so far. + * + * @param config The client configuration. + * + * @return an instance of this Config class. + */ + public static Config getInstance(Document config) { + if (INSTANCE == null) { + INSTANCE = new Config(config); + } + + return INSTANCE; + } + + + /** + * Returns an instance of this class. If it has not been initialized with a + * valid configuration, null is returned. + * + * @return an instance of this class or null, if the Config has not been + * initialized using {@link getInstance(Document)} so far. + */ + public static Config getInstance() { + return INSTANCE; + } + + + /** + * Returns the URL of the artifact server. + * + * @return the artifact server url. + */ + public String getServerUrl() { + Node server = config.getElementsByTagName("server").item(0); + return server.getFirstChild().getNodeValue(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,215 @@ +package de.intevation.flys.client.client; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.xml.client.XMLParser; + +import com.smartgwt.client.widgets.layout.VLayout; +import com.smartgwt.client.widgets.layout.HLayout; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.River; +import de.intevation.flys.client.shared.model.User; + +import de.intevation.flys.client.client.services.ArtifactService; +import de.intevation.flys.client.client.services.ArtifactServiceAsync; +import de.intevation.flys.client.client.services.RiverService; +import de.intevation.flys.client.client.services.RiverServiceAsync; +import de.intevation.flys.client.client.services.UserService; +import de.intevation.flys.client.client.services.UserServiceAsync; +import de.intevation.flys.client.client.ui.CollectionView; +import de.intevation.flys.client.client.ui.FLYSHeader; +import de.intevation.flys.client.client.ui.FLYSView; +import de.intevation.flys.client.client.ui.FLYSWorkspace; +import de.intevation.flys.client.client.ui.MainMenu; +import de.intevation.flys.client.client.ui.ProjectList; +import de.intevation.flys.client.client.ui.FLYSFooter; + + +/** + * Entry point classes define onModuleLoad(). + * + * @author Ingo Weinzierl + */ +public class FLYS implements EntryPoint { + + /** The UserService used to retrieve information about the current user. */ + protected UserServiceAsync userService = GWT.create(UserService.class); + + /** The RiverService used to retrieve the supported rivers of the server.*/ + protected RiverServiceAsync riverService = GWT.create(RiverService.class); + + /** The ArtifactService used to communicate with the Artifact server. */ + protected ArtifactServiceAsync artifactService = + GWT.create(ArtifactService.class); + + /** The menu bar at the top of the application.*/ + protected MainMenu menu; + + /** The content window. It takes the whole space beneath the menu bar.*/ + protected FLYSView view; + + /** The project list that displays the projects of the user.*/ + protected ProjectList projectList; + + /** The FLYSWorkspace.*/ + protected FLYSWorkspace workspace; + + /** The footer. */ + protected FLYSFooter footer; + + /** The user who is currently logged in.*/ + protected User currentUser; + + /** The list of rivers supported by the server.*/ + protected River[] rivers; + + + /** + * This is the entry point method. + */ + public void onModuleLoad() { + + VLayout vertical = new VLayout(); + vertical.setLayoutMargin(1); + vertical.setWidth100(); + vertical.setHeight100(); + + HLayout spacerBar = new HLayout(); + spacerBar.setWidth("100%"); + spacerBar.setHeight("20px"); + spacerBar.setStyleName("bgBlueLight"); + + menu = new MainMenu(this); + view = new FLYSView(); + footer = new FLYSFooter(this); + + vertical.addMember(new FLYSHeader()); + vertical.addMember(menu); + vertical.addMember(spacerBar); + vertical.addMember(view); + vertical.addMember(footer); + + RootPanel.get("app").add(vertical); + + initConfiguration(); + String serverUrl = Config.getInstance().getServerUrl(); + + getRivers(); + + userService.getCurrentUser(serverUrl, new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not find a logged in user."); + // TODO do something + } + + public void onSuccess(User user) { + GWT.log("Found a user. Set '"+ user.getName() + "'"); + setCurrentUser(user); + + menu.setCurrentUser(user); + + projectList = new ProjectList(user); + workspace = new FLYSWorkspace(); + view.setProjectList(projectList); + view.setFLYSWorkspace(workspace); + } + }); + } + + + /** + * This method should be called at system start. It initialzes the client + * configuration. + */ + protected void initConfiguration() { + String xml = FLYSResources.INSTANCE.initialConfiguration().getText(); + Config.getInstance(XMLParser.parse(xml)); + } + + + /** + * Returns the user that is currently logged in. + * + * @return the current user. + */ + public User getCurrentUser() { + return currentUser; + } + + + /** + * Sets the current user. + */ + public void setCurrentUser(User user) { + currentUser = user; + } + + + /** + * Returns the project list. + */ + public ProjectList getProjectList() { + return projectList; + } + + + /** + * Returns a list of rivers supported by the artifact server. + * + * @return a list of rivers supported by the artifact server. + */ + public River[] getRivers() { + if (rivers == null) { + String url = Config.getInstance().getServerUrl(); + GWT.log("Fetch rivers from server '" + url + "'"); + + riverService.list(url, new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not recieve a list of rivers."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(River[] newRivers) { + GWT.log("Retrieved " + newRivers.length + " new rivers."); + rivers = newRivers; + } + }); + } + + return rivers; + } + + + /** + * This method creates a new CollectionView and adds it to the workspace. + */ + public void newProject() { + CollectionView view = new CollectionView(this); + workspace.addView(view); + + view.addCollectionChangeHandler(getProjectList()); + } + + + /** + * Create a new Artifact. + */ + public void newArtifact(String factory) { + String url = Config.getInstance().getServerUrl(); + + artifactService.create(url, factory, new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not create the new artifact."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Artifact artifact) { + GWT.log("Successfully created a new artifact."); + } + }); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYSImages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSImages.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,22 @@ +package de.intevation.flys.client.client; + +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.ImageResource; + + +/** + * This interface grants access to the images used in this application. + * + * @author Ingo Weinzierl + */ +public interface FLYSImages extends ClientBundle { + + @Source("images/bfg_logo.gif") + ImageResource logoBfg(); + + @Source("images/flys_logo.gif") + ImageResource logoFlys(); + + @Source("images/gewkarte.png") + ImageResource riverMap(); +} diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,111 @@ +package de.intevation.flys.client.client; + +import com.google.gwt.i18n.client.ConstantsWithLookup; + + +/** + * @author Ingo Weinzierl + */ +public interface FLYSMessages extends ConstantsWithLookup { + + String title(); + + String fullname(); + + String user(); + + String guest(); + + String projects(); + + String manage_projects(); + + String logout(); + + String switch_language(); + + String info(); + + String no_projects(); + + String load_projects(); + + String date_format(); + + String datetime_format(); + + String new_project(); + + String new_calculation(); + + String module_selection(); + + String river_selection(); + + String winfo(); + + String minfo(); + + String map(); + + String chart(); + + String fix(); + + String next(); + + String location_distance_state(); + + String location(); + + String distance(); + + String unitFrom(); + + String unitTo(); + + String unitWidth(); + + String unitLocation(); + + String wrongFormat(); + + String wqTitle(); + + String wqW(); + + String wqQ(); + + String wqSingle(); + + String wqRange(); + + String unitWSingle(); + + String unitWFrom(); + + String unitWTo(); + + String unitWStep(); + + String unitQSingle(); + + String unitQFrom(); + + String unitQTo(); + + String unitQStep(); + + String footerHome(); + + String footerContact(); + + String footerImpressum(); + + String buttonNext(); + + String imageBack(); + + String discharge_curve(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,53 @@ +title = FLYS-3.0 +fullname = Flusshydrologische Software +user = Benutzer: +guest = Gast +logout = Abmelden +projects = Projekte +manage_projects = Projekte verwalten +switch_language = Englisch +info = Info +no_projects = Keine alten Berechnungen gefunden. +load_projects = Lade Berechnungen... +date_format = dd.MM.yyyy +datetime_format = dd.MM.yyyy HH:mm +new_project = Neues Projekt +new_calculation = Neue Berechnung +module_selection = Modul +river_selection = Gewässer +winfo = WINFO +minfo = MINFO +map = Neue Karte +chart = Neues Diagramm +fix = Fixierungsanalyse +next = Weiter +location_distance_state = Berechnungsort/strecke wählen +location = Ort +distance = Strecke +unitFrom = km - +unitTo = km a +unitWidth = m +unitLocation = km +wrongFormat = Falsches Format + +wqTitle = Eingabe für W/Q Daten +wqW = W am Pegel [cm] +wqQ = Q [m³/s] +wqSingle = Einzelwerte +wqRange = Wertebereich +unitWSingle = cm +unitWFrom = cm - +unitWTo = cm a +unitWStep = cm +unitQSingle = m³/s +unitQFrom = m³/s - +unitQTo = m³/s a +unitQStep = m³/s +footerHome = Home +footerContact = Kontakt +footerImpressum = Impressum + +buttonNext = Ãœbernehmen +imageBack = images/back_de.png + +discharge_curve = Abflusskurve diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,50 @@ +title = FLYS-3.0 +fullname = Flusshydrologische Software +user = User: +guest = guest +logout = Logout +projects = Calculations +manage_projects = Manage Projects +switch_language = German +info = Info +no_projects = No existing calculations found. +load_projects = Load calculations... +date_format = yyyy-MM-dd +datetime_format = yyyy-MM-dd HH:mm +new_project = New Project +new_calculation = New Calculation +module_selection = Module +river_selection = Rivers +winfo = WINFO +minfo = MINFO +map = New Map +chart = New Chart +fix = TODO FIX ANALYSE TODO +next = Next +location_distance_state = Choose calculation location/distance +location = Location +distance = Distance +unitFrom = km +unitTo = km a +unitWidth = m +unitLocation = km +wrongFormat = Wrong format + +wqTitle = Input for W/Q Data +wqW = W at Gauge [cm] +wqQ = Q [m³/s] +wqSingle = Single values +wqRange = Range +unitWSingle = cm +unitWFrom = cm - +unitWTo = cm a +unitWStep = cm +unitQSingle = m³/s +unitQFrom = m³/s - +unitQTo = m³/s a +unitQStep = m³/s + +buttonNext = Next +imageBack = images/back_en.png + +discharge_curve = Discharge Curve diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/FLYSResources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSResources.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,21 @@ +package de.intevation.flys.client.client; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.TextResource; + + +/** + * A {@link ClientBundle} that is used to handle resources in this client. + * + * @author Ingo Weinzierl + */ +public interface FLYSResources extends ClientBundle { + + public static final FLYSResources INSTANCE = + GWT.create(FLYSResources.class); + + @Source("config.xml") + public TextResource initialConfiguration(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/config.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/config.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,3 @@ + + http://localhost:8181 + diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeEvent.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,29 @@ +package de.intevation.flys.client.client.event; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This events stores references to the old collection and the new one. + * + * @author Ingo Weinzierl + */ +public class CollectionChangeEvent { + + protected Collection oldCollection; + protected Collection newCollection; + + public CollectionChangeEvent(Collection old, Collection newArt) { + oldCollection = old; + newCollection = newArt; + } + + public Collection getOldValue() { + return oldCollection; + } + + public Collection getNewValue() { + return newCollection; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeHandler.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,18 @@ +package de.intevation.flys.client.client.event; + + +/** + * Handler interface for CollectionChangeEvent events. + * + * @author Ingo Weinzierl + */ +public interface CollectionChangeHandler { + + /** + * Called when a CollectionChangeEvent is fired. + * + * @param event The CollectionChangeEvent. + */ + public void onCollectionChange(CollectionChangeEvent event); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/HasCollectionChangeHandlers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasCollectionChangeHandlers.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,16 @@ +package de.intevation.flys.client.client.event; + + +/** + * @author Ingo Weinzierl + */ +public interface HasCollectionChangeHandlers { + + /** + * Adds a new CollectionChangeHandler. + * + * @param handler The new CollectionChangeHandler. + */ + public void addCollectionChangeHandler(CollectionChangeHandler handler); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/HasParameterChangeHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasParameterChangeHandler.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,16 @@ +package de.intevation.flys.client.client.event; + + +/** + * @author Ingo Weinzierl + */ +public interface HasParameterChangeHandler { + + /** + * Adds a new ParameterChangeHandler. + * + * @param handler The new ParameterChangeHandler. + */ + public void addParameterChangeHandler(ParameterChangeHandler handler); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepBackHandlers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepBackHandlers.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + + +/** + * @author Ingo Weinzierl + */ +public interface HasStepBackHandlers extends Serializable { + + public void addStepBackHandler(StepBackHandler handler); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepForwardHandlers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepForwardHandlers.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + + +/** + * @author Ingo Weinzierl + */ +public interface HasStepForwardHandlers extends Serializable { + + public void addStepForwardHandler(StepForwardHandler handler); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeEvent.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,29 @@ +package de.intevation.flys.client.client.event; + +import de.intevation.flys.client.shared.model.Artifact; + + +/** + * This events stores references to the old artifact and the new one. + * + * @author Ingo Weinzierl + */ +public class ParameterChangeEvent { + + protected Artifact oldArtifact; + protected Artifact newArtifact; + + public ParameterChangeEvent(Artifact old, Artifact newArt) { + oldArtifact = old; + newArtifact = newArt; + } + + public Artifact getOldValue() { + return oldArtifact; + } + + public Artifact getNewValue() { + return newArtifact; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeHandler.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,18 @@ +package de.intevation.flys.client.client.event; + + +/** + * Handler interface for ParameterChangeEvent events. + * + * @author Ingo Weinzierl + */ +public interface ParameterChangeHandler { + + /** + * Called when a ParameterChangeEvent is fired. + * + * @param event The ParameterChangeEvent. + */ + public void onParameterChange(ParameterChangeEvent event); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackEvent.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,34 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + + +/** + * @author Ingo Weinzierl + */ +public class StepBackEvent implements Serializable { + + /** The identifier of the target state.*/ + protected String target; + + + /** + * Creates a new StepBackEvent with the identifier of the target state. + * + * @param target The identifier of the target state. + */ + public StepBackEvent(String target) { + this.target = target; + } + + + /** + * A method to retrieve the target identifier. + * + * @return the target identifier. + */ + public String getTarget() { + return target; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackHandler.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + + +/** + * @author Ingo Weinzierl + */ +public interface StepBackHandler extends Serializable { + + public void onStepBack(StepBackEvent event); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardEvent.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + +import de.intevation.flys.client.shared.model.Data; + + +/** + * @author Ingo Weinzierl + */ +public class StepForwardEvent implements Serializable { + + /** The selected data.*/ + protected Data[] data; + + /** + * Creates a new StepForwardEvent with the Data that has been selected in + * the UI. + * + * @param data The selected data. + */ + public StepForwardEvent(Data[] data) { + this.data = data; + } + + + /** + * A method to retrieve the data stored in the event. + * + * @return the data. + */ + public Data[] getData() { + return data; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardHandler.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,13 @@ +package de.intevation.flys.client.client.event; + +import java.io.Serializable; + + +/** + * @author Ingo Weinzierl + */ +public interface StepForwardHandler extends Serializable { + + public void onStepForward(StepForwardEvent event); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/images/bfg_logo.gif Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/bfg_logo.gif has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/images/flys_logo.gif Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/flys_logo.gif has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/images/gewkarte.png Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/gewkarte.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This interface describes the service to add an existing artifact to an + * existing collection. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("add-artifact") +public interface AddArtifactService extends RemoteService { + + /** + * Adds an artifact to a collection. + * + * @param collection The Collection that should be extended. + * @param artifact The artifact that should be added. + * @param url The url of the artifact server. + * + * @return the Collection after the operation. + */ + Collection add(Collection collection, Artifact artifact, String url); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.Collection; + + +/** + * @author Ingo Weinzierl + */ +public interface AddArtifactServiceAsync { + + public void add( + Collection collection, + Artifact artifact, + String url, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,27 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Artifact; + +/** + * This interface provides artifact specific operation ADVANCE. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("advance") +public interface AdvanceService extends RemoteService { + + /** + * This method inserts new data into the an existing artifact. + * + * @param serverUrl The url of the artifact server. + * @param artifact The artifact. + * @param target The identifier of the target state. + * + * @return the artifact which description might have been changed. + */ + public Artifact advance(String serverUrl, Artifact artifact, String target); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,21 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Artifact; + + +/** + * This interface provides artifact specific operation ADVANCE. + * + * @author Ingo Weinzierl + */ +public interface AdvanceServiceAsync { + + public void advance( + String serverUrl, + Artifact artifact, + String target, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,27 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Artifact; + +/** + * This interface provides artifact specific services as CREATE, DESCRIBE, FEED, + * ADVANCE and OUT. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("artifact") +public interface ArtifactService extends RemoteService { + + /** + * This method creates a new artifact based on the given factory. + * + * @param serverUrl The url of the artifact server. + * @param factory The factory that should be used for the artifact creation. + * + * @return the new artifact. + */ + public Artifact create(String serverUrl, String factory); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,19 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Artifact; + + +/** + * This interface provides artifact specific services as CREATE, DESCRIBE, FEED, + * ADVANCE and OUT. + * + * @author Ingo Weinzierl + */ +public interface ArtifactServiceAsync { + + public void create( + String serverUrl, String factory, AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,25 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This interface describes the service for creating new collections. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("create-collection") +public interface CreateCollectionService extends RemoteService { + + /** + * This method creates a new collection in the artifact server and returns + * the uuid of this collection. + * + * @return the uuid of the created collection. + */ + Collection create(String serverUrl, String ownerId); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This interface describes the service for creating new collections. + * + * @author Ingo Weinzierl + */ +public interface CreateCollectionServiceAsync { + + void create( + String serverUrl, + String owner, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,28 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This service describes an operation the fetches the DESCRIBE document of a + * specific collection and returns a Collection. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("describe-collection") +public interface DescribeCollectionService extends RemoteService { + + /** + * Adds an artifact to a collection. + * + * @param uuid The uuid of the desired collection. + * @param url The url of the artifact server. + * + * @return the Collection after the operation. + */ + Collection describe(String uuid, String url); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,18 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * @author Ingo Weinzierl + */ +public interface DescribeCollectionServiceAsync { + + public void describe( + String uuid, + String url, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/RiverService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/RiverService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,26 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.River; + +/** + * This interface provides a method to list the supported rivers of the artifact + * server. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("rivers") +public interface RiverService extends RemoteService { + + /** + * This method returns a list of rivers provided by the artifact server. + * + * @param serverUrl The url of the artifact server. + * + * @return a list of rivers provided by the artifact server. + */ + public River[] list(String serverUrl); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,18 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.River; + + +/** + * This interface provides a method to list the supported rivers of the artifact + * server. + * + * @author Ingo Weinzierl + */ +public interface RiverServiceAsync { + + public void list(String serverUrl, AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,28 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.Data; + +/** + * This interface provides artifact specific operation FEED. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("forward") +public interface StepForwardService extends RemoteService { + + /** + * This method inserts new data into the an existing artifact. + * + * @param serverUrl The url of the artifact server. + * @param artifact The artifact. + * @param data The data that should be inserted. + * + * @return the artifact which description might have been changed. + */ + public Artifact go(String serverUrl, Artifact artifact, Data[] data); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,22 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.Data; + + +/** + * This interface provides artifact specific operation FEED. + * + * @author Ingo Weinzierl + */ +public interface StepForwardServiceAsync { + + public void go( + String serverUrl, + Artifact artifact, + Data[] data, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,27 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This interface describes a method that retrieves a list of Collections owned + * by a specified user. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("user-collections") +public interface UserCollectionsService extends RemoteService { + + /** + * This method retrieves the user that is currently logged in. + * + * @param serverUrl The url of the artifact server. + * + * @return the current {@link User}. + */ + Collection[] getUserCollections(String serverUrl, String userid); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,21 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.Collection; + + +/** + * This interface describes a method that retrieves a list of Collections owned + * by a specified user. + * + * @author Ingo Weinzierl + */ +public interface UserCollectionsServiceAsync { + + void getUserCollections( + String serverUrl, + String userid, + AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/UserService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserService.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,26 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import de.intevation.flys.client.shared.model.User; + + +/** + * This interface describes services for the user. + * + * @author Ingo Weinzierl + */ +@RemoteServiceRelativePath("user") +public interface UserService extends RemoteService { + + /** + * This method retrieves the user that is currently logged in. + * + * @param serverUrl The url of the artifact server. + * + * @return the current {@link User}. + */ + User getCurrentUser(String serverUrl); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,17 @@ +package de.intevation.flys.client.client.services; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +import de.intevation.flys.client.shared.model.User; + + +/** + * This interface describes services for the user. + * + * @author Ingo Weinzierl + */ +public interface UserServiceAsync { + + void getCurrentUser(String serverUrl, AsyncCallback callback); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,186 @@ +package de.intevation.flys.client.client.ui; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Img; +import com.smartgwt.client.widgets.events.ClickEvent; +import com.smartgwt.client.widgets.events.ClickHandler; +import com.smartgwt.client.widgets.Button; + +import de.intevation.flys.client.client.FLYSMessages; +import de.intevation.flys.client.client.event.HasStepBackHandlers; +import de.intevation.flys.client.client.event.HasStepForwardHandlers; +import de.intevation.flys.client.client.event.StepBackEvent; +import de.intevation.flys.client.client.event.StepBackHandler; +import de.intevation.flys.client.client.event.StepForwardEvent; +import de.intevation.flys.client.client.event.StepForwardHandler; +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataList; + + +/** + * An abstract UIProvider that provides some basic methods. + * + * @author Ingo Weinzierl + */ +public abstract class AbstractUIProvider +implements UIProvider, HasStepForwardHandlers, ClickHandler, + HasStepBackHandlers +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MSG = GWT.create(FLYSMessages.class); + + + /** The StepForwardHandlers.*/ + protected List forwardHandlers; + + /** The StepForwardHandlers.*/ + protected List backHandlers; + + /** The container that is used to position helper widgets.*/ + protected Canvas helperContainer; + + + /** + * Creates a new UIProvider instance of this class. + */ + public AbstractUIProvider() { + forwardHandlers = new ArrayList(); + backHandlers = new ArrayList(); + } + + + /** + * Appends a StepBackHandler that wants to listen to StepBackEvents. + * + * @param handler A new StepBackHandler. + */ + public void addStepBackHandler(StepBackHandler handler) { + if (handler != null) { + backHandlers.add(handler); + } + } + + + /** + * Appends a StepForwardHandler that wants to listen to StepForwardEvents. + * + * @param handler A new StepForwardHandler. + */ + public void addStepForwardHandler(StepForwardHandler handler) { + if (handler != null) { + forwardHandlers.add(handler); + } + } + + + /** + * This method is called after the user has clicked one of the buttons to + * step back to a previous state. + * + * @param e The StepBackEvent. + */ + protected void fireStepBackEvent(StepBackEvent e) { + GWT.log("AbstractUIProvider - fireStepBackEvent() handlers: " + backHandlers.size()); + for (StepBackHandler handler: backHandlers) { + handler.onStepBack(e); + } + } + + + /** + * This method is called after the user has clicked on the 'next' button to + * step to the next state. + * + * @param e The StepForwardEvent. + */ + protected void fireStepForwardEvent(StepForwardEvent e) { + GWT.log("AbstractUIProvider - fireStepForwardEvent() handlers: " + forwardHandlers.size()); + for (StepForwardHandler handler: forwardHandlers) { + handler.onStepForward(e); + } + } + + + /** + * This method is used to listen to click events on the 'next' button. The + * fireStepForwardEvent() method is called here. + * + * @param e The click event. + */ + public void onClick(ClickEvent e) { + Data[] data = getData(); + + fireStepForwardEvent(new StepForwardEvent(data)); + } + + + /** + * Creates the 'next' button to step forward to the next state. + * + * @return the 'next' button. + */ + protected Canvas getNextButton() { + Button next = new Button(MSG.buttonNext()); + next.addClickHandler(this); + + return next; + } + + + /** + * Creates the 'back' button to step back to a previous state. + * + * @param targetState The identifier of the target state. + * + * @return the 'back' button. + */ + protected Canvas getBackButton(final String targetState) { + String url = GWT.getHostPageBaseURL() + MSG.imageBack(); + Img back = new Img(url, 16, 16); + + back.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + fireStepBackEvent(new StepBackEvent(targetState)); + } + }); + + return back; + } + + + /** + * This method injects a container that is used to position helper widgets. + * + * @param helperContainer A container that is used to position helper + * widgets. + */ + public void setContainer(Canvas helperContainer) { + this.helperContainer = helperContainer; + } + + + /** + * This method needs to be implemented by concrete subclasses. It should + * create a new Canvas object with a representation of data. + * + * @param data The data that should be displayed. + * + * @return a Canvas object that displays data. + */ + public abstract Canvas create(DataList data); + + + /** + * This method needs to be implemented by concrete subclasses. It should + * return the selected data. + * + * @return the selected data. + */ + protected abstract Data[] getData(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,99 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Img; +import com.smartgwt.client.widgets.layout.HLayout; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.OutputMode; +import de.intevation.flys.client.client.Config; + + +/** + * @author Ingo Weinzierl + */ +public class ChartOutputTab extends OutputTab { + + /** The canvas that wraps the theme editor.*/ + protected Canvas left; + + /** The canvas that wraps the chart.*/ + protected Canvas right; + + + /** + * The default constructor to create a new ChartOutputTab. + * + * @param title The title of this tab. + * @param collection The Collection which this chart belongs to. + * @param mode The OutputMode. + */ + public ChartOutputTab(String title, Collection collection, OutputMode mode){ + super(title, collection, mode); + + left = new Canvas(); + right = new Canvas(); + + left.setWidth("25%"); + right.setWidth("*"); + + HLayout hLayout = new HLayout(); + hLayout.setWidth100(); + hLayout.setHeight100(); + hLayout.setMembersMargin(10); + + hLayout.addMember(left); + hLayout.addMember(right); + + Img chart = getChartImg(); + chart.setWidth100(); + chart.setHeight100(); + + right.addChild(chart); + + setPane(hLayout); + } + + + /** + * Builds the chart image and returns it. + * + * @return the chart image. + */ + protected Img getChartImg() { + return new Img(getImgUrl()); + } + + + /** + * Builds the URL that points to the chart image. + * + * @return the URL to the chart image. + */ + protected String getImgUrl() { + Config config = Config.getInstance(); + String server = config.getServerUrl(); + String uuid = collection.getItem(0).identifier(); + String hash = collection.getItem(0).hash(); + + String imgUrl = GWT.getModuleBaseURL(); + imgUrl += "chart"; + imgUrl += "?target=chart"; + imgUrl += "&server=" + server; + imgUrl += "&mode=img"; + imgUrl += "&width=600"; + imgUrl += "&height=400"; + imgUrl += "&points=false"; + imgUrl += "&uuid=" + uuid; + imgUrl += "&hash=" + hash; + + GWT.log("IMAGE URL = " + imgUrl); + + // TODO Build the correct url that points to the OUT() resource of the + // collection. + return imgUrl; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Date; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.DateTimeFormat; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.IButton; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.grid.ListGrid; +import com.smartgwt.client.widgets.grid.ListGridRecord; + +import de.intevation.flys.client.shared.model.CollectionRecord; + +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * @author Ingo Weinzierl + */ +public class CollectionGrid extends ListGrid { + + /** The message class that provides i18n strings.*/ + FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** + * The default constructor that creates a new ListGrid item. + * + * @param collection The artifact collection. + */ + public CollectionGrid() { + } + + @Override + protected Canvas createRecordComponent( + final ListGridRecord record, Integer col) + { + String field = getFieldName(col); + + if (field == null) return null; + if (field.equals("date")) return createDateField(record); + else if (field.equals("name")) return createNameField(record); + else if (field.equals("publish")) return createPublishField(record); + else if (field.equals("delete")) return createDeleteField(record); + + return null; + } + + + /** + * This method creates the date field for the collection grid. + * + * @param record The record to be displayed. + */ + protected Canvas createDateField(ListGridRecord record) { + CollectionRecord rec = (CollectionRecord) record; + + Date date = rec.getCreationTime(); + DateTimeFormat dtf = DateTimeFormat.getFormat( + messages.datetime_format()); + + String formatted = dtf.format(date); + + Label label = new Label(formatted); + label.setHeight(15); + label.setWidth100(); + + return label; + } + + + /** + * This method creates the name field for the collection grid. + * + * @param record The record to be displayed. + */ + protected Canvas createNameField(ListGridRecord record) { + CollectionRecord rec = (CollectionRecord) record; + + String name = rec.getName(); + int len = name.length(); + int sec = len - 15; + String sub = name.substring(0, 14) + "..." + name.substring(sec, len-1); + + Label label = new Label(sub); + label.setHeight(15); + label.setWidth100(); + + return label; + } + + + /** + * This method creates the field for the collection grid that provides a + * button to publish the collection. + * + * @param record The record to be displayed. + */ + protected Canvas createPublishField(ListGridRecord record) { + IButton button = new IButton(); + button.setHeight(15); + button.setTitle("PUB"); + return button; + } + + + /** + * This method creates the field for the collection grid that provides a + * button to delete the collection. + * + * @param record The record to be displayed. + */ + protected Canvas createDeleteField(ListGridRecord record) { + IButton button = new IButton(); + button.setHeight(15); + button.setTitle("DEL"); + return button; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,377 @@ +package de.intevation.flys.client.client.ui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; + +import com.smartgwt.client.widgets.Window; +import com.smartgwt.client.widgets.layout.Layout; +import com.smartgwt.client.widgets.layout.VLayout; +import com.smartgwt.client.widgets.tab.TabSet; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.ArtifactDescription; +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.OutputMode; +import de.intevation.flys.client.shared.model.User; + +import de.intevation.flys.client.client.Config; +import de.intevation.flys.client.client.FLYS; +import de.intevation.flys.client.client.FLYSMessages; +import de.intevation.flys.client.client.event.HasCollectionChangeHandlers; +import de.intevation.flys.client.client.event.CollectionChangeEvent; +import de.intevation.flys.client.client.event.CollectionChangeHandler; +import de.intevation.flys.client.client.event.ParameterChangeEvent; +import de.intevation.flys.client.client.event.ParameterChangeHandler; +import de.intevation.flys.client.client.services.AddArtifactService; +import de.intevation.flys.client.client.services.AddArtifactServiceAsync; +import de.intevation.flys.client.client.services.CreateCollectionService; +import de.intevation.flys.client.client.services.CreateCollectionServiceAsync; +import de.intevation.flys.client.client.services.DescribeCollectionService; +import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync; + + +/** + * @author Ingo Weinzierl + */ +public class CollectionView +extends Window +implements CollectionChangeHandler, HasCollectionChangeHandlers, + ParameterChangeHandler +{ + /** The ArtifactService used to communicate with the Artifact server. */ + protected CreateCollectionServiceAsync createCollectionService = + GWT.create(CreateCollectionService.class); + + /** The AddArtifactService used to add an artifact to a collection. */ + protected AddArtifactServiceAsync addArtifactService = + GWT.create(AddArtifactService.class); + + /** The DescribeCollectionService used to update the existing collection. */ + protected DescribeCollectionServiceAsync describeCollectionService = + GWT.create(DescribeCollectionService.class); + + /** The message class that provides i18n strings.*/ + protected FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** The FLYS instance used to call services.*/ + protected FLYS flys; + + /** The ParameterList.*/ + protected ParameterList parameterList; + + /** The list of ValueChangeHandlers.*/ + protected List handlers; + + /** The collection to be displayed.*/ + protected Collection collection; + + /** The artifact that handles the parameterization.*/ + protected Artifact artifact; + + protected TabSet tabs; + + /** The output tab.*/ + protected Map outputTabs; + + /** The layout.*/ + protected Layout layout; + + + /** + * This constructor creates a new CollectionView that is used to display the + * collection. + * + * @param collection The collection to be displayed. + */ + public CollectionView(FLYS flys) { + this.flys = flys; + this.tabs = new TabSet(); + this.outputTabs = new HashMap(); + this.handlers = new ArrayList(); + this.layout = new VLayout(); + this.parameterList = new ParameterList( + flys, this, messages.new_project()); + + addCollectionChangeHandler(this); + + parameterList.addParameterChangeHandler(this); + parameterList.addParameterChangeHandler(parameterList); + + init(); + } + + + /** + * This method handles the initial layout stuff. + */ + protected void init() { + setWidth(750); + setHeight(600); + + layout.setWidth100(); + + setCanDragReposition(true); + setCanDragResize(true); + setKeepInParentRect(true); + + setTitle(""); + + addItem(layout); + + layout.addMember(tabs); + tabs.addTab(parameterList); + } + + + /** + * This method triggers the CreateCollectionService to create a new + * collection in the artifact server. + * + * @param ownerId The uuid of the user that should own the new collection. + */ + protected void createNewCollection(String ownerId) { + GWT.log("CollectionView.createNewCollection"); + + Config config = Config.getInstance(); + final String serverUrl = config.getServerUrl(); + + createCollectionService.create( + serverUrl, ownerId, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not create the new collection."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Collection collection) { + GWT.log("Successfully created a new collection."); + + Artifact artifact = getArtifact(); + addArtifactService.add(collection, artifact, serverUrl, + new AsyncCallback() { + + public void onFailure(Throwable caught) { + GWT.log("An error occured while adding artifact."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Collection newCollection) { + GWT.log("Successfully added artifact."); + setCollection(newCollection); + } + } + ); + } + }); + } + + + protected FLYS getFlys() { + return flys; + } + + + + /** + * This method registers a new ValueChangeHandler. + * + * @param handler The new ValueChangeHandler. + */ + public void addCollectionChangeHandler(CollectionChangeHandler handler) { + if (handler != null) { + handlers.add(handler); + } + } + + + + /** + * This method calls the onValueChange() method of all + * registered ValueChangeHanders. + */ + protected void fireCollectionChangeEvent( + Collection old, Collection newCol) + { + for (CollectionChangeHandler handler: handlers) { + handler.onCollectionChange(new CollectionChangeEvent(old, newCol)); + } + } + + + /** + * This method returns true, if the Collection is new and no plugins has + * been chosen. + * + * @return true, if the Collection is new. + */ + public boolean isNew() { + return collection.getItemLength() == 0 ? true : false; + } + + + /** + * Returns the artifact that is used for the parameterization. + * + * @return the artifact that is used for the parameterization. + */ + protected Artifact getArtifact() { + return artifact; + } + + + /** + * Set the current artifact that is the master of the parameterization. + * + * @param artifact The new artifact. + */ + protected void setArtifact(Artifact artifact) { + this.artifact = artifact; + } + + + /** + * Implements the onCollectionChange() method to do update the GUI after the + * parameterization has changed. + * + * @param event The ParameterChangeEvent. + */ + public void onParameterChange(ParameterChangeEvent event) { + GWT.log("CollectionView.onParameterChange"); + + Artifact art = event.getNewValue(); + ArtifactDescription desc = art.getArtifactDescription(); + OutputMode[] outs = desc.getOutputModes(); + + setArtifact(art); + clearOutputTabs(); + + Collection collection = getCollection(); + + if (outs != null && collection == null) { + User user = getFlys().getCurrentUser(); + createNewCollection(user.identifier()); + } + else if (outs != null && collection != null) { + Config config = Config.getInstance(); + String url = config.getServerUrl(); + + describeCollectionService.describe(collection.identifier(), url, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not DESCRIBE collection."); + GWT.log(caught.getMessage()); + } + + + public void onSuccess(Collection newCollection) { + GWT.log("Successfully DESCRIBED collection."); + setCollection(newCollection); + } + } + ); + } + else { + updateView(); + } + } + + + /** + * Returns the collection of displayed by this view. + * + * @return the collection of this view. + */ + protected Collection getCollection() { + return collection; + } + + + /** + * Set the current collection. + * + * @param collection The new collection. + */ + protected void setCollection(Collection collection) { + Collection tmp = this.collection; + this.collection = collection; + + fireCollectionChangeEvent(tmp, this.collection); + } + + + public void onCollectionChange(CollectionChangeEvent event) { + Collection newCol = event.getNewValue(); + + Map outs = newCol.getOutputModes(); + + Set keys = outs.keySet(); + for (String outname: keys) { + addOutputTab(outname, outs.get(outname)); + } + + updateView(); + } + + + /** + * Adds a new tab for the OutputMode out. + * + * @param name The name and title of the output. + */ + protected void addOutputTab(String name, OutputMode out) { + GWT.log("Add new output tab for '" + name + "'"); + + // TODO Source this out to a factory that creates the different + // OutputTabs. + String title = messages.getString(name); + OutputTab tab = new ChartOutputTab(title, getCollection(), out); + outputTabs.put(name, tab); + } + + + /** + * Removes all output mode tabs from tab bar. + */ + protected void clearOutputTabs() { + GWT.log("Clear OutputTabs."); + + int num = tabs.getNumTabs(); + + for (int i = num-1; i >= 1; i--) { + tabs.removeTab(i); + } + + outputTabs.clear(); + } + + + /** + * Update the view (refresh the list of old and current data). + */ + protected void updateView() { + GWT.log("CollectionView.updateView()"); + updateOutputTabs(); + } + + + /** + * This method is used to update the tabs to show specific output modes. + */ + protected void updateOutputTabs() { + GWT.log("Update output tabs."); + if (outputTabs != null) { + Set keys = outputTabs.keySet(); + + for (String key: keys) { + tabs.addTab(outputTabs.get(key)); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,163 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.NumberFormat; + +import com.smartgwt.client.types.TitleOrientation; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.StaticTextItem; +import com.smartgwt.client.widgets.form.fields.TextItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; + +import de.intevation.flys.client.client.FLYSMessages; + +public class DoubleArrayPanel +extends DynamicForm +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** The constant input field name.*/ + public static final String FIELD_NAME = "doublearray"; + + + /** + * Creates a new form with a single input field that displays an array of + * double values. + * + * @param name The name of the TextItem. + * @param title The title of the TextItem. + * @param values The double values that should be displayed initially. + * @param handler The BlurHandler that is used to valide the input. + */ + public DoubleArrayPanel( + String title, + double[] values, + BlurHandler handler) + { + TextItem ti = new TextItem(FIELD_NAME); + StaticTextItem sti = new StaticTextItem("staticarray"); + + ti.setShowTitle(false); + sti.setShowTitle(false); + sti.setValue(title); + + ti.addBlurHandler(handler); + + setFields(ti, sti); + setTitleOrientation(TitleOrientation.RIGHT); + setNumCols(2); + + if (values == null) { + return; + } + + NumberFormat f = NumberFormat.getDecimalFormat(); + + StringBuilder text = new StringBuilder(); + boolean firstItem = true; + + for (double val: values) { + if (!firstItem) { + text.append(" "); + } + + text.append(f.format(val)); + + firstItem = false; + } + + ti.setValue(text.toString()); + } + + + /** + * This method validates the entered text in the location input field. If + * there are values that doesn't represent a valid location, an error is + * displayed. + * + * @param item The FormItem. + */ + protected boolean validateForm(FormItem item) { + if (item instanceof StaticTextItem) { + return true; + } + + boolean valid = true; + String value = (String) item.getValue(); + + if (value == null) { + return valid; + } + + String[] parts = value.split(" "); + + if (parts == null) { + return valid; + } + + NumberFormat f = NumberFormat.getDecimalFormat(); + Map errors = getErrors(); + + try { + for (String part: parts) { + double location = f.parse(part); + } + + errors.remove(item.getFieldName()); + } + catch (NumberFormatException nfe) { + errors.put(item.getFieldName(), MESSAGES.wrongFormat()); + + valid = false; + } + + setErrors(errors, true); + + return valid; + } + + + /** + * This method returns the double array that has been entered in + * item. + * + * @param item The item that contains the desired values. + * + * @return the values as double array. + */ + public double[] getInputValues(FormItem item) { + String value = (String) item.getValue(); + + if (value == null) { + return null; + } + + String[] parts = value.split(" "); + + if (parts == null) { + return null; + } + + double[] values = new double[parts.length]; + + NumberFormat f = NumberFormat.getDecimalFormat(); + + int i = 0; + for (String part: parts) { + try { + values[i++] = f.parse(part); + } + catch (NumberFormatException nfe) { + // do nothing + } + } + + return values; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,187 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.NumberFormat; + +import com.smartgwt.client.types.Alignment; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FloatItem; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.StaticTextItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; + +import de.intevation.flys.client.client.FLYSMessages; + + + +/** + * This class creates a DynamicForm with three input fields. + * + * @author Ingo Weinzierl + */ +public class DoubleRangePanel +extends DynamicForm +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** The constant name of the input field to enter the start of a distance.*/ + public static final String FIELD_FROM = "from"; + + /** The constant name of the input field to enter the end of a distance.*/ + public static final String FIELD_TO = "to"; + + /** The constant name of the input field to enter the step width of a + * distance.*/ + public static final String FIELD_WIDTH = "step"; + + + /** + * Creates a new form with a single input field that displays an array of + * double values. + * + * @param name The name of the TextItem. + * @param title The title of the TextItem. + * @param values The double values that should be displayed initially. + * @param handler The BlurHandler that is used to valide the input. + */ + public DoubleRangePanel( + String titleFrom, String titleTo, String titleStep, + double from, double to, double step, + int width, + BlurHandler handler) + { + FloatItem fromItem = new FloatItem(FIELD_FROM); + FloatItem toItem = new FloatItem(FIELD_TO); + FloatItem stepItem = new FloatItem(FIELD_WIDTH); + + fromItem.addBlurHandler(handler); + toItem.addBlurHandler(handler); + stepItem.addBlurHandler(handler); + + NumberFormat f = NumberFormat.getDecimalFormat(); + + fromItem.setValue(f.format(from)); + toItem.setValue(f.format(to)); + stepItem.setValue(f.format(step)); + + StaticTextItem fromText = new StaticTextItem("staticFrom"); + fromText.setValue(titleFrom); + fromText.setShowTitle(false); + fromItem.setShowTitle(false); + + StaticTextItem toText = new StaticTextItem("staticTo"); + toText.setValue(titleTo); + toText.setShowTitle(false); + toItem.setShowTitle(false); + + StaticTextItem stepText = new StaticTextItem("staticStep"); + stepText.setValue(titleStep); + stepText.setShowTitle(false); + stepItem.setShowTitle(false); + + int itemWidth = width / 6; + fromItem.setWidth(itemWidth); + fromText.setWidth(itemWidth); + toItem.setWidth(itemWidth); + toText.setWidth(itemWidth); + stepItem.setWidth(itemWidth); + stepText.setWidth(itemWidth); + + setFields(fromItem, fromText, toItem, toText, stepItem, stepText); + setFixedColWidths(false); + setNumCols(6); + setWidth(width); + setAlign(Alignment.CENTER); + } + + + /** + * This method validates the entered text in the input fields. If + * there are values that doesn't represent a valid float, an error is + * displayed. + * + * @param item The FormItem. + */ + protected boolean validateForm(FormItem item) { + if (item instanceof StaticTextItem) { + return true; + } + + boolean valid = true; + + String v = (String) item.getValue(); + + NumberFormat f = NumberFormat.getDecimalFormat(); + Map errors = getErrors(); + + try { + double value = f.parse(v); + + errors.remove(item.getFieldName()); + } + catch (NumberFormatException nfe) { + errors.put(item.getFieldName(), MESSAGES.wrongFormat()); + + item.focusInItem(); + + valid = false; + } + + setErrors(errors, true); + + return valid; + } + + + /** + * Returns the double value of value. + * + * @return the double value of value. + */ + protected double getDouble(String value) { + NumberFormat f = NumberFormat.getDecimalFormat(); + + return f.parse(value); + } + + + /** + * Returns the start value. + * + * @return the start value. + */ + public double getFrom() { + String v = getValueAsString(FIELD_FROM); + + return getDouble(v); + } + + + /** + * Returns the end value. + * + * @return the end value. + */ + public double getTo() { + String v = getValueAsString(FIELD_TO); + + return getDouble(v); + } + + + /** + * Returns the step width. + * + * @return the step width. + */ + public double getStep() { + String v = getValueAsString(FIELD_WIDTH); + + return getDouble(v); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,89 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.types.Alignment; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.layout.HLayout; + +import de.intevation.flys.client.client.FLYS; +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * @author Raimund Renkert + */ +public class FLYSFooter extends HLayout { + + /** The interface that provides i18n messages. */ + private FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** An instance to FLYS.*/ + protected FLYS flys; + + /** The button to open the project list.*/ + protected Label home; + + /** The button to switch between the english and german version.*/ + protected Label contact; + + /** The button to open an info panel.*/ + protected Label impressum; + + /** + * The default constructor for creating a new MainMenu. + */ + public FLYSFooter(FLYS flys) { + this.flys = flys; + + home = new Label(messages.footerHome()); + contact = new Label(messages.footerContact()); + impressum = new Label(messages.footerImpressum()); + + init(); + } + + + /** + * This method is called by the constructor after creating the necessary + * components. It initializes layout specific stuff like width, height, + * colors and so on and appends the components. + */ + protected void init() { + setStyleName("bgBlueDark"); + setHeight("25px"); + setLayoutMargin(5); + + home.setStyleName("fontLightSmall"); + contact.setStyleName("fontLightSmall"); + impressum.setStyleName("fontLightSmall"); + + HLayout panel = new HLayout(); + panel.setWidth("100%"); + panel.setMembersMargin(5); + panel.setAlign(Alignment.RIGHT); + panel.addMember(home); + panel.addMember(contact); + panel.addMember(impressum); + home.setAlign(Alignment.RIGHT); + contact.setAlign(Alignment.RIGHT); + impressum.setAlign(Alignment.RIGHT); + + home.setWidth(70); + contact.setWidth(70); + impressum.setWidth(80); + + addMember(panel); + } + + + /** + * Returns the FLYS instance stored in this class. + * + * @return the flys instance. + */ + protected FLYS getFlys() { + return flys; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,93 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ImageResource; + +import com.smartgwt.client.types.Alignment; +import com.smartgwt.client.widgets.Img; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.client.FLYSImages; +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * @author Ingo Weinzierl + */ +public class FLYSHeader extends HLayout { + + /** The interface that provides the image resources. */ + private FLYSImages IMAGES = GWT.create(FLYSImages.class); + + /** The interface that provides the message resources. */ + private FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + /** The height used for this header.*/ + public static final int HEIGHT = 75; + + /** The height used for the images.*/ + public static final int IMG_HEIGHT = 50; + + + public FLYSHeader() { + init(); + } + + public void init() { + setWidth100(); + setHeight(HEIGHT); + setLayoutLeftMargin(5); + setLayoutRightMargin(5); + + ImageResource flysRes = IMAGES.logoFlys(); + ImageResource bfgRes = IMAGES.logoBfg(); + + Img flys = new Img( + flysRes.getURL(), + calcWidth(flysRes,IMG_HEIGHT), + IMG_HEIGHT); + + Img bfg = new Img( + bfgRes.getURL(), + calcWidth(bfgRes, HEIGHT), + HEIGHT); + + Label fullname = new Label(MESSAGES.fullname()); + fullname.setHeight(HEIGHT - IMG_HEIGHT); + fullname.setStyleName ("fontNormalMid"); + + VLayout left = new VLayout(); + left.addMember(flys); + left.addMember(fullname); + + HLayout right = new HLayout(); + right.setAlign(Alignment.RIGHT); + right.addMember(bfg); + + addMember(left); + addMember(right); + } + + + /** + * This method calculates the wight of an image relative to the given + * height. + * + * @param res The ImageResource that points to the image. + * @param height The pre-defined height. + * + * @return the calculated width that should be used for the image. + */ + protected int calcWidth(ImageResource res, int height) { + int widthOrig = res.getWidth(); + int heightOrig = res.getHeight(); + + double factor = (double)heightOrig / height; + double width = (double)widthOrig / factor; + + return (int) width * 10 / 10; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSView.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,79 @@ +package de.intevation.flys.client.client.ui; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.layout.HLayout; + + +/** + * @author Ingo Weinzierl + */ +public class FLYSView extends Canvas { + + /** The project list displaying the projects of a user.*/ + protected ProjectList projectList; + + /** The workspace that handles the artifact collection views.*/ + protected FLYSWorkspace workspace; + + /** The layout provided by this widget.*/ + protected HLayout layout; + + + /** + * The default constructor for creating a new empty FLYSView. After creating + * the components, {@link init()} is called to do the layout work. + */ + public FLYSView() { + layout = new HLayout(); + + init(); + } + + + /** + * This method is called to do the layout work. + */ + protected void init() { + setWidth("100%"); + setHeight("*"); + + setStyleName("bgWhite"); + setBorder("1px solid #808080"); + + layout.setHeight("100%"); + layout.setWidth("100%"); + + addChild(layout); + } + + + /** + * Set the current project list. Previous ProjectLists are replaced by the + * new one. + */ + public void setProjectList(ProjectList projectList) { + if (this.projectList != null) { + removeChild(this.projectList); + } + + this.projectList = projectList; + layout.addMember(this.projectList); + } + + + /** + * Set the current FLYSWorkspace. Previous workspaces are replaced by the + * new one. + * + * @param workspaces The new FLYSWorkspace. + */ + public void setFLYSWorkspace(FLYSWorkspace workspace) { + if (this.workspace != null) { + removeChild(this.workspace); + } + + this.workspace = workspace; + layout.addMember(this.workspace); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.flys.client.client.ui; + +import com.smartgwt.client.widgets.Canvas; + +import java.util.ArrayList; +import java.util.List; + + +/** + * @author Ingo Weinzierl + */ +public class FLYSWorkspace extends Canvas { + + /** A map that contains the open CollectionViews. */ + protected List views; + + + /** + * The default constructor creates an empty FLYSWorkspace with no + * CollectionViews opened. + */ + public FLYSWorkspace() { + views = new ArrayList(); + } + + + /** + * This method adds a new CollectionView to this workspace and stores a + * reference in {@link views}. + * + * @param collectionView A new CollectionView. + */ + public void addView(CollectionView collectionView) { + views.add(collectionView); + addChild(collectionView); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,554 @@ +package de.intevation.flys.client.client.ui; + +import java.util.LinkedHashMap; +import java.util.List; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; +import com.smartgwt.client.widgets.form.fields.events.BlurEvent; +import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; +import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.RadioGroupItem; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * This UIProvider creates a widget to enter locations or a distance. + * + * @author Ingo Weinzierl + */ +public class LocationDistancePanel +extends AbstractUIProvider +implements ChangeHandler, BlurHandler +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** The constant name of the input field to enter locations.*/ + public static final String FIELD_LOCATION = "location"; + + /** The constant name of the input field to enter distance.*/ + public static final String FIELD_DISTANCE = "distance"; + + /** The constant name of the input field to enter the start of a distance.*/ + public static final String FIELD_FROM = "from"; + + /** The constant name of the input field to enter the end of a distance.*/ + public static final String FIELD_TO = "to"; + + /** The constant name of the input field to enter the step width of a + * distance.*/ + public static final String FIELD_WIDTH = "width"; + + public static final int WIDTH = 250; + + + /** The radio group for input mode selection.*/ + protected DynamicForm mode; + + /** A container that will contain the location or the distance panel.*/ + protected HLayout container; + + /** The min value for a distance.*/ + protected double min; + + /** The max value for a distance.*/ + protected double max; + + /** The 'from' value entered in the distance mode.*/ + protected double from; + + /** The 'to' value entered in the distance mode.*/ + protected double to; + + /** The 'step' value entered in the distance mode.*/ + protected double step; + + /** The values entered in the location mode.*/ + protected double[] values; + + + /** + * Creates a new LocationDistancePanel instance. + */ + public LocationDistancePanel() { + } + + + /** + * This method creates a widget that contains a label, a panel with + * checkboxes to switch the input mode between location and distance input, + * and a the mode specific panel. + * + * @param data The data that might be inserted. + * + * @return a panel. + */ + public Canvas create(DataList data) { + VLayout layout = new VLayout(); + layout.setMembersMargin(10); + + initDefaults(data); + + Label label = new Label(MESSAGES.location_distance_state()); + Canvas widget = createWidget(data); + Canvas submit = getNextButton(); + + widget.setHeight(50); + label.setHeight(25); + + layout.addMember(label); + layout.addMember(widget); + layout.addMember(submit); + + return layout; + } + + + public Canvas createOld(DataList dataList) { + List items = dataList.getAll(); + + Data dFrom = getData(items, "ld_from"); + Data dTo = getData(items, "ld_to"); + Data dStep = getData(items, "ld_step"); + + DataItem[] from = dFrom.getItems(); + DataItem[] to = dTo.getItems(); + DataItem[] step = dStep.getItems(); + + HLayout layout = new HLayout(); + layout.setWidth("400px"); + + Label label = new Label(dataList.getLabel()); + label.setWidth("200px"); + + StringBuilder sb = new StringBuilder(); + sb.append(from[0].getLabel()); + sb.append(" " + MESSAGES.unitFrom() + " "); + sb.append(to[0].getLabel()); + sb.append(" " + MESSAGES.unitTo() + " "); + sb.append(step[0].getLabel()); + sb.append(" " + MESSAGES.unitWidth()); + + Canvas back = getBackButton(dataList.getState()); + + Label selected = new Label(sb.toString()); + selected.setWidth("130px"); + + layout.addMember(label); + layout.addMember(selected); + layout.addMember(back); + + return layout; + } + + + /** + * This method reads the default values defined in the DataItems of the Data + * objects in list. + * + * @param list The DataList container that stores the Data objects. + */ + protected void initDefaults(DataList list) { + Data f = getData(list.getAll(), "ld_from"); + Data t = getData(list.getAll(), "ld_to"); + Data s = getData(list.getAll(), "ld_step"); + + DataItem[] fItems = f.getItems(); + DataItem[] tItems = t.getItems(); + DataItem[] sItems = s.getItems(); + + min = Double.valueOf(fItems[0].getStringValue()); + max = Double.valueOf(tItems[0].getStringValue()); + step = Double.valueOf(sItems[0].getStringValue()); + + this.from = min; + this.to = max; + this.step = step; + } + + + /** + * This method greps the Data with name name from the list and + * returns it. + * + * @param items A list of Data. + * @param name The name of the Data that we are searching for. + * + * @return the Data with the name name. + */ + protected Data getData(List data, String name) { + for (Data d: data) { + if (name.equals(d.getLabel())) { + return d; + } + } + + return null; + } + + + protected Canvas createWidget(DataList data) { + VLayout layout = new VLayout(); + container = new HLayout(); + Canvas checkboxPanel = createRadioButtonPanel(); + + // the initial view will display the location input mode + Canvas locationPanel = new DoubleArrayPanel( + MESSAGES.unitLocation(), + getLocationValues(), + this); + container.addMember(locationPanel); + + layout.addMember(checkboxPanel); + layout.addMember(container); + + // TODO Add a table on the right to select locations by mouse click + + return layout; + } + + + /** + * This method returns the selected data. + * + * @return the selected/inserted data. + */ + public Data[] getData() { + // XXX If we have entered a value and click right afterwards on the + // 'next' button, the BlurEvent is not fired, and the values are not + // saved. So, we gonna save those values explicitly. + if (isLocationMode()) { + Canvas member = container.getMember(0); + if (member instanceof DoubleArrayPanel) { + DoubleArrayPanel form = (DoubleArrayPanel) member; + saveLocationValues(form); + } + } + else { + Canvas member = container.getMember(0); + if (member instanceof DoubleRangePanel) { + DoubleRangePanel form = (DoubleRangePanel) member; + saveDistanceValues(form); + } + } + + return new Data[] { getDataFrom(), getDataTo(), getDataStep() }; + } + + + /** + * Returns the Data object for the 'from' attribute. + * + * @return the Data object for the 'from' attribute. + */ + protected Data getDataFrom() { + String value = Double.valueOf(getFinalFrom()).toString(); + DataItem item = new DefaultDataItem("ld_from", "ld_from", value); + return new DefaultData( + "ld_from", null, null, new DataItem[] { item }); + } + + + /** + * Returns the Data object for the 'to' attribute. + * + * @return the Data object for the 'to' attribute. + */ + protected Data getDataTo() { + String value = Double.valueOf(getFinalTo()).toString(); + DataItem item = new DefaultDataItem("ld_to", "ld_to", value); + return new DefaultData( + "ld_to", null, null, new DataItem[] { item }); + } + + + /** + * Returns the Data object for the 'step' attribute. + * + * @return the Data object for the 'step' attribute. + */ + protected Data getDataStep() { + String value = Double.valueOf(getFinalStep()).toString(); + DataItem item = new DefaultDataItem("ld_step","ld_step", value); + return new DefaultData( + "ld_step", null, null, new DataItem[] { item }); + } + + + /** + * Returns the value of 'from' depending on the selected input mode. + * + * @return the value of 'from' depending on the selected input mode. + */ + protected double getFinalFrom() { + if (isLocationMode()) { + double[] values = getLocationValues(); + double value = Double.MAX_VALUE; + + for (double v: values) { + value = value < v ? value : v; + } + + return value; + } + else { + return getFrom(); + } + } + + + /** + * Returns the value of 'to' depending on the selected input mode. + * + * @return the value of 'to' depending on the selected input mode. + */ + protected double getFinalTo() { + if (isLocationMode()) { + double[] values = getLocationValues(); + double value = Double.MIN_VALUE; + + for (double v: values) { + value = value > v ? value : v; + } + + return value; + } + else { + return getTo(); + } + } + + + /** + * Returns the value of 'step' depending on the selected input mode. + * + * @return the value of 'step' depending on the selected input mode. + */ + protected double getFinalStep() { + if (isLocationMode()) { + // we have no field to enter the 'step' attribute in the location + // mode + return 0.0; + } + else { + return getStep(); + } + } + + + /** + * Determines the current input mode. + * + * @return true, if 'location' is the current input mode, otherwise false. + */ + public boolean isLocationMode() { + String inputMode = mode.getValueAsString("mode"); + + return inputMode.equals(FIELD_LOCATION) ? true : false; + } + + + /** + * This method switches the input mode between location and distance input. + * + * @param event The click event fired by a RadioButtonGroupItem. + */ + public void onChange(ChangeEvent event) { + String value = (String) event.getValue(); + + if (value == null) { + return; + } + + if (value.equals(FIELD_LOCATION)) { + Canvas locationPanel = new DoubleArrayPanel( + MESSAGES.unitLocation(), + getLocationValues(), + this); + + container.removeMembers(container.getMembers()); + container.addMember(locationPanel); + } + else { + Canvas distancePanel = new DoubleRangePanel( + MESSAGES.unitFrom(), MESSAGES.unitTo(), MESSAGES.unitWidth(), + getFrom(), getTo(), getStep(), + 250, + this); + + container.removeMembers(container.getMembers()); + container.addMember(distancePanel); + } + } + + + /** + * This method is used to validate the inserted data in the form fields. + * + * @param event The BlurEvent that gives information about the FormItem that + * has been modified and its value. + */ + public void onBlur(BlurEvent event) { + FormItem item = event.getItem(); + String field = item.getFieldName(); + + if (field == null) { + return; + } + + if (field.equals(DoubleArrayPanel.FIELD_NAME)) { + DoubleArrayPanel p = (DoubleArrayPanel) event.getForm(); + + saveLocationValue(p, item); + } + else { + DoubleRangePanel p = (DoubleRangePanel) event.getForm(); + + saveDistanceValue(p, item); + } + } + + + /** + * Validates and stores all values entered in the location mode. + * + * @param p The DoubleArrayPanel. + */ + protected void saveLocationValues(DoubleArrayPanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) { + saveLocationValue(p, item); + } + } + } + + + /** + * Validates and stores all values entered in the distance mode. + * + * @param p The DoubleRangePanel. + */ + protected void saveDistanceValues(DoubleRangePanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + saveDistanceValue(p, item); + } + } + + + /** + * Validates and stores a value entered in the location mode. + * + * @param p The DoubleArrayPanel. + * @param item The item that needs to be validated. + */ + protected void saveLocationValue(DoubleArrayPanel p, FormItem item) { + if (p.validateForm(item)) { + setLocationValues(p.getInputValues(item)); + } + } + + + /** + * Validates and stores value entered in the distance mode. + * + * @param p The DoubleRangePanel. + * @param item The item that needs to be validated. + */ + protected void saveDistanceValue(DoubleRangePanel p, FormItem item) { + if (p.validateForm(item)) { + setFrom(p.getFrom()); + setTo(p.getTo()); + setStep(p.getStep()); + } + } + + + /** + * This method creates the panel that contains the checkboxes to switch + * between the input mode 'location' and 'distance'. + * + * @return the checkbox panel. + */ + protected Canvas createRadioButtonPanel() { + mode = new DynamicForm(); + + RadioGroupItem radio = new RadioGroupItem("mode"); + radio.setShowTitle(false); + radio.setVertical(false); + + LinkedHashMap values = new LinkedHashMap(); + values.put(FIELD_LOCATION, MESSAGES.location()); + values.put(FIELD_DISTANCE, MESSAGES.distance()); + + LinkedHashMap initial = new LinkedHashMap(); + initial.put("mode", FIELD_LOCATION); + + radio.setValueMap(values); + radio.addChangeHandler(this); + + mode.setFields(radio); + mode.setValues(initial); + + return mode; + } + + + protected double getFrom() { + return from; + } + + + protected void setFrom(double from) { + this.from = from; + } + + + protected double getTo() { + return to; + } + + + protected void setTo(double to) { + this.to = to; + } + + + protected double getStep() { + return step; + } + + + protected void setStep(double step) { + this.step = step; + } + + + protected double[] getLocationValues() { + return values; + } + + + protected void setLocationValues(double[] values) { + this.values = values; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/MainMenu.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MainMenu.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,202 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.types.Alignment; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.events.ClickEvent; +import com.smartgwt.client.widgets.events.ClickHandler; +import com.smartgwt.client.widgets.layout.HLayout; + +import de.intevation.flys.client.client.FLYS; +import de.intevation.flys.client.client.FLYSMessages; +import de.intevation.flys.client.shared.model.User; + + +/** + * @author Ingo Weinzierl + */ +public class MainMenu extends HLayout { + + /** The interface that provides i18n messages. */ + private FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** An instance to FLYS.*/ + protected FLYS flys; + + /** The user that is currently logged in. */ + protected User currentUser; + + /** The label that displays the current logged in user. */ + protected Label userText; + + /** The button to log the current user out.*/ + protected Label logout; + + /** The button to add new projects.*/ + protected Label newProject; + + /** The button to open the project list.*/ + protected Label projectList; + + /** The button to switch between the english and german version.*/ + protected Label language; + + /** The button to open an info panel.*/ + protected Label info; + + /** + * The default constructor for creating a new MainMenu. + */ + public MainMenu(FLYS flys) { + this.flys = flys; + + String guest = messages.user() + " " + messages.guest(); + + userText = new Label(guest); + newProject = new Label(messages.new_project()); + projectList = new Label(messages.manage_projects()); + logout = new Label(messages.logout()); + language = new Label(messages.switch_language()); + info = new Label(messages.info()); + + newProject.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + GWT.log("Clicked 'New Project' button."); + createNewProject(); + } + }); + + projectList.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + GWT.log("Clicked 'Open ProjectList' button."); + ProjectList list = getFlys().getProjectList(); + if (list.isVisible()) + list.hide(); + else + list.show(); + } + }); + + logout.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + GWT.log("Clicked 'logout' button."); + GWT.log("IMPLEMENT the 'logout' function."); + } + }); + + language.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + GWT.log("Clicked 'language' button."); + GWT.log("IMPLEMENT the 'switch language' function."); + } + }); + + info.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + GWT.log("Clicked 'info' button."); + GWT.log("IMPLEMENT the 'open info panel' function."); + } + }); + + init(); + } + + + /** + * This method is called by the constructor after creating the necessary + * components. It initializes layout specific stuff like width, height, + * colors and so on and appends the components. + */ + protected void init() { + setStyleName("bgBlueDark"); + setHeight("25px"); + setLayoutMargin(5); + + newProject.setStyleName("fontLightSmall"); + projectList.setStyleName("fontLightSmall"); + userText.setStyleName("fontLightSmall"); + newProject.setStyleName("fontLightSmall"); + logout.setStyleName("fontLightSmall"); + language.setStyleName("fontLightSmall"); + info.setStyleName("fontLightSmall"); + + projectList.setWidth("140px"); + + HLayout leftPanel = new HLayout(); + leftPanel.setWidth("80%"); + leftPanel.setMembersMargin(5); + leftPanel.addMember(newProject); + leftPanel.addMember(projectList); + + userText.setAlign(Alignment.RIGHT); + logout.setAlign(Alignment.RIGHT); + info.setAlign(Alignment.RIGHT); + language.setAlign(Alignment.RIGHT); + + userText.setWidth(200); + logout.setWidth(70); + info.setWidth(40); + language.setWidth(70); + + HLayout rightPanel = new HLayout(); + rightPanel.setAlign(Alignment.RIGHT); + rightPanel.setMembersMargin(3); + rightPanel.setLayoutRightMargin(5); + rightPanel.addMember(userText); + rightPanel.addMember(logout); + rightPanel.addMember(language); + rightPanel.addMember(info); + + addMember(leftPanel); + addMember(rightPanel); + } + + + /** + * Returns the FLYS instance stored in this class. + * + * @return the flys instance. + */ + protected FLYS getFlys() { + return flys; + } + + + /** + * Set the current {@link User} and call {@link updateCurrentUser()} + * afterwards. + * + * @param user the new user. + */ + public void setCurrentUser(User currentUser) { + this.currentUser = currentUser; + + updateCurrentUser(); + } + + + /** + * Update the text field that shows the current user. If no user is + * currently logged in, the text will display {@link FLYSMessages.guest()}. + */ + public void updateCurrentUser() { + String name = currentUser != null + ? currentUser.getName() + : messages.guest(); + + GWT.log("Update the current user: " + name); + + String username = messages.user() + " " + name; + userText.setContents(username); + } + + + /** + * Create a new project by calling FLYS.newProject(). + */ + protected void createNewProject() { + flys.newProject(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/MapSelection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MapSelection.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ImageResource; + +import com.smartgwt.client.types.VerticalAlignment; +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Img; +import com.smartgwt.client.widgets.layout.HLayout; + +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.client.FLYSImages; + + +/** + * This UIProvider displays the DataItems contained in the Data object in a + * combo box as SelectProvider does. Furthermore, there is a map displayed that + * lets the user choose a river by selecting it on the map. + * + * @author Ingo Weinzierl + */ +public class MapSelection extends SelectProvider { + + /** The interface that provides the image resources. */ + private FLYSImages IMAGES = GWT.create(FLYSImages.class); + + + public MapSelection() { + } + + + /** + * This method currently returns a + * {@link com.smartgwt.client.widgets.form.DynamicForm} that contains all + * data items in a combobox stored in data.
+ * + * TODO: The map panel for the river selection needs to be + * implemented! + * + * @param data The {@link DataList} object. + * + * @return a combobox. + */ + protected Canvas createWidget(DataList data) { + GWT.log("MapSelection - create()"); + + HLayout h = new HLayout(); + h.setAlign(VerticalAlignment.TOP); + + Canvas form = super.createWidget(data); + form.setWidth(250); + form.setLayoutAlign(VerticalAlignment.TOP); + + ImageResource mapRes = IMAGES.riverMap(); + Img map = new Img(mapRes.getURL(), 400, 452); + + // TODO implement event handling in the river map + + h.addMember(form); + helperContainer.addChild(map); + + return h; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,156 @@ +package de.intevation.flys.client.client.ui; + +import java.util.LinkedHashMap; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.types.VerticalAlignment; +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.RadioGroupItem; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; + +import de.intevation.flys.client.client.FLYSMessages; + +/** + * The ModuleSelection combines the river selection and the module selection in + * one widget. It will display a vertical splitted widget - the upper part will + * render checkboxes for each module, the lower one will display a combobox at + * the left and a map panel on the right to choose the river. + * + * @author Ingo Weinzierl + */ +public class ModuleSelection extends MapSelection { + + /** The message class that provides i18n strings.*/ + protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); + + + /** Constant field name for the plugin selection.*/ + public static final String FIELD_PLUGIN = "plugin"; + + /** Constant value for the WINFO plugin.*/ + public static final String FIELD_PLUGIN_WINFO = "winfo"; + + /** Constant value for the MINFO plugin.*/ + public static final String FIELD_PLUGIN_MINFO = "minfo"; + + /** Constant value for the MAP plugin.*/ + public static final String FIELD_PLUGIN_MAP = "map"; + + /** Constant value for the CHART plugin.*/ + public static final String FIELD_PLUGIN_CHART = "chart"; + + /** Constant value for the FIX plugin.*/ + public static final String FIELD_PLUGIN_FIX = "fix"; + + + /** The module checkboxes.*/ + protected RadioGroupItem radio; + + + /** + * The default constructor. + */ + public ModuleSelection() { + } + + + /** + * This method returns a widget that renders the checkboxes for each module + * and the MapSelection that lets the user choose the river. + * + * @param data The provided rivers. + * + * @return the module selection combined with the river selection. + */ + public Canvas create(DataList data) { + VLayout newLayout = new VLayout(); + newLayout.setMembersMargin(10); + //newLayout.setAlign(VerticalAlignment.TOP); + + Canvas moduleSelection = createWidget(); + Canvas riverSelection = super.createWidget(data); + Canvas go = getNextButton(); + //go.setLayoutAlign(VerticalAlignment.TOP); + + riverSelection.setHeight(25); + moduleSelection.setHeight(25); + + newLayout.addMember(moduleSelection); + newLayout.addMember(riverSelection); + newLayout.addMember(go); + + return newLayout; + } + + + /** + * Creates a widget that displays a checkbox for each module. + * + * @return a widget with checkboxes. + */ + protected Canvas createWidget() { + HLayout layout = new HLayout(); + + Label label = new Label(MESSAGES.module_selection()); + DynamicForm form = new DynamicForm(); + + radio = new RadioGroupItem("plugin"); + + label.setWidth(50); + + LinkedHashMap values = new LinkedHashMap(); + values.put(FIELD_PLUGIN_WINFO, messages.winfo()); + values.put(FIELD_PLUGIN_MINFO, messages.minfo()); + values.put(FIELD_PLUGIN_FIX, messages.fix()); + values.put(FIELD_PLUGIN_CHART, messages.chart()); + values.put(FIELD_PLUGIN_MAP, messages.map()); + + radio.setShowTitle(false); + radio.setVertical(true); + radio.setValueMap(values); + + LinkedHashMap initial = new LinkedHashMap(); + initial.put(FIELD_PLUGIN, FIELD_PLUGIN_WINFO); + + form.setFields(radio); + form.setValues(initial); + + layout.addMember(label); + layout.addMember(form); + + return layout; + } + + + /** + * This method prepares the data of two widgets - the module selection and + * the river selection. The returning field will contain the Data that + * represents the module selection at first position, the second position + * stores the Data object that represents the river selection. + * + * @return the Data that was chosen in this widget. + */ + protected Data[] getData() { + Data[] river = super.getData(); + + String module = radio.getValueAsString(); + + DataItem[] items = new DefaultDataItem[1]; + items[0] = new DefaultDataItem(module, module, module); + + Data data = new DefaultData("module", null, null, items); + + return new Data[] {data, river[0]}; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/OutputTab.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/OutputTab.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.flys.client.client.ui; + +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.tab.Tab; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.OutputMode; + + +public class OutputTab extends Tab { + + /** The OutputMode that should be displayed in this tab.*/ + protected OutputMode mode; + + /** The Collection that should be displayed in this tab.*/ + protected Collection collection; + + + /** + * The default constructor that creates a new Tab for displaying a specific + * OutputMode of a Collection. + * + * @param title The title of the tab. + * @param collection The collection that need to be displayed. + * @param outputmode The OutputMode that need to be displayed. + */ + public OutputTab(String title, Collection collection, OutputMode mode) { + super(title); + + this.collection = collection; + this.mode = mode; + + setPane(new Label("Implement concrete subclasses to vary the output.")); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,429 @@ +package de.intevation.flys.client.client.ui; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; + +import com.smartgwt.client.types.VerticalAlignment; +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; +import com.smartgwt.client.widgets.tab.Tab; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.ArtifactDescription; +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; +import de.intevation.flys.client.shared.model.River; +import de.intevation.flys.client.client.Config; +import de.intevation.flys.client.client.FLYS; +import de.intevation.flys.client.client.FLYSMessages; +import de.intevation.flys.client.client.event.HasParameterChangeHandler; +import de.intevation.flys.client.client.event.HasStepBackHandlers; +import de.intevation.flys.client.client.event.HasStepForwardHandlers; +import de.intevation.flys.client.client.event.ParameterChangeEvent; +import de.intevation.flys.client.client.event.ParameterChangeHandler; +import de.intevation.flys.client.client.event.StepBackEvent; +import de.intevation.flys.client.client.event.StepBackHandler; +import de.intevation.flys.client.client.event.StepForwardEvent; +import de.intevation.flys.client.client.event.StepForwardHandler; +import de.intevation.flys.client.client.services.AdvanceService; +import de.intevation.flys.client.client.services.AdvanceServiceAsync; +import de.intevation.flys.client.client.services.ArtifactService; +import de.intevation.flys.client.client.services.ArtifactServiceAsync; +import de.intevation.flys.client.client.services.StepForwardService; +import de.intevation.flys.client.client.services.StepForwardServiceAsync; + + +public class ParameterList +extends Tab +implements StepBackHandler, StepForwardHandler, ParameterChangeHandler, + HasParameterChangeHandler +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MSG = GWT.create(FLYSMessages.class); + + /** The ArtifactService used to communicate with the Artifact server. */ + protected ArtifactServiceAsync artifactService = + GWT.create(ArtifactService.class); + + /** The StepForwardService used to put data into an existing artifact. */ + protected StepForwardServiceAsync forwardService = + GWT.create(StepForwardService.class); + + /** The StepForwardService used to put data into an existing artifact. */ + protected AdvanceServiceAsync advanceService = + GWT.create(AdvanceService.class); + + + /** The list of ParameterizationChangeHandler.*/ + protected List parameterHandlers; + + protected FLYS flys; + + protected CollectionView cView; + + protected Artifact artifact; + + protected List old; + protected DataList current; + + protected UIProvider uiProvider; + + protected VLayout oldItems; + protected VLayout currentItems; + protected Canvas helperPanel; + + public ParameterList(FLYS flys, CollectionView cView, String title) { + super(title); + + this.cView = cView; + this.flys = flys; + + parameterHandlers = new ArrayList(); + old = new ArrayList(); + oldItems = new VLayout(); + currentItems = new VLayout(); + + init(); + } + + + protected void init() { + HLayout rootLayout = new HLayout(); + rootLayout.setMembersMargin(20); + + VLayout left = new VLayout(); + + if (old == null || old.size() == 0) { + oldItems.setHeight(0); + } + + oldItems.setMembersMargin(10); + currentItems.setAlign(VerticalAlignment.TOP); + + left.setMembersMargin(20); + left.setWidth(300); + + left.addMember(oldItems); + left.addMember(currentItems); + + // This canvas is used to render helper widgets + helperPanel = new Canvas(); + + rootLayout.addMember(left); + rootLayout.addMember(helperPanel); + + Canvas moduleSelection = renderNew(); + moduleSelection.setLayoutAlign(VerticalAlignment.TOP); + currentItems.addMember(moduleSelection); + + setPane(rootLayout); + } + + + protected void setArtifact(Artifact artifact) { + Artifact tmp = this.artifact; + this.artifact = artifact; + + fireParameterChangeEvent(tmp, this.artifact); + } + + + /** + * This method registers a new ParameterChangeHandler. + * + * @param handler The new ParameterChangeHandler. + */ + public void addParameterChangeHandler(ParameterChangeHandler handler) { + if (handler != null) { + parameterHandlers.add(handler); + } + } + + + /** + * This method calls the onParameterChange() method of all + * registered ParameterChangeHandler. + */ + protected void fireParameterChangeEvent(Artifact old, Artifact newArt) { + for (ParameterChangeHandler handler: parameterHandlers) { + handler.onParameterChange(new ParameterChangeEvent(old, newArt)); + } + } + + + /** + * This method creates a Canvas displaying the plugins of FLYS combined with + * a widget to select a river. + * + * @return a Canvas that displays the supported plugins and rivers of FLYS. + */ + protected Canvas renderNew() { + River[] rivers = flys.getRivers(); + DataItem[] items = new DataItem[rivers.length]; + + int i = 0; + for (River river: rivers) { + String name = river.getName(); + items[i++] = new DefaultDataItem(name, null, name); + } + + Data data = new DefaultData( + "river", + MSG.river_selection(), + null, + items); + + ModuleSelection widget = new ModuleSelection(); + HasStepForwardHandlers handler = (HasStepForwardHandlers) widget; + + widget.setContainer(helperPanel); + + handler.addStepForwardHandler(new StepForwardHandler() { + public void onStepForward(StepForwardEvent event) { + Data[] data = event.getData(); + + DataItem[] moduleItems = data[0].getItems(); + DataItem[] riversItems = data[1].getItems(); + + String module = moduleItems[0].getStringValue(); + String river = riversItems[0].getStringValue(); + + if (module == null) { + // TODO throw / show error! + return; + } + + String newTitle = MSG.getString(module); + setTitle(newTitle); + + final String serverUrl = Config.getInstance().getServerUrl(); + final Data[] feedData = new Data[] { data[1] }; + artifactService.create( + serverUrl, module.toLowerCase(), + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not create the new artifact."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Artifact artifact) { + GWT.log("Successfully created a new artifact."); + + forwardService.go(serverUrl, artifact, feedData, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not feed the artifact."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Artifact artifact) { + GWT.log("Successfully feed the artifact."); + setArtifact(artifact); + } + }); + } + }); + } + }); + + DataList list = new DataList(); + list.add(data); + + return widget.create(list); + } + + + protected void clearOldData() { + old.clear(); + } + + + public void addOldData(DataList old) { + if (old != null) { + this.old.add(old); + } + + refreshOld(); + } + + + public void addOldDatas(DataList[] old) { + if (old != null && old.length > 0) { + for (DataList o: old) { + if (!exists(o)) { + GWT.log("Data '" + o.getLabel() + "' is new."); + addOldData(o); + } + } + + return; + } + + addOldData(null); + } + + + public boolean exists(DataList data) { + String stateName = data.getState(); + + for (DataList o: old) { + if (stateName.equals(o.getState())) { + return true; + } + } + + return false; + } + + + public void setCurrentData(DataList current, UIProvider uiProvider) { + this.current = current; + this.uiProvider = uiProvider; + + refreshCurrent(); + } + + + public void refreshOld() { + // XXX maybe we should not remove all items but just add the newest item + // to the list. + oldItems.removeMembers(oldItems.getMembers()); + + for (DataList dataList: old) { + HLayout h = new HLayout(); + h.setAlign(VerticalAlignment.TOP); + h.setHeight(20); + + String provider = dataList.getUIProvider(); + UIProvider uiprovider = UIProviderFactory.getProvider(provider); + ((HasStepBackHandlers) uiprovider).addStepBackHandler(this); + + oldItems.addMember(uiprovider.createOld(dataList)); + } + + int minHeight = oldItems.getMinHeight(); + if (minHeight <= 20) { + oldItems.setHeight(20); + } + else { + oldItems.setHeight(minHeight); + } + } + + + /** + * This method refreshes the part displaying the data of the current state. + * The UI is created using the UIProvider stored in the Data object. + */ + public void refreshCurrent() { + currentItems.removeMembers(currentItems.getMembers()); + + if (current != null && uiProvider != null) { + Canvas c = uiProvider.create(current); + c.setLayoutAlign(VerticalAlignment.TOP); + + currentItems.addMember(c); + } + } + + + /** + * This method is called if the user clicks on the 'next' button to advance + * to the next state. + * + * @param event The StepForwardEvent. + */ + public void onStepForward(StepForwardEvent event) { + GWT.log("CollectionView - onStepForward()"); + String serverUrl = Config.getInstance().getServerUrl(); + + forwardService.go(serverUrl, artifact, event.getData(), + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not feed the artifact."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Artifact artifact) { + GWT.log("Successfully feed the artifact."); + setArtifact(artifact); + } + }); + } + + + /** + * This method is used to remove all old items from this list after the user + * has clicked the step back button. + * + * @param e The StepBackEvent that holds the identifier of the target state. + */ + public void onStepBack(StepBackEvent e) { + final String target = e.getTarget(); + final String serverUrl = Config.getInstance().getServerUrl(); + + advanceService.advance(serverUrl, artifact, target, + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not go back to '" + target + "'"); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Artifact artifact) { + GWT.log("Successfully step back to '" + target + "'"); + + old.clear(); + oldItems.removeMembers(oldItems.getMembers()); + + setArtifact(artifact); + } + } + ); + } + + + /** + * Implements the onCollectionChange() method to do update the GUI after the + * parameterization has changed. + * + * @param event The ParameterChangeEvent. + */ + public void onParameterChange(ParameterChangeEvent event) { + GWT.log("ParameterList.onParameterChange"); + + for (Canvas c: helperPanel.getChildren()) { + helperPanel.removeChild(c); + } + + Artifact art = event.getNewValue(); + ArtifactDescription desc = art.getArtifactDescription(); + + DataList currentData = desc.getCurrentData(); + if (currentData != null) { + // the user has to enter some attributes + String uiProvider = currentData.getUIProvider(); + UIProvider provider = UIProviderFactory.getProvider(uiProvider); + + provider.setContainer(helperPanel); + + ((HasStepForwardHandlers) provider).addStepForwardHandler(this); + ((HasStepBackHandlers) provider).addStepBackHandler(this); + + setCurrentData(currentData, provider); + } + else { + // we have reached a final state with no more user input + setCurrentData(null, null); + } + + addOldDatas(desc.getOldData()); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,169 @@ +package de.intevation.flys.client.client.ui; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.grid.ListGrid; +import com.smartgwt.client.widgets.grid.ListGridField; +import com.smartgwt.client.widgets.grid.ListGridRecord; +import com.smartgwt.client.widgets.layout.VLayout; +import com.smartgwt.client.types.VerticalAlignment; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.CollectionRecord; +import de.intevation.flys.client.shared.model.User; + +import de.intevation.flys.client.client.Config; +import de.intevation.flys.client.client.FLYSMessages; +import de.intevation.flys.client.client.event.CollectionChangeEvent; +import de.intevation.flys.client.client.event.CollectionChangeHandler; +import de.intevation.flys.client.client.services.UserCollectionsService; +import de.intevation.flys.client.client.services.UserCollectionsServiceAsync; + + +/** + * The project list shows a list of projects of a specific user. + * + * @author Ingo Weinzierl + */ +public class ProjectList +extends VLayout +implements CollectionChangeHandler +{ + /** The interface that provides i18n messages. */ + private FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** The UserService used to retrieve information about the current user. */ + protected UserCollectionsServiceAsync userCollectionsService = + GWT.create(UserCollectionsService.class); + + /** The user whose projects should be displayed.*/ + protected User user; + + /** The grid that contains the project rows.*/ + protected ListGrid grid; + + /** + * The default constructor that creates a new ProjectList for a specific + * user. + * + * @param user The user. + */ + public ProjectList(User user) { + this.user = user; + + grid = new CollectionGrid(); + initGrid(); + init(); + + updateUserCollections(); + } + + + protected void initGrid() { + grid.setEmptyMessage(messages.no_projects()); + grid.setLoadingDataMessage(messages.load_projects()); + grid.setShowRecordComponents(true); + grid.setShowRecordComponentsByCell(true); + grid.setCanRemoveRecords(false); + grid.setShowHeader(false); + grid.setWidth100(); + grid.setHeight100(); + + ListGridField date = new ListGridField("date", "date"); + ListGridField name = new ListGridField("name", "name"); + + date.setWidth(100); + name.setWidth(195); + + grid.setFields(date, name); + } + + + /** + * The init() method handles the layout stuff for this widget. + */ + protected void init() { + setWidth(300); + setHeight100(); + setShowResizeBar(true); + setShowEdges(false); + setLayoutMargin(0); + setLayoutAlign(VerticalAlignment.TOP); + + Label title = new Label(messages.projects()); + title.setHeight("20"); + title.setMargin(5); + title.setWidth100(); + title.setStyleName("fontLightSmall"); + + Canvas titleWrapper = new Canvas(); + titleWrapper.setStyleName("bgBlueDark"); + titleWrapper.setWidth100(); + titleWrapper.setHeight("20px"); + titleWrapper.addChild(title); + + Canvas gridWrapper = new Canvas(); + gridWrapper.setPadding(0); + titleWrapper.setWidth100(); + gridWrapper.addChild(grid); + + addMember(titleWrapper); + addMember(gridWrapper); + } + + + public void onCollectionChange(CollectionChangeEvent event) { + GWT.log("ProjectList.onCollectionChange"); + + updateUserCollections(); + } + + + protected void updateUserCollections() { + Config config = Config.getInstance(); + String url = config.getServerUrl(); + + userCollectionsService.getUserCollections(url, user.identifier(), + new AsyncCallback() { + public void onFailure(Throwable caught) { + GWT.log("Could not recieve a list of user collections."); + GWT.log(caught.getMessage()); + } + + public void onSuccess(Collection[] collections) { + int num = collections != null ? collections.length : 0; + + GWT.log("Received " + num + " user collections."); + + if (num == 0) { + return; + } + + updateGrid(collections); + } + } + ); + } + + + protected void clearGrid() { + ListGridRecord[] records = grid.getRecords(); + + for (ListGridRecord record: records) { + grid.removeData(record); + } + } + + + protected void updateGrid(Collection[] collections) { + clearGrid(); + + for (Collection c: collections) { + grid.addData(new CollectionRecord(c)); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,166 @@ +package de.intevation.flys.client.client.ui; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.types.VerticalAlignment; +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.ComboBoxItem; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; + +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * This UIProvider displays the DataItems of the Data object in a combo box. + * + * @author Ingo Weinzierl + */ +public class SelectProvider +extends AbstractUIProvider +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages messages = GWT.create(FLYSMessages.class); + + /** The combobox.*/ + protected DynamicForm form; + + + /** + * This method currently returns a + * {@link com.smartgwt.client.widgets.form.DynamicForm} that contains all + * data items in a combobox stored in data. + * + * @param data The {@link Data} object. + * + * @return a combobox. + */ + public Canvas create(DataList data) { + VLayout v = new VLayout(); + v.setMembersMargin(10); + + Canvas content = createWidget(data); + Canvas button = getNextButton(); + + v.addMember(content); + v.addMember(button); + + return v; + } + + + public Canvas createOld(DataList dataList) { + HLayout layout = new HLayout(); + VLayout vLayout = new VLayout(); + layout.setWidth("400px"); + + Label label = new Label(dataList.getLabel()); + label.setWidth("200px"); + + int size = dataList.size(); + for (int i = 0; i < size; i++) { + Data data = dataList.get(i); + DataItem[] items = data.getItems(); + + for (DataItem item: items) { + HLayout hLayout = new HLayout(); + + hLayout.addMember(label); + hLayout.addMember(new Label(item.getLabel())); + + vLayout.addMember(hLayout); + vLayout.setWidth("130px"); + } + } + + Canvas back = getBackButton(dataList.getState()); + + layout.addMember(label); + layout.addMember(vLayout); + layout.addMember(back); + + return layout; + } + + + /** + * This method creates the content of the widget. + * + * @param data The {@link Data} object. + * + * @return a combobox. + */ + protected Canvas createWidget(DataList data) { + GWT.log("SelectProvider - create()"); + + VLayout layout = new VLayout(); + layout.setAlign(VerticalAlignment.TOP); + layout.setHeight(25); + + form = new DynamicForm(); + + int size = data.size(); + + for (int i = 0; i < size; i++) { + Data d = data.get(i); + + Label label = new Label(d.getDescription()); + label.setValign(VerticalAlignment.TOP); + label.setHeight(20); + + ComboBoxItem combobox = new ComboBoxItem(d.getLabel()); + + LinkedHashMap it = new LinkedHashMap(); + + for (DataItem item: d.getItems()) { + it.put(item.getStringValue(), item.getLabel()); + } + + label.setWidth(50); + combobox.setValueMap(it); + combobox.setShowTitle(false); + form.setItems(combobox); + + layout.addMember(label); + layout.addMember(form); + } + + layout.setAlign(VerticalAlignment.TOP); + + return layout; + } + + + protected Data[] getData() { + Map values = form.getValues(); + Iterator keys = values.keySet().iterator(); + + Data[] list = new Data[values.size()]; + int i = 0; + + while (keys.hasNext()) { + String fieldname = (String) keys.next(); + String selection = (String) values.get(fieldname); + + DataItem item = new DefaultDataItem(fieldname, null, selection); + + list[i++] = new DefaultData( + fieldname, null, null, new DataItem[] { item }); + } + + return list; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProvider.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.flys.client.client.ui; + +import java.io.Serializable; + +import com.smartgwt.client.widgets.Canvas; + +import de.intevation.flys.client.shared.model.DataList; + + +/** + * This interface describes a method that creates a Canvas element displaying + * DataItems for a current state of the artifact. + * + * @author Ingo Weinzierl + */ +public interface UIProvider extends Serializable { + + /** + * This method creates a Canvas element showing the DataItems in + * data. + * + * @param data The DataList object. + * + * @return the Canvas showing the Data. + */ + public Canvas create(DataList data); + + + /** + * This method creates a Canvas element showing the old Data objects in the + * DataList data. + * + * @param dataList The DataList which elements should be displayed. + * + * @return a Canvas displaying the Data. + */ + public Canvas createOld(DataList dataList); + + + /** + * This method injects a container that is used to position helper widgets. + * + * @param container A container that is used to position helper widgets. + */ + public void setContainer(Canvas container); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,25 @@ +package de.intevation.flys.client.client.ui; + +public class UIProviderFactory { + + private UIProviderFactory() { + } + + public static UIProvider getProvider(String uiProvider) { + if (uiProvider == null || uiProvider.equals("")) { + return new SelectProvider(); + } + else if (uiProvider.equals("select_with_map")) { + return new MapSelection(); + } + else if (uiProvider.equals("location_distance_panel")) { + return new LocationDistancePanel(); + } + else if (uiProvider.equals("wq_panel")) { + return new WQInputPanel(); + } + else { + return new SelectProvider(); + } + } +} diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,810 @@ +package de.intevation.flys.client.client.ui; + +import java.util.LinkedHashMap; +import java.util.List; + +import com.google.gwt.core.client.GWT; + +import com.smartgwt.client.widgets.Canvas; +import com.smartgwt.client.widgets.Label; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.form.fields.FormItem; +import com.smartgwt.client.widgets.form.fields.RadioGroupItem; +import com.smartgwt.client.widgets.form.fields.events.BlurHandler; +import com.smartgwt.client.widgets.form.fields.events.BlurEvent; +import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; +import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; +import com.smartgwt.client.widgets.layout.HLayout; +import com.smartgwt.client.widgets.layout.VLayout; + +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; +import de.intevation.flys.client.client.FLYSMessages; + + +/** + * This UIProvider creates a widget to enter W or Q data. + * + * @author Ingo Weinzierl + */ +public class WQInputPanel +extends AbstractUIProvider +implements ChangeHandler, BlurHandler +{ + /** The message class that provides i18n strings.*/ + protected FLYSMessages MSG = GWT.create(FLYSMessages.class); + + + /** The constant field name for choosing w or q mode.*/ + public static final String FIELD_WQ = "wq"; + + /** The constant field value for W input mode.*/ + public static final String FIELD_WQ_W = "W"; + + /** The constant field value for Q input mode.*/ + public static final String FIELD_WQ_Q = "Q"; + + /** The constant field name for choosing single values or range.*/ + public static final String FIELD_MODE = "mode"; + + /** The constant field value for single input mode.*/ + public static final String FIELD_MODE_SINGLE = "single"; + + /** The constant field value for range input mode.*/ + public static final String FIELD_MODE_RANGE = "range"; + + /** The constant value that determines the width of the left panel.*/ + public static final int WIDTH_LEFT = 200; + + + /** The container that manages the w and q panels.*/ + protected VLayout container; + + /** The RadioGroupItem that determines the w/q input mode.*/ + protected DynamicForm modes; + + /** The min values for the 'from' property in the W-Range input mode.*/ + protected double minW; + + /** The min values for the 'from' property in the Q-Range input mode.*/ + protected double minQ; + + /** The max values for the 'from' property in the W-Range input mode.*/ + protected double maxW; + + /** The max values for the 'from' property in the Q-Range input mode.*/ + protected double maxQ; + + /** The 'from' value entered in the range W mode.*/ + protected double fromW; + + /** The 'to' value entered in the range W mode.*/ + protected double toW; + + /** The 'step' value entered in the range W mode.*/ + protected double stepW; + + /** The values entered in the single W mode.*/ + protected double[] valuesW; + + /** The 'from' value entered in the range Q mode.*/ + protected double fromQ; + + /** The 'to' value entered in the range Q mode.*/ + protected double toQ; + + /** The 'step' value entered in the range Q mode.*/ + protected double stepQ; + + /** The values entered in the single Q mode.*/ + protected double[] valuesQ; + + + /** + * Creates a new WQInputPanel instance. + */ + public WQInputPanel() { + } + + + /** + * This method calls createWidget and puts a 'next' button to the bottom. + * + * @param data The data that is displayed. + * + * @return the widget. + */ + public Canvas create(DataList data) { + initDefaults(data); + + Canvas widget = createWidget(data); + Canvas submit = getNextButton(); + Label label = new Label(MSG.wqTitle()); + + label.setHeight(25); + widget.setHeight(65); + + VLayout layout = new VLayout(); + layout.setMembersMargin(10); + + layout.addMember(label); + layout.addMember(widget); + layout.addMember(submit); + + return layout; + } + + + public Canvas createOld(DataList dataList) { + List items = dataList.getAll(); + + Data dMode = getData(items, "wq_mode"); + Data dFrom = getData(items, "wq_from"); + Data dTo = getData(items, "wq_to"); + Data dStep = getData(items, "wq_step"); + + DataItem[] mode = dMode.getItems(); + DataItem[] from = dFrom.getItems(); + DataItem[] to = dTo.getItems(); + DataItem[] step = dStep.getItems(); + + HLayout layout = new HLayout(); + layout.setWidth("400px"); + + Label label = new Label(dataList.getLabel()); + label.setWidth("200px"); + + String text = mode[0].getStringValue().equals(FIELD_WQ_W) + ? createWString(from[0], to[0], step[0]) + : createQString(from[0], to[0], step[0]); + + Label selected = new Label(text); + selected.setWidth("130px"); + + Canvas back = getBackButton(dataList.getState()); + + layout.addMember(label); + layout.addMember(selected); + layout.addMember(back); + + return layout; + } + + + /** + * This method reads the default values defined in the DataItems of the Data + * objects in list. + * + * @param list The DataList container that stores the Data objects. + */ + protected void initDefaults(DataList list) { + Data f = getData(list.getAll(), "wq_from"); + Data t = getData(list.getAll(), "wq_to"); + Data s = getData(list.getAll(), "wq_step"); + + DataItem fQItem = getDataItem(f.getItems(), "minQ"); + DataItem fWItem = getDataItem(f.getItems(), "minW"); + DataItem tQItem = getDataItem(t.getItems(), "maxQ"); + DataItem tWItem = getDataItem(t.getItems(), "maxW"); + DataItem sQItem = getDataItem(s.getItems(), "stepQ"); + DataItem sWItem = getDataItem(s.getItems(), "stepW"); + + minW = Double.valueOf(fWItem.getStringValue()); + maxW = Double.valueOf(tWItem.getStringValue()); + stepW = Double.valueOf(sWItem.getStringValue()); + + minQ = Double.valueOf(fQItem.getStringValue()); + maxQ = Double.valueOf(tQItem.getStringValue()); + stepQ = Double.valueOf(sQItem.getStringValue()); + + this.fromW = minW; + this.toW = maxW; + this.stepW = stepW; + + this.fromQ = minQ; + this.toQ = maxQ; + this.stepQ = stepQ; + } + + + protected String createWString(DataItem from, DataItem to, DataItem step) { + StringBuilder sb = new StringBuilder(); + sb.append(from.getLabel()); + sb.append(" " + MSG.unitWFrom() + " "); + sb.append(to.getLabel()); + sb.append(" " + MSG.unitWTo() + " "); + sb.append(step.getLabel()); + sb.append(" " + MSG.unitWStep()); + + return sb.toString(); + } + + + protected String createQString(DataItem from, DataItem to, DataItem step) { + StringBuilder sb = new StringBuilder(); + sb.append(from.getLabel()); + sb.append(" " + MSG.unitQFrom() + " "); + sb.append(to.getLabel()); + sb.append(" " + MSG.unitQTo() + " "); + sb.append(step.getLabel()); + sb.append(" " + MSG.unitQStep()); + + return sb.toString(); + } + + + /** + * This method greps the Data with name name from the list and + * returns it. + * + * @param items A list of Data. + * @param name The name of the Data that we are searching for. + * + * @return the Data with the name name. + */ + protected Data getData(List data, String name) { + for (Data d: data) { + if (name.equals(d.getLabel())) { + return d; + } + } + + return null; + } + + /** + * This method greps the DataItem with name name from the list and + * returns it. + * + * @param items A list of DataItems. + * @param name The name of the DataItem that we are searching for. + * + * @return the DataItem with the name name. + */ + protected DataItem getDataItem(DataItem[] items, String name) { + for (DataItem item: items) { + if (name.equals(item.getLabel())) { + return item; + } + } + + return null; + } + + + /** + * This method creates the whole widget. There is a panel on the left, that + * allows the user to enter values manually by keyboard. On the right, there + * is a table that allows the user to enter values by mouse click. + * + * @param data The data that is displayed in the table on the right. + * + * @return the widget. + */ + protected Canvas createWidget(DataList data) { + VLayout layout = new VLayout(); + container = new VLayout(); + Canvas modeForm = createModePanel(); + + // the initial panel is the Single-W panel. + double[] values = getSingleW(); + container.addMember(new DoubleArrayPanel( + MSG.unitWSingle(), values, this)); + + layout.addMember(modeForm); + layout.addMember(container); + + // TODO add a table on the right to select Q values + + return layout; + } + + + /** + * This method creates the mode panel. It contains two radio button panels + * that allows the user to switch the input mode between w/q and + * single/range input. + * + * @return a panel. + */ + protected Canvas createModePanel() { + RadioGroupItem wq = new RadioGroupItem(FIELD_WQ); + wq.setShowTitle(false); + wq.setVertical(false); + wq.setWidth(WIDTH_LEFT); + + RadioGroupItem mode = new RadioGroupItem(FIELD_MODE); + mode.setShowTitle(false); + mode.setVertical(false); + mode.setWidth(WIDTH_LEFT); + + LinkedHashMap wqValues = new LinkedHashMap(); + wqValues.put(FIELD_WQ_W, MSG.wqW()); + wqValues.put(FIELD_WQ_Q, MSG.wqQ()); + + LinkedHashMap modeValues = new LinkedHashMap(); + modeValues.put(FIELD_MODE_SINGLE, MSG.wqSingle()); + modeValues.put(FIELD_MODE_RANGE, MSG.wqRange()); + + wq.setValueMap(wqValues); + mode.setValueMap(modeValues); + + wq.addChangeHandler(this); + mode.addChangeHandler(this); + + modes = new DynamicForm(); + modes.setFields(wq, mode); + modes.setWidth(WIDTH_LEFT); + modes.setNumCols(1); + + LinkedHashMap initial = new LinkedHashMap(); + initial.put(FIELD_WQ, FIELD_WQ_W); + initial.put(FIELD_MODE, FIELD_MODE_SINGLE); + modes.setValues(initial); + + return modes; + } + + + /** + * This method returns the selected data. + * + * @return the selected/inserted data. + */ + public Data[] getData() { + // XXX If we have entered a value and click right afterwards on the + // 'next' button, the BlurEvent is not fired, and the values are not + // saved. So, we gonna save those values explicitly. + if (!isRangeMode()) { + Canvas member = container.getMember(0); + if (member instanceof DoubleArrayPanel) { + DoubleArrayPanel form = (DoubleArrayPanel) member; + if (isWMode()) { + saveSingleWValues(form); + } + else { + saveSingleQValues(form); + } + } + } + else { + Canvas member = container.getMember(0); + if (member instanceof DoubleRangePanel) { + DoubleRangePanel form = (DoubleRangePanel) member; + + if (isWMode()) { + saveRangeWValues(form); + } + else { + saveRangeQValues(form); + } + } + } + + return new Data[] { + getDataMode(), + getDataFrom(), + getDataTo(), + getDataStep() }; + } + + + /** + * Returns the Data object for the 'mode' attribute. + * + * @return the Data object for the 'mode' attribute. + */ + protected Data getDataMode() { + String wqMode = modes.getValueAsString(FIELD_WQ); + DataItem item = new DefaultDataItem("wq_mode", "wq_mode", wqMode); + return new DefaultData( + "wq_mode", null, null, new DataItem[] { item }); + } + + + /** + * Returns the Data object for the 'from' attribute. + * + * @return the Data object for the 'from' attribute. + */ + protected Data getDataFrom() { + String value = Double.valueOf(getFinalFrom()).toString(); + DataItem item = new DefaultDataItem("wq_from", "wq_from", value); + return new DefaultData( + "wq_from", null, null, new DataItem[] { item }); + } + + + /** + * Returns the Data object for the 'to' attribute. + * + * @return the Data object for the 'to' attribute. + */ + protected Data getDataTo() { + String value = Double.valueOf(getFinalTo()).toString(); + DataItem item = new DefaultDataItem("wq_to", "wq_to", value); + return new DefaultData( + "wq_to", null, null, new DataItem[] { item }); + } + + + /** + * Returns the Data object for the 'step' attribute. + * + * @return the Data object for the 'step' attribute. + */ + protected Data getDataStep() { + String value = Double.valueOf(getFinalStep()).toString(); + DataItem item = new DefaultDataItem("wq_step","wq_step", value); + return new DefaultData( + "wq_step", null, null, new DataItem[] { item }); + } + + + /** + * Returns the value of 'from' depending on the selected input mode. + * + * @return the value of 'from' depending on the selected input mode. + */ + protected double getFinalFrom() { + boolean wMode = isWMode(); + boolean rangeMode = isRangeMode(); + + if (rangeMode) { + return wMode ? getFromW() : getFromQ(); + + } + else { + double[] values = wMode ? getSingleW() : getSingleQ(); + double value = Double.MAX_VALUE; + + for (double v: values) { + value = value < v ? value : v; + } + + return value; + } + } + + + /** + * Returns the value of 'to' depending on the selected input mode. + * + * @return the value of 'to' depending on the selected input mode. + */ + protected double getFinalTo() { + boolean wMode = isWMode(); + boolean rangeMode = isRangeMode(); + + if (rangeMode) { + return wMode ? getToW() : getToQ(); + + } + else { + double[] values = wMode ? getSingleW() : getSingleQ(); + double value = Double.MIN_VALUE; + + for (double v: values) { + value = value > v ? value : v; + } + + return value; + } + } + + + /** + * Returns the value of 'step' depending on the selected input mode. + * + * @return the value of 'step' depending on the selected input mode. + */ + protected double getFinalStep() { + boolean wMode = isWMode(); + boolean rangeMode = isRangeMode(); + + if (rangeMode) { + // we have no field to enter the 'step' attribute in the + // range mode + return 0.0; + } + else { + if (wMode) { + return getStepW(); + } + else { + // we have no field to enter the 'step' attribute in the + // range mode + return getStepQ(); + } + } + } + + + /** + * Determines the range/single mode. + * + * @return true if the range mode is activated. + */ + public boolean isRangeMode() { + String rMode = modes.getValueAsString(FIELD_MODE); + + return rMode.equals(FIELD_MODE_RANGE) ? true : false; + } + + + /** + * Determines the w/q mode. + * + * @return true, if the W mode is activated. + */ + public boolean isWMode() { + String wq = modes.getValueAsString(FIELD_WQ); + + return wq.equals(FIELD_WQ_W) ? true : false; + } + + + /** + * This method changes the lower panel with the input fields depending on + * the combination of the two radio button panels. + * + * @param event The ChangeEvent. + */ + public void onChange(ChangeEvent event) { + DynamicForm form = event.getForm(); + FormItem item = event.getItem(); + + String wqMode = null; + String inputMode = null; + + if (item.getFieldName().equals(FIELD_MODE)) { + wqMode = form.getValueAsString(FIELD_WQ); + inputMode = (String) event.getValue(); + } + else { + wqMode = (String) event.getValue(); + inputMode = form.getValueAsString(FIELD_MODE); + } + + container.removeMembers(container.getMembers()); + + Canvas newPanel = null; + + if (wqMode.equals(FIELD_WQ_W)) { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + // Single W mode + double[] values = getSingleW(); + + newPanel = new DoubleArrayPanel( + MSG.unitWSingle(), values, this); + } + else { + // Range W mode + double from = getFromW(); + double to = getToW(); + double step = getStepW(); + + newPanel = new DoubleRangePanel( + MSG.unitWFrom(), MSG.unitWTo(), MSG.unitWStep(), + from, to, step, + 250, + this); + } + } + else { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + // Single Q mode + double[] values = getSingleQ(); + + newPanel = new DoubleArrayPanel( + MSG.unitQSingle(), values, this); + } + else { + // Range Q mode + double from = getFromQ(); + double to = getToQ(); + double step = getStepQ(); + + newPanel = new DoubleRangePanel( + MSG.unitQFrom(), MSG.unitQTo(), MSG.unitQStep(), + from, to, step, + 250, + this); + } + } + + container.addMember(newPanel); + } + + + /** + * This method is called if the value of one of the input fields might have + * changed. The entered values are validated and stored. + * + * @param event The BlurEvent. + */ + public void onBlur(BlurEvent event) { + DynamicForm form = event.getForm(); + FormItem item = event.getItem(); + + String wqMode = (String) modes.getValue(FIELD_WQ); + String inputMode = (String) modes.getValue(FIELD_MODE); + + if (wqMode.equals(FIELD_WQ_W)) { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + DoubleArrayPanel p = (DoubleArrayPanel) form; + saveSingleWValue(p, item); + } + else { + DoubleRangePanel p = (DoubleRangePanel) form; + saveRangeWValue(p, item); + } + } + else { + if (inputMode.equals(FIELD_MODE_SINGLE)) { + DoubleArrayPanel p = (DoubleArrayPanel) form; + saveSingleQValue(p, item); + } + else { + DoubleRangePanel p = (DoubleRangePanel) form; + saveRangeQValue(p, item); + } + } + } + + + protected void saveSingleWValues(DoubleArrayPanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) { + saveSingleWValue(p, item); + } + } + } + + + protected void saveSingleQValues(DoubleArrayPanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) { + saveSingleQValue(p, item); + } + } + } + + + protected void saveSingleWValue(DoubleArrayPanel p, FormItem item) { + if (p.validateForm(item)) { + setSingleW(p.getInputValues(item)); + } + } + + + protected void saveSingleQValue(DoubleArrayPanel p, FormItem item) { + if (p.validateForm(item)) { + setSingleQ(p.getInputValues(item)); + } + } + + + protected void saveRangeWValues(DoubleRangePanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + saveRangeWValue(p, item); + } + } + + + protected void saveRangeQValues(DoubleRangePanel p) { + FormItem[] formItems = p.getFields(); + + for (FormItem item: formItems) { + saveRangeQValue(p, item); + } + } + + + protected void saveRangeWValue(DoubleRangePanel p, FormItem item) { + if (p.validateForm(item)) { + setFromW(p.getFrom()); + setToW(p.getTo()); + setStepW(p.getStep()); + } + } + + + protected void saveRangeQValue(DoubleRangePanel p, FormItem item) { + if (p.validateForm(item)) { + setFromQ(p.getFrom()); + setToQ(p.getTo()); + setStepQ(p.getStep()); + } + } + + + protected double[] getSingleQ() { + return valuesQ; + } + + + protected void setSingleQ(double[] values) { + valuesQ = values; + } + + + protected double getFromQ() { + return fromQ; + } + + + protected void setFromQ(double fromQ) { + this.fromQ = fromQ; + } + + + protected double getToQ() { + return toQ; + } + + + protected void setToQ(double toQ) { + this.toQ = toQ; + } + + + protected double getStepQ() { + return stepQ; + } + + + protected void setStepQ(double stepQ) { + this.stepQ = stepQ; + } + + + protected double[] getSingleW() { + return valuesW; + } + + + protected void setSingleW(double[] values) { + valuesW = values; + } + + + protected double getFromW() { + return fromW; + } + + + protected void setFromW(double fromW) { + this.fromW = fromW; + } + + + protected double getToW() { + return toW; + } + + + protected void setToW(double toW) { + this.toW = toW; + } + + + protected double getStepW() { + return stepW; + } + + + protected void setStepW(double stepW) { + this.stepW = stepW; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import de.intevation.artifacts.common.utils.ClientProtocolUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.client.services.AddArtifactService; + + +/** + * @author Ingo Weinzierl + */ +public class AddArtifactServiceImpl +extends DescribeCollectionServiceImpl +implements AddArtifactService +{ + public Collection add(Collection collection, Artifact artifact, String url) { + System.out.println("AddArtifactServiceImpl.add"); + + Document add = ClientProtocolUtils.newAddArtifactDocument( + artifact.getUuid(), null); + + HttpClient client = new HttpClientImpl(url); + + try { + Document response = (Document) client.doCollectionAction( + add, collection.identifier(), new DocumentResponseHandler()); + + Collection c = parseCollection(response); + + if (c == null) { + throw new NullPointerException("No collection returned."); + } + + return c; + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,70 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.client.services.AdvanceService; + + +/** + * This interface provides artifact specific operation ADVANCE. + * + * @author Ingo Weinzierl + */ +public class AdvanceServiceImpl +extends RemoteServiceServlet +implements AdvanceService +{ + public static final String XPATH_RESULT = "/art:result/text()"; + + public static final String OPERATION_FAILURE = "FAILED"; + + + public Artifact advance(String serverUrl, Artifact artifact, String target){ + Document advance = ClientProtocolUtils.newAdvanceDocument( + artifact.getUuid(), + artifact.getHash(), + target); + + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document description = (Document) client.advance( + new de.intevation.artifacts.httpclient.objects.Artifact( + artifact.getUuid(), + artifact.getHash()), + advance, + new DocumentResponseHandler()); + + if (description == null) { + return null; + } + + String result = XMLUtils.xpathString( + description, + XPATH_RESULT, + ArtifactNamespaceContext.INSTANCE); + + if (result == null || !result.equals(OPERATION_FAILURE)) { + return (Artifact) new FLYSArtifactCreator().create(description); + } + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,359 @@ +package de.intevation.flys.client.server; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.flys.client.shared.model.ArtifactDescription; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.shared.model.DataList; +import de.intevation.flys.client.shared.model.DefaultArtifactDescription; +import de.intevation.flys.client.shared.model.DefaultData; +import de.intevation.flys.client.shared.model.DefaultDataItem; +import de.intevation.flys.client.shared.model.DefaultOutputMode; +import de.intevation.flys.client.shared.model.OutputMode; + + +/** + * This factory class helps creating an {@link ArtifactDescription} based on the + * DESCRIBE document of an artifact returned by the artifact server. Use the + * {@link createArtifactDescription(org.w3c.dom.Document)} method with the + * DESCRIBE document to create such an {@link ArtifactDescription}. + * + * @author Ingo Weinzierl + */ +public class ArtifactDescriptionFactory { + + public static final String XPATH_STATE_NAME = "@art:name"; + + public static final String XPATH_UIPROVIDER = "@art:uiprovider"; + + public static final String XPATH_REACHABLE_STATE = "art:state"; + + public static final String XPATH_STATIC_STATE_NODE = "art:state"; + + public static final String XPATH_STATIC_DATA_NODE = "art:data"; + + public static final String XPATH_STATIC_ITEM_NODE = "art:item"; + + /** + * This method creates the {@link ArtifactDescription} of the DESCRIBE + * document doc. + * + * @param doc A DESCRIBE document. + * + * @return the {@link ArtifactDescription}. + */ + public static ArtifactDescription createArtifactDescription(Document doc) { + System.out.println("ArtifactDescriptionFactory - create()"); + + Node currentState = ClientProtocolUtils.getCurrentState(doc); + Node staticNode = ClientProtocolUtils.getStaticUI(doc); + Node dynamicNode = ClientProtocolUtils.getDynamicUI(doc); + Node reachable = ClientProtocolUtils.getReachableStates(doc); + NodeList outputs = ClientProtocolUtils.getOutputModes(doc); + + String state = (String) XMLUtils.xpath( + currentState, + XPATH_STATE_NAME, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + System.out.println("Current state name: " + state); + + DataList currentData = extractCurrentData(dynamicNode, state); + DataList[] old = extractOldData(staticNode); + String[] states = extractReachableStates(reachable); + OutputMode[] outs = extractOutputModes(outputs); + + return new DefaultArtifactDescription( + old, + currentData, + state, + states, + outs); + } + + + /** + * This method extracts the data that the user is able to enter in the + * current state of the artifact. + * + * @param dynamicNode The dynamic node of the DESCRIBE document. + * @param state The name of the current state. + * + * @return A {@link Data} object that represents the data which might be + * entered by the user in the current state or null, if no data might be + * entered. + */ + protected static DataList extractCurrentData(Node dynamicNode, String state) { + System.out.println("ArtifactDescriptionFactory - extractCurrentData()"); + + NodeList data = ClientProtocolUtils.getSelectNode(dynamicNode); + String uiProvider = extractUIProvider(dynamicNode); + + if (data == null || data.getLength() == 0) { + return null; + } + + int dataNum = data.getLength(); + DataList list = new DataList(state, dataNum, uiProvider); + + for (int i = 0; i < dataNum; i++) { + Node d = data.item(i); + + NodeList choices = ClientProtocolUtils.getItemNodes(d); + String label = ClientProtocolUtils.getLabel(d); + String name = XMLUtils.xpathString( + d, "@art:name", ArtifactNamespaceContext.INSTANCE); + + DataItem[] dataItems = extractCurrentDataItems(choices); + + list.add(new DefaultData(name, label, null, dataItems)); + } + + return list; + } + + + /** + * This method extract the {@link DataItem}s of the DESCRIBE document. + * + * @param items The items in the DESCRIBE document. + * + * @return the {@link DataItem}s. + */ + protected static DataItem[] extractCurrentDataItems(NodeList items) { + System.out.println( + "ArtifactDescriptionFactory - extractCurrentDataItems()"); + + if (items == null || items.getLength() == 0) { + System.out.println("No data items found."); + return null; + } + + int count = items.getLength(); + + List dataItems = new ArrayList(count); + + for (int i = 0; i < count; i++) { + Node item = items.item(i); + String label = ClientProtocolUtils.getLabel(item); + String value = ClientProtocolUtils.getValue(item); + + dataItems.add(new DefaultDataItem(label, null, value)); + } + + return (DataItem[]) dataItems.toArray(new DataItem[count]); + } + + + /** + * This method extracts the data objects from the data node of the static ui + * part of the DESCRIBE document. + * + * @param staticNode The static ui node of the DESCRIBE. + * + * @return the DataList objects. + */ + protected static DataList[] extractOldData(Node staticNode) { + System.out.println("ArtifactDescriptionFactory - extractOldData()"); + + NodeList stateNodes = (NodeList) XMLUtils.xpath( + staticNode, + XPATH_STATIC_STATE_NODE, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (stateNodes == null || stateNodes.getLength() == 0) { + System.out.println("No old items found."); + return null; + } + + int count = stateNodes.getLength(); + DataList[] data = new DataList[count]; + + for (int i = 0; i < count; i++) { + Node tmp = stateNodes.item(i); + + String name = XMLUtils.xpathString( + tmp, "@art:name", ArtifactNamespaceContext.INSTANCE); + String uiprovider = XMLUtils.xpathString( + tmp, "@art:uiprovider", ArtifactNamespaceContext.INSTANCE); + String label = XMLUtils.xpathString( + tmp, "@art:label", ArtifactNamespaceContext.INSTANCE); + + NodeList dataNodes = (NodeList) XMLUtils.xpath( + tmp, + XPATH_STATIC_DATA_NODE, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (dataNodes == null || dataNodes.getLength() == 0) { + continue; + } + + int size = dataNodes.getLength(); + DataList list = new DataList(name, size, uiprovider, label); + + for (int j = 0; j < size; j++) { + Node dataNode = dataNodes.item(j); + + String dName = XMLUtils.xpathString( + dataNode, "@art:name", ArtifactNamespaceContext.INSTANCE); + String dType = XMLUtils.xpathString( + dataNode, "@art:type", ArtifactNamespaceContext.INSTANCE); + + DataItem[] items = extractOldDataItems(dataNode); + + list.add(new DefaultData(dName, dName, dType, items)); + + data[i] = list; + } + } + + return data; + } + + + /** + * This method extracts the data items from the data nodes that are placed + * in the static ui part of the DESCRIBE document. + * + * @param dataNode A data node that contains items. + * + * @return a list of DataItems. + */ + protected static DataItem[] extractOldDataItems(Node dataNode) { + NodeList itemList = (NodeList) XMLUtils.xpath( + dataNode, + XPATH_STATIC_ITEM_NODE, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (itemList == null || itemList.getLength() == 0) { + System.out.println("No old data items found."); + return null; + } + + int count = itemList.getLength(); + + DataItem[] items = new DataItem[count]; + + for (int i = 0; i < count; i++) { + Node tmp = itemList.item(i); + + String value = XMLUtils.xpathString( + tmp, "@art:value", ArtifactNamespaceContext.INSTANCE); + String label = XMLUtils.xpathString( + tmp, "@art:label", ArtifactNamespaceContext.INSTANCE); + + items[i] = new DefaultDataItem(label, label, value); + } + + return items; + } + + + /** + * This method extracts the UIProvider specified by the data node. + * + * @param data The data node. + * + * @return the UIProvider that is specified in the data node. + */ + protected static String extractUIProvider(Node ui) { + return (String) XMLUtils.xpath( + ui, + XPATH_UIPROVIDER, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method extracts the reachable states of the current artifact. + * + * @param reachable The reachable states node. + * + * @return an array with identifiers of reachable states. + */ + protected static String[] extractReachableStates(Node reachable) { + System.out.println("ArtifactDescriptionFactory - extractReachableStates()"); + + NodeList list = (NodeList) XMLUtils.xpath( + reachable, + XPATH_REACHABLE_STATE, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (list == null || list.getLength() == 0) { + return null; + } + + int count = list.getLength(); + + String[] states = new String[count]; + + for (int i = 0; i < count; i++) { + Node state = list.item(i); + + String name = XMLUtils.xpathString( + state, "@art:name", ArtifactNamespaceContext.INSTANCE); + + states[i] = name; + } + + return states; + } + + + /** + * This method extract available output modes of the the current artifact. + * + * @param outputs A list of nodes that contain information about output + * modes. + * + * @return an array of Output modes. + */ + protected static OutputMode[] extractOutputModes(NodeList outputs) { + System.out.println("ArtifactDescriptionFactory - extractOutputModes()"); + + if (outputs == null || outputs.getLength() == 0) { + return null; + } + + int size = outputs.getLength(); + + List outs = new ArrayList(size); + + for (int i = 0; i < size; i++) { + Node out = outputs.item(i); + + String name = XMLUtils.xpathString( + out, "@art:name", ArtifactNamespaceContext.INSTANCE); + String desc = XMLUtils.xpathString( + out, "@art:description", ArtifactNamespaceContext.INSTANCE); + String mimeType = XMLUtils.xpathString( + out, "@art:mime-type", ArtifactNamespaceContext.INSTANCE); + + if (name != null) { + outs.add(new DefaultOutputMode(name, desc, mimeType)); + } + else { + System.err.println("Found an invalid output mode."); + } + } + + return (OutputMode[]) outs.toArray(new OutputMode[size]); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,41 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.utils.ClientProtocolUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.client.services.ArtifactService; + + +/** + * This interface provides artifact specific services as CREATE, DESCRIBE, FEED, + * ADVANCE and OUT. + * + * @author Ingo Weinzierl + */ +public class ArtifactServiceImpl +extends RemoteServiceServlet +implements ArtifactService +{ + public Artifact create(String serverUrl, String factory) { + Document create = ClientProtocolUtils.newCreateDocument(factory); + HttpClient client = new HttpClientImpl(serverUrl); + + try { + return (Artifact) client.create(create, new FLYSArtifactCreator()); + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,63 @@ +package de.intevation.flys.client.server; + +import java.io.OutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.w3c.dom.Document; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.objects.Artifact; +import de.intevation.artifacts.httpclient.utils.ArtifactProtocolUtils; + + +/** + * This service is used to request a chart from the artifact server. The + * response is directed directly to the output stream, so the image that is + * retrieved is displayed in the UI afterwards. + * + * @author Ingo Weinzierl + */ +public class ChartOutputServiceImpl +extends HttpServlet +{ + public void doGet(HttpServletRequest req, HttpServletResponse resp) { + System.out.println("ChartOutputServiceImpl.doGet"); + + try { + OutputStream out = resp.getOutputStream(); + + String serverUrl = req.getParameter("server"); + String uuid = req.getParameter("uuid"); + String hash = req.getParameter("hash"); + String width = req.getParameter("width"); + String height = req.getParameter("height"); + String target = req.getParameter("target"); + String mimeType = "image/png"; + + Map opts = new HashMap(); + opts.put("width", width); + opts.put("height", height); + opts.put("mimeType", mimeType); + opts.put("points", "false"); + + Document chart = ArtifactProtocolUtils.createChartDocument( + new Artifact(hash, uuid), opts); + + HttpClient client = new HttpClientImpl(serverUrl); + client.out(new Artifact(uuid, hash), chart, target, out); + + out.close(); + out.flush(); + } + catch (IOException ioe) { + System.err.println(ioe.getMessage()); + } + } +} diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,59 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.DefaultCollection; +import de.intevation.flys.client.client.services.CreateCollectionService; + + +/** + * This interface provides the createCollection service to create new + * collections in the artifact server. + * + * @author Ingo Weinzierl + */ +public class CreateCollectionServiceImpl +extends RemoteServiceServlet +implements CreateCollectionService +{ + /** XPath to figure out the uuid of the created collection.*/ + public static final String XPATH_COLLECTION_UUID = + "/art:result/art:artifact-collection/@art:uuid"; + + + public Collection create(String serverUrl, String ownerId) { + System.out.println("Start creating a new collection."); + + Document create = + ClientProtocolUtils.newCreateCollectionDocument(null); + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document doc = (Document) client.createCollection( + create, ownerId, new DocumentResponseHandler()); + + String uuid = XMLUtils.xpathString( + doc, XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE); + + return new DefaultCollection(uuid); + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,223 @@ +package de.intevation.flys.client.server; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.CollectionItem; +import de.intevation.flys.client.shared.model.DefaultCollection; +import de.intevation.flys.client.shared.model.DefaultCollectionItem; +import de.intevation.flys.client.shared.model.DefaultOutputMode; +import de.intevation.flys.client.shared.model.OutputMode; +import de.intevation.flys.client.client.services.DescribeCollectionService; + + +/** + * This service implements a method that queries the DESCRIBE document of a + * specific collection and returns a Collection object with the information of + * the document. + * + * @author Ingo Weinzierl + */ +public class DescribeCollectionServiceImpl +extends RemoteServiceServlet +implements DescribeCollectionService +{ + public Collection describe(String uuid, String serverUrl) { + System.out.println("DescribeCollectionServiceImpl.describe"); + + Document describe = ClientProtocolUtils.newDescribeCollectionDocument( + uuid); + + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document response = (Document) client.doCollectionAction( + describe, uuid, new DocumentResponseHandler()); + + Collection c = parseCollection(response); + + if (c == null) { + throw new NullPointerException("No collection returned."); + } + + return c; + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } + + + /** + * This method takes the DESCRIBE document of the Collections describe() + * operation and extracts the information about the collection itself and + * the collection items. + * + * @param description The DESCRIBE document of the Collections describe() + * operation. + * + * @return a Collection with CollectionItems. + */ + protected Collection parseCollection(Document description) { + System.out.println("AddArtifactServiceImpl.parseCollection"); + + if (description == null) { + System.err.println("The DESCRIBE of the Collection is null!"); + return null; + } + + String uuid = XMLUtils.xpathString( + description, + "art:artifact-collection/@art:uuid", + ArtifactNamespaceContext.INSTANCE); + + if (uuid == null || uuid.equals("")) { + System.err.println("Found an invalid Collection!"); + return null; + } + + Collection c = new DefaultCollection(uuid); + + NodeList items = (NodeList) XMLUtils.xpath( + description, + "art:artifact-collection/art:artifacts/art:artifact", + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (items == null || items.getLength() == 0) { + System.out.println("No collection item found for this collection."); + + return c; + } + + int size = items.getLength(); + + for (int i = 0; i < size; i++) { + CollectionItem item = parseCollectionItem(items.item(i)); + + if (item != null) { + c.addItem(item); + } + } + + System.out.println( + "Found " + c.getItemLength() + " collection items " + + "for the Collection '" + c.identifier() + "'."); + + return c; + } + + + /** + * This method extracts the CollectionItem from node with its output + * modes. The output modes are parsed using the parseOutputModes() method. + * + * @param node A node that contains information about a CollectionItem. + * + * @return a CollectionItem. + */ + protected CollectionItem parseCollectionItem(Node node) { + System.out.println("AddArtifactServiceImpl.parseCollectionItem"); + + if (node == null) { + System.err.println("The node for parsing CollectionItem is null!"); + return null; + } + + String uuid = XMLUtils.xpathString( + node, "@art:uuid", ArtifactNamespaceContext.INSTANCE); + + String hash = XMLUtils.xpathString( + node, "@art:hash", ArtifactNamespaceContext.INSTANCE); + + if (uuid == null || uuid.equals("")) { + System.err.println("Found an invalid CollectionItem!"); + } + + Node outputmodes = (Node) XMLUtils.xpath( + node, + "art:outputmodes", + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + + List modes = parseOutputModes(outputmodes); + + return new DefaultCollectionItem(uuid, hash, modes); + } + + + /** + * This method extracts the OutputModes available for a specific + * CollectionItem and returns them as list. + * + * @param node The root node of the outputmodes list. + * + * @return a list of OutputModes. + */ + protected List parseOutputModes(Node node) { + System.out.println("AddArtifactServiceImpl.parseOutputModes"); + + if (node == null) { + System.err.println("The node for parsing OutputModes is null!"); + return null; + } + + NodeList list = (NodeList) XMLUtils.xpath( + node, + "art:output", + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (list == null || list.getLength() == 0) { + System.err.println("No outputmode nodes found!"); + return null; + } + + int size = list.getLength(); + + List modes = new ArrayList(size); + + for (int i = 0; i < size; i++) { + Node tmp = list.item(i); + String name = XMLUtils.xpathString( + tmp, "@art:name", ArtifactNamespaceContext.INSTANCE); + String desc = XMLUtils.xpathString( + tmp, "@art:description", ArtifactNamespaceContext.INSTANCE); + String mime = XMLUtils.xpathString( + tmp, "@art:mime-type", ArtifactNamespaceContext.INSTANCE); + + if (name == null || name.equals("")) { + System.err.println("Found an invalid output mode."); + + continue; + } + + // TODO Parse Facets + + modes.add(new DefaultOutputMode(name, desc, mime)); + } + + return modes; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,78 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import de.intevation.artifacts.common.utils.XMLUtils; +import de.intevation.artifacts.common.ArtifactNamespaceContext; + +import de.intevation.artifacts.httpclient.utils.ArtifactCreator; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.DefaultArtifact; + + +/** + * An implementation of an {@link ArtifactCreator}. This class uses the document + * that is returned by the artifact server to parse important information (like + * uuid, hash) and returns a new {@link Artifact} instance. + * + * @author Ingo Weinzierl + */ +public class FLYSArtifactCreator implements ArtifactCreator { + + /** The XPath to the artifact's uuid.*/ + public static final String XPATH_UUID = "/art:result/art:uuid/@art:value"; + + /** The XPath to the artifact's hash value.*/ + public static final String XPATH_HASH = "/art:result/art:hash/@art:value"; + + + /** + * Creates a new instance of an {@link ArtifactCreator}. + */ + public FLYSArtifactCreator() { + } + + + /** + * This concreate implementation returns an instance of {@link Artifact} + * that is used in the FLYS GWT Client code. + * + * @param doc A document that describes the artifact that has been created + * in the artifact server. + * + * @return an instance if {@link Artifact}. + */ + public Object create(Document doc) { + Artifact artifact = extractArtifact(doc); + artifact.setArtifactDescription( + ArtifactDescriptionFactory.createArtifactDescription(doc)); + + return artifact; + } + + + /** + * This method extracts the UUID und HASH information of the returned + * artifact document. + * + * @param doc The result of the CREATE operation. + * + * @return an instance of an {@link Artifact}. + */ + protected Artifact extractArtifact(Document doc) { + System.out.println("FLYSArtifactCreator - extractArtifact()"); + + String uuid = XMLUtils.xpathString( + doc, XPATH_UUID, ArtifactNamespaceContext.INSTANCE); + + String hash = XMLUtils.xpathString( + doc, XPATH_HASH, ArtifactNamespaceContext.INSTANCE); + + System.out.println("NEW Artifact UUID: " + uuid); + System.out.println("NEW Artifact HASH: " + hash); + + return new DefaultArtifact(uuid, hash); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,83 @@ +package de.intevation.flys.client.server; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; + +import de.intevation.flys.client.shared.model.DefaultRiver; +import de.intevation.flys.client.shared.model.River; +import de.intevation.flys.client.client.services.RiverService; + + +/** + * This interface provides a method to list the supported rivers of the artifact + * server. + * + * @author Ingo Weinzierl + */ +public class RiverServiceImpl +extends RemoteServiceServlet +implements RiverService +{ + /** The XPath string that points to the rivers in the resulting document.*/ + public static final String XPATH_RIVERS = "/art:rivers/art:river"; + + + public River[] list(String serverUrl) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + doc.appendChild(ec.create("action")); + + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document res = client.callService(serverUrl, "rivers", doc); + + NodeList rivers = (NodeList) XMLUtils.xpath( + res, + XPATH_RIVERS, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int count = rivers.getLength(); + + List theRivers = new ArrayList(count); + + for (int i = 0; i < count; i++) { + Node tmp = rivers.item(i); + + String name = XMLUtils.xpathString( + tmp, "@art:name", ArtifactNamespaceContext.INSTANCE); + + theRivers.add(new DefaultRiver(name)); + } + + return (River[]) theRivers.toArray(new River[count]); + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,146 @@ +package de.intevation.flys.client.server; + +import org.w3c.dom.Document; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.ClientProtocolUtils; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; +import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; + +import de.intevation.flys.client.shared.model.Artifact; +import de.intevation.flys.client.shared.model.ArtifactDescription; +import de.intevation.flys.client.shared.model.Data; +import de.intevation.flys.client.shared.model.DataItem; +import de.intevation.flys.client.client.services.StepForwardService; + + +/** + * This interface provides a method that bundles the artifact specific + * operations FEED and ADVANCE. + * + * @author Ingo Weinzierl + */ +public class StepForwardServiceImpl +extends AdvanceServiceImpl +implements StepForwardService +{ + /** XPath that points to the result text of a feed or advance operation.*/ + public static final String XPATH_RESULT = "/art:result/text()"; + + /** A constant that marks errors.*/ + public static final String OPERATION_FAILURE = "FAILED"; + + + /** + * This method wraps the artifact operations FEED and ADVANCE. FEED is + * always triggerd, ADVANCE only, if there is at least one reachable state. + * + * @param serverUrl The url of the artifact server. + * @param artifact The artifact that needs to be fed. + * @param data An array of Data objects that contain the information that + * + * @return the modified artifact. + */ + public Artifact go(String serverUrl, Artifact artifact, Data[] data) { + Artifact afterFeed = feed(serverUrl, artifact, data); + + if (afterFeed == null) { + System.err.println("StepForwardService.feed() - FAILED"); + // XXX Better handling here! + return null; + } + + ArtifactDescription desc = afterFeed.getArtifactDescription(); + String[] reachable = desc.getReachableStates(); + + if (reachable == null || reachable.length == 0) { + System.out.println("Did not find any reachable state."); + return afterFeed; + } + + // We use the first reachable state as default target, maybe we need to + // change this later. + return advance(serverUrl, afterFeed, reachable[0]); + } + + + /** + * This method triggers the FEED operation. + * + * @param serverUrl The url of the artifact server. + * @param artifact The artifact that needs to be fed. + * @param data An array of Data objects that contain the information that + * are used for the FEED operation. + * + * @return a new artifact parsed from the description of FEED. + */ + protected Artifact feed(String serverUrl, Artifact artifact, Data[] data) { + Document feed = ClientProtocolUtils.newFeedDocument( + artifact.getUuid(), + artifact.getHash(), + createKVP(data)); + + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document description = (Document) client.feed( + new de.intevation.artifacts.httpclient.objects.Artifact( + artifact.getUuid(), + artifact.getHash()), + feed, + new DocumentResponseHandler()); + + if (description == null) { + System.err.println("StepForwardService.feed() - FAILED"); + return artifact; + } + + String result = XMLUtils.xpathString( + description, + XPATH_RESULT, + ArtifactNamespaceContext.INSTANCE); + + if (result == null || !result.equals(OPERATION_FAILURE)) { + System.out.println("StepForwardService.feed() - SUCCESS"); + return (Artifact) new FLYSArtifactCreator().create(description); + } + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + System.err.println("StepForwardService.feed() - FAILED"); + + return artifact; + } + + + /** + * This method creates an array of key/value pairs from an array of Data + * objects. The string array is used as parameter for the feed() operation. + * + * @param data The data that should be transformed into the string array. + * + * @return a string array that contains key/value pairs. + */ + protected String[][] createKVP(Data[] data) { + String[][] kvp = new String[data.length][]; + + int i = 0; + + for (Data d: data) { + DataItem[] items = d.getItems(); + String key = d.getLabel(); + String value = items[0].getStringValue(); + + kvp[i++] = new String[] { key, value }; + } + + return kvp; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,109 @@ +package de.intevation.flys.client.server; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; + +import de.intevation.flys.client.shared.model.Collection; +import de.intevation.flys.client.shared.model.DefaultCollection; +import de.intevation.flys.client.client.services.UserCollectionsService; + + +/** + * This service returns a list of collections owned by a specified user. + * NOTE: The Collections returned by this service provide no information + * about the CollectionItems or OutputModes of the Collection. You need to fetch + * these information explicitly using another service. + * + * @author Ingo Weinzierl + */ +public class UserCollectionsServiceImpl +extends RemoteServiceServlet +implements UserCollectionsService +{ + public Collection[] getUserCollections(String serverUrl, String userid) { + System.out.println("UserCollectionsServiceImpl.getUserCollections"); + + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document result = client.listUserCollections(userid); + + NodeList list = (NodeList) XMLUtils.xpath( + result, + "/art:artifact-collections/art:artifact-collection", + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (list == null || list.getLength() == 0) { + System.out.println("No collection found for user: " + userid); + return null; + } + + int num = list.getLength(); + + List all = new ArrayList(num); + + for (int i = 0; i < num; i++) { + Collection c = createCollection(list.item(i)); + + if (c != null) { + all.add(c); + } + } + + System.out.println("User has " + all.size() + " collections."); + + return (Collection[]) all.toArray(new Collection[all.size()]); + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + System.err.println("No user collections found."); + return null; + } + + + /** + * Extracts a SimpleCollection from node. + * + * @param node Contains information about a collection. + * + * @return a list of Simplecollections. + */ + protected Collection createCollection(Node node) { + String creationStr = XMLUtils.xpathString( + node, "@art:creation", ArtifactNamespaceContext.INSTANCE); + + String name = XMLUtils.xpathString( + node, "@art:name", ArtifactNamespaceContext.INSTANCE); + + String uuid = XMLUtils.xpathString( + node, "@art:uuid", ArtifactNamespaceContext.INSTANCE); + + if (uuid != null) { + long time = Long.parseLong(creationStr); + return new DefaultCollection(uuid, name, new Date(time)); + } + + System.err.println("Found an invalid Collection."); + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/server/UserServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserServiceImpl.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,63 @@ +package de.intevation.flys.client.server; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import de.intevation.artifacts.httpclient.exceptions.ConnectionException; +import de.intevation.artifacts.httpclient.http.HttpClient; +import de.intevation.artifacts.httpclient.http.HttpClientImpl; + +import de.intevation.flys.client.client.services.UserService; +import de.intevation.flys.client.shared.model.DefaultUser; +import de.intevation.flys.client.shared.model.User; + + +/** + * @author Ingo Weinzierl + */ +public class UserServiceImpl +extends RemoteServiceServlet +implements UserService +{ + public User getCurrentUser(String serverUrl) { + HttpClient client = new HttpClientImpl(serverUrl); + + try { + Document users = (Document) client.listUsers(); + + String XPATH_USERS = "/art:users/art:user"; + + NodeList theUsers = (NodeList) XMLUtils.xpath( + users, + XPATH_USERS, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + if (theUsers != null && theUsers.getLength() > 0) { + Node user = theUsers.item(0); + + String uuid = XMLUtils.xpathString( + user, "@art:uuid", ArtifactNamespaceContext.INSTANCE); + String name = XMLUtils.xpathString( + user, "@art:name", ArtifactNamespaceContext.INSTANCE); + + return new DefaultUser(uuid, name); + } + } + catch (ConnectionException ce) { + System.err.println(ce.getLocalizedMessage()); + } + + System.err.println("No users existing in the server."); + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/FieldVerifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/FieldVerifier.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,42 @@ +package de.intevation.flys.client.shared; + +/** + *

+ * FieldVerifier validates that the name the user enters is valid. + *

+ *

+ * This class is in the shared package because we use it in both + * the client code and on the server. On the client, we verify that the name is + * valid before sending an RPC request so the user doesn't have to wait for a + * network round trip to get feedback. On the server, we verify that the name is + * correct to ensure that the input is correct regardless of where the RPC + * originates. + *

+ *

+ * When creating a class that is used on both the client and the server, be sure + * that all code is translatable and does not use native JavaScript. Code that + * is note translatable (such as code that interacts with a database or the file + * system) cannot be compiled into client side JavaScript. Code that uses native + * JavaScript (such as Widgets) cannot be run on the server. + *

+ */ +public class FieldVerifier { + + /** + * Verifies that the specified name is valid for our service. + * + * In this example, we only require that the name is at least four + * characters. In your application, you can use more complex checks to ensure + * that usernames, passwords, email addresses, URLs, and other fields have the + * proper syntax. + * + * @param name the name to validate + * @return true if valid, false if invalid + */ + public static boolean isValidName(String name) { + if (name == null) { + return false; + } + return name.length() > 3; + } +} diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/Artifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Artifact.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * This class represents an artifact for the client. It contains the necessary + * information for the client and the communication with the artifact server. + * + * @author Ingo Weinzierl + */ +public interface Artifact extends Serializable { + + /** + * Returns the UUID of the artifact. + * + * @return the UUID. + */ + public String getUuid(); + + + /** + * Returns the hash of the artifact. + * + * @return the hash. + */ + public String getHash(); + + + /** + * Returns the ArtifactDescription. + * + * @return the artifact description. + */ + public ArtifactDescription getArtifactDescription(); + + + /** + * Sets a new ArtifactDescription. + * + * @param artifactDescription The new artifact description. + */ + public void setArtifactDescription(ArtifactDescription artifactDescription); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,56 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * The artifact description describes a state of an artifact. There are + * operations defined that return former inserted data, possible input values + * and output targets that are available in the current state of the artifact. + * + * @author Ingo Weinzierl + */ +public interface ArtifactDescription extends Serializable { + + /** + * Returns the data that have been inserted in former states of the + * artifact. + * + * @return the old data of former states. + */ + public DataList[] getOldData(); + + + /** + * Returns the data with all its options that might be inserted in the + * current state of the artifact. + * + * @return the current data. + */ + public DataList getCurrentData(); + + + /** + * Returns the current state as string. + * + * @return the current state. + */ + public String getCurrentState(); + + + /** + * Returns the reachable states as string. + * + * @return the reachable states. + */ + public String[] getReachableStates(); + + + /** + * Returns the available output modes. + * + * @return the available output modes. + */ + public OutputMode[] getOutputModes(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,31 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; +import java.util.Date; +import java.util.Map; + + +/** + * The artifact collection. + * + * @author Ingo Weinzierl + */ +public interface Collection extends Serializable { + + public String identifier(); + + public String getName(); + + public Date getCreationTime(); + + public Date getLastAccess(); + + public void addItem(CollectionItem item); + + public int getItemLength(); + + public CollectionItem getItem(int idx); + + public Map getOutputModes(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; +import java.util.List; + + +/** + * The CollectionItem interface that provides methods to get information about + * artifacts and its output modes. + * + * @author Ingo Weinzierl + */ +public interface CollectionItem extends Serializable { + + /** + * Returns the identifier of the wrapped artifact. + * + * @return the identifier of the wrapped artifact. + */ + String identifier(); + + + /** + * Returns the hash of the wrapped artifact. + * + * @return the hash of the wrapped artifact. + */ + String hash(); + + + /** + * Returns the output modes of the wrapped artifact. + * + * @return the output modes of the wrapped artifact. + */ + List getOutputModes(); + + + /** + * Returns the facets of the wrapped artifact for a specific output mode. + * + * @param outputmode The name of an output mode that is supported by this + * item. + * + * @return the facets of the wrapped artifact for a specific output mode. + */ + List getFacets(String outputmode); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.flys.client.shared.model; + +import java.util.Date; + +import com.smartgwt.client.widgets.grid.ListGridRecord; + + +/** + * The CollectionRecord is a wrapper to put Collection objects into a ListGrid. + * + * @author Ingo Weinzierl + */ +public class CollectionRecord extends ListGridRecord { + + /** The artifact collection. */ + protected Collection collection; + + + /** + * The default constructor. + * + * @param collection The artifact collection. + */ + public CollectionRecord(Collection collection) { + this.collection = collection; + } + + + /** + * Returns the date of the creation. + * + * @return the creation time. + */ + public Date getCreationTime() { + return collection.getCreationTime(); + } + + + /** + * Returns the name of the collection. + * + * @return the name of the collection. + */ + public String getName() { + String name = collection.getName(); + return name != null && name.length() > 0 + ? name + : collection.identifier(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/Data.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Data.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,46 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * A Data object represents the necessary data of a single state of the + * artifact. It might provide several DataItems or just a single DataItem. The + * type makes it possible to validate the input in the client. + * + * @author Ingo Weinzierl + */ +public interface Data extends Serializable { + + /** + * Returns the label of the item. + * + * @return the label. + */ + public String getLabel(); + + + /** + * Returns the description of the item. + * + * @return the description. + */ + public String getDescription(); + + + /** + * Returns the type of the item. + * + * @return the type. + */ + public String getType(); + + + /** + * Returns the DataItems provided by this Data object. + * + * @return the DataItems. + */ + public DataItem[] getItems(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DataItem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataItem.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,37 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * A DataItem represents a concrete item that might be selected, chosen or + * inserted by the user. + * + * @author Ingo Weinzierl + */ +public interface DataItem extends Serializable { + + /** + * Returns the label of the item. + * + * @return the label. + */ + public String getLabel(); + + + /** + * Returns the description of the item. + * + * @return the description; + */ + public String getDescription(); + + + /** + * Returns the value of the item. + * + * @return the value. + */ + public String getStringValue(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DataList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataList.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,165 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Ingo Weinzierl + */ +public class DataList implements Serializable { + + /** The list of Data objects managed by this list.*/ + protected List data; + + /** The name of the state that this list belongs to.*/ + protected String state; + + /** The name of a UIProvider that is recommended to render this DataList.*/ + protected String uiprovider; + + /** The label that should be used to label data objects.*/ + protected String label; + + + /** + * The default constructor that creates a new DataList without Data objects + * and no UIProvider. + */ + public DataList() { + data = new ArrayList(); + } + + + /** + * Constructor. + * + * @param state The name of the state that this list belongs to. + * @param size The initial size of the list. + */ + public DataList(String state, int size) { + this.state = state; + this.data = new ArrayList(size); + } + + + /** + * A constructor that creates a new DataList without Data objects and no + * UIProvider. Size defines the initial size of the list. + * + * @param state The name of the state that this list belongs to. + * @param size The initial size of the list. + * @param uiprovider The UIProvider that should be used to render this list. + */ + public DataList(String state, int size, String uiprovider) { + this(state, size); + this.uiprovider = uiprovider; + } + + + /** + * A constructor that creates a new DataList without Data objects and no + * UIProvider. Size defines the initial size of the list. + * + * @param state The name of the state that this list belongs to. + * @param size The initial size of the list. + * @param uiprovider The UIProvider that should be used to render this list. + * @param label The label. + */ + public DataList(String state, int size, String uiprovider, String label) { + this(state, size, uiprovider); + this.label = label; + } + + + /** + * Adds a new Data object to the list. + * + * @param obj The Data object. + */ + public void add(Data obj) { + if (obj != null) { + data.add(obj); + } + } + + + /** + * Adds a new Data objects to the list. + * + * @param obj The Data object. + */ + public void add(Data[] obj) { + if (obj != null) { + for (Data o: obj) { + data.add(o); + } + } + } + + + /** + * Returns the Data element at position idx. + * + * @param idx The position of an element that should be returned. + * + * @return the Data element at position idx. + */ + public Data get(int idx) { + if (idx < size()) { + return data.get(idx); + } + + return null; + } + + + /** + * Returns the whole list of Data objects. + * + * @return the whole list of Data objects. + */ + public List getAll() { + return data; + } + + /** + * Returns the number of Data objects in the list. + * + * @param the number of Data objects in the list. + */ + public int size() { + return data.size(); + } + + + /** + * Returns the name of the state that this list belongs to. + * + * @return the name of the state that this list belongs to. + */ + public String getState() { + return state; + } + + + /** + * Returns the label for this list. + * + * @return the label of this list. + */ + public String getLabel() { + return label; + } + + + /** + * Retrieves the name of a UIProvider or null if no one is recommended. + * + * @return the name of a UIProvider or null if no one is recommended. + */ + public String getUIProvider() { + return uiprovider; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,60 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of an artifact that might be used in the client. + * + * @author Ingo Weinzierl + */ +public class DefaultArtifact implements Artifact { + + /** The artifact's uuid.*/ + protected String uuid; + + /** The artifacts hash value.*/ + protected String hash; + + /** The current artifact description.*/ + protected ArtifactDescription artifactDescription; + + /** + * This constructor should not be used to create new instances of this + * class. An empty artifact without uuid and hash will be the result of + * this constructor call. + */ + public DefaultArtifact() { + } + + + /** + * This constructor creates a new artifact instance with a uuid and a hash. + * + * @param uuid The artifact's uuid. + * @param hash The artifact's hash. + */ + public DefaultArtifact(String uuid, String hash) { + this.uuid = uuid; + this.hash = hash; + } + + + public String getUuid() { + return uuid; + } + + + public String getHash() { + return hash; + } + + + public ArtifactDescription getArtifactDescription() { + return artifactDescription; + } + + + public void setArtifactDescription(ArtifactDescription description) { + this.artifactDescription = description; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,99 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of an {@link ArtifactDescription}. This class just + * implements constructors to create new instances and the necessary methods of + * the interface. + * + * @author Ingo Weinzierl + */ +public class DefaultArtifactDescription implements ArtifactDescription { + + /** Data that have been inserted in former states.*/ + protected DataList[] oldData; + + /** The Data that is allowed to be inserted in the current state.*/ + protected DataList currentData; + + /** The current state name.*/ + protected String currentState; + + /** The names of reachable states.*/ + protected String[] reachableStates; + + /** The output modes of this state.*/ + protected OutputMode[] outputModes; + + + public DefaultArtifactDescription() { + } + + + /** + * The default constructor. + * + * @param old The data that have been inserted in former states. + * @param current The data that might be inserted in the current state. + * @param state The name of the current state. + * @param reachableStates The names of the reachable states. + */ + public DefaultArtifactDescription( + DataList[] old, + DataList current, + String state, + String[] reachableStates) + { + this.oldData = old; + this.currentData = current; + this.currentState = state; + this.reachableStates = reachableStates; + } + + + /** + * The default constructor. + * + * @param old The data that have been inserted in former states. + * @param current The data that might be inserted in the current state. + * @param state The name of the current state. + * @param reachableStates The names of the reachable states. + * @param outputModes The available output modes of this artifact. + */ + public DefaultArtifactDescription( + DataList[] old, + DataList current, + String state, + String[] reachableStates, + OutputMode[] outputModes) + { + this(old, current, state, reachableStates); + this.outputModes = outputModes; + } + + + public DataList[] getOldData() { + return oldData; + } + + + public DataList getCurrentData() { + return currentData; + } + + + public String getCurrentState() { + return currentState; + } + + + public String[] getReachableStates() { + return reachableStates; + } + + + public OutputMode[] getOutputModes() { + return outputModes; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,136 @@ +package de.intevation.flys.client.shared.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * The default implementation of a {@link Collection}. + * + * @author Ingo Weinzierl + */ +public class DefaultCollection implements Collection { + + /** The uuid of the collection. */ + protected String uuid; + + /** The name of the collection.*/ + protected String name; + + /** The creation time of this collection.*/ + protected Date creation; + + /** The list of artifacts that are managed by this Collection.*/ + protected List items; + + + /** + * Constructor without arguments is necessary for GWT. + */ + public DefaultCollection() { + } + + + /** + * Creates a new DefaultCollection with a UUID. + * + * @param uuid The UUID. + */ + public DefaultCollection(String uuid) { + this.uuid = uuid; + this.items = new ArrayList(); + } + + + /** + * Creates a new DefaultCollection with uuid and name. + * + * @param uuid The identifier of this collection. + * @param name The name of this collection. + */ + public DefaultCollection(String uuid, String name) { + this(uuid); + + this.name = name; + } + + + /** + * Creates a new DefaultCollection with uuid and name. + * + * @param uuid The identifier of this collection. + * @param name The name of this collection. + * @param creation The creation time. + */ + public DefaultCollection(String uuid, String name, Date creation) { + this(uuid, name); + + this.creation = creation; + } + + + public String identifier() { + return uuid; + } + + + public Date getCreationTime() { + return creation; + } + + + public Date getLastAccess() { + return new Date(); + } + + + public String getName() { + return name; + } + + + public void addItem(CollectionItem item) { + if (item != null) { + items.add(item); + } + } + + + public int getItemLength() { + return items.size(); + } + + + public CollectionItem getItem(int idx) { + if (idx >= getItemLength()) { + return null; + } + + return items.get(idx); + } + + + public Map getOutputModes() { + Map modes = new HashMap(); + + for (CollectionItem item: items) { + List itemModes = item.getOutputModes(); + + if (itemModes != null) { + for (OutputMode itemMode: itemModes) { + String name = itemMode.getName(); + if (!modes.containsKey(name)) { + // we dont want duplicated OutputModes in our result. + modes.put(name, itemMode); + } + } + } + } + + return modes; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,73 @@ +package de.intevation.flys.client.shared.model; + +import java.util.List; + + +/** + * The default implementation of a CollectionItem. + * + * @author Ingo Weinzierl + */ +public class DefaultCollectionItem implements CollectionItem { + + /** The identifier that specifies the artifact related to this item.*/ + protected String identifier; + + /** The hash that specifies the artifact related to this item.*/ + protected String hash; + + /** The list of output modes supported by the artifact of this item.*/ + protected List outputModes; + + + /** + * An empty constructor. + */ + public DefaultCollectionItem() { + } + + + /** + * The default constructor to create a new CollectionItem related to an + * artifact with output modes. + * + * @param identifier The identifier of an artifact. + * @param outputModes The output modes supported by this item. + */ + public DefaultCollectionItem( + String identifier, + String hash, + List modes) { + this.identifier = identifier; + this.hash = hash; + this.outputModes = modes; + } + + + public String identifier() { + return identifier; + } + + + public String hash() { + return hash; + } + + + public List getOutputModes() { + return outputModes; + } + + + public List getFacets(String outputmode) { + for (OutputMode mode: outputModes) { + if (outputmode.equals(mode.getName())) { + // TODO Return facets, but facets are not implemented for + // OutputModes yet! + } + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultData.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,69 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of a {@link Data} item. This class just implements + * constructors to create instances and the necessary methods of the interface. + * + * @author Ingo Weinzierl + */ +public class DefaultData implements Data { + + /** The label of this Data object.*/ + protected String label; + + /** The description.*/ + protected String description; + + /** The type.*/ + protected String type; + + /** The DataItems.*/ + protected DataItem[] items; + + + public DefaultData() { + } + + + /** + * The default constructor to create new DefaultData objects. + * + * @param label The label. + * @param description The description. + * @param type The type. + * @param items The DataItems. + */ + public DefaultData( + String label, + String description, + String type, + DataItem[] items) + { + this.label = label; + this.description = description; + this.type = type; + this.items = items; + } + + + public String getLabel() { + return label; + } + + + public String getDescription() { + return description; + } + + + public String getType() { + return type; + } + + + public DataItem[] getItems() { + return items; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultDataItem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultDataItem.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of a {@link DataItem}. This class just implements + * constructors to create instances and the necessary methods of the interface. + * + * @author Ingo Weinzierl + */ +public class DefaultDataItem implements DataItem { + + /** The label.*/ + protected String label; + + /** The description.*/ + protected String description; + + /** The value.*/ + protected String value; + + + public DefaultDataItem() { + } + + + /** + * The default constructor to create new instances. + * + * @param label The label. + * @param description The description. + * @param value The value. + */ + public DefaultDataItem(String label, String description, String value) { + this.label = label; + this.description = description; + this.value = value; + } + + + public String getLabel() { + return label; + } + + + public String getDescription() { + return description; + } + + + public String getStringValue() { + return value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultFacet.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of a Facet. + * + * @author Ingo Weinzierl + */ +public class DefaultFacet implements Facet { + + /** The name of the facet.*/ + protected String name; + + + /** + * An empty constructor. + */ + public DefaultFacet() { + } + + + /** + * The default constructor to create new DefaultFacets. + * + * @param name The name of the facet. + */ + public DefaultFacet(String name) { + this.name = name; + } + + + public String getName() { + return name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The default implementation of an Output. + * + * @author Ingo Weinzierl + */ +public class DefaultOutputMode implements OutputMode { + + /** The name of this mode.*/ + protected String name; + + /** The description of this mode.*/ + protected String description; + + /** The mime-type of this mode.*/ + protected String mimeType; + + + /** A convinience constructor.*/ + public DefaultOutputMode() { + } + + + /** + * The default constructor. + * + * @param name The name of this mode. + * @param description The description of this mode. + * @param mimeType The mime-type of this mode. + */ + public DefaultOutputMode(String name, String description, String mimeType) { + this.name = name; + this.description = description; + this.mimeType = mimeType; + } + + + public String getName() { + return name; + } + + + public String getDescription() { + return description; + } + + + public String getMimeType() { + return mimeType; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultRiver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultRiver.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,50 @@ +package de.intevation.flys.client.shared.model; + + +/** + * The simpliest default implementation of a River that just stores a name. + * + * @author Ingo Weinzierl + */ +public class DefaultRiver implements River { + + /** The name of the river.*/ + protected String name; + + /** + * The default constructor that creates empty river objects. + */ + public DefaultRiver() { + } + + + /** + * This constructor should be used to create new rivers. + * + * @param name The name of the river. + */ + public DefaultRiver(String name) { + this.name = name; + } + + + /** + * Sets the name of the river. + * + * @param name The name of the river. + */ + public void setName(String name) { + this.name = name; + } + + + /** + * Returns the name of the river. + * + * @return the name of the river. + */ + public String getName() { + return name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultUser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultUser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.flys.client.shared.model; + + +/** + * Trivial implementation of a user. Useful to be subclassed. + * + * @author Ingo Weinzierl + */ +public class DefaultUser +implements User +{ + /** The identifier of the user.*/ + protected String identifier; + + /** The name of the user.*/ + protected String name; + + + /** + * The default constructor. + */ + public DefaultUser() { + } + + + /** + * A constructor that creates a new user. + * + * @param identifier The uuid of the user. + * @param name The name of the user. + */ + public DefaultUser(String identifier, String name) { + this.identifier = identifier; + this.name = name; + } + + + /** + * Returns the identifier of this user. + * + * @return the identifier of this user. + */ + public String identifier() { + return identifier; + } + + + /** + * Returns the name of the user. + * + * @return the name of the user. + */ + public String getName() { + return name; + } + + + /** + * Set the identifier of the user. + * + * @param identifier The new identifier. + */ + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + + /** + * Set the name of the user. + * + * @param name The name for this user. + */ + public void setName(String name) { + this.name = name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/Facet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Facet.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * The interface that provides methods to retrieve information about a Facet. + * + * @author Ingo Weinzierl + */ +public interface Facet extends Serializable { + + /** + * Returns the name of a facet. + * + * @return the name of a facet. + */ + String getName(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/OutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/OutputMode.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,37 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +/** + * This interface describes an output mode of an artifact. + * + * @author Ingo Weinzierl + */ +public interface OutputMode extends Serializable { + + /** + * Retrieves the name of this mode. + * + * @return the name of this mode. + */ + String getName(); + + + /** + * Retrieves the description of this mode. + * + * @return the description of this mode. + */ + String getDescription(); + + + /** + * Retrieves the mime-type of this mode. + * + * + * @return the mime-type of this mode. + */ + String getMimeType(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/River.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/River.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,12 @@ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + +/** + * @author Ingo Weinzierl + */ +public interface River extends Serializable { + + String getName(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/java/de/intevation/flys/client/shared/model/User.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/User.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.flys.client.shared.model; + +import java.io.Serializable; + + +public interface User +extends Serializable +{ + String identifier(); + + String getName(); + + void setName(String name); + + void setIdentifier(String identifier); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/FLYS.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/webapp/FLYS.css Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,90 @@ +/** Add css rules here for your application. */ + + +/** Example rules used by the template application (remove for your app) */ +h1 { + font-size: 2em; + font-weight: bold; + color: #777777; + margin: 40px 0px 70px; + text-align: center; +} + +.sendButton { + display: block; + font-size: 16pt; +} + +/** Most GWT widgets already have a style name defined */ +.gwt-DialogBox { + width: 400px; +} + +.dialogVPanel { + margin: 5px; +} + +.serverResponseLabelError { + color: red; +} + +/** Set ids using widget.getElement().setId("idOfElement") */ +#closeButton { + margin: 15px 6px 6px; +} + + +/** BfG Colors */ +.bgWhite { + background-color: #ffffff; +} + +.bgBlueLight { + background-color: #cfe1f1; +} + +.bgBlueMid { + background-color: #a9c9e6; +} + +.bgBlueDark { + background-color: #669fd1; +} + + +/** Fontstyles */ +.fontLightSmall { + font-family: Arial,Verdana,sans-serif; + font-size: 10pt; + color: #cfe1f1; +} + +.fontLightMid { + font-family: Arial,Verdana,sans-serif; + font-size: 12pt; + color: #cfe1f1; +} + +.fontLightBig { + font-family: Arial,Verdana,sans-serif; + font-size: 18pt; + color: #cfe1f1; +} + +.fontNormalSmall { + font-family: Arial,Verdana,sans-serif; + font-size: 10pt; + color: #a9c9e6; +} + +.fontNormalMid { + font-family: Arial,Verdana,sans-serif; + font-size: 12pt; + color: #a9c9e6; +} + +.fontNormalBig { + font-family: Arial,Verdana,sans-serif; + font-size: 18pt; + color: #a9c9e6; +} diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/FLYS.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/webapp/FLYS.html Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + FLYS-3.0 + + + + + + + + + + + + + + + + + + + + + + +
+ + diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/WEB-INF/web.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/main/webapp/WEB-INF/web.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,114 @@ + + + + + + + + user + de.intevation.flys.client.server.UserServiceImpl + + + + user + /flys/user + + + + artifact + de.intevation.flys.client.server.ArtifactServiceImpl + + + + artifact + /flys/artifact + + + + create-collection + de.intevation.flys.client.server.CreateCollectionServiceImpl + + + + create-collection + /flys/create-collection + + + + rivers + de.intevation.flys.client.server.RiverServiceImpl + + + + rivers + /flys/rivers + + + + forward + de.intevation.flys.client.server.StepForwardServiceImpl + + + + forward + /flys/forward + + + + advance + de.intevation.flys.client.server.AdvanceServiceImpl + + + + advance + /flys/advance + + + + add-artifact + de.intevation.flys.client.server.AddArtifactServiceImpl + + + + add-artifact + /flys/add-artifact + + + + describe-collection + de.intevation.flys.client.server.DescribeCollectionServiceImpl + + + + describe-collection + /flys/describe-collection + + + + user-collections + de.intevation.flys.client.server.UserCollectionsServiceImpl + + + + user-collections + /flys/user-collections + + + + ChartOutputService + de.intevation.flys.client.server.ChartOutputServiceImpl + + + + ChartOutputService + /flys/chart + + + + + FLYS.html + + + diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/back.png Binary file flys-client/src/main/webapp/images/back.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/back_de.png Binary file flys-client/src/main/webapp/images/back_de.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/back_en.png Binary file flys-client/src/main/webapp/images/back_en.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/next.png Binary file flys-client/src/main/webapp/images/next.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/next_de.png Binary file flys-client/src/main/webapp/images/next_de.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/main/webapp/images/next_en.png Binary file flys-client/src/main/webapp/images/next_en.png has changed diff -r 5391c329168c -r 2b745b5e731c flys-client/src/test/java/de/intevation/flys/client/FLYSJUnit.gwt.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-client/src/test/java/de/intevation/flys/client/FLYSJUnit.gwt.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,11 @@ + + + + + + + + +