Mercurial > dive4elements > river
changeset 207:2b745b5e731c 0.1
merged flys-backend/0.1
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:07 +0200 |
parents | 27d3d0093993 (current diff) 5391c329168c (diff) |
children | 979967d80fdf |
files | |
diffstat | 53 files changed, 6679 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/ChangeLog Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,500 @@ +2011-03-28 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Range.java: + Forgot to save the last change before commit. + +2011-03-28 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Range.java: + Added methods to find out if two ranges intersects. + +2011-03-24 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Gauge.java: + Added an one to many relation to the discharge tables of a gauge. + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + Finished import of WSTs. + + TODO 1: Speed it up! It takes on a high end machine over 7(!) + minutes only for the data of the Saar. + TODO 2: Double precision floating point representations produced + by the the parsers leed to unique constraint violations + in the backend on a second run. So the import is currently + only working on freshly initialized data bases. + More consequent working with BigDecimal and some + rounding may be of help here. + + * src/main/java/de/intevation/flys/model/WstColumnValue.java: + Added convinience constructors. + + * src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java: + Added getPeer() method. + + * src/main/java/de/intevation/flys/importer/ImportWstColumn.java: + Add a list of the ImportWstColumnValues produced by the WST parser. + + * src/main/java/de/intevation/flys/importer/WstParser.java: Add + the (km, w) values to the ImportWstColumns. + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/WstParser.java: + Build models for wsts, wst columns and q ranges and + store them in the backend. TODO: store the w values. + + * src/main/java/de/intevation/flys/model/WstQRange.java + src/main/java/de/intevation/flys/model/Wst.java, + src/main/java/de/intevation/flys/model/Range.java, + src/main/java/de/intevation/flys/model/WstColumnQRange.java, + src/main/java/de/intevation/flys/model/WstColumn.java: + Added convinience constructors. + + * src/main/java/de/intevation/flys/importer/ImportWstQRange.java, + src/main/java/de/intevation/flys/importer/ImportWst.java, + src/main/java/de/intevation/flys/importer/ImportRiver.java, + src/main/java/de/intevation/flys/importer/ImportWstColumnQRange.java, + src/main/java/de/intevation/flys/importer/ImportWstColumn.java, + src/main/java/de/intevation/flys/importer/ImportRange.java: + Added getPeer() methods. + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/WstParser.java: + The unit extraction in the WST parser of desktop FLYS + is broken! Add a hack here to repair this for our + importer. Desktop FLYS needs a fix, too! + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/WstParser.java: + Ported some stuff ver from WSTSource.java of desktop flys to + parse WST files. TODO: create instances of the import models. + + * src/main/java/de/intevation/flys/utils/StringUtil.java: + Copied from desktop flys. Used for some string operations + in WST parser. + + * src/main/java/de/intevation/flys/importer/Importer.java: + Added system property 'flys.backend.importer.dry.run'. + Set to true only the parsing is done and no writing + to the backend. Default: false. + + * src/main/java/de/intevation/flys/App.java, + src/main/java/de/intevation/flys/model/MainValueType.java: + Removed needless imports. + +2011-03-22 Ingo Weinzierl <ingo@intevation.de> + + * src/main/java/de/intevation/flys/model/DischargeTableValue.java, + src/main/java/de/intevation/flys/model/DischargeTable.java: Added new + constructors. + + * src/main/java/de/intevation/flys/importer/AtFileParser.java: New. This + parser is used to '*.at' files. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: Added code to + import discharge tables. + + * src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java, + src/main/java/de/intevation/flys/importer/ImportDischargeTable.java: New. + Helper models for import discharge tables. + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/WstParser.java, + src/main/java/de/intevation/flys/importer/ImportRiver.java: + Added stub for WST parser. + +2011-03-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/ImportWstQRange.java, + src/main/java/de/intevation/flys/importer/ImportWst.java, + src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java, + src/main/java/de/intevation/flys/importer/ImportWstColumnQRange.java, + src/main/java/de/intevation/flys/importer/ImportWstColumn.java: + Added importer helper model stubs for WST imports. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + Second part of parsing/storing main values. Should be finished now. + + * src/main/java/de/intevation/flys/importer/ImportNamedMainValue.java, + src/main/java/de/intevation/flys/importer/ImportMainValue.java: + New. Helper models for import main values, + + * src/main/java/de/intevation/flys/model/MainValue.java, + src/main/java/de/intevation/flys/model/NamedMainValue.java: + Added convinience constructors. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: + Write main values to backend, too. + + * src/main/java/de/intevation/flys/importer/StaFileParser.java: + Build importer models for main values. + + * src/main/java/de/intevation/flys/importer/ImportMainValueType.java: + Data was called 'value'. Now it is 'name' to fit the + schema. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql.sql: Fixed wrong unique constraint. + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Added some logging when storing gauges. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Gauge.java: + Add forgotten column river_id. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: + Small HQL fix. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Gauge.java: + Added convinience contructor. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: + Fixed getPeer() method. + + * src/main/java/de/intevation/flys/importer/StaFileParser.java: + Fixed parsing of STA files. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/ImportRiver.java, + src/main/java/de/intevation/flys/importer/ImportGauge.java: + Propagate river into storing of gauges. + +2011-03-21 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/Importer.java: + Added code to store rivers not only annotations. + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Added stub code to write gauges. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + First part of parsing main values. + + * src/main/java/de/intevation/flys/App.java: Commented out + creation of dummy rivers. + + * src/main/java/de/intevation/flys/model/NamedMainValues.java: + Moved to NamedMainValue. + + * src/main/java/de/intevation/flys/model/NamedMainValue.java: + New. Formerly NamedMainValues. + + * src/main/java/de/intevation/flys/model/MainValue.java: + New. Forgotten part of the model. + + * src/main/java/de/intevation/flys/model/MainValueType.java: + Data is String not BigDecimal + + * src/main/java/de/intevation/flys/model/Range.java: Removed + contructor with double arguments. Using BigDecimal now. + + * src/main/java/de/intevation/flys/importer/PegelGltParser.java: + Propagate BigDecimal usage. + + * src/main/java/de/intevation/flys/importer/Importer.java: + Removed needless import. Added TODO + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Parse the dependencies of the gauges, too. + + * src/main/java/de/intevation/flys/importer/StaFileParser.java: + New. Parser for STA files. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: + Call STA file parser. + + * src/main/java/de/intevation/flys/importer/AnnotationsParser.java, + src/main/java/de/intevation/flys/importer/ImportRange.java: + Uses BigDecimal now. + + * src/main/java/de/intevation/flys/importer/ImportAttribute.java: + Fixed wrong type cast in equals. + + * src/main/java/de/intevation/flys/importer/ImportMainValueType.java: + New. Helper model for importing main value types. + + * src/main/java/de/intevation/flys/backend/SessionFactoryProvider.java: + Register forgotten MainValue model. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + Store annotations in backend. + + * src/main/java/de/intevation/flys/model/Annotation.java: + New convinience constructor. + + * src/main/java/de/intevation/flys/model/River.java: + Added toString() method. + + * src/main/java/de/intevation/flys/model/Range.java: + Fixed nasty mistake in @OneToOne annotatation. + New convinience constructors. + + * src/main/java/de/intevation/flys/importer/ImportPosition.java + src/main/java/de/intevation/flys/importer/ImportAnnotation.java, + src/main/java/de/intevation/flys/importer/ImportRange.java + src/main/java/de/intevation/flys/importer/ImportAttribute.java: + Make storing to backend work. It's a bit too slow. :-/ + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Fetch peer from backend. Added method to store annotations. + * src/main/java/de/intevation/flys/importer/Importer.java: + Stored annotations into backend. More eloquent SQL exception + handling. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/Attribute.java, + src/main/java/de/intevation/flys/model/Position.java: + Added convinience constructors. + + * src/main/java/de/intevation/flys/importer/ImportPosition.java, + src/main/java/de/intevation/flys/importer/ImportAttribute.java: + Bound them to there backend peers. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/AnnotationsParser.java: + New. Added parser to read *.KM files. + + * src/main/java/de/intevation/flys/importer/ImportPosition.java, + src/main/java/de/intevation/flys/importer/PegelGltParser.java, + src/main/java/de/intevation/flys/importer/ImportRiver.java, + src/main/java/de/intevation/flys/importer/ImportAnnotation.java, + src/main/java/de/intevation/flys/importer/ImportRange.java, + src/main/java/de/intevation/flys/importer/InfoGewParser.java, + src/main/java/de/intevation/flys/importer/ImportAttribute.java: + Adjusted to load the annotations from *.KM files. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/ImportPosition.java, + src/main/java/de/intevation/flys/importer/ImportRange.java, + src/main/java/de/intevation/flys/importer/ImportAttribute.java, + src/main/java/de/intevation/flys/importer/ImportAnnotation.java: + New helper models for import. + + * src/main/java/de/intevation/flys/importer/PegelGltParser.java, + src/main/java/de/intevation/flys/importer/ImportGauge.java: + Use new models. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/PegelGltParser.java: + New. Parser for PEGEL.GLT files. + + * src/main/java/de/intevation/flys/importer/ImportGauge.java: + New. Import model for gauges. + + * src/main/java/de/intevation/flys/utils/DBCPConnectionProvider.java: + Removed needless imports. + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Added method to parse the gauges. + + * src/main/java/de/intevation/flys/importer/InfoGewParser.java: + Trigger pegel glt file parsing. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/Importer.java: + Used thread local pattern to make sharing of session easier. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/Importer.java: + Fixed error in HQL statement. + +2011-03-17 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/utils/DBCPConnectionProvider.java: + Commented out a debug block because it leaks the db password. + +2011-03-16 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/importer/InfoGewParser.java: + Expose imported rivers. + + * src/main/java/de/intevation/flys/importer/InfoGewParser.java: + Store imported rivers into database. Needs testing! + +2011-03-16 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/backend/SessionFactoryProvider.java: + Default connection parameters are now overwritable with + system properties (defaults in brackets): + - user name: flys.backend.user (flys) + - user password: flys.backend.password (flys) + - db dialect: flys.backend.dialect (org.hibernate.dialect.PostgreSQLDialect) + - db driver: flys.backend.driver (org.postgresql.Driver) + - db url: flys.backend.url (jdbc:postgresql://localhost:5432/flys) + +2011-03-16 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/backend/SessionFactoryProvider.java: + Expose createSessionFactory() as public to be usable without + a artifact database running. + +2011-03-16 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/utils/FileTools.java: + Tools for handling with filenames. Currently there is + a repair(File) method with repairs letter case errors + which is useful when reading windows filenames on a + un*x platform. + + * src/main/java/de/intevation/flys/importer/Importer.java: + Standalone app to read data from the file system and + store it in a database. Currently it does not store + anything. It only loads info gew files. + + * src/main/java/de/intevation/flys/importer/InfoGewParser.java: + Info gew parser. + + * src/main/java/de/intevation/flys/importer/ImportRiver.java: + Helper model of a river used produced by parsing the + info gew files. + +2011-03-15 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/backend/SessionFactoryProvider.java: + New. SessionFactoryProvider.getSessionFactory() provides a + SessionFactory to use the Hibernate O/R mapper for the FLYS backend. + +2011-03-15 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * pom.xml: Added dependency to artifacts-commons to + be able to use the global configuration of the artifact database. + +2011-03-15 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/App.java: Wire all POJOs + to corresponding factory. + + * src/main/java/de/intevation/flys/model/*.java: Generate + all foreign key constraints. TODO: name them correctly + because the machine generated names are ugly and do + not fit the PostgreSQL names. + + * doc/schema/postgresql.sql: Small quantifier fix in descriptions + of wst columns. + +2011-03-14 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql.sql: Fixed wrong spelled + column references in foreign keys introduces with + last change. + +2011-03-14 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * src/main/java/de/intevation/flys/model/*.java: Added + column annotations for simple fields. TODO: foreign keys. + +2011-03-14 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql.sql, doc/schema/postgresql-cleanup.sql: + Fixed inconsistent table names. + + * src/main/java/de/intevation/flys/model/*.java: Added + entity and id annotations. + +2011-03-14 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql.sql, doc/schema/postgresql-cleanup.sql: + Added missing sequences. + + * doc/schema/sqlite.sql: Deleted. Not longer supported. + +2011-03-11 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql-cleanup.sql: Forgot to add. + + * src/main/java/de/intevation/flys/App.java: Use + Apache Commons DBCP as Hibernate connection provide. + + * src/main/java/de/intevation/flys/model/River.java: + Added a constructor with string argument. Set the + sequence increment to 1 (eat up 100 at a time before). + + * pom.xml: Added PostgreSQL 8.4 driver as runtime dependency. + +2011-03-11 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/postgresql-cleanup.sql: New. Tear down schema + for a postgres database. + + * doc/schema/postgresql.sql: Added squence for + auto generating ids in river table. Cleaned up schema. + + * src/main/java/de/intevation/flys/App.java: Simple + test app to interact with hibernate. Needs to be removed + because its only a toy. + + * src/main/java/de/intevation/flys/utils/DBCPConnectionProvider.java: + New. Binds Apache Commons to Hibernate. + + * pom.xml: Added dependencies to log4j, commons dbcp, + JPA of hibernate. + + * src/main/java/de/intevation/flys/model/River.java: Added + JPA annotations. + + * src/main/java/de/intevation/flys/model/*.java: Replaced + Long with Integer because column ids are only four bytes wide. + +2011-03-11 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/sqlite.sql, doc/schema/postgresql.sql: Fixed + smaller issues in ddl. + + * src/main/java/de/intevation/flys/model/*.java: Added POJOs + of to be mapped. TODO: Map them! + + * pom.xml: Added plugin config for hibernate. + +2011-03-09 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * pom.xml: Added dependency (and corresponding repository) to + Hibernate Core 3.6.1 Final + +2011-03-09 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * pom.xml, src/**: Created a new empty maven project: + $ mvn archetype:create \ + -DgroupId=de.intevation.flys \ + -DartifactId=flys-backend + +2011-03-09 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * README: New. Some setup instructions. + + * doc/schema/postgresql.sql: New. Schema converted to PostgreSQL + + * doc/schema/sqlite.sql: Fixed defect foreign key constraints. + +2011-03-09 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * doc/schema/sqlite.sql: Factorized time intervals out into + a separated table. + +2011-01-22 Sascha L. Teichmann <sascha.teichmann@intevation.de> + + * contrib/import-kms.py, contrib/import-gew.py: Initial scripts + to import data into SQLite database. They still need some work. + +2011-02-10 Sascha L. Teichmann <sascha.teichmann@intevation.de>: + + * doc/schema/sqlite.sql: Added initial schema for + FLYS database.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/README Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,10 @@ +For the artifact database +# su - postgres +$ createuser --no-createrole --no-superuser --pwprompt --no-createdb artifacts +$ createdb --encoding=UTF-8 --owner artifacts artifactsdb + +For the flys database + +# su - postgres +$ createuser --no-createrole --no-superuser --pwprompt --no-createdb flys +$ createdb --encoding=UTF-8 --owner flys flystest1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/contrib/import-gew.py Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,223 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import os +import codecs +import re + +HAUPTWERT = re.compile(r"\s*([^\s]+)\s+([^\s+]+)\s+([QWDT-])") +WHITESPACE = re.compile(r"\s+") + +class KM(object): + + def __init__(self, filename): + self.filename = filename + self.load_values() + + def load_values(self): + with codecs.open(self.filename, "r", "latin-1") as f: + for line in f: + line = line.strip() + if not line or line.startswith("*"): + parts = [s.strip() for s in line.split(";")] + # TODO: Use code from import-kms.py + +class AbflussTafel(object): + + def __init__(self, filename): + self.filename = filename + self.name = "" + self.values = [] + self.load_values() + + def load_values(self): + with codecs.open(self.filename, "r", "latin-1") as f: + first = True + for line in f: + line = line.strip() + if not line: continue + if line.startswith("#! name="): + self.name = line[8:] + continue + if line.startswith("#") or line.startswith("*"): + continue + line = line.replace(",", ".") + splits = WHITESPACE.split(line) + + if len(splits) < 2 or len(splits) > 11: + continue + + w = float(splits[0]) + + shift = 0 + + if len(splits) != 11 and first: + shift = 11 - len(splits) + + for idx, q in enumerate(splits[1:]): + i_w = w + shift + idx + i_q = float(q) + w_q = (i_w/100.0, i_q/100.0) + self.values.append(w_q) + + first = False + + +class Hauptwert(object): + def __init__(self, name, value, kind): + self.name = name + self.extra = value + self.kind = kind + +class Pegel(object): + def __init__(self, name, start, stop, sta, at, html): + self.name = name + self.start = start + self.stop = stop + self.sta = sta + self.at = at + self.html = html + self.aeo = 0.0 + self.nullpunkt = 0.0 + self.km = 0.0 + self.hauptwerte = [] + self.load_hauptwerte() + self.at_data = AbflussTafel(self.at) + + def load_hauptwerte(self): + with codecs.open(self.sta, "r", "latin-1") as f: + for line_no, line in enumerate(f): + line = line.rstrip() + if line_no == 0: + first = False + name = line[16:37].strip() + line = [s.replace(",", ".") for s in line[37:].split()] + self.aeo = float(line[0]) + self.nullpunkt = float(line[1]) + print >> sys.stderr, "pegel name: '%s'" % name + print >> sys.stderr, "pegel aeo: '%f'" % self.aeo + print >> sys.stderr, "pegel nullpunkt: '%f'" % self.nullpunkt + elif line_no == 1: + self.km = float(line[29:36].strip().replace(",", ".")) + print >> sys.stderr, "km: '%f'" % self.km + else: + if not line: continue + line = line.replace(",", ".") + m = HAUPTWERT.match(line) + if not m: continue + self.hauptwerte.append(Hauptwert( + m.group(1), float(m.group(2)), m.group(3))) + +class Gewaesser(object): + + def __init__(self, name=None, b_b=None, wst=None): + self.name = name + self.b_b = b_b + self.wst = wst + self.pegel = [] + + def load_pegel(self): + dir_name = os.path.dirname(self.wst) + pegel_glt = find_file(dir_name, "PEGEL.GLT") + if not pegel_glt: + print >> sys.stderr, "Missing PEGEL.GLT for %r" % self.name + return + + print >> sys.stderr, "pegel_glt: %r" % pegel_glt + + with codecs.open(pegel_glt, "r", "latin-1") as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + # using re to cope with quoted columns, + # shlex has unicode problems. + parts = [p for p in re.split("( |\\\".*?\\\"|'.*?')", line) + if p.strip()] + if len(parts) < 7: + print >> sys.stderr, "too less colums (need 7): %r" % line + continue + + print >> sys.stderr, "%r" % parts + self.pegel.append(Pegel( + parts[0], + min(float(parts[2]), float(parts[3])), + max(float(parts[2]), float(parts[3])), + norm_path(parts[4], dir_name), + norm_path(parts[5], dir_name), + parts[6])) + + + def __repr__(self): + return u"Gewaesser(name=%r, b_b=%r, wst=%r)" % ( + self.name, self.b_b, self.wst) + +def norm_path(path, ref): + if not os.path.isabs(path): + path = os.path.normpath(os.path.join(ref, path)) + return path + +def find_file(path, what): + what = what.lower() + for filename in os.listdir(path): + p = os.path.join(path, filename) + if os.path.isfile(p) and filename.lower() == what: + return p + return None + + +def read_gew(filename): + + gewaesser = [] + + current = Gewaesser() + + filename = os.path.abspath(filename) + dirname = os.path.dirname(filename) + + with codecs.open(filename, "r", "latin-1") as f: + for line in f: + line = line.strip() + if not line or line.startswith("*"): + continue + + if line.startswith(u"Gewässer:"): + if current.name: + gewaesser.append(current) + current = Gewaesser() + current.name = line[len(u"Gewässer:"):].strip() + elif line.startswith(u"B+B-Info:"): + current.b_b = norm_path(line[len(u"B+B-Info:"):].strip(), + dirname) + elif line.startswith(u"WSTDatei:"): + current.wst = norm_path(line[len(u"WSTDatei:"):].strip(), + dirname) + + if current.name: + gewaesser.append(current) + + return gewaesser + +def main(): + + if len(sys.argv) < 2: + print >> sys.stderr, "missing gew file" + sys.exit(1) + + gew_filename = sys.argv[1] + + if not os.path.isfile(gew_filename): + print >> sys.stderr, "'%s' is not a file" % gew_filename + sys.exit(1) + + gewaesser = read_gew(gew_filename) + + for gew in gewaesser: + gew.load_pegel() + + + +if __name__ == '__main__': + main() +# vim: set fileencoding=utf-8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/contrib/import-kms.py Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,213 @@ +#!/usr/bin/env python + +import sys +import logging +import re +import os + +import sqlite3 as db +import locale +import codecs + +from optparse import OptionParser + +log = logging.getLogger(__name__) +log.setLevel(logging.WARNING) +log.addHandler(logging.StreamHandler(sys.stderr)) + +RANGE = re.compile("([^#]*)#(.*)") +DEFAULT_DATABASE = "flys.db" + +SQL_NEXT_ID = "SELECT coalesce(max(id), -1) + 1 FROM %s" +SQL_SELECT_ID = "SELECT id FROM %s WHERE %s = ?" +SQL_INSERT_ID = "INSERT INTO %s (id, %s) VALUES (?, ?)" + +SQL_SELECT_RANGE_ID = """ +SELECT id FROM ranges WHERE river_id = ? AND a = ? AND b = ? +""" +SQL_INSERT_RANGE_ID = """ +INSERT INTO ranges (id, river_id, a, b) VALUES (?, ?, ?, ?) +""" +SQL_SELECT_ANNOTATION_ID = """ +SELECT id FROM annotations +WHERE range_id = ? AND attribute_id = ? AND position_id = ? +""" +SQL_INSERT_ANNOTATION_ID = """ +INSERT INTO annotations (id, range_id, attribute_id, position_id) +VALUES (?, ?, ?, ?) +""" + +def encode(s): + try: + return unicode(s, "latin-1") + except UnicodeDecodeError: + return unicode.encode(s, locale.getpreferredencoding()) + +class hashabledict(dict): + def __key(self): + return tuple((k, self[k]) for k in sorted(self)) + def __hash__(self): + return hash(self.__key()) + def __eq__(self, other): + return self.__key() == other.__key() + +def cache(f): + def func(*args, **kw): + key = (args, hashabledict(kw)) + try: + return f.__cache__[key] + except KeyError: + value = f(*args, **kw) + f.__cache__[key] = value + return value + f.__cache__ = {} + return func + +NEXT_IDS = {} +def next_id(cur, relation): + idx = NEXT_IDS.get(relation) + if idx is None: + cur.execute(SQL_NEXT_ID % relation) + idx = cur.fetchone()[0] + NEXT_IDS[relation] = idx + 1 + return idx + +def get_id(cur, relation, attribute, value): + select_stmt = SQL_SELECT_ID % (relation, attribute) + #log.debug(select_stmt) + cur.execute(select_stmt, (value,)) + row = cur.fetchone() + if row: return row[0] + idx = next_id(cur, relation) + insert_stmnt = SQL_INSERT_ID % (relation, attribute) + #log.debug(insert_stmnt) + cur.execute(insert_stmnt, (idx, value)) + cur.connection.commit() + log.debug("insert %s '%s' id: '%d'" % (relation, value, idx)) + return idx + +#@cache +def get_river_id(cur, name): + return get_id(cur, "rivers", "name", name) + +#@cache +def get_attribute_id(cur, value): + return get_id(cur, "attributes", "value", value) + +#@cache +def get_position_id(cur, value): + return get_id(cur, "positions", "value", value) + +#@cache +def get_range_id(cur, river_id, a, b): + cur.execute(SQL_SELECT_RANGE_ID, (river_id, a, b)) + row = cur.fetchone() + if row: return row[0] + idx = next_id(cur, "ranges") + cur.execute(SQL_INSERT_RANGE_ID, (idx, river_id, a, b)) + cur.connection.commit() + return idx + +#@cache +def get_annotation_id(cur, range_id, attribute_id, position_id): + cur.execute(SQL_SELECT_ANNOTATION_ID, ( + range_id, attribute_id, position_id)) + row = cur.fetchone() + if row: return row[0] + idx = next_id(cur, "annotations") + cur.execute(SQL_INSERT_ANNOTATION_ID, ( + idx, range_id, attribute_id, position_id)) + cur.connection.commit() + return idx + +def files(root, accept=lambda x: True): + if os.path.isfile(root): + if accept(root): yield root + elif os.path.isdir(root): + stack = [ root ] + while stack: + cur = stack.pop() + for f in os.listdir(cur): + p = os.path.join(cur, f) + if os.path.isdir(p): + stack.append(p) + elif os.path.isfile(p) and accept(p): + yield p + +def feed_km(cur, river_id, km_file): + + log.info("processing: %s" % km_file) + + for line in codecs.open(km_file, "r", "latin-1"): + line = line.strip() + if not line or line.startswith('*'): + continue + parts = [x.strip() for x in line.split(';')] + if len(parts) < 3: + log.error("cannot process: '%s'" % line) + continue + m = RANGE.match(parts[2]) + try: + if m: + x = [float(x.replace(",", ".")) for x in m.groups()] + a, b = min(x), max(x) + if a == b: b = None + else: + a, b = float(parts[2].replace(",", ".")), None + except ValueError: + log.error("cannot process: '%s'" % line) + continue + + attribute = parts[0] + position = parts[1] + attribute_id = get_attribute_id(cur, attribute) if attribute else None + position_id = get_position_id(cur, position) if position else None + + range_id = get_range_id(cur, river_id, a, b) + + get_annotation_id(cur, range_id, attribute_id, position_id) + +def main(): + + usage = "usage: %prog [options] river km-file ..." + parser = OptionParser(usage=usage) + parser.add_option( + "-v", "--verbose", action="store_true", + dest="verbose", + help="verbose output") + parser.add_option( + "-r", "--recursive", action="store_true", + dest="recursive", default=False, + help="recursive") + parser.add_option( + "-d", "--database", action="store", + dest="database", + help="database to connect with", + default=DEFAULT_DATABASE) + + options, args = parser.parse_args() + + if options.verbose: + log.setLevel(logging.INFO) + + if len(args) < 1: + log.error("missing river argument") + sys.exit(1) + + river = unicode(args[0], locale.getpreferredencoding()) + + with db.connect(options.database) as con: + cur = con.cursor() + river_id = get_river_id(cur, river) + + for arg in args[1:]: + if options.recursive: + for km_file in files( + arg, lambda x: x.lower().endswith(".km")): + feed_km(cur, river_id, km_file) + else: + feed_km(cur, river_id, arg) + + +if __name__ == '__main__': + main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/doc/schema/postgresql-cleanup.sql Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,44 @@ +BEGIN; + +DROP TABLE wst_column_q_ranges; +DROP TABLE wst_q_ranges; +DROP TABLE wst_column_values; +DROP TABLE wst_column; +DROP TABLE wst; + +DROP TABLE discharge_table_values; +DROP TABLE discharge_tables; + +DROP TABLE main_values CASCADE; +DROP TABLE time_intervals CASCADE; +DROP TABLE named_main_values CASCADE; +DROP TABLE main_value_types CASCADE; + +DROP TABLE gauges CASCADE; + +DROP TABLE annotations CASCADE; +DROP TABLE positions CASCADE; +DROP TABLE ranges CASCADE; +DROP TABLE attributes CASCADE; + +DROP TABLE rivers CASCADE; + +DROP SEQUENCE WST_COLUMN_Q_RANGES_ID_SEQ; +DROP SEQUENCE WST_Q_RANGES_ID_SEQ; +DROP SEQUENCE WST_COLUMN_VALUES_ID_SEQ; +DROP SEQUENCE WST_COLUMNS_ID_SEQ; +DROP SEQUENCE WSTS_ID_SEQ; +DROP SEQUENCE DISCHARGE_TABLE_VALUES_ID_SEQ; +DROP SEQUENCE DISCHARGE_TABLES_ID_SEQ; +DROP SEQUENCE MAIN_VALUES_ID_SEQ; +DROP SEQUENCE TIME_INTERVALS_ID_SEQ; +DROP SEQUENCE NAMED_MAIN_VALUES_ID_SEQ; +DROP SEQUENCE MAIN_VALUE_TYPES_ID_SEQ; +DROP SEQUENCE GAUGES_ID_SEQ; +DROP SEQUENCE ANNOTATIONS_ID_SEQ; +DROP SEQUENCE POSITIONS_ID_SEQ; +DROP SEQUENCE RANGES_ID_SEQ; +DROP SEQUENCE ATTRIBUTES_ID_SEQ; +DROP SEQUENCE RIVERS_ID_SEQ; + +COMMIT;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/doc/schema/postgresql.sql Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,194 @@ +BEGIN; + +-- Gewaesser +CREATE SEQUENCE RIVERS_ID_SEQ; + +CREATE TABLE rivers ( + id int PRIMARY KEY NOT NULL, + name VARCHAR(256) NOT NULL UNIQUE +); + +-- Bruecke, Haefen, etc. +CREATE SEQUENCE ATTRIBUTES_ID_SEQ; + +CREATE TABLE attributes ( + id int PRIMARY KEY NOT NULL, + value VARCHAR(256) NOT NULL UNIQUE +); + +-- segments from/to at a river +CREATE SEQUENCE RANGES_ID_SEQ; + +CREATE TABLE ranges ( + id int PRIMARY KEY NOT NULL, + river_id int NOT NULL REFERENCES rivers(id), + a NUMERIC NOT NULL, + b NUMERIC, + UNIQUE (river_id, a, b) +); + +-- Lage 'links', 'rechts', etc. +CREATE SEQUENCE POSITIONS_ID_SEQ; + +CREATE TABLE positions ( + id int PRIMARY KEY NOT NULL, + value VARCHAR(256) NOT NULL UNIQUE +); + +-- Some object (eg. Hafen) at a segment of river +-- plus its position. +CREATE SEQUENCE ANNOTATIONS_ID_SEQ; + +CREATE TABLE annotations ( + id int PRIMARY KEY NOT NULL, + range_id int NOT NULL REFERENCES ranges(id), + attribute_id int NOT NULL REFERENCES attributes(id), + position_id int REFERENCES positions(id) +); + +-- Pegel +CREATE SEQUENCE GAUGES_ID_SEQ; + +CREATE TABLE gauges ( + id int PRIMARY KEY NOT NULL, + name VARCHAR(256) NOT NULL, + river_id int NOT NULL REFERENCES rivers(id), + station NUMERIC NOT NULL UNIQUE, + aeo NUMERIC NOT NULL, + + -- Pegelnullpunkt + datum NUMERIC NOT NULL, + -- Streckengueltigkeit + range_id int NOT NULL REFERENCES ranges (id), + + UNIQUE (name, river_id), + UNIQUE (river_id, station) +); + +-- Type of a Hauptwert 'W', 'Q', 'D', etc. +CREATE SEQUENCE MAIN_VALUE_TYPES_ID_SEQ; + +CREATE TABLE main_value_types ( + id int PRIMARY KEY NOT NULL, + name VARCHAR(256) NOT NULL UNIQUE +); + +-- Named type of a Hauptwert (eg. HQ100) +CREATE SEQUENCE NAMED_MAIN_VALUES_ID_SEQ; + +CREATE TABLE named_main_values ( + id int PRIMARY KEY NOT NULL, + name VARCHAR(256) NOT NULL UNIQUE, + type_id int NOT NULL REFERENCES main_value_types(id), + UNIQUE (name, type_id) +); + +-- Table for time intervals +CREATE SEQUENCE TIME_INTERVALS_ID_SEQ; + +CREATE TABLE time_intervals ( + id int PRIMARY KEY NOT NULL, + start_time TIMESTAMP NOT NULL, + stop_time TIMESTAMP, + CHECK (start_time <= stop_time) +); + +-- Stammdaten +CREATE SEQUENCE MAIN_VALUES_ID_SEQ; + +CREATE TABLE main_values ( + id int PRIMARY KEY NOT NULL, + gauge_id int NOT NULL REFERENCES gauges(id), + named_value_id int NOT NULL REFERENCES named_main_values(id), + value NUMERIC NOT NULL, + + time_interval_id int REFERENCES time_intervals(id), + + -- TODO: better checks + UNIQUE (gauge_id, named_value_id, time_interval_id) +); + +-- Abflusstafeln +CREATE SEQUENCE DISCHARGE_TABLES_ID_SEQ; + +CREATE TABLE discharge_tables ( + id int PRIMARY KEY NOT NULL, + gauge_id int NOT NULL REFERENCES gauges(id), + + time_interval_id int REFERENCES time_intervals(id), + + -- TODO: better checks + UNIQUE (gauge_id, time_interval_id) +); + +-- Values of the Abflusstafeln +CREATE SEQUENCE DISCHARGE_TABLE_VALUES_ID_SEQ; + +CREATE TABLE discharge_table_values ( + id int PRIMARY KEY NOT NULL, + table_id int NOT NULL REFERENCES discharge_tables(id), + q NUMERIC NOT NULL, + w NUMERIC NOT NULL, + + UNIQUE (table_id, q, w) +); + +-- WST files +CREATE SEQUENCE WSTS_ID_SEQ; + +CREATE TABLE wsts ( + id int PRIMARY KEY NOT NULL, + river_id int NOT NULL REFERENCES rivers(id), + description VARCHAR(256) NOT NULL, + -- TODO: more meta infos + UNIQUE (river_id, description) +); + +-- columns of WST files +CREATE SEQUENCE WST_COLUMNS_ID_SEQ; + +CREATE TABLE wst_columns ( + id int PRIMARY KEY NOT NULL, + wst_id int NOT NULL REFERENCES wsts(id), + name VARCHAR(256) NOT NULL, + description VARCHAR(256), + + time_interval_id int REFERENCES time_intervals(id), + + UNIQUE (wst_id, name) +); + +-- w values in WST file column +CREATE SEQUENCE WST_COLUMN_VALUES_ID_SEQ; + +CREATE TABLE wst_column_values ( + id int PRIMARY KEY NOT NULL, + wst_column_id int NOT NULL REFERENCES wst_columns(id), + position NUMERIC NOT NULL, + w NUMERIC NOT NULL, + + UNIQUE (position, wst_column_id), + UNIQUE (position, wst_column_id, w) +); + +-- bind q values to range +CREATE SEQUENCE WST_Q_RANGES_ID_SEQ; + +CREATE TABLE wst_q_ranges ( + id int PRIMARY KEY NOT NULL, + range_id int NOT NULL REFERENCES ranges(id), + q NUMERIC NOT NULL +); + +-- bind q ranges to wst columns +CREATE SEQUENCE WST_COLUMN_Q_RANGES_ID_SEQ; + +CREATE TABLE wst_column_q_ranges ( + id int PRIMARY KEY NOT NULL, + wst_column_id int NOT NULL REFERENCES wst_columns(id), + wst_q_range_id int NOT NULL REFERENCES wst_q_ranges(id), + + UNIQUE (wst_column_id, wst_q_range_id) +); + +COMMIT;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/pom.xml Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,90 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>de.intevation.flys</groupId> + <artifactId>flys-backend</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>flys-backend</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>hibernate3-maven-plugin</artifactId> + <version>2.2</version> + <!-- + <configuration> + <componentProperties> + <propertyfile>src/main/config/hbm.properties</propertyfile> + </componentProperties> + </configuration> + --> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.0.2</version> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>de.intevation.artifacts.common</groupId> + <artifactId>artifacts-common</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>3.8.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <version>3.6.2.Final</version> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-entitymanager</artifactId> + <version>3.6.2.Final</version> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.14</version> + </dependency> + <dependency> + <groupId>commons-dbcp</groupId> + <artifactId>commons-dbcp</artifactId> + <version>1.2.2</version> + </dependency> + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + <version>8.4-702.jdbc4</version> + <scope>runtime</scope> + </dependency> + </dependencies> + + <repositories> + <repository> + <id>repository.jboss.org/nexus</id> + <name>JBoss Repository - Nexus</name> + <url>http://repository.jboss.org/nexus/content/groups/public/</url> + </repository> + </repositories> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/App.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.flys; + +import org.hibernate.cfg.Configuration; + +import de.intevation.flys.model.Annotation; +import de.intevation.flys.model.Attribute; +import de.intevation.flys.model.DischargeTable; +import de.intevation.flys.model.DischargeTableValue; +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.MainValueType; +import de.intevation.flys.model.NamedMainValue; +import de.intevation.flys.model.MainValue; +import de.intevation.flys.model.Position; +import de.intevation.flys.model.Range; +import de.intevation.flys.model.River; +import de.intevation.flys.model.TimeInterval; +import de.intevation.flys.model.WstColumn; +import de.intevation.flys.model.WstColumnQRange; +import de.intevation.flys.model.WstColumnValue; +import de.intevation.flys.model.Wst; +import de.intevation.flys.model.WstQRange; + +import org.hibernate.dialect.resolver.DialectFactory; + +import java.util.Properties; + +import org.hibernate.cfg.Environment; + +public class App +{ + private static final String USER = + System.getProperty("flys.user", "flys"); + + private static final String PASS = + System.getProperty("flys.pass", "flys"); + + public static void dumpSchema(Configuration cfg) { + System.out.println("BEGIN;"); + + String [] setupScript = cfg.generateSchemaCreationScript( + DialectFactory.constructDialect( + "org.hibernate.dialect.PostgreSQLDialect")); + + for (String line: setupScript) { + System.out.println(line + ";"); + } + + System.out.println("COMMIT;"); + } + + public static void main(String [] args) + throws Exception + { + Configuration cfg = new Configuration(); + + cfg.addAnnotatedClass(Annotation.class); + cfg.addAnnotatedClass(Attribute.class); + cfg.addAnnotatedClass(DischargeTable.class); + cfg.addAnnotatedClass(DischargeTableValue.class); + cfg.addAnnotatedClass(Gauge.class); + cfg.addAnnotatedClass(MainValueType.class); + cfg.addAnnotatedClass(NamedMainValue.class); + cfg.addAnnotatedClass(MainValue.class); + cfg.addAnnotatedClass(Position.class); + cfg.addAnnotatedClass(Range.class); + cfg.addAnnotatedClass(River.class); + cfg.addAnnotatedClass(TimeInterval.class); + cfg.addAnnotatedClass(WstColumn.class); + cfg.addAnnotatedClass(WstColumnQRange.class); + cfg.addAnnotatedClass(WstColumnValue.class); + cfg.addAnnotatedClass(Wst.class); + cfg.addAnnotatedClass(WstQRange.class); + Properties props = new Properties(); + + dumpSchema(cfg); + + props.setProperty( + Environment.DIALECT, + "org.hibernate.dialect.PostgreSQLDialect"); + + props.setProperty( + "hibernate.connection.provider_class", + "org.hibernate.connection.DBCPConnectionProvider"); + + props.setProperty( + Environment.USER, + USER); + + props.setProperty( + Environment.PASS, + PASS); + + props.setProperty( + Environment.DRIVER, + "org.postgresql.Driver"); + + props.setProperty( + Environment.URL, + "jdbc:postgresql://localhost:54321/flystest1"); + + cfg.mergeProperties(props); + + /* + + SessionFactory sessionFactory = cfg.buildSessionFactory(); + + Session session = sessionFactory.openSession(); + session.beginTransaction(); + + River river = new River("Hase-" + new java.util.Date()); + + session.save(river); + + System.out.println("river id: " + river.getId()); + + session.getTransaction().commit(); + session.close(); + */ + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/backend/SessionFactoryProvider.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,158 @@ +package de.intevation.flys.backend; + +import de.intevation.artifacts.common.utils.Config; + +import java.util.Properties; + +import org.hibernate.SessionFactory; + +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import de.intevation.flys.model.Annotation; +import de.intevation.flys.model.Attribute; +import de.intevation.flys.model.DischargeTable; +import de.intevation.flys.model.DischargeTableValue; +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.MainValueType; +import de.intevation.flys.model.NamedMainValue; +import de.intevation.flys.model.MainValue; +import de.intevation.flys.model.Position; +import de.intevation.flys.model.Range; +import de.intevation.flys.model.River; +import de.intevation.flys.model.TimeInterval; +import de.intevation.flys.model.WstColumn; +import de.intevation.flys.model.WstColumnQRange; +import de.intevation.flys.model.WstColumnValue; +import de.intevation.flys.model.Wst; +import de.intevation.flys.model.WstQRange; + +import org.apache.log4j.Logger; + +public final class SessionFactoryProvider +{ + private static Logger log = Logger.getLogger(SessionFactoryProvider.class); + + public static final String XPATH_USER = + "/artifact-database/backend-database/user/text()"; + + public static final String XPATH_PASSWORD = + "/artifact-database/backend-database/password/text()"; + + public static final String XPATH_DIALECT = + "/artifact-database/backend-database/dialect/text()"; + + public static final String XPATH_DRIVER = + "/artifact-database/backend-database/driver/text()"; + + public static final String XPATH_URL = + "/artifact-database/backend-database/url/text()"; + + public static final String DEFAULT_USER = + System.getProperty("flys.backend.user", "flys"); + + public static final String DEFAULT_PASSWORD = + System.getProperty("flys.backend.password", "flys"); + + public static final String DEFAULT_DIALECT = + System.getProperty( + "flys.backend.dialect", + "org.hibernate.dialect.PostgreSQLDialect"); + + public static final String DEFAULT_DRIVER = + System.getProperty( + "flys.backend.driver", + "org.postgresql.Driver"); + + public static final String DEFAULT_URL = + System.getProperty( + "flys.backend.url", + "jdbc:postgresql://localhost:5432/flys"); + + private static SessionFactory sessionFactory; + + private SessionFactoryProvider() { + } + + public static synchronized SessionFactory getSessionFactory() { + if (sessionFactory == null) { + String user = + Config.getStringXPath(XPATH_USER, DEFAULT_USER); + String password = + Config.getStringXPath(XPATH_PASSWORD, DEFAULT_PASSWORD); + String dialect = + Config.getStringXPath(XPATH_DIALECT, DEFAULT_DIALECT); + String driver = + Config.getStringXPath(XPATH_DRIVER, DEFAULT_DRIVER); + String url = + Config.getStringXPath(XPATH_URL, DEFAULT_URL); + + sessionFactory = createSessionFactory( + user, password, dialect, driver, url); + } + return sessionFactory; + } + + public static SessionFactory createSessionFactory() { + return createSessionFactory( + DEFAULT_USER, + DEFAULT_PASSWORD, + DEFAULT_DIALECT, + DEFAULT_DRIVER, + DEFAULT_URL); + } + + public static SessionFactory createSessionFactory( + String user, + String password, + String dialect, + String driver, + String url + ) { + Configuration cfg = new Configuration(); + + // TODO: Use package reflection here. + cfg.addAnnotatedClass(Annotation.class); + cfg.addAnnotatedClass(Attribute.class); + cfg.addAnnotatedClass(DischargeTable.class); + cfg.addAnnotatedClass(DischargeTableValue.class); + cfg.addAnnotatedClass(Gauge.class); + cfg.addAnnotatedClass(MainValueType.class); + cfg.addAnnotatedClass(NamedMainValue.class); + cfg.addAnnotatedClass(MainValue.class); + cfg.addAnnotatedClass(Position.class); + cfg.addAnnotatedClass(Range.class); + cfg.addAnnotatedClass(River.class); + cfg.addAnnotatedClass(TimeInterval.class); + cfg.addAnnotatedClass(WstColumn.class); + cfg.addAnnotatedClass(WstColumnQRange.class); + cfg.addAnnotatedClass(WstColumnValue.class); + cfg.addAnnotatedClass(Wst.class); + cfg.addAnnotatedClass(WstQRange.class); + + if (log.isDebugEnabled()) { + log.debug("user: " + user); + log.debug("dialect: " + dialect); + log.debug("driver: " + driver); + log.debug("url: " + url); + } + + Properties props = new Properties(); + + // We rely on our own connection pool + props.setProperty( + "hibernate.connection.provider_class", + "org.hibernate.connection.DBCPConnectionProvider"); + + props.setProperty(Environment.DIALECT, dialect); + props.setProperty(Environment.USER, user); + props.setProperty(Environment.PASS, password); + props.setProperty(Environment.DRIVER, driver); + props.setProperty(Environment.URL, url); + + cfg.mergeProperties(props); + + return cfg.buildSessionFactory(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/AnnotationsParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,138 @@ +package de.intevation.flys.importer; + +import java.util.HashMap; +import java.util.TreeSet; +import java.util.List; +import java.util.ArrayList; + +import java.io.IOException; +import java.io.File; +import java.io.LineNumberReader; +import java.io.InputStreamReader; +import java.io.FileInputStream; + +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + +import de.intevation.flys.utils.FileTools; + +public class AnnotationsParser +{ + private static Logger log = Logger.getLogger(AnnotationsParser.class); + + public static final String ENCODING = "ISO-8859-1"; + + public static final String [] TO_SCAN = { + "Basisdaten", + "Streckendaten" + }; + + protected HashMap<String, ImportAttribute> attributes; + protected HashMap<String, ImportPosition> positions; + protected TreeSet<ImportAnnotation> annotations; + + public AnnotationsParser() { + attributes = new HashMap<String, ImportAttribute>(); + positions = new HashMap<String, ImportPosition>(); + annotations = new TreeSet<ImportAnnotation>(); + } + + public void parseFile(File file) throws IOException { + log.info("parsing km file: '" + file + "'"); + LineNumberReader in = null; + try { + in = + new LineNumberReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + String line = null; + while ((line = in.readLine()) != null) { + if ((line = line.trim()).length() == 0 + || line.startsWith("*")) { + continue; + } + + String [] parts = line.split("\\s*;\\s*"); + + if (parts.length < 3) { + log.warn("not enough columns in line " + + in.getLineNumber()); + continue; + } + + ImportPosition position = positions.get(parts[0]); + if (position == null) { + position = new ImportPosition(parts[0]); + positions.put(parts[0], position); + } + + ImportAttribute attribute = attributes.get(parts[1]); + if (attribute == null) { + attribute = new ImportAttribute(parts[1]); + attributes.put(parts[1], attribute); + } + + String [] r = parts[2].replace(",", ".").split("\\s*#\\s*"); + + BigDecimal from, to; + + try { + from = new BigDecimal(r[0]); + to = r.length < 2 ? null : new BigDecimal(r[1]); + if (to != null && from.compareTo(to) > 0) { + BigDecimal t = from; from = to; to = t; + } + } + catch (NumberFormatException nfe) { + log.warn("invalid number in line " + in.getLineNumber()); + continue; + } + + ImportRange range = new ImportRange(from, to); + + ImportAnnotation annotation = new ImportAnnotation( + attribute, position, range); + + if (!annotations.add(annotation)) { + log.debug("duplicated annotation in line " + + in.getLineNumber()); + } + } + } + finally { + if (in != null) { + in.close(); + } + } + } + + public void parse(File root) throws IOException { + + for (String toScan: TO_SCAN) { + File directory = FileTools.repair(new File(root, toScan)); + if (!directory.isDirectory()) { + log.warn("'" + directory + "' is not a directory."); + continue; + } + File [] files = directory.listFiles(); + if (files == null) { + log.warn("cannot list directory '" + directory + "'"); + continue; + } + + for (File file: files) { + if (file.isFile() && file.canRead() + && file.getName().toLowerCase().endsWith(".km")) { + parseFile(file); + } + } + } // for all directories to scan + } + + public List<ImportAnnotation> getAnnotations() { + return new ArrayList<ImportAnnotation>(annotations); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/AtFileParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,117 @@ +package de.intevation.flys.importer; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.math.BigDecimal; +import java.text.NumberFormat; +import java.text.ParseException; + +import org.apache.log4j.Logger; + +import de.intevation.flys.importer.ImportDischargeTable; +import de.intevation.flys.importer.ImportDischargeTableValue; + + +public class AtFileParser { + + public static final String ENCODING = "ISO-8859-1"; + + private static Logger logger = Logger.getLogger(AtFileParser.class); + + private static NumberFormat nf = NumberFormat.getInstance(); + + + public AtFileParser() { + } + + + public ImportDischargeTable parse(ImportGauge gauge) throws IOException { + + File file = gauge.getAtFile(); + + logger.info("parsing AT file: " + file); + + BufferedReader br = null; + + String line = null; + + boolean beginning = true; + + ImportDischargeTable dischargeTable = new ImportDischargeTable(); + + try { + br = new BufferedReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + while ((line = br.readLine()) != null) { + String tmp = line.trim(); + + if (tmp.length() == 0) { + continue; + } + + if (tmp.startsWith("#! name=")) { + // XXX Skip the name, because we don't know where to save + // it at the moment + + //String name = tmp.substring(8); + continue; + } + + if (tmp.startsWith("#") || tmp.startsWith("*")) { + continue; + } + + String[] splits = tmp.replace(',', '.').split("\\s+"); + + if ((splits.length < 2) || (splits.length > 11)) { + logger.warn("Found an invalid row in the AT file."); + continue; + } + + String strW = splits[0].trim(); + double W = nf.parse(strW).doubleValue(); + + /* shift is used to differenciate between lines with + * exactly 10 Qs and lines with less than 10 Qs. The shift + * is only modified when it is the first line. + */ + int shift = 0; + + if (splits.length != 11 && beginning) { + shift = 11 - splits.length; + } + + + for (int i = 1; i < splits.length; i++) { + double iW = W + shift + i; + double iQ = nf.parse(splits[i].trim()).doubleValue(); + + dischargeTable.addDischargeTableValue( + new ImportDischargeTableValue( + new BigDecimal(iQ/100.0), + new BigDecimal(iW/100.0))); + } + + beginning = false; + } + } + catch (ParseException pe) { + logger.warn(pe.getMessage()); + } + finally { + if (br != null) { + br.close(); + } + } + + logger.info("Finished parsing AT file: " + file); + + return dischargeTable; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportAnnotation.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,101 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Annotation; +import de.intevation.flys.model.Range; +import de.intevation.flys.model.Position; +import de.intevation.flys.model.Attribute; +import de.intevation.flys.model.River; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportAnnotation +implements Comparable<ImportAnnotation> +{ + protected ImportAttribute attribute; + protected ImportPosition position; + protected ImportRange range; + + protected Annotation peer; + + public ImportAnnotation() { + } + + public ImportAnnotation( + ImportAttribute attribute, + ImportPosition position, + ImportRange range + ) { + this.attribute = attribute; + this.position = position; + this.range = range; + } + + public int compareTo(ImportAnnotation other) { + int d = attribute.compareTo(other.attribute); + if (d != 0) { + return d; + } + + if ((d = position.compareTo(other.position)) != 0) { + return d; + } + + if ((d = range.compareTo(other.range)) != 0) { + return d; + } + + return 0; + } + + public ImportAttribute getAttribute() { + return attribute; + } + + public void setAttribute(ImportAttribute attribute) { + this.attribute = attribute; + } + + public ImportPosition getPosition() { + return position; + } + + public void setPosition(ImportPosition position) { + this.position = position; + } + + public ImportRange getRange() { + return range; + } + + public void setRange(ImportRange range) { + this.range = range; + } + + public Annotation getPeer(River river) { + if (peer == null) { + Range r = range.getPeer(river); + Attribute a = attribute.getPeer(); + Position p = position.getPeer(); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from Annotation where " + + "range=:range and attribute=:attribute and position=:position"); + query.setParameter("range", r); + query.setParameter("attribute", a); + query.setParameter("position", p); + List<Annotation> annotations = query.list(); + if (annotations.isEmpty()) { + peer = new Annotation(r, a, p); + session.save(peer); + } + else { + peer = annotations.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportAttribute.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Attribute; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportAttribute +implements Comparable<ImportAttribute> +{ + protected String value; + + protected Attribute peer; + + public ImportAttribute() { + } + + public ImportAttribute(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int compareTo(ImportAttribute other) { + return value.compareTo(other.value); + } + + @Override + public boolean equals(Object other) { + if (other == this) return true; + if (!(other instanceof ImportAttribute)) return false; + return value.equals(((ImportAttribute)other).value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + public Attribute getPeer() { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery("from Attribute where value=:value"); + query.setString("value", value); + List<Attribute> attributes = query.list(); + if (attributes.isEmpty()) { + peer = new Attribute(value); + session.save(peer); + } + else { + peer = attributes.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportDischargeTable.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,75 @@ +package de.intevation.flys.importer; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.Query; + +import de.intevation.flys.model.DischargeTable; +import de.intevation.flys.model.Gauge; + + +public class ImportDischargeTable +{ + protected DischargeTable peer; + + protected List<ImportDischargeTableValue> dischargeTableValues; + + + public ImportDischargeTable() { + dischargeTableValues = new ArrayList<ImportDischargeTableValue>(); + } + + + public void addDischargeTableValue(ImportDischargeTableValue value) { + dischargeTableValues.add(value); + } + + + public void setDischargeTableValues(List<ImportDischargeTableValue> values){ + this.dischargeTableValues = values; + } + + + public List<ImportDischargeTableValue> getDischargeTableValues() { + return dischargeTableValues; + } + + + public DischargeTable getPeer(Gauge gauge) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + + Query query = session.createQuery( + "from DischargeTable where gauge.id=:gauge"); + query.setParameter("gauge", gauge.getId()); + + List<DischargeTable> dischargeTables = query.list(); + if (dischargeTables.isEmpty()) { + peer = new DischargeTable(gauge); + session.save(peer); + } + else { + peer = dischargeTables.get(0); + } + } + + return peer; + } + + + public void storeDependencies(Gauge gauge) { + storeDischargeTableValues(gauge); + } + + + public void storeDischargeTableValues(Gauge gauge) { + DischargeTable dischargeTable = getPeer(gauge); + + for (ImportDischargeTableValue value: dischargeTableValues) { + value.getPeer(dischargeTable); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,59 @@ +package de.intevation.flys.importer; + +import java.math.BigDecimal; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.Query; + +import de.intevation.flys.model.DischargeTable; +import de.intevation.flys.model.DischargeTableValue; + + +public class ImportDischargeTableValue +{ + private Integer id; + + private BigDecimal q; + private BigDecimal w; + + private ImportDischargeTable dischargeTable; + + private DischargeTableValue peer; + + + public ImportDischargeTableValue() { + } + + + public ImportDischargeTableValue(BigDecimal q, BigDecimal w) { + this.dischargeTable = dischargeTable; + this.q = q; + this.w = w; + } + + + public DischargeTableValue getPeer(DischargeTable dischargeTable) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + + Query query = session.createQuery( + "from DischargeTableValue where " + + "dischargeTable.id=:tableId and q=:q and w=:w"); + query.setParameter("tableId", dischargeTable.getId()); + query.setParameter("q", q); + query.setParameter("w", w); + + List<DischargeTableValue> dischargeTableValues = query.list(); + if (dischargeTableValues.isEmpty()) { + peer = new DischargeTableValue(dischargeTable, q, w); + session.save(peer); + } + else { + peer = dischargeTableValues.get(0); + } + } + + return peer; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportGauge.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,186 @@ +package de.intevation.flys.importer; + +import java.io.File; + +import java.util.List; + +import java.math.BigDecimal; + +import de.intevation.flys.model.River; +import de.intevation.flys.model.Gauge; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.io.IOException; + +public class ImportGauge +{ + protected ImportRange range; + + protected File staFile; + protected File atFile; + + protected String name; + protected BigDecimal aeo; + protected BigDecimal datum; + protected BigDecimal station; + + protected Gauge peer; + + protected ImportDischargeTable dischargeTable; + + protected List<ImportMainValueType> mainValueTypes; + protected List<ImportNamedMainValue> namedMainValues; + protected List<ImportMainValue> mainValues; + + public ImportGauge() { + } + + public ImportGauge(ImportRange range, File staFile, File atFile) { + this.range = range; + this.staFile = staFile; + this.atFile = atFile; + } + + public void setRange(ImportRange range) { + this.range = range; + } + + public void setStaFile(File staFile) { + this.staFile = staFile; + } + + public File getStaFile() { + return staFile; + } + + public void setAtFile(File atFile) { + this.atFile = atFile; + } + + public File getAtFile() { + return atFile; + } + + public BigDecimal getAeo() { + return aeo; + } + + public void setAeo(BigDecimal aeo) { + this.aeo = aeo; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getDatum() { + return datum; + } + + public void setDatum(BigDecimal datum) { + this.datum = datum; + } + + public BigDecimal getStation() { + return station; + } + + public void setStation(BigDecimal station) { + this.station = station; + } + + public ImportDischargeTable getDischargeTable() { + return dischargeTable; + } + + public void setDischargeTable(ImportDischargeTable dischargeTable) { + this.dischargeTable = dischargeTable; + } + + public List<ImportMainValueType> getMainValueTypes() { + return mainValueTypes; + } + + public void setMainValueTypes(List<ImportMainValueType> mainValueTypes) { + this.mainValueTypes = mainValueTypes; + } + + public List<ImportNamedMainValue> getNamedMainValues() { + return namedMainValues; + } + + public void setNamedMainValues(List<ImportNamedMainValue> namedMainValues) { + this.namedMainValues = namedMainValues; + } + + public List<ImportMainValue> getMainValues() { + return mainValues; + } + + public void setMainValues(List<ImportMainValue> mainValues) { + this.mainValues = mainValues; + } + + public void parseDependencies() throws IOException { + StaFileParser sfp = new StaFileParser(); + sfp.parse(this); + + AtFileParser afp = new AtFileParser(); + setDischargeTable(afp.parse(this)); + } + + public void storeDependencies(River river) { + + Gauge gauge = getPeer(river); + + for (ImportMainValueType mainValueType: mainValueTypes) { + mainValueType.getPeer(); + } + + for (ImportNamedMainValue namedMainValue: namedMainValues) { + namedMainValue.getPeer(); + } + + for (ImportMainValue mainValue: mainValues) { + mainValue.getPeer(river); + } + + storeDischargeTable(gauge); + } + + + public void storeDischargeTable(Gauge gauge) { + dischargeTable.getPeer(gauge); + dischargeTable.storeDependencies(gauge); + } + + public Gauge getPeer(River river) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from Gauge where name=:name " + + "and river.id=:river"); + query.setString("name", name); + query.setParameter("river", river.getId()); + List<Gauge> gauges = query.list(); + if (gauges.isEmpty()) { + peer = new Gauge( + name, river, + station, aeo, datum, + range.getPeer(river)); + session.save(peer); + } + else { + peer = gauges.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportMainValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,83 @@ +package de.intevation.flys.importer; + +import java.util.List; + +import java.math.BigDecimal; + +import de.intevation.flys.model.MainValue; +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.River; +import de.intevation.flys.model.NamedMainValue; + +import org.hibernate.Session; +import org.hibernate.Query; + +public class ImportMainValue +{ + protected ImportGauge gauge; + protected ImportNamedMainValue mainValue; + protected BigDecimal value; + + protected MainValue peer; + + public ImportMainValue() { + } + + public ImportMainValue( + ImportGauge gauge, + ImportNamedMainValue mainValue, + BigDecimal value + ) { + this.gauge = gauge; + this.mainValue = mainValue; + this.value = value; + } + + public ImportGauge getGauge() { + return gauge; + } + + public void setGauge(ImportGauge gauge) { + this.gauge = gauge; + } + + public ImportNamedMainValue getMainValue() { + return mainValue; + } + + public void setMainValue(ImportNamedMainValue mainValue) { + this.mainValue = mainValue; + } + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + public MainValue getPeer(River river) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery("from MainValue where " + + "gauge.id=:gauge_id and mainValue.id=:name_id " + + "and value=:value"); + Gauge g = gauge.getPeer(river); + NamedMainValue n = mainValue.getPeer(); + query.setParameter("gauge_id", g.getId()); + query.setParameter("name_id", n.getId()); + query.setParameter("value", value); + List<MainValue> values = query.list(); + if (values.isEmpty()) { + peer = new MainValue(g, n, value, null); + session.save(peer); + } + else { + peer = values.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportMainValueType.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.MainValueType; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportMainValueType +implements Comparable<ImportMainValueType> +{ + protected String name; + + protected MainValueType peer; + + public ImportMainValueType() { + } + + public ImportMainValueType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int compareTo(ImportMainValueType other) { + return name.compareTo(other.name); + } + + @Override + public boolean equals(Object other) { + if (other == this) return true; + if (!(other instanceof ImportMainValueType)) return false; + return name.equals(((ImportMainValueType)other).name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + public MainValueType getPeer() { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery("from MainValueType where name=:name"); + query.setString("name", name); + List<MainValueType> values = query.list(); + if (values.isEmpty()) { + peer = new MainValueType(name); + session.save(peer); + } + else { + peer = values.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportNamedMainValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,66 @@ +package de.intevation.flys.importer; + +import java.util.List; + +import de.intevation.flys.model.NamedMainValue; +import de.intevation.flys.model.MainValueType; + +import org.hibernate.Session; +import org.hibernate.Query; + +public class ImportNamedMainValue +{ + protected ImportMainValueType mainValueType; + protected String name; + + protected NamedMainValue peer; + + public ImportNamedMainValue() { + } + + public ImportNamedMainValue( + ImportMainValueType mainValueType, + String name + ) { + this.mainValueType = mainValueType; + this.name = name; + } + + public ImportMainValueType getMainValueType() { + return mainValueType; + } + + public void setMainValueType(ImportMainValueType mainValueType) { + this.mainValueType = mainValueType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public NamedMainValue getPeer() { + if (peer == null) { + MainValueType type = mainValueType.getPeer(); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from NamedMainValue where " + + "name=:name and type.id=:id"); + query.setString("name", name); + query.setParameter("id", type.getId()); + List<NamedMainValue> named = query.list(); + if (named.isEmpty()) { + peer = new NamedMainValue(name, type); + session.save(peer); + } + else { + peer = named.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportPosition.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Position; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportPosition +implements Comparable<ImportPosition> +{ + protected String value; + + protected Position peer; + + public ImportPosition() { + } + + public ImportPosition(String value) { + this.value = value; + } + + public int compareTo(ImportPosition other) { + return value.compareTo(other.value); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Position getPeer() { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery("from Position where value=:value"); + query.setString("value", value); + List<Position> positions = query.list(); + if (positions.isEmpty()) { + peer = new Position(value); + session.save(peer); + } + else { + peer = positions.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportRange.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,89 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Range; +import de.intevation.flys.model.River; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + +public class ImportRange +implements Comparable<ImportRange> +{ + private static Logger log = Logger.getLogger(ImportRange.class); + + protected BigDecimal a; + protected BigDecimal b; + + protected Range peer; + + public ImportRange() { + } + + public ImportRange(BigDecimal a, BigDecimal b) { + this.a = a; + this.b = b; + } + + private static final int compare(BigDecimal a, BigDecimal b) { + if (a == null && b == null) { + return 0; + } + if (a == null && b != null) { + return -1; + } + if (a != null && b == null) { + return +1; + } + return a.compareTo(b); + } + + public int compareTo(ImportRange other) { + int cmp = compare(a, other.a); + if (cmp != 0) return cmp; + return compare(b, other.b); + } + + public BigDecimal getA() { + return a; + } + + public void setA(BigDecimal a) { + this.a = a; + } + + public BigDecimal getB() { + return b; + } + + public void setB(BigDecimal b) { + this.b = b; + } + + public Range getPeer(River river) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from Range where a=:a and b=:b and river=:river"); + query.setParameter("a", a); + query.setParameter("b", b); + query.setParameter("river", river); + log.debug("a: " + a + " b: " + b + " river.id: " + river.getId()); + List<Range> ranges = query.list(); + if (ranges.isEmpty()) { + peer = new Range(a, b, river); + session.save(peer); + } + else { + peer = ranges.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,161 @@ +package de.intevation.flys.importer; + +import java.util.List; + +import java.io.File; +import java.io.IOException; + +import org.apache.log4j.Logger; + +import de.intevation.flys.model.River; + +import de.intevation.flys.utils.FileTools; + +import org.hibernate.Session; +import org.hibernate.Query; + +public class ImportRiver +{ + private static Logger log = Logger.getLogger(ImportRiver.class); + + public static final String PEGEL_GLT = "PEGEL.GLT"; + + protected String name; + + protected File wstFile; + + protected File bbInfoFile; + + protected List<ImportGauge> gauges; + + protected List<ImportAnnotation> annotations; + + protected ImportWst wst; + + protected River peer; + + public ImportRiver() { + } + + public ImportRiver(String name, File wstFile, File bbInfoFile) { + this.name = name; + this.wstFile = wstFile; + this.bbInfoFile = bbInfoFile; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public File getWstFile() { + return wstFile; + } + + public void setWstFile(File wstFile) { + this.wstFile = wstFile; + } + + public File getBBInfo() { + return bbInfoFile; + } + + public void setBBInfo(File bbInfoFile) { + this.bbInfoFile = bbInfoFile; + } + + public ImportWst getWst() { + return wst; + } + + public void setWst(ImportWst wst) { + this.wst = wst; + } + + public void parseDependencies() throws IOException { + parseGauges(); + parseAnnotations(); + parseWst(); + } + + public void parseWst() throws IOException { + WstParser wstParser = new WstParser(); + wstParser.parse(wstFile); + wst = wstParser.getWst(); + } + + public void parseGauges() throws IOException { + File gltFile = new File(wstFile.getParentFile(), PEGEL_GLT); + gltFile = FileTools.repair(gltFile); + + if (!gltFile.isFile() || !gltFile.canRead()) { + log.warn("cannot read gauges from '" + gltFile + "'"); + return; + } + + PegelGltParser pgltp = new PegelGltParser(); + pgltp.parse(gltFile); + + gauges = pgltp.getGauges(); + + for (ImportGauge gauge: gauges) { + gauge.parseDependencies(); + } + } + + public void parseAnnotations() throws IOException { + File riverDir = wstFile.getParentFile().getParentFile(); + AnnotationsParser aparser = new AnnotationsParser(); + aparser.parse(riverDir); + + annotations = aparser.getAnnotations(); + } + + public void storeDependencies() { + storeAnnotations(); + storeGauges(); + storeWst(); + } + + public void storeWst() { + River river = getPeer(); + wst.storeDependencies(river); + } + + public void storeAnnotations() { + River river = getPeer(); + for (ImportAnnotation annotation: annotations) { + annotation.getPeer(river); + } + } + + public void storeGauges() { + log.info("store gauges:"); + River river = getPeer(); + for (ImportGauge gauge: gauges) { + log.info("\tgauge: " + gauge.getName()); + gauge.storeDependencies(river); + } + } + + public River getPeer() { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery("from River where name=:name"); + query.setString("name", name); + List<River> rivers = query.list(); + if (rivers.isEmpty()) { + peer = new River(name); + session.save(peer); + } + else { + peer = rivers.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWst.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,76 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Wst; +import de.intevation.flys.model.River; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +public class ImportWst +{ + protected String description; + + protected Map<String, ImportWstColumn> columns; + + protected Wst peer; + + public ImportWst() { + columns = new HashMap<String, ImportWstColumn>(); + } + + public ImportWst(String description) { + this(); + this.description = description; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ImportWstColumn getColumn(String name) { + ImportWstColumn column = columns.get(name); + if (column == null) { + column = new ImportWstColumn(this, name, null); + columns.put(name, column); + } + return column; + } + + public void storeDependencies(River river) { + Wst wst = getPeer(river); + + for (ImportWstColumn column: columns.values()) { + column.storeDependencies(river); + } + } + + public Wst getPeer(River river) { + if (peer == null) { + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from Wst where " + + "river=:river and description=:description"); + query.setParameter("river", river); + query.setParameter("description", description); + List<Wst> wsts = query.list(); + if (wsts.isEmpty()) { + peer = new Wst(river, description); + session.save(peer); + } + else { + peer = wsts.get(0); + } + + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,108 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.Wst; +import de.intevation.flys.model.WstColumn; +import de.intevation.flys.model.River; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; +import java.util.ArrayList; + +import java.math.BigDecimal; + +public class ImportWstColumn +{ + protected ImportWst wst; + protected String name; + protected String description; + + protected List<ImportWstColumnQRange> columnQRanges; + protected List<ImportWstColumnValue> columnValues; + + protected WstColumn peer; + + public ImportWstColumn() { + columnQRanges = new ArrayList<ImportWstColumnQRange>(); + columnValues = new ArrayList<ImportWstColumnValue>(); + } + + public ImportWstColumn( + ImportWst wst, + String name, + String description + ) { + this(); + this.wst = wst; + this.name = name; + this.description = description; + } + + public ImportWst getWst() { + return wst; + } + + public void setWst(ImportWst wst) { + this.wst = wst; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public void addColumnValue(BigDecimal position, BigDecimal w) { + columnValues.add( + new ImportWstColumnValue(this, position, w)); + } + + public void addColumnQRange(ImportWstQRange columnQRange) { + columnQRanges.add( + new ImportWstColumnQRange(this, columnQRange)); + } + + public void storeDependencies(River river) { + WstColumn column = getPeer(river); + for (ImportWstColumnQRange columnQRange: columnQRanges) { + columnQRange.getPeer(river); + } + for (ImportWstColumnValue columnValue: columnValues) { + columnValue.getPeer(river); + } + } + + public WstColumn getPeer(River river) { + if (peer == null) { + Wst w = wst.getPeer(river); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from WstColumn where " + + "wst=:wst and name=:name and description=:description"); + query.setParameter("wst", w); + query.setParameter("name", name); + query.setParameter("description", description); + List<WstColumn> columns = query.list(); + if (columns.isEmpty()) { + peer = new WstColumn(w, name, description, null); + session.save(peer); + } + else { + peer = columns.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumnQRange.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,69 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.WstColumnQRange; +import de.intevation.flys.model.WstQRange; +import de.intevation.flys.model.WstColumn; +import de.intevation.flys.model.River; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportWstColumnQRange +{ + protected ImportWstColumn wstColumn; + protected ImportWstQRange qRange; + + protected WstColumnQRange peer; + + public ImportWstColumnQRange() { + } + + public ImportWstColumnQRange( + ImportWstColumn wstColumn, + ImportWstQRange qRange + ) { + this.wstColumn = wstColumn; + this.qRange = qRange; + } + + public ImportWstColumn getWstColumn() { + return wstColumn; + } + + public void setWstColumn(ImportWstColumn wstColumn) { + this.wstColumn = wstColumn; + } + + public ImportWstQRange getQRange() { + return qRange; + } + + public void setQRange(ImportWstQRange qRange) { + this.qRange = qRange; + } + + public WstColumnQRange getPeer(River river) { + if (peer == null) { + WstColumn c = wstColumn.getPeer(river); + WstQRange q = qRange.getPeer(river); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from WstColumnQRange where " + + "wstColumn=:c and wstQRange=:q"); + query.setParameter("c", c); + query.setParameter("q", q); + List<WstColumnQRange> cols = query.list(); + if (cols.isEmpty()) { + peer = new WstColumnQRange(c, q); + session.save(peer); + } + else { + peer = cols.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,81 @@ +package de.intevation.flys.importer; + +import de.intevation.flys.model.WstColumnValue; +import de.intevation.flys.model.WstColumn; +import de.intevation.flys.model.River; + +import java.math.BigDecimal; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportWstColumnValue +{ + protected BigDecimal position; + protected BigDecimal w; + protected ImportWstColumn wstColumn; + + protected WstColumnValue peer; + + public ImportWstColumnValue() { + } + + public ImportWstColumnValue( + ImportWstColumn wstColumn, + BigDecimal position, + BigDecimal w + ) { + this.wstColumn = wstColumn; + this.position = position; + this.w = w; + } + + public BigDecimal getPosition() { + return position; + } + + public void setPosition(BigDecimal position) { + this.position = position; + } + + public BigDecimal getW() { + return w; + } + + public void setW(BigDecimal w) { + this.w = w; + } + + public ImportWstColumn getWstColumn() { + return wstColumn; + } + + public void setWstColumn(ImportWstColumn wstColumn) { + this.wstColumn = wstColumn; + } + + public WstColumnValue getPeer(River river) { + if (peer == null) { + WstColumn c = wstColumn.getPeer(river); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from WstColumnValue where " + + "wstColumn=:c and position=:p and w=:w"); + query.setParameter("c", c); + query.setParameter("p", position); + query.setParameter("w", w); + List<WstColumnValue> values = query.list(); + if (values.isEmpty()) { + peer = new WstColumnValue(c, position, w); + session.save(peer); + } + else { + peer = values.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstQRange.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,69 @@ +package de.intevation.flys.importer; + +import java.math.BigDecimal; + +import de.intevation.flys.model.WstQRange; +import de.intevation.flys.model.River; +import de.intevation.flys.model.Range; + +import org.hibernate.Session; +import org.hibernate.Query; + +import java.util.List; + +public class ImportWstQRange +{ + protected ImportRange range; + protected BigDecimal q; + + protected WstQRange peer; + + public ImportWstQRange() { + } + + public ImportWstQRange( + ImportRange range, + BigDecimal q + ) { + this.range = range; + this.q = q; + } + + public ImportRange getRange() { + return range; + } + + public void setRange(ImportRange range) { + this.range = range; + } + + public BigDecimal getQ() { + return q; + } + + public void setQ(BigDecimal q) { + this.q = q; + } + + public WstQRange getPeer(River river) { + if (peer == null) { + Range r = range.getPeer(river); + Session session = Importer.sessionHolder.get(); + Query query = session.createQuery( + "from WstQRange where " + + "range=:range and q=:q"); + query.setParameter("range", r); + query.setParameter("q", q); + List<WstQRange> wstQRanges = query.list(); + if (wstQRanges.isEmpty()) { + peer = new WstQRange(r, q); + session.save(peer); + } + else { + peer = wstQRanges.get(0); + } + } + return peer; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/Importer.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,119 @@ +package de.intevation.flys.importer; + +import java.io.File; +import java.io.IOException; + +import java.util.List; + +import java.sql.SQLException; + +import org.apache.log4j.Logger; + +import org.hibernate.SessionFactory; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.HibernateException; + +import de.intevation.flys.backend.SessionFactoryProvider; + +public class Importer +{ + private static Logger log = Logger.getLogger(Importer.class); + + public static final boolean DRY_RUN = + Boolean.getBoolean("flys.backend.importer.dry.run"); + + public static final ThreadLocal<Session> sessionHolder = + new ThreadLocal<Session>(); + + protected List<ImportRiver> rivers; + + public Importer() { + } + + public Importer(List<ImportRiver> rivers) { + this.rivers = rivers; + } + + public List<ImportRiver> getRivers() { + return rivers; + } + + public void setRivers(List<ImportRiver> rivers) { + this.rivers = rivers; + } + + public void writeRivers() { + log.debug("write rivers started"); + + Session session = sessionHolder.get(); + + for (ImportRiver river: rivers) { + log.debug("writing river '" + river.getName() + "'"); + river.storeDependencies(); + session.flush(); + } + + log.debug("write rivers finished"); + } + + public void writeToDatabase() { + SessionFactory sessionFactory = + SessionFactoryProvider.createSessionFactory(); + + Session session = sessionFactory.openSession(); + + sessionHolder.set(session); + + Transaction tx = null; + + try { + tx = session.beginTransaction(); + + try { + writeRivers(); + } + catch (HibernateException he) { + Throwable t = he.getCause(); + while (t instanceof SQLException) { + SQLException sqle = (SQLException)t; + log.error("SQL exeception chain:", sqle); + t = sqle.getNextException(); + } + throw he; + } + + tx.commit(); + } + catch (RuntimeException re) { + if (tx != null) { + tx.rollback(); + } + throw re; + } + finally { + session.close(); + sessionHolder.remove(); + } + } + + public static void main(String [] args) { + + InfoGewParser infoGewParser = new InfoGewParser(); + + for (String gew: args) { + log.info("parsing info gew file: " + gew); + try { + infoGewParser.parse(new File(gew)); + } + catch (IOException ioe) { + log.error("cannot while parsing: " + gew); + } + } + + if (!DRY_RUN) { + new Importer(infoGewParser.getRivers()).writeToDatabase(); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/InfoGewParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,119 @@ +package de.intevation.flys.importer; + +import java.io.File; + +import java.util.List; +import java.util.ArrayList; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +import org.apache.log4j.Logger; + +import de.intevation.flys.utils.FileTools; + +public class InfoGewParser +{ + private static Logger log = Logger.getLogger(InfoGewParser.class); + + public static final String ENCODING = "ISO-8859-1"; + + public static final Pattern GEWAESSER = + Pattern.compile("^\\s*Gew\u00e4sser\\s*:\\s*(.+)"); + + public static final Pattern WST_DATEI = + Pattern.compile("^\\s*WSTDatei\\s*:\\s*(.+)"); + + public static final Pattern BB_INFO = + Pattern.compile("^\\s*B\\+B-Info\\s*:\\s*(.+)"); + + protected ArrayList<ImportRiver> rivers; + + public InfoGewParser() { + rivers = new ArrayList<ImportRiver>(); + } + + public List<ImportRiver> getRivers() { + return rivers; + } + + public static final String normalize(String f) { + return f.replace("\\", "/").replace("/", File.separator); + } + + public void parse(File file) throws IOException { + + LineNumberReader in = null; + + File root = file.getParentFile(); + + ImportRiver importRiver = new ImportRiver(); + try { + in = + new LineNumberReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + String line = null; + + String riverName = null; + File wstFile = null; + File bbInfoFile = null; + + while ((line = in.readLine()) != null) { + if ((line = line.trim()).length() == 0) { + continue; + } + Matcher m = GEWAESSER.matcher(line); + + if (m.matches()) { + String river = m.group(1); + log.info("Found river '" + river + "'"); + if (riverName != null) { + rivers.add(new ImportRiver(riverName, wstFile, bbInfoFile)); + } + riverName = river; + wstFile = null; + bbInfoFile = null; + } + else if ((m = WST_DATEI.matcher(line)).matches()) { + String wstFilename = m.group(1); + File wst = new File(wstFilename = normalize(wstFilename)); + if (!wst.isAbsolute()) { + wst = new File(root, wstFilename); + } + wst = FileTools.repair(wst); + log.info("Found wst file '" + wst + "'"); + if (!wst.isFile() || !wst.canRead()) { + log.warn("cannot access WST file '" + wstFilename + "'"); + continue; + } + wstFile = wst; + } + else if ((m = BB_INFO.matcher(line)).matches()) { + //TODO: Make it relative to the wst file. + String bbInfo = m.group(1); + bbInfoFile = new File(normalize(bbInfo)); + } + } + if (riverName != null) { + rivers.add(new ImportRiver(riverName, wstFile, bbInfoFile)); + } + } + finally { + if (in != null) { + in.close(); + } + } + + for (ImportRiver river: rivers) { + river.parseDependencies(); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/PegelGltParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,99 @@ +package de.intevation.flys.importer; + +import java.io.File; + +import java.util.List; +import java.util.ArrayList; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + +import de.intevation.flys.utils.FileTools; + +public class PegelGltParser +{ + private static Logger log = Logger.getLogger(PegelGltParser.class); + + public static final String ENCODING = "ISO-8859-1"; + + public static final String KM = "km:"; + + protected List<ImportGauge> gauges; + + public PegelGltParser() { + gauges = new ArrayList<ImportGauge>(); + } + + public List<ImportGauge> getGauges() { + return gauges; + } + + public void parse(File file) throws IOException { + + File parent = file.getParentFile(); + + log.info("parsing GLT file '" + file + "'"); + LineNumberReader in = null; + try { + in = + new LineNumberReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + String line = null; + while ((line = in.readLine()) != null) { + if ((line = line.trim()).length() == 0) { + continue; + } + + int kmPos = line.indexOf(KM); + if (kmPos < 0) { + log.warn("no gauge found in line " + in.getLineNumber()); + continue; + } + + String gaugeName = line.substring(0, kmPos).trim(); + log.info("Found gauge '" + gaugeName + "'"); + + line = line.substring(kmPos + KM.length()).trim(); + + String [] parts = line.split("\\s+"); + if (parts.length < 4) { + log.warn("line " + in.getLineNumber() + + " has not enough columns"); + continue; + } + + BigDecimal from = new BigDecimal(parts[0].replace(",", ".")); + BigDecimal to = new BigDecimal(parts[1].replace(",", ".")); + if (from.compareTo(from) > 0) { + BigDecimal t = from; from = to; to = t; + } + ImportRange range = new ImportRange(from, to); + File staFile = FileTools.repair(new File(parent, parts[2])); + File atFile = FileTools.repair(new File(parent, parts[3])); + + if (log.isDebugEnabled()) { + log.debug("\tfrom: " + from); + log.debug("\tto: " + to); + log.debug("\tsta: " + staFile); + log.debug("\tat: " + atFile); + } + + gauges.add(new ImportGauge(range, staFile, atFile)); + } + } + finally { + if (in != null) { + in.close(); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/StaFileParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,156 @@ +package de.intevation.flys.importer; + +import java.io.File; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +import java.math.BigDecimal; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import java.util.HashMap; +import java.util.ArrayList; + +import org.apache.log4j.Logger; + +public class StaFileParser +{ + private static Logger log = Logger.getLogger(StaFileParser.class); + + public static final String ENCODING = "ISO-8859-1"; + + public static final Pattern QWTD_ = + Pattern.compile("\\s*([^\\s]+)\\s+([^\\s]+)\\s+([QWTD-]).*"); + + public StaFileParser() { + } + + public boolean parse(ImportGauge gauge) throws IOException { + + File file = gauge.getStaFile(); + + log.info("parsing STA file: " + file); + LineNumberReader in = null; + try { + in = + new LineNumberReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + String line = in.readLine(); + + if (line == null) { + log.warn("STA file is empty."); + return false; + } + + if (line.length() < 37) { + log.warn("first line in STA file is too short."); + return false; + } + + gauge.setName(line.substring(16, 37).trim()); + + String [] values = line.substring(38).trim().split("\\s+", 2); + + if (values.length < 2) { + log.warn("Not enough columns for aeo and datum"); + } + try { + gauge.setAeo(new BigDecimal(values[0].replace(",", "."))); + gauge.setDatum(new BigDecimal(values[1].replace(",", "."))); + } + catch (NumberFormatException nfe) { + log.warn("cannot parse aeo or datum"); + return false; + } + + line = in.readLine(); + + if (line == null) { + log.warn("STA file has not enough lines"); + return false; + } + + if (line.length() < 36) { + log.warn("second line is too short"); + return false; + } + + try { + gauge.setStation( + new BigDecimal(line.substring(29, 36).trim())); + } + catch (NumberFormatException nfe) { + log.warn("parsing of the datum of the gauge failed"); + return false; + } + + // overread the next six lines + for (int i = 0; i < 6; ++i) { + if ((line = in.readLine()) == null) { + log.warn("STA file is too short"); + return false; + } + } + + HashMap<String, ImportMainValueType> types = + new HashMap<String, ImportMainValueType>(); + + ArrayList<ImportNamedMainValue> namedMainValues = + new ArrayList<ImportNamedMainValue>(); + + ArrayList<ImportMainValue> mainValues = + new ArrayList<ImportMainValue>(); + + while ((line = in.readLine()) != null) { + Matcher m = QWTD_.matcher(line); + if (m.matches()) { + BigDecimal value; + try { + value = new BigDecimal(m.group(2).replace(",", ".")); + } + catch (NumberFormatException nfe) { + log.warn("value not parseable in line " + + in.getLineNumber()); + continue; + } + String typeString = m.group(3); + log.debug("\t type: " + typeString); + ImportMainValueType type = types.get(typeString); + if (type == null) { + type = new ImportMainValueType(typeString); + types.put(typeString, type); + } + String name = m.group(1); + ImportNamedMainValue namedMainValue = + new ImportNamedMainValue(type, name); + namedMainValues.add(namedMainValue); + + ImportMainValue mainValue = + new ImportMainValue(gauge, namedMainValue, value); + + mainValues.add(mainValue); + } + else { + // TODO: treat as a comment + } + } + gauge.setMainValueTypes( + new ArrayList<ImportMainValueType>(types.values())); + gauge.setNamedMainValues(namedMainValues); + gauge.setMainValues(mainValues); + } + finally { + if (in != null) { + in.close(); + } + } + log.info("finished parsing STA file: " + file); + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/importer/WstParser.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,388 @@ +package de.intevation.flys.importer; + +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; + +import java.io.File; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.InputStreamReader; +import java.io.FileInputStream; + +import java.text.NumberFormat; + +import org.apache.log4j.Logger; + +import de.intevation.flys.utils.StringUtil; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import java.math.BigDecimal; + +public class WstParser +{ + private static Logger log = Logger.getLogger(WstParser.class); + + public static final String COLUMN_BEZ_TEXT = "column-bez-text"; + public static final String COLUMN_BEZ_BREITE = "column-bez-breite"; + public static final String COLUMN_QUELLE = "column-quelle"; + public static final String COLUMN_DATUM = "column-datum"; + + public static final Double UNDEFINED_ZERO = Double.valueOf(0.0); + + public static final String ENCODING = "ISO-8859-1"; + + public static final Pattern UNIT_COMMENT = + Pattern.compile("\\*\\s*[kK][mM]\\s+(.+)"); + + public static final Pattern UNIT = + Pattern.compile("[^\\[]*\\[([^]]+)\\].*"); + + protected ImportWst wst; + + public WstParser() { + } + + public ImportWst getWst() { + return wst; + } + + public void setWst(ImportWst wst) { + this.wst = wst; + } + + public void parse(File file) throws IOException { + + log.info("Parsing WST file '" + file + "'"); + + wst = new ImportWst(file.getName()); + + LineNumberReader in = null; + try { + in = + new LineNumberReader( + new InputStreamReader( + new FileInputStream(file), ENCODING)); + + String input; + boolean first = true; + int columnCount = 0; + + String [] lsHeader = null; + String [] lsBezeichner = null; + String [] langBezeichner = null; + int [] colNaWidths = null; + String [] quellen = null; + String [] daten = null; + double [] aktAbfluesse = null; + double [] firstAbfluesse = null; + + double minKm = Double.MAX_VALUE; + double maxKm = -Double.MAX_VALUE; + + boolean columnHeaderChecked = false; + + double lastKm = Double.MAX_VALUE; + + String einheit = "Wasserstand [NN + m]"; + + HashMap<String, Double> oldEscapeLine = null; + + while ((input = in.readLine()) != null) { + String line = input; + if (first) { // fetch number of columns + if ((line = line.trim()).length() == 0) { + continue; + } + try { + columnCount = Integer.parseInt(line); + if (columnCount <= 0) { + throw new NumberFormatException( + "number columns <= 0"); + } + log.debug("Number of columns: " + columnCount); + lsBezeichner = new String[columnCount]; + lsHeader = new String[columnCount]; + aktAbfluesse = new double[columnCount]; + } + catch (NumberFormatException nfe) { + log.warn(nfe); + continue; + } + first = false; + continue; + } + + line = line.replace(',', '.'); + + if (line.startsWith("*\u001f")) { + Double [] data = + parseLineAsDouble(line, columnCount, false, true); + + if (oldEscapeLine != null) { + addInterval(minKm, maxKm, oldEscapeLine); + minKm = Double.MAX_VALUE; + maxKm = -Double.MAX_VALUE; + } + + oldEscapeLine = new HashMap<String, Double>(); + for (int i = 0; i < columnCount; ++i) { + if (lsHeader[i] != null) { + oldEscapeLine.put(lsHeader[i], data[i]); + } + } + + for (int i = Math.min(data.length, aktAbfluesse.length)-1; + i >= 0; --i) { + aktAbfluesse[i] = data[i].doubleValue(); + } + + if (firstAbfluesse == null) { + firstAbfluesse = (double [])aktAbfluesse.clone(); + } + continue; + } + + if (line.startsWith("*!")) { + String spezial = line.substring(2).trim(); + + if (spezial.length() == 0) { + continue; + } + + if (spezial.startsWith(COLUMN_BEZ_TEXT)) { + spezial = spezial.substring(COLUMN_BEZ_TEXT.length()).trim(); + if (spezial.length() == 0) { + continue; + } + langBezeichner = StringUtil.splitQuoted(spezial, '"'); + } + else if (spezial.startsWith(COLUMN_BEZ_BREITE)) { + spezial = spezial.substring(COLUMN_BEZ_BREITE.length()).trim(); + + if (spezial.length() == 0) { + continue; + } + + String[] split = spezial.split("\\s+"); + + colNaWidths = new int[split.length]; + for (int i=0; i < split.length; i++) { + colNaWidths[i] = Integer.parseInt(split[i]); + } + } + else if (spezial.startsWith(COLUMN_QUELLE)) { + if (spezial.length() == 0) { + continue; + } + quellen = StringUtil.splitQuoted(spezial, '"'); + } + else if (spezial.startsWith(COLUMN_DATUM)) { + spezial = spezial.substring(COLUMN_DATUM.length()).trim(); + if (spezial.length() == 0) { + continue; + } + daten = StringUtil.splitQuoted(spezial, '"'); + } + continue; + } + + if (line.length() < 11) { + continue; + } + + if (line.startsWith("*")) { + Matcher m = UNIT_COMMENT.matcher(line); + if (m.matches()) { + log.debug("unit comment found"); + // XXX: This hack is needed because desktop + // FLYS is broken figuring out the unit + String [] units = m.group(1).split("\\s{2,}"); + m = UNIT.matcher(units[0]); + einheit = m.matches() ? m.group(1) : units[0]; + log.debug("unit: " + einheit); + } + continue; + } + + if (firstAbfluesse != null) { + if (!columnHeaderChecked) { + int unknownCount = 0; + for (int i = 0; i < lsHeader.length; ++i) { + if (lsBezeichner[i] == null + || lsBezeichner[i].length() == 0) { + double q = firstAbfluesse[i]; + if (q < 0.001) { + lsBezeichner[i] = + "<unbekannt #" + unknownCount + ">"; + ++unknownCount; + } + else { + lsBezeichner[i] = "Q="+format(q); + } + } + lsHeader[i] = lsBezeichner[i]; + } + columnHeaderChecked = true; + } + + Double [] data = + parseLineAsDouble(line, columnCount, true, false); + + double kaem = data[0]; + + if (kaem < minKm) { + minKm = kaem; + } + if (kaem > maxKm) { + maxKm = kaem; + } + + lastKm = kaem; + + // extract values + for (int i = 0; i < columnCount; ++i) { + addValue(kaem, data[i].doubleValue(), lsBezeichner[i]); + } + + } + else { // firstAbfluesse == null + if (langBezeichner != null) { + lsBezeichner = StringUtil.fitArray( + langBezeichner, lsBezeichner); + } + else if (colNaWidths != null) { + for (int j = 0, i = 0, N = input.length(); + j < colNaWidths.length && i < N; + i += colNaWidths[j++] + ) { + lsBezeichner[j] = input.substring( + i, i+colNaWidths[j]).trim(); + } + } + else { + // first column begins at position 8 in line + for (int i = 8, col = 0; i < input.length(); i += 9) { + if ((i + 9) > input.length()) { + i = input.length() - 10; + } + // one column header is 9 chars wide + lsBezeichner[col++] = + input.substring(i, i + 9).trim(); + + if (col == lsBezeichner.length) { + break; + } + } + } + } + + } + addInterval(minKm, maxKm, oldEscapeLine); + } + finally { + if (in != null) { + in.close(); + } + } + } + + protected void addValue(double km, double w, String columnName) { + ImportWstColumn column = wst.getColumn(columnName); + column.addColumnValue(new BigDecimal(km), new BigDecimal(w)); + } + + private static final NumberFormat NF = getNumberFormat(); + + private static final NumberFormat getNumberFormat() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumFractionDigits(2); + nf.setMaximumFractionDigits(2); + return nf; + } + + protected static String format(double value) { + return NF.format(value); + } + + protected void addInterval( + double from, + double to, + Map<String, Double> values + ) { + log.debug("addInterval: " + from + " " + to); + + if (values == null) { + return; + } + + if (from > to) { double t = from; from = to; to = t; } + + ImportRange range = new ImportRange( + new BigDecimal(from), + new BigDecimal(to)); + + for (Map.Entry<String, Double> entry: values.entrySet()) { + BigDecimal q = new BigDecimal(entry.getValue()); + ImportWstQRange wstQRange = new ImportWstQRange(range, q); + + String columnName = entry.getKey(); + ImportWstColumn column = wst.getColumn(columnName); + column.addColumnQRange(wstQRange); + } + } + + private static final Double [] parseLineAsDouble( + String line, + int count, + boolean bStation, + boolean bParseEmptyAsZero + ) { + String [] tokens = parseLine(line, count, bStation); + + Double [] doubles = new Double[tokens.length]; + + for (int i = 0; i < doubles.length; ++i) { + String token = tokens[i].trim(); + if (token.length() != 0) { + doubles[i] = Double.valueOf(token); + } + else if (bParseEmptyAsZero) { + doubles[i] = UNDEFINED_ZERO; + } + } + + return doubles; + } + + private static String [] parseLine( + String line, + int tokenCount, + boolean bParseStation + ) { + ArrayList<String> strings = new ArrayList<String>(); + + if (bParseStation) { + if (line.length() < 8) { + throw new IllegalArgumentException("station too short"); + } + strings.add(line.substring(0, 8)); + } + + int pos = 9; + for (int i = 0; i < tokenCount; ++i) { + if (line.length() >= pos + 8) { + strings.add(line.substring(pos, pos + 8)); + } + else { + strings.add(""); + } + pos += 9; + } + + return strings.toArray(new String[strings.size()]); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Annotation.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,81 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "annotations") +public class Annotation +implements Serializable +{ + private Integer id; + private Range range; + private Attribute attribute; + private Position position; + + public Annotation() { + } + + public Annotation(Range range, Attribute attribute, Position position) { + this.range = range; + this.attribute = attribute; + this.position = position; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_ANNOTATIONS_ID_SEQ", + sequenceName = "ANNOTATIONS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_ANNOTATIONS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "range_id") + public Range getRange() { + return range; + } + + public void setRange(Range range) { + this.range = range; + } + + @OneToOne + @JoinColumn(name = "attribute_id") + public Attribute getAttribute() { + return attribute; + } + + public void setAttribute(Attribute attribute) { + this.attribute = attribute; + } + + @OneToOne + @JoinColumn(name = "position_id") + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Attribute.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; + +@Entity +@Table(name = "attributes") +public class Attribute +implements Serializable +{ + private Integer id; + + private String value; + + public Attribute() { + } + + public Attribute(String value) { + this.value = value; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_ATTRIBUTES_ID_SEQ", + sequenceName = "ATTRIBUTES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_ATTRIBUTES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "value") + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/DischargeTable.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,85 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +import java.util.List; + +@Entity +@Table(name = "discharge_tables") +public class DischargeTable +implements Serializable +{ + private Integer id; + private Gauge gauge; + private TimeInterval timeInterval; + + private List<DischargeTableValue> dischargeTableValues; + + public DischargeTable() { + } + + public DischargeTable(Gauge gauge) { + this.gauge = gauge; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_DISCHARGE_TABLES_ID_SEQ", + sequenceName = "DISCHARGE_TABLES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_DISCHARGE_TABLES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "time_interval_id" ) + public TimeInterval getTimeInterval() { + return timeInterval; + } + + public void setTimeInterval(TimeInterval timeInterval) { + this.timeInterval = timeInterval; + } + + @OneToOne + @JoinColumn(name = "gauge_id" ) + public Gauge getGauge() { + return gauge; + } + + public void setGauge(Gauge gauge) { + this.gauge = gauge; + } + + @OneToMany + @JoinColumn(name = "table_id") + public List<DischargeTableValue> getDischargeTableValues() { + return dischargeTableValues; + } + + public void setDischargeTableValues( + List<DischargeTableValue> dischargeTableValues + ) { + this.dischargeTableValues = dischargeTableValues; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/DischargeTableValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,84 @@ +package de.intevation.flys.model; + +import java.math.BigDecimal; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "discharge_table_values") +public class DischargeTableValue +implements Serializable +{ + private Integer id; + private DischargeTable dischargeTable; + private BigDecimal q; + private BigDecimal w; + + public DischargeTableValue() { + } + + public DischargeTableValue( + DischargeTable dischargeTable, BigDecimal q, BigDecimal w) + { + this.dischargeTable = dischargeTable; + this.q = q; + this.w = w; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_DISCHARGE_TABLE_VALUES_ID_SEQ", + sequenceName = "DISCHARGE_TABLE_VALUES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_DISCHARGE_TABLE_VALUES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "table_id" ) + public DischargeTable getDischargeTable() { + return dischargeTable; + } + + public void setDischargeTable(DischargeTable dischargeTable) { + this.dischargeTable = dischargeTable; + } + + + @Column(name = "q") + public BigDecimal getQ() { + return q; + } + + public void setQ(BigDecimal q) { + this.q = q; + } + + @Column(name = "w") + public BigDecimal getW() { + return w; + } + + public void setW(BigDecimal w) { + this.w = w; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Gauge.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,137 @@ +package de.intevation.flys.model; + +import java.math.BigDecimal; + +import java.io.Serializable; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.OneToMany; + +@Entity +@Table(name = "gauges") +public class Gauge +implements Serializable +{ + private Integer id; + private String name; + private River river; + private BigDecimal station; + private BigDecimal aeo; + private BigDecimal datum; + private Range range; + + private List<DischargeTable> dischargeTables; + + public Gauge() { + } + + public Gauge( + String name, + River river, + BigDecimal station, + BigDecimal aeo, + BigDecimal datum, + Range range + ) { + this.name = name; + this.river = river; + this.station = station; + this.aeo = aeo; + this.datum = datum; + this.range = range; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_GAUGES_ID_SEQ", + sequenceName = "GAUGES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_GAUGES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "river_id" ) + public River getRiver() { + return river; + } + + public void setRiver(River river) { + this.river = river; + } + + @Column(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Column(name = "station") // FIXME: type mapping needed + public BigDecimal getStation() { + return station; + } + + public void setStation(BigDecimal station) { + this.station = station; + } + + @Column(name = "aeo") // FIXME: type mapping needed + public BigDecimal getAeo() { + return aeo; + } + + public void setAeo(BigDecimal aeo) { + this.aeo = aeo; + } + + @Column(name = "datum") // FIXME: type mapping needed + public BigDecimal getDatum() { + return datum; + } + + public void setDatum(BigDecimal datum) { + this.datum = datum; + } + + @OneToOne + @JoinColumn(name = "range_id" ) + public Range getRange() { + return range; + } + + public void setRange(Range range) { + this.range = range; + } + + @OneToMany + @JoinColumn(name = "gauge_id") + public List<DischargeTable> getDischargeTables() { + return dischargeTables; + } + + public void setDischargeTables(List<DischargeTable> dischargeTables) { + this.dischargeTables = dischargeTables; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/MainValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; +import javax.persistence.GenerationType; + +import java.math.BigDecimal; + +@Entity +@Table(name = "main_values") +public class MainValue +implements Serializable +{ + private Integer id; + + private Gauge gauge; + + private NamedMainValue mainValue; + + private BigDecimal value; + + private TimeInterval timeInterval; + + public MainValue() { + } + + public MainValue( + Gauge gauge, + NamedMainValue mainValue, + BigDecimal value, + TimeInterval timeInterval + ) { + this.gauge = gauge; + this.mainValue = mainValue; + this.value = value; + this.timeInterval = timeInterval; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_MAIN_VALUES_ID_SEQ", + sequenceName = "MAIN_VALUES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_MAIN_VALUES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "gauge_id") + public Gauge getGauge() { + return gauge; + } + + public void setGauge(Gauge gauge) { + this.gauge = gauge; + } + + @OneToOne + @JoinColumn(name = "named_value_id") + public NamedMainValue getMainValue() { + return mainValue; + } + + public void setMainValue(NamedMainValue mainValue) { + this.mainValue = mainValue; + } + + @Column(name = "value") // FIXME: type mapping needed? + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + @OneToOne + @JoinColumn(name = "time_interval_id") + public TimeInterval getTimeInterval() { + return timeInterval; + } + + public void setTimeInterval(TimeInterval timeInterval) { + this.timeInterval = timeInterval; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/MainValueType.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; + +@Entity +@Table(name = "main_value_types") +public class MainValueType +implements Serializable +{ + private Integer id; + private String name; + + public MainValueType() { + } + + public MainValueType(String name) { + this.name = name; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_MAIN_VALUE_TYPES_ID_SEQ", + sequenceName = "MAIN_VALUE_TYPES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_MAIN_VALUE_TYPES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "name") // FIXME: Type conversion needed? + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/NamedMainValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,68 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "named_main_values") +public class NamedMainValue +implements Serializable +{ + private Integer id; + private String name; + private MainValueType type; + + public NamedMainValue() { + } + + public NamedMainValue(String name, MainValueType type) { + this.name = name; + this.type = type; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_NAMED_MAIN_VALUES_ID_SEQ", + sequenceName = "NAMED_MAIN_VALUES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_NAMED_MAIN_VALUES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @OneToOne + @JoinColumn(name = "type_id" ) + public MainValueType getType() { + return type; + } + + public void setType(MainValueType type) { + this.type = type; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Position.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,71 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.OneToMany; +import javax.persistence.JoinColumn; +import javax.persistence.GenerationType; + +import java.util.List; + +@Entity +@Table(name = "positions") +public class Position +implements Serializable +{ + private Integer id; + + private String value; + + private List<Annotation> annotations; + + public Position() { + } + + public Position(String value) { + this.value = value; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_POSITIONS_ID_SEQ", + sequenceName = "POSITIONS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_POSITIONS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "value") + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @OneToMany + @JoinColumn(name="position_id") + public List<Annotation> getAnnotations() { + return annotations; + } + + public void setAnnotations(List<Annotation> annotations) { + this.annotations = annotations; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Range.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,144 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; + +@Entity +@Table(name = "ranges") +public class Range +implements Serializable +{ + private Integer id; + private BigDecimal a; + private BigDecimal b; + + private River river; + + public Range() { + } + + public Range(double a, double b, River river) { + this(new BigDecimal(a), new BigDecimal(b), river); + } + + public Range(BigDecimal a, BigDecimal b, River river) { + this.a = a; + this.b = b; + this.river = river; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_RANGES_ID_SEQ", + sequenceName = "RANGES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_RANGES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "a") // FIXME: type mapping needed? + public BigDecimal getA() { + return a; + } + + public void setA(BigDecimal a) { + this.a = a; + } + + @Column(name = "b") // FIXME: type mapping needed? + public BigDecimal getB() { + return b; + } + + public void setB(BigDecimal b) { + this.b = b; + } + + @OneToOne + @JoinColumn(name = "river_id") + public River getRiver() { + return river; + } + + public void setRiver(River river) { + this.river = river; + } + + public int code() { + int code = 0; + if (a != null) code = 1; + if (b != null) code |= 2; + return code; + } + + public boolean intersects(BigDecimal c) { + return !(a.compareTo(c) > 0 || b.compareTo(c) < 0); + } + + public boolean intersects(Range other) { + + int code = code(); + int ocode = other.code(); + + if (code == 0 || ocode == 0) { + return false; + } + + switch (code) { + case 1: // has a + switch (ocode) { + case 1: // has a + return a.compareTo(other.a) == 0; + case 2: // has b + return a.compareTo(other.b) == 0; + case 3: // has range + return other.intersects(a); + } + break; + case 2: // has b + switch (ocode) { + case 1: // has a + return b.compareTo(other.a) == 0; + case 2: // has b + return b.compareTo(other.b) == 0; + case 3: // has range + return other.intersects(b); + } + break; + case 3: // has range + switch (ocode) { + case 1: // has a + return intersects(other.a); + case 2: // has b + return intersects(other.b); + case 3: // has range + return !(other.b.compareTo(a) < 0 + ||other.a.compareTo(b) > 0); + } + break; + + } + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/River.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,75 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.OneToMany; +import javax.persistence.JoinColumn; +import javax.persistence.GenerationType; + +import java.util.List; + +@Entity +@Table(name = "rivers") +public class River +implements Serializable +{ + private Integer id; + + private String name; + + private List<Gauge> gauges; + + @Id + @SequenceGenerator( + name = "SEQUENCE_RIVERS_ID_SEQ", + sequenceName = "RIVERS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_RIVERS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public River() { + } + + public River(String name) { + this.name = name; + } + + @OneToMany + @JoinColumn(name="river_id") + public List<Gauge> getGauges() { + return gauges; + } + + public void setGauges(List<Gauge> gauges) { + this.gauges = gauges; + } + + public String toString() { + return name != null ? name : ""; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/TimeInterval.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,62 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; + +@Entity +@Table(name = "time_intervals") +public class TimeInterval +implements Serializable +{ + private Integer id; + private Date startTime; + private Date stopTime; + + public TimeInterval() { + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_TIME_INTERVALS_ID_SEQ", + sequenceName = "TIME_INTERVALS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_TIME_INTERVALS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Column(name = "start_time") // FIXME: type mapping needed? + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + @Column(name = "stop_time") // FIXME: type mapping needed? + public Date getStopTime() { + return stopTime; + } + + public void setStopTime(Date stopTime) { + this.stopTime = stopTime; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/Wst.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,68 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; + +@Entity +@Table(name = "wsts") +public class Wst +implements Serializable +{ + private Integer id; + private River river; + private String description; + + public Wst() { + } + + public Wst(River river, String description) { + this.river = river; + this.description = description; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_WSTS_ID_SEQ", + sequenceName = "WSTS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_WSTS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "river_id" ) + public River getRiver() { + return river; + } + + public void setRiver(River river) { + this.river = river; + } + + @Column(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/WstColumn.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.flys.model; + +import java.util.List; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.OneToMany; + +@Entity +@Table(name = "wst_columns") +public class WstColumn +implements Serializable +{ + private Integer id; + private Wst wst; + private String name; + private String description; + private TimeInterval timeInterval; + private List<WstColumnQRange> columnQRanges; + private List<WstColumnValue> columnValues; + + public WstColumn() { + } + + public WstColumn( + Wst wst, + String name, + String description, + TimeInterval timeInterval + ) { + this.wst = wst; + this.name = name; + this.description = description; + this.timeInterval = timeInterval; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_WST_COLUMNS_ID_SEQ", + sequenceName = "WST_COLUMNS_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_WST_COLUMNS_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "wst_id" ) + public Wst getWst() { + return wst; + } + + public void setWst(Wst wst) { + this.wst = wst; + } + + @Column(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Column(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @OneToOne + @JoinColumn(name = "time_interval_id" ) + public TimeInterval getTimeInterval() { + return timeInterval; + } + + public void setTimeInterval(TimeInterval timeInterval) { + this.timeInterval = timeInterval; + } + + @OneToMany + @JoinColumn(name="wst_column_id") + public List<WstColumnQRange> getColumnQRanges() { + return columnQRanges; + } + + public void setColumnQRanges(List<WstColumnQRange> columnQRanges) { + this.columnQRanges = columnQRanges; + } + + @OneToMany + @JoinColumn(name="wst_column_id") + public List<WstColumnValue> getColumnValues() { + return columnValues; + } + + public void setColumnValues(List<WstColumnValue> columnValues) { + this.columnValues = columnValues; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/WstColumnQRange.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,73 @@ +package de.intevation.flys.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "wst_column_q_ranges") +public class WstColumnQRange +implements Serializable +{ + private Integer id; + private WstColumn wstColumn; + private WstQRange wstQRange; + + public WstColumnQRange() { + } + + public WstColumnQRange( + WstColumn wstColumn, + WstQRange wstQRange + ) { + this.wstColumn = wstColumn; + this.wstQRange = wstQRange; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_WST_Q_RANGES_ID_SEQ", + sequenceName = "WST_Q_RANGES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_WST_Q_RANGES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "wst_column_id" ) + public WstColumn getWstColumn() { + return wstColumn; + } + + public void setWstColumn(WstColumn wstColumn) { + this.wstColumn = wstColumn; + } + + @OneToOne + @JoinColumn(name = "wst_q_range_id" ) + public WstQRange getWstQRange() { + return wstQRange; + } + + public void setWstQRange(WstQRange wstQRange) { + this.wstQRange = wstQRange; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/WstColumnValue.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,85 @@ +package de.intevation.flys.model; + +import java.math.BigDecimal; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "wst_column_values") +public class WstColumnValue +implements Serializable +{ + private Integer id; + private WstColumn wstColumn; + private BigDecimal position; + private BigDecimal w; + + public WstColumnValue() { + } + + public WstColumnValue( + WstColumn wstColumn, + BigDecimal position, + BigDecimal w + ) { + this.wstColumn = wstColumn; + this.position = position; + this.w = w; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_WST_COLUMN_VALUES_ID_SEQ", + sequenceName = "WST_COLUMN_VALUES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_WST_COLUMN_VALUES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "wst_column_id") + public WstColumn getWstColumn() { + return wstColumn; + } + + public void setWstColumn(WstColumn wstColumn) { + this.wstColumn = wstColumn; + } + + @Column(name = "position") // FIXME: type mapping needed? + public BigDecimal getPosition() { + return position; + } + + public void setPosition(BigDecimal position) { + this.position = position; + } + + @Column(name = "w") // FIXME: type mapping needed? + public BigDecimal getW() { + return w; + } + + public void setW(BigDecimal w) { + this.w = w; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/WstQRange.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,70 @@ +package de.intevation.flys.model; + +import java.math.BigDecimal; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.GeneratedValue; +import javax.persistence.Column; +import javax.persistence.SequenceGenerator; +import javax.persistence.GenerationType; +import javax.persistence.OneToOne; +import javax.persistence.JoinColumn; + +@Entity +@Table(name = "wst_q_ranges") +public class WstQRange +implements Serializable +{ + private Integer id; + private Range range; + private BigDecimal q; + + public WstQRange() { + } + + public WstQRange(Range range, BigDecimal q) { + this.range = range; + this.q = q; + } + + @Id + @SequenceGenerator( + name = "SEQUENCE_WST_Q_RANGES_ID_SEQ", + sequenceName = "WST_Q_RANGES_ID_SEQ", + allocationSize = 1) + @GeneratedValue( + strategy = GenerationType.SEQUENCE, + generator = "SEQUENCE_WST_Q_RANGES_ID_SEQ") + @Column(name = "id") + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @OneToOne + @JoinColumn(name = "range_id" ) + public Range getRange() { + return range; + } + + public void setRange(Range range) { + this.range = range; + } + + @Column(name = "q") // FIXME: type mapping needed?! + public BigDecimal getQ() { + return q; + } + + public void setQ(BigDecimal q) { + this.q = q; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/utils/DBCPConnectionProvider.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,244 @@ +/* + * Copyright 2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.hibernate.connection; + +import java.sql.Connection; +import java.sql.SQLException; + +import java.util.Iterator; +import java.util.Properties; +import java.util.Map; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.dbcp.BasicDataSourceFactory; + +import org.apache.log4j.Logger; + +import org.hibernate.HibernateException; + +import org.hibernate.connection.ConnectionProviderFactory; +import org.hibernate.connection.ConnectionProvider; + +import org.hibernate.cfg.Environment; + +/** + * <p>A connection provider that uses an Apache commons DBCP connection pool.</p> + * + * <p>To use this connection provider set:<br> + * <code>hibernate.connection.provider_class org.hibernate.connection.DBCPConnectionProvider</code></p> + * + * <pre>Supported Hibernate properties: + * hibernate.connection.driver_class + * hibernate.connection.url + * hibernate.connection.username + * hibernate.connection.password + * hibernate.connection.isolation + * hibernate.connection.autocommit + * hibernate.connection.pool_size + * hibernate.connection (JDBC driver properties)</pre> + * <br> + * All DBCP properties are also supported by using the hibernate.dbcp prefix. + * A complete list can be found on the DBCP configuration page: + * <a href="http://jakarta.apache.org/commons/dbcp/configuration.html">http://jakarta.apache.org/commons/dbcp/configuration.html</a>. + * <br> + * <pre>Example: + * hibernate.connection.provider_class org.hibernate.connection.DBCPConnectionProvider + * hibernate.connection.driver_class org.hsqldb.jdbcDriver + * hibernate.connection.username sa + * hibernate.connection.password + * hibernate.connection.url jdbc:hsqldb:test + * hibernate.connection.pool_size 20 + * hibernate.dbcp.initialSize 10 + * hibernate.dbcp.maxWait 3000 + * hibernate.dbcp.validationQuery select 1 from dual</pre> + * + * <p>More information about configuring/using DBCP can be found on the + * <a href="http://jakarta.apache.org/commons/dbcp/">DBCP website</a>. + * There you will also find the DBCP wiki, mailing lists, issue tracking + * and other support facilities</p> + * + * @see org.hibernate.connection.ConnectionProvider + * @author Dirk Verbeeck + */ +public class DBCPConnectionProvider +implements ConnectionProvider +{ + private static Logger log = Logger.getLogger(DBCPConnectionProvider.class); + + private static final String PREFIX = "hibernate.dbcp."; + + private BasicDataSource ds; + + // Old Environment property for backward-compatibility + // (property removed in Hibernate3) + private static final String DBCP_PS_MAXACTIVE = + "hibernate.dbcp.ps.maxActive"; + + // Property doesn't exists in Hibernate2 + private static final String AUTOCOMMIT = + "hibernate.connection.autocommit"; + + public void configure(Properties props) throws HibernateException { + try { + log.debug("Configure DBCPConnectionProvider"); + + // DBCP properties used to create the BasicDataSource + Properties dbcpProperties = new Properties(); + + // DriverClass & url + String jdbcDriverClass = props.getProperty(Environment.DRIVER); + String jdbcUrl = props.getProperty(Environment.URL); + dbcpProperties.put("driverClassName", jdbcDriverClass); + dbcpProperties.put("url", jdbcUrl); + + // Username / password + String username = props.getProperty(Environment.USER); + String password = props.getProperty(Environment.PASS); + dbcpProperties.put("username", username); + dbcpProperties.put("password", password); + + // Isolation level + String isolationLevel = props.getProperty(Environment.ISOLATION); + if (isolationLevel != null + && (isolationLevel = isolationLevel.trim()).length() > 0) { + dbcpProperties.put("defaultTransactionIsolation", isolationLevel); + } + + // Turn off autocommit (unless autocommit property is set) + String autocommit = props.getProperty(AUTOCOMMIT); + if (autocommit != null + && (autocommit = autocommit.trim()).length() > 0) { + dbcpProperties.put("defaultAutoCommit", autocommit); + } else { + dbcpProperties.put("defaultAutoCommit", String.valueOf(Boolean.FALSE)); + } + + // Pool size + String poolSize = props.getProperty(Environment.POOL_SIZE); + if (poolSize != null + && (poolSize = poolSize.trim()).length() > 0 + && Integer.parseInt(poolSize) > 0) { + dbcpProperties.put("maxActive", poolSize); + } + + // Copy all "driver" properties into "connectionProperties" + Properties driverProps = + ConnectionProviderFactory.getConnectionProperties(props); + + if (driverProps.size() > 0) { + StringBuilder connectionProperties = new StringBuilder(); + for (Iterator iter = driverProps.entrySet().iterator(); + iter.hasNext(); + ) { + Map.Entry entry = (Map.Entry)iter.next(); + String key = (String)entry.getKey(); + String value = (String)entry.getValue(); + connectionProperties + .append(key) + .append('=') + .append(value); + if (iter.hasNext()) { + connectionProperties.append(';'); + } + } + dbcpProperties.put( + "connectionProperties", connectionProperties.toString()); + } + + // Copy all DBCP properties removing the prefix + for (Iterator iter = props.entrySet().iterator() ; iter.hasNext() ;) { + Map.Entry entry = (Map.Entry)iter.next(); + String key = (String)entry.getKey(); + if (key.startsWith(PREFIX)) { + String property = key.substring(PREFIX.length()); + String value = (String)entry.getValue(); + dbcpProperties.put(property, value); + } + } + + // Backward-compatibility + if (props.getProperty(DBCP_PS_MAXACTIVE) != null) { + dbcpProperties.put( + "poolPreparedStatements", + String.valueOf(Boolean.TRUE)); + dbcpProperties.put( + "maxOpenPreparedStatements", + props.getProperty(DBCP_PS_MAXACTIVE)); + } + + // Some debug info + /* // commented out, because it leaks the password + if (log.isDebugEnabled()) { + log.debug("Creating a DBCP BasicDataSource" + + " with the following DBCP factory properties:"); + StringWriter sw = new StringWriter(); + dbcpProperties.list(new PrintWriter(sw, true)); + log.debug(sw.toString()); + } + */ + + // Let the factory create the pool + ds = (BasicDataSource)BasicDataSourceFactory + .createDataSource(dbcpProperties); + + // The BasicDataSource has lazy initialization + // borrowing a connection will start the DataSource + // and make sure it is configured correctly. + + // Connection conn = ds.getConnection(); + // conn.close(); + } + catch (Exception e) { + String message = "Could not create a DBCP pool"; + log.fatal(message, e); + if (ds != null) { + BasicDataSource x = ds; ds = null; + try { + x.close(); + } + catch (SQLException sqle) { + } + } + throw new HibernateException(message, e); + } + log.debug("Configure DBCPConnectionProvider complete"); + } + + public Connection getConnection() throws SQLException { + return ds.getConnection(); + } + + public void closeConnection(Connection conn) throws SQLException { + conn.close(); + } + + public void close() throws HibernateException { + try { + if (ds != null) { + BasicDataSource x = ds; ds = null; + x.close(); + } + } + catch (SQLException sqle) { + throw new HibernateException("Could not close DBCP pool", sqle); + } + } + + public boolean supportsAggressiveRelease() { + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/utils/FileTools.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,78 @@ +package de.intevation.flys.utils; + +import java.io.File; + +import java.util.Stack; + +import org.apache.log4j.Logger; + +public class FileTools +{ + private static Logger log = Logger.getLogger(FileTools.class); + + private FileTools() { + } + + public static File repair(File file) { + file = file.getAbsoluteFile(); + if (file.exists()) { + return file; + } + Stack<String> parts = new Stack<String>(); + File curr = file; + while (curr != null) { + String name = curr.getName(); + if (name.length() > 0) { + parts.push(curr.getName()); + } + curr = curr.getParentFile(); + } + + curr = null; + OUTER: while (!parts.isEmpty()) { + String f = parts.pop(); + log.debug("fixing: '" + f + "'"); + if (curr == null) { + // XXX: Not totaly correct because there + // more than one root on none unix systems. + for (File root: File.listRoots()) { + File [] files = root.listFiles(); + if (files == null) { + log.warn("cannot list '" + root); + continue; + } + for (File candidate: files) { + if (candidate.getName().equalsIgnoreCase(f)) { + curr = new File(root, candidate.getName()); + continue OUTER; + } + } + } + break; + } + else { + File [] files = curr.listFiles(); + if (files == null) { + log.warn("cannot list: '" + curr + "'"); + return file; + } + for (File candidate: files) { + if (candidate.getName().equalsIgnoreCase(f)) { + curr = new File(curr, candidate.getName()); + continue OUTER; + } + } + curr = null; + break; + } + } + + if (curr == null) { + log.warn("cannot repair path '" + file + "'"); + return file; + } + + return curr; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/utils/StringUtil.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,787 @@ +package de.intevation.flys.utils; + +/** + * Copyright (c) 2006 by Intevation GmbH + * + * @author Sascha L. Teichmann (teichmann@intevation.de) + * @author Ludwig Reiter (ludwig@intevation.de) + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL coming with FLYS for details. + */ +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Locale; + +import java.net.URLEncoder; +import java.net.URLDecoder; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.PrintWriter; + +public final class StringUtil { + final static String NUMBER_SEPERATOR = ";"; + final static String LINE_SEPERATOR = ":"; + + private StringUtil() { + } + + public static final String double2DArrayToString(double[][] values) { + + if (values == null) { + throw new IllegalArgumentException("keine double[][]-Werte"); + } + + StringBuilder strbuf = new StringBuilder(); + + for (int i=0; i < values.length; i++) { + if (i>0) { + strbuf.append(LINE_SEPERATOR); + } + for (int j=0; j < values[i].length; j++) { + if (j > 0) { + strbuf.append(NUMBER_SEPERATOR); + } + strbuf.append(values[i][j]); + } + } + + return strbuf.toString(); + } + + public static final double[][] stringToDouble2DArray(String str) { + if (str == null || str.length() == 0) { + return null; + } + + String[] lineSplit = str.split(LINE_SEPERATOR); + double[][] array2D = new double[lineSplit.length][]; + for (int i=0; i < lineSplit.length; i++) { + String[] numberSplit = lineSplit[i].split(NUMBER_SEPERATOR); + + double[] numbers = new double[numberSplit.length]; + for (int j=0; j < numberSplit.length; j++) { + numbers[j] = Double.valueOf(numberSplit[j]).doubleValue(); + } + + array2D[i] = numbers; + } + + return array2D; + } + + public static final String [] splitLines(String s) { + if (s == null) { + return null; + } + ArrayList<String> list = new ArrayList<String>(); + + BufferedReader in = null; + + try { + in = + new BufferedReader( + new StringReader(s)); + + String line; + + while ((line = in.readLine()) != null) { + list.add(line); + } + } + catch (IOException ioe) { + return null; + } + finally { + if (in != null) + try { + in.close(); + } + catch (IOException ioe) {} + } + + return list.toArray(new String[list.size()]); + } + + public static final String concat(String [] s) { + return concat(s, null); + } + + public static final String concat(String [] s, String glue) { + if (s == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length; ++i) { + if (i > 0 && glue != null) { + sb.append(glue); + } + sb.append(s[i]); + } + return sb.toString(); + } + + public static final String [] splitAfter(String [] src, int N) { + if (src == null) { + return null; + } + + ArrayList<String> list = new ArrayList<String>(src.length); + for (int i = 0; i < src.length; ++i) { + String s = src[i]; + int R; + if (s == null || (R = s.length()) == 0) { + list.add(s); + } + else { + while (R > N) { + list.add(s.substring(0, N)); + s = s.substring(N); + R = s.length(); + } + list.add(s); + } + } + return list.toArray(new String[list.size()]); + } + + public static final String [] splitQuoted(String s) { + return splitQuoted(s, '"'); + } + + public static final String[] fitArray(String [] src, String [] dst) { + if (src == null) { + return dst; + } + if (dst == null) { + return src; + } + + if (src.length == dst.length) { + return src; + } + + System.arraycopy(src, 0, dst, 0, Math.min(dst.length, src.length)); + + return dst; + } + + public static final String [] splitQuoted(String s, char quoteChar) { + if (s == null) { + return null; + } + ArrayList<String> l = new ArrayList<String>(); + int mode = 0, last_mode = 0; + StringBuilder sb = new StringBuilder(); + for (int N = s.length(), i = 0; i < N; ++i) { + char c = s.charAt(i); + switch (mode) { + case 0: // unquoted mode + if (c == quoteChar) { + mode = 1; // to quoted mode + if (sb.length() > 0) { + l.add(sb.toString()); + sb.setLength(0); + } + } + else if (c == '\\') { + last_mode = 0; + mode = 2; // escape mode + } + else if (!Character.isWhitespace(c)) { + sb.append(c); + } + else if (sb.length() > 0) { + l.add(sb.toString()); + sb.setLength(0); + } + break; + case 1: // quote mode + if (c == '\\') { + last_mode = 1; + mode = 2; // escape mode + } + else if (c == quoteChar) { // leave quote mode + l.add(sb.toString()); + sb.setLength(0); + mode = 0; // to unquoted mode + } + else { + sb.append(c); + } + break; + case 2: // escape mode + sb.append(c); + mode = last_mode; + break; + } + } + if (sb.length() > 0) { + l.add(sb.toString()); + } + return l.toArray(new String[l.size()]); + } + + public static final String [] splitUnique(String s) { + return splitUnique(s, "[\\s,]+"); + } + + public static final String [] splitUnique(String s, String sep) { + return s != null ? unique(s.split(sep)) : null; + } + + public static final String [] unique(String [] str) { + if (str == null || str.length == 1) { + return str; + } + + Arrays.sort(str); + + for (int i = 1; i < str.length; ++i) + if (str[i].equals(str[i-1])) { + ArrayList<String> list = new ArrayList<String>(str.length); + + for (int j = 0; j < i; ++j) { + list.add(str[j]); + } + + String last = str[i]; + + for (++i; i < str.length; ++i) + if (!last.equals(str[i])) { + list.add(last = str[i]); + } + + return list.toArray(new String[list.size()]); + } + + return str; + } + + public static final String [] ensureEmptyExistence(String [] str) { + if (str == null) { + return null; + } + + for (int i = 0; i < str.length; ++i) + if (str[i].length() == 0) { + if (i != 0) { // copy to front + String t = str[0]; + str[0] = str[i]; + str[i] = t; + } + return str; + } + + String [] n = new String[str.length+1]; + n[0] = ""; + System.arraycopy(str, 0, n, 1, str.length); + return n; + } + + public static final String ensureWidthPadLeft(String s, int width, char pad) { + int N = s.length(); + if (N >= width) { + return s; + } + StringBuilder sb = new StringBuilder(width); + for (; N < width; ++N) { + sb.append(pad); + } + sb.append(s); + return sb.toString(); + } + + public static final String [] splitWhiteSpaceWithNAsPad( + String s, + int N, + String pad + ) { + if (s == null) { + return null; + } + + boolean copyChars = true; + int count = 0; // number of WS + + int S = s.length(); + + ArrayList<String> parts = new ArrayList<String>(); + + StringBuilder part = new StringBuilder(S); + + for (int i = 0; i < S; ++i) { + char c = s.charAt(i); + if (copyChars) { // char mode + if (Character.isWhitespace(c)) { + if (part.length() > 0) { + parts.add(part.toString()); + part.setLength(0); + } + count = 1; + copyChars = false; // to WS mode + } + else { + part.append(c); + } + } + else { // counting WS + if (Character.isWhitespace(c)) { + ++count; + } + else { + while (count >= N) {// enough to insert pad? + parts.add(pad); + count -= N; + } + part.append(c); + count = 0; + copyChars = true; // back to char mode + } + } + } // for all chars + + if (copyChars) { + if (part.length() > 0) { + parts.add(part.toString()); + } + } + else { + while (count >= N) { // enough to insert pad? + parts.add(pad); + count -= N; + } + } + + return parts.toArray(new String[parts.size()]); + } + + public static final String encodeURL(String url) { + try { + return url != null + ? URLEncoder.encode(url, "UTF-8") + : ""; + } + catch (UnsupportedEncodingException usee) { + throw new RuntimeException(usee.getLocalizedMessage()); + } + } + + public static final String decodeURL(String url) { + try { + return url != null + ? URLDecoder.decode(url, "UTF-8") + : ""; + } + catch (UnsupportedEncodingException usee) { + throw new RuntimeException(usee.getLocalizedMessage()); + } + } + + public static final boolean isEmpty(String s) { + return s == null || s.length() == 0; + } + + public static final String empty(String s) { + return s == null ? "" : s; + } + + + public static final String trim(String s) { + return s != null ? s.trim() : null; + } + + public static final String uniqueWhitespaces(String s) { + if (s == null) { + return null; + } + + boolean wasWS = false; + StringBuilder sb = new StringBuilder(); + + for (int N = s.length(), i = 0; i < N; ++i) { + char c = s.charAt(i); + if (Character.isWhitespace(c)) { + if (!wasWS) { + sb.append(c); + wasWS = true; + } + } + else { + sb.append(c); + wasWS = false; + } + } + + return sb.toString(); + } + + public static final String replaceNewlines(String s) { + return s == null + ? null + : s.replace('\r', ' ').replace('\n', ' '); + } + + /* + public static final String quoteReplacement(String s) { + + if (s == null || (s.indexOf('\\') == -1 && s.indexOf('$') == -1)) + return s; + + StringBuilder sb = new StringBuilder(); + + for (int N = s.length(), i = 0; i < N; ++i) { + char c = s.charAt(i); + if (c == '\\' || c == '$') sb.append('\\'); + sb.append(c); + } + + return sb.toString(); + } + */ + + public static final String quoteReplacement(String s) { + + if (s == null) { + return null; + } + + for (int N = s.length(), i = 0; i < N; ++i) { // plain check loop + char c = s.charAt(i); + if (c == '$' || c == '\\') { // first special -> StringBuilder + StringBuilder sb = new StringBuilder(s.substring(0, i)) + .append('\\') + .append(c); + for (++i; i < N; ++i) { // build StringBuilder with rest + if ((c = s.charAt(i)) == '$' || c == '\\') { + sb.append('\\'); + } + sb.append(c); + } + return sb.toString(); + } + } + + return s; + } + + public static final String repeat(String what, int times) { + return repeat(what, times, new StringBuilder()).toString(); + } + + public static final StringBuilder repeat(String what, int times, StringBuilder sb) { + while (times-- > 0) { + sb.append(what); + } + return sb; + } + + /** + * Gibt den Dateinamen in S ohne Dateiendung zurück. + */ + public static final String cutExtension(String s) { + if (s == null) { + return null; + } + int dot = s.lastIndexOf('.'); + return dot >= 0 + ? s.substring(0, dot) + : s; + } + + public static final String extension(String s) { + if (s == null) { + return null; + } + int dot = s.lastIndexOf('.'); + return dot >= 0 + ? s.substring(dot+1) + : s; + } + + public static final String [] splitExtension(String x) { + if (x == null) { + return null; + } + int i = x.lastIndexOf('.'); + return i < 0 + ? new String[] { x, null } + : new String[] { x.substring(0, Math.max(0, i)), x.substring(i+1).toLowerCase() }; + } + + public static String entityEncode(String s) { + if (s == null || s.length() == 0) { + return s; + } + + StringBuilder sb = new StringBuilder(); + for (int i=0, N =s.length(); i < N; i++) { + char c = s.charAt(i); + switch (c) { + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '&': + sb.append("&"); + break; + default: + sb.append(c); + } + } + return sb.toString(); + } + + public static String entityDecode(String s) { + if (s == null || s.length() == 0) { + return s; + } + + boolean amp = false; + StringBuilder sb = new StringBuilder(); + StringBuilder ampbuf = new StringBuilder(); + for (int i=0, N =s.length(); i < N; i++) { + char c = s.charAt(i); + if (amp) { + if (c == ';') { + amp = false; + String str = ampbuf.toString(); + ampbuf.setLength(0); + if (str.equals("lt")) { + sb.append('<'); + } + else if (str.equals("gt")) { + sb.append('>'); + } + else if (str.equals("amp")) { + sb.append('&'); + } + else { + sb.append('&').append(str).append(';'); + } + } + else { + ampbuf.append(c); + } + } + else if (c=='&') { + amp = true; + } + else { + sb.append(c); + } + + } + return sb.toString(); + } + + public static final String quote(String s) { + return quote(s, '"'); + } + + public static final String quote(String s, char quoteChar) { + if (s == null) { + return null; + } + + int N = s.length(); + + if (N == 0) + return new StringBuilder(2) + .append(quoteChar) + .append(quoteChar) + .toString(); + + StringBuilder sb = null; + + int i = 0; + + for (; i < N; ++i) { + char c = s.charAt(i); + + if (Character.isWhitespace(c)) { + sb = new StringBuilder() + .append(quoteChar) + .append(s.substring(0, i+1)); + break; + } + else if (c == quoteChar) { + sb = new StringBuilder() + .append(quoteChar) + .append(s.substring(0, i)) + .append('\\') + .append(quoteChar); + break; + } + } + + if (sb == null) { + return s; + } + + for (++i; i < N; ++i) { + char c = s.charAt(i); + if (c == quoteChar || c == '\\') { + sb.append('\\'); + } + + sb.append(c); + } + + return sb.append(quoteChar).toString(); + } + + /* + public static String sprintf(String format, Object... args) { + return sprintf(null, format, args); + } + */ + + public static String sprintf(Locale locale, String format, Object ... args) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.printf(locale, format, args); + pw.flush(); + return sw.toString(); + } + + + public static void testQuote() { + System.err.println("testing quote:"); + + String cases [] = { + "", "''", + "test", "test", + "test test", "'test test'", + " test", "' test'", + "test ", "'test '", + " test ", "' test '", + "'test", "'\\'test'", + "'", "'\\''", + " ' ' ", "' \\' \\' '", + "te'st", "'te\\'st'" + }; + + int failed = 0; + + for (int i = 0; i < cases.length; i += 2) { + String in = cases[i]; + String out = cases[i+1]; + + String res = quote(in, '\''); + if (!res.equals(out)) { + ++failed; + System.err.println( + "quote failed on: >" + in + + "< result: >" + res + + "< expected: >" + out + "<"); + } + } + + int T = cases.length/2; + + System.err.println("tests total: " + T); + System.err.println("tests failed: " + failed); + System.err.println("tests passed: " + (T - failed)); + } + + public static void testQuoteReplacement() { + System.err.println("testing quoteReplacement:"); + + String cases [] = { + "", "", + "test", "test", + "$", "\\$", + "\\", "\\\\", + "\\$", "\\\\\\$", + "test\\$", "test\\\\\\$", + "\\test", "\\\\test", + "test$", "test\\$", + "test$test", "test\\$test", + "$test$", "\\$test\\$" + }; + + int failed = 0; + + for (int i = 0; i < cases.length; i += 2) { + String in = cases[i]; + String out = cases[i+1]; + + String res = quoteReplacement(in); + if (!res.equals(out)) { + ++failed; + System.err.println( + "quoteReplacement failed on: '" + in + + "' result: '" + res + + "' expected: '" + out + "'"); + } + } + + int T = cases.length/2; + + System.err.println("tests total: " + T); + System.err.println("tests failed: " + failed); + System.err.println("tests passed: " + (T - failed)); + } + + public static void testStringArray2D() { + int total = 0; + int fail = 0; + int passed = 0; + + System.err.println("testing StringArray2D:"); + + double[][] testarray = {{1.0, 2.0, 3.0}, + {1.1, 2.1, 3.1}, + {100.2, 200.2} + }; + String str = double2DArrayToString(testarray); + + total += 1; + if (str.equals("1.0;2.0;3.0:1.1;2.1;3.1:100.2;200.2")) { + passed +=1; + } + else { + fail +=1; + System.err.println("Der Ergebnis-String ist nicht richtig:"); + System.err.println(str); + } + + + + double[][] testarray2 = stringToDouble2DArray(str); + boolean failed = false; + + total +=1; + for (int i=0; i < testarray.length; i++) + for (int j=0; j < testarray[i].length; j++) + if (testarray[i][j] != testarray2[i][j]) { + System.err.println("Test scheitert bei i=" +i +" j=" +j); + System.err.println("alter Wert=" + testarray[i][j] +" neuer Wert=" +testarray2[i][j]); + failed = true; + } + if (failed) { + fail +=1; + } + else { + passed +=1; + } + System.err.println("tests total: "+ total); + System.err.println("tests failed: "+ fail); + System.err.println("tests passed: "+ passed); + } + + public static void main(String [] args) { + + testQuoteReplacement(); + testQuote(); + testStringArray2D(); + } +} +// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/test/java/de/intevation/flys/AppTest.java Fri Sep 28 12:14:07 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.flys; + +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 ); + } +}