teichmann@5844: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5844: * Software engineering by Intevation GmbH teichmann@5844: * teichmann@5992: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5844: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5992: * documentation coming with Dive4Elements River for details. teichmann@5844: */ teichmann@5844: teichmann@5829: package org.dive4elements.river.importer; sascha@1204: mschaefer@8986: import java.util.Comparator; sascha@1204: import java.util.List; sascha@1204: import java.util.Map; sascha@1204: import java.util.TreeMap; sascha@1204: mschaefer@8986: import org.dive4elements.river.importer.common.StoreMode; mschaefer@8986: import org.dive4elements.river.model.CrossSection; mschaefer@8986: import org.dive4elements.river.model.CrossSectionLine; mschaefer@8986: import org.dive4elements.river.model.CrossSectionPoint; mschaefer@8986: import org.hibernate.Query; mschaefer@8986: import org.hibernate.Session; mschaefer@8986: felix@4705: /** felix@4705: * A CrossSectionLine (containing points) ready to be transformed into a mapped felix@4705: * object and written to db (used in importer). felix@4705: */ sascha@1204: public class ImportCrossSectionLine sascha@1204: { sascha@1204: public static final Comparator INDEX_CMP = mschaefer@8986: new Comparator() { mschaefer@8986: @Override mschaefer@8986: public int compare(final CrossSectionPoint a, final CrossSectionPoint b) { mschaefer@8986: return a.getColPos().compareTo(b.getColPos()); mschaefer@8986: } mschaefer@8986: }; sascha@1204: felix@5047: protected Double km; sascha@1204: protected ImportCrossSection crossSection; felix@5047: protected List points; mschaefer@8986: protected StoreMode storeMode; sascha@1204: sascha@1204: protected CrossSectionLine peer; sascha@1204: sascha@1204: public ImportCrossSectionLine() { sascha@1204: } sascha@1204: mschaefer@8986: public ImportCrossSectionLine(final Double km, final List points) { sascha@1204: this.km = km; sascha@1204: this.points = points; mschaefer@8986: this.storeMode = StoreMode.NONE; sascha@1204: } sascha@1204: sascha@1204: public ImportCrossSection getCrossSection() { mschaefer@8986: return this.crossSection; sascha@1204: } sascha@1204: mschaefer@8986: public void setCrossSection(final ImportCrossSection crossSection) { sascha@1204: this.crossSection = crossSection; sascha@1204: } sascha@1204: sascha@2860: public Double getKm() { mschaefer@8986: return this.km; sascha@1204: } sascha@1204: mschaefer@8986: public void setKm(final Double km) { sascha@1204: this.km = km; sascha@1204: } sascha@1204: sascha@1204: public void storeDependencies() { sascha@1204: storePoints(); sascha@1204: } sascha@1204: felix@4705: felix@4705: /** Write a line and its points. */ sascha@1204: protected void storePoints() { mschaefer@8986: final CrossSectionLine csl = getPeer(); mschaefer@8986: if (this.storeMode == StoreMode.INSERT) { mschaefer@8986: insertPoints(); mschaefer@8986: return; mschaefer@8986: } mschaefer@8986: final Map map = mschaefer@8986: new TreeMap<>(INDEX_CMP); sascha@1204: felix@4705: // Build index for faster (index) collision lookup. mschaefer@8986: final List ps = csl.getPoints(); sascha@1205: if (ps != null) { mschaefer@8986: for (final CrossSectionPoint point: ps) { sascha@1205: map.put(point, point); sascha@1205: } sascha@1204: } sascha@1204: mschaefer@8986: final Session session = ImporterSession.getInstance().getDatabaseSession(); sascha@1204: mschaefer@8986: final CrossSectionPoint key = new CrossSectionPoint(); sascha@1204: felix@4705: // Somehow it looks as if even with the map it is still possible that felix@4705: // multiple points with same id enter hibernate (and then violate a felix@4705: // constraint). -> TODO mschaefer@8986: for (final XY xy: this.points) { sascha@1204: key.setColPos(xy.getIndex()); sascha@1204: CrossSectionPoint csp = map.get(key); sascha@1204: if (csp == null) { // create new sascha@1204: csp = new CrossSectionPoint( mschaefer@8986: csl, key.getColPos(), mschaefer@8986: Double.valueOf(xy.getX()), mschaefer@8986: Double.valueOf(xy.getY())); sascha@1204: } sascha@1204: else { // update old sascha@2860: csp.setX(Double.valueOf(xy.getX())); sascha@2860: csp.setY(Double.valueOf(xy.getY())); sascha@1204: } sascha@1204: session.save(csp); sascha@1204: } sascha@1204: } sascha@1204: mschaefer@8986: /** mschaefer@8986: * Insert the points of a new line into the database without previously querying the database mschaefer@8986: */ mschaefer@8986: private void insertPoints() { mschaefer@8986: final Session session = ImporterSession.getInstance().getDatabaseSession(); mschaefer@8986: for (final XY xy : this.points) { mschaefer@8986: session.save(new CrossSectionPoint(getPeer(), xy.getIndex(), xy.getX(), xy.getY())); mschaefer@8986: } mschaefer@8986: } mschaefer@8986: felix@6280: /** Pull database-mapped object from db, or create (and save) one. */ sascha@1204: public CrossSectionLine getPeer() { mschaefer@8986: if (this.peer == null) { mschaefer@8986: final CrossSection cs = this.crossSection.getPeer(); mschaefer@8986: final Session session = ImporterSession.getInstance().getDatabaseSession(); mschaefer@8986: List lines; mschaefer@8986: if (this.crossSection.storeMode == StoreMode.INSERT) mschaefer@8986: lines = null; mschaefer@8986: else { mschaefer@8986: final Query query = session.createQuery("from CrossSectionLine where crossSection=:cs and km=:km"); mschaefer@8986: query.setParameter("cs", cs); mschaefer@8986: query.setParameter("km", this.km); mschaefer@8986: lines = query.list(); mschaefer@8986: } mschaefer@8986: if ((lines == null) || lines.isEmpty()) { mschaefer@8986: this.peer = new CrossSectionLine(cs, this.km); mschaefer@8986: session.save(this.peer); mschaefer@8986: this.storeMode = StoreMode.INSERT; sascha@1204: } sascha@1204: else { mschaefer@8986: this.peer = lines.get(0); mschaefer@8986: this.storeMode = StoreMode.UPDATE; sascha@1204: } sascha@1204: } mschaefer@8986: return this.peer; sascha@1204: } sascha@1204: } sascha@1204: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :