view backend/src/main/java/org/dive4elements/river/importer/ImportCrossSectionLine.java @ 9709:b74f817435fe

comment removed
author dnt_bjoernsen <d.tironi@bjoernsen.de>
date Wed, 27 Jan 2021 11:47:38 +0100
parents 392bbcd8a88b
children
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.importer;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.dive4elements.river.importer.common.StoreMode;
import org.dive4elements.river.model.CrossSection;
import org.dive4elements.river.model.CrossSectionLine;
import org.dive4elements.river.model.CrossSectionPoint;
import org.hibernate.Query;
import org.hibernate.Session;

/**
 * A CrossSectionLine (containing points) ready to be transformed into a mapped
 * object and written to db (used in importer).
 */
public class ImportCrossSectionLine
{
    public static final Comparator<CrossSectionPoint> INDEX_CMP =
            new Comparator<CrossSectionPoint>() {
        @Override
        public int compare(final CrossSectionPoint a, final CrossSectionPoint b) {
            return a.getColPos().compareTo(b.getColPos());
        }
    };

    protected Double km;
    protected ImportCrossSection crossSection;
    protected List<XY> points;
    protected StoreMode storeMode;

    protected CrossSectionLine peer;

    public ImportCrossSectionLine() {
    }

    public ImportCrossSectionLine(final Double km, final List<XY> points) {
        this.km     = km;
        this.points = points;
        this.storeMode = StoreMode.NONE;
    }

    public ImportCrossSection getCrossSection() {
        return this.crossSection;
    }

    public void setCrossSection(final ImportCrossSection crossSection) {
        this.crossSection = crossSection;
    }

    public Double getKm() {
        return this.km;
    }

    public void setKm(final Double km) {
        this.km = km;
    }

    public void storeDependencies() {
        storePoints();
    }


    /** Write a line and its points. */
    protected void storePoints() {
        final CrossSectionLine csl = getPeer();
        if (this.storeMode == StoreMode.INSERT) {
            insertPoints();
            return;
        }
        final Map<CrossSectionPoint, CrossSectionPoint> map =
                new TreeMap<>(INDEX_CMP);

        // Build index for faster (index) collision lookup.
        final List<CrossSectionPoint> ps = csl.getPoints();
        if (ps != null) {
            for (final CrossSectionPoint point: ps) {
                map.put(point, point);
            }
        }

        final Session session = ImporterSession.getInstance().getDatabaseSession();

        final CrossSectionPoint key = new CrossSectionPoint();

        // Somehow it looks as if even with the map it is still possible that
        // multiple points with same id enter hibernate (and then violate a
        // constraint). -> TODO
        for (final XY xy: this.points) {
            key.setColPos(xy.getIndex());
            CrossSectionPoint csp = map.get(key);
            if (csp == null) { // create new
                csp = new CrossSectionPoint(
                        csl, key.getColPos(),
                        Double.valueOf(xy.getX()),
                        Double.valueOf(xy.getY()));
            }
            else { // update old
                csp.setX(Double.valueOf(xy.getX()));
                csp.setY(Double.valueOf(xy.getY()));
            }
            session.save(csp);
        }
    }

    /**
     * Insert the points of a new line into the database without previously querying the database
     */
    private void insertPoints() {
        final Session session = ImporterSession.getInstance().getDatabaseSession();
        for (final XY xy : this.points) {
            session.save(new CrossSectionPoint(getPeer(), xy.getIndex(), xy.getX(), xy.getY()));
        }
    }

    /** Pull database-mapped object from db, or create (and save) one. */
    public CrossSectionLine getPeer() {
        if (this.peer == null) {
            final CrossSection cs = this.crossSection.getPeer();
            final Session session = ImporterSession.getInstance().getDatabaseSession();
            List<CrossSectionLine> lines;
            if (this.crossSection.storeMode == StoreMode.INSERT)
                lines = null;
            else {
                final Query query = session.createQuery("from CrossSectionLine where crossSection=:cs and km=:km");
                query.setParameter("cs", cs);
                query.setParameter("km", this.km);
                lines = query.list();
            }
            if ((lines == null) || lines.isEmpty()) {
                this.peer = new CrossSectionLine(cs, this.km);
                session.save(this.peer);
                this.storeMode = StoreMode.INSERT;
            }
            else {
                this.peer = lines.get(0);
                this.storeMode = StoreMode.UPDATE;
            }
        }
        return this.peer;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org