sascha@167: package de.intevation.flys.model;
sascha@167: 
sascha@167: import java.io.Serializable;
ingo@468: import java.math.BigDecimal;
ingo@468: import java.util.List;
sascha@167: 
sascha@171: import javax.persistence.Entity;
sascha@171: import javax.persistence.Id;
sascha@171: import javax.persistence.Table;
sascha@171: import javax.persistence.GeneratedValue;
sascha@171: import javax.persistence.Column;
sascha@171: import javax.persistence.SequenceGenerator;
sascha@171: import javax.persistence.GenerationType;
sascha@174: import javax.persistence.JoinColumn;
sascha@174: import javax.persistence.OneToOne;
sascha@475: import javax.persistence.OneToMany;
sascha@171: 
ingo@468: import org.apache.log4j.Logger;
ingo@468: 
ingo@468: import org.hibernate.Session;
ingo@2374: import org.hibernate.SQLQuery;
ingo@468: import org.hibernate.Query;
ingo@2374: import org.hibernate.type.StandardBasicTypes;
ingo@468: 
ingo@468: import de.intevation.flys.backend.SessionHolder;
ingo@468: 
ingo@468: 
sascha@171: @Entity
sascha@171: @Table(name = "wsts")
sascha@167: public class Wst
sascha@167: implements   Serializable
sascha@167: {
ingo@468:     private static Logger logger = Logger.getLogger(Wst.class);
ingo@468: 
sascha@171:     private Integer id;
sascha@171:     private River   river;
sascha@171:     private String  description;
sascha@467:     private Integer kind;
sascha@167: 
sascha@475:     private List<WstColumn> columns;
sascha@475: 
ingo@2374: 
ingo@2374:     public static final String SQL_SELECT_MINMAX =
ingo@2374:         "select min(q) as minQ, max(q) as maxQ from wst_q_values " +
felix@2794:         "where wst_id = :wst and not (a > :km or b < :km)";
ingo@2374: 
sascha@167:     public Wst() {
sascha@167:     }
sascha@167: 
sascha@201:     public Wst(River river, String description) {
ingo@2347:         this(river, description, 0);
sascha@467:     }
sascha@467: 
ingo@2347:     public Wst(River river, String description, Integer kind) {
sascha@201:         this.river       = river;
sascha@201:         this.description = description;
sascha@467:         this.kind        = kind;
sascha@201:     }
sascha@201: 
sascha@171:     @Id
sascha@171:     @SequenceGenerator(
sascha@171:         name           = "SEQUENCE_WSTS_ID_SEQ",
sascha@171:         sequenceName   = "WSTS_ID_SEQ",
sascha@171:         allocationSize = 1)
sascha@171:     @GeneratedValue(
sascha@171:         strategy  = GenerationType.SEQUENCE,
sascha@171:         generator = "SEQUENCE_WSTS_ID_SEQ")
sascha@171:     @Column(name = "id")
sascha@171:     public Integer getId() {
sascha@171:         return id;
sascha@171:     }
sascha@171: 
sascha@168:     public void setId(Integer id) {
sascha@167:         this.id = id;
sascha@167:     }
sascha@167: 
sascha@174:     @OneToOne
sascha@174:     @JoinColumn(name = "river_id" )
sascha@174:     public River getRiver() {
sascha@174:         return river;
sascha@174:     }
sascha@174: 
sascha@167:     public void setRiver(River river) {
sascha@167:         this.river = river;
sascha@167:     }
sascha@167: 
sascha@172:     @Column(name = "description")
sascha@172:     public String getDescription() {
sascha@172:         return description;
sascha@172:     }
sascha@172: 
sascha@167:     public void setDescription(String description) {
sascha@167:         this.description = description;
sascha@167:     }
sascha@467: 
sascha@467:     @Column(name = "kind")
sascha@467:     public Integer getKind() {
sascha@467:         return kind;
sascha@467:     }
sascha@467: 
sascha@467:     public void setKind(Integer kind) {
sascha@467:         this.kind = kind;
sascha@467:     }
ingo@468: 
sascha@475:     @OneToMany
sascha@475:     @JoinColumn(name="wst_id")
sascha@475:     public List<WstColumn> getColumns() {
sascha@475:         return columns;
sascha@475:     }
sascha@475: 
sascha@475:     public void setColumns(List<WstColumn> columns) {
sascha@475:         this.columns = columns;
sascha@475:     }
ingo@468: 
ingo@2346: 
ingo@468:     /**
ingo@468:      * Determines the min and max Q values of this WST. The min value is placed
ingo@468:      * in the first field of the resulting array - the max value is placed in
ingo@468:      * the second field.
ingo@468:      *
ingo@468:      * @return the min and max Q values of this WST.
ingo@468:      */
ingo@468:     public double[] determineMinMaxQ() {
ingo@468:         double[] ab = river.determineMinMaxDistance();
ingo@468:         return determineMinMaxQ(new Range(ab[0], ab[1], river));
ingo@468:     }
ingo@468: 
ingo@468: 
ingo@468:     /**
ingo@468:      * Determines the min and max Q values of this WST in the given range. The
ingo@468:      * min value is placed in the first field of the resulting array - the max
ingo@468:      * value is placed in the second field.
ingo@468:      *
ingo@468:      * @param range The range used for querying the Q values.
ingo@468:      *
ingo@468:      * @return the min and max Q values of this WST.
ingo@468:      */
ingo@468:     public double[] determineMinMaxQ(Range range) {
ingo@2372:         if (range != null) {
ingo@2372:             return determineMinMaxQ(
ingo@2372:                 range.getA().doubleValue(),
ingo@2372:                 range.getB().doubleValue());
ingo@2372:         }
ingo@2372: 
ingo@2372:         return null;
ingo@2372:     }
ingo@2372: 
ingo@2372: 
ingo@2372:     /**
ingo@2372:      * Determines the min and max Q values of this WST in the given range. The
ingo@2372:      * min value is placed in the first field of the resulting array - the max
ingo@2372:      * value is placed in the second field.
ingo@2372:      *
ingo@2372:      * @param fromKm the lower km value.
ingo@2372:      * @param toKm the upper km value.
ingo@2372:      *
ingo@2372:      * @return the min and max Q values of this WST.
ingo@2372:      */
ingo@2372:     public double[] determineMinMaxQ(double fromKm, double toKm) {
ingo@468:         Session session = SessionHolder.HOLDER.get();
ingo@468: 
ingo@468:         Query query = session.createQuery(
ingo@468:           "select min(q), max(q) from WstQRange where " +
ingo@468:           " id in " +
ingo@468:           "  (select wstQRange.id from WstColumnQRange where " +
ingo@468:           "    wstColumn.id in (select id from WstColumn where wst.id = :wst)) " +
ingo@468:           " and range.id in " +
ingo@468:           "  (select id from Range where not (a > :end or b < :start))");
ingo@468: 
sascha@469:         query.setParameter("wst",   getId());
ingo@2372:         query.setParameter("start", new BigDecimal(fromKm));
ingo@2372:         query.setParameter("end",   new BigDecimal(toKm));
ingo@468: 
sascha@469:         List<Object []> results = query.list();
ingo@468: 
sascha@469:         if (results.isEmpty()) {
sascha@469:             return null;
sascha@469:         }
sascha@469: 
sascha@469:         Object [] result = results.get(0);
sascha@469: 
sascha@469:         return new double [] {
sascha@469:             ((BigDecimal)result[0]).doubleValue(),
sascha@469:             ((BigDecimal)result[1]).doubleValue() };
ingo@468:     }
ingo@2374: 
ingo@2374: 
ingo@2374:     public double[] determineMinMaxQFree(double km) {
ingo@2374:         Session session = SessionHolder.HOLDER.get();
ingo@2374: 
ingo@2374:         SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_MINMAX)
ingo@2374:             .addScalar("minQ", StandardBasicTypes.DOUBLE)
ingo@2374:             .addScalar("maxQ", StandardBasicTypes.DOUBLE);
ingo@2374: 
ingo@2374:         sqlQuery.setInteger("wst", getId());
ingo@2374:         sqlQuery.setDouble("km", km);
ingo@2374: 
ingo@2374:         List<Object[]> minmaxQ = sqlQuery.list();
ingo@2374: 
felix@2794: 
ingo@2374:         if (minmaxQ.isEmpty()) {
ingo@2374:             return null;
ingo@2374:         }
ingo@2374: 
ingo@2374:         Object[] mm = minmaxQ.get(0);
ingo@2374: 
felix@2794:         if (mm[0] == null || mm[1] == null) {
ingo@2795:             logger.warn ("No min/max Q for km " + km + " found.");
felix@2794:             return null;
felix@2794:         }
felix@2794: 
ingo@2374:         return new double[] { (Double) mm[0], (Double) mm[1] };
ingo@2374:     }
sascha@167: }
sascha@167: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :