Package net.sf.chellow.physical

Source Code of net.sf.chellow.physical.Channel

/*******************************************************************************
*
*  Copyright (c) 2005, 2012 Wessex Water Services Limited
*  This file is part of Chellow.
*
*  Chellow is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  Chellow is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with Chellow.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/

package net.sf.chellow.physical;

import java.math.BigDecimal;
import java.net.URI;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;

import net.sf.chellow.hhimport.HhDatumRaw;
import net.sf.chellow.monad.Hiber;
import net.sf.chellow.monad.HttpException;
import net.sf.chellow.monad.InternalException;
import net.sf.chellow.monad.Invocation;
import net.sf.chellow.monad.MonadUtils;
import net.sf.chellow.monad.Urlable;
import net.sf.chellow.monad.UserException;
import net.sf.chellow.monad.XmlTree;
import net.sf.chellow.monad.types.MonadUri;
import net.sf.chellow.monad.types.UriPathElement;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Channel extends PersistentEntity {

  private SupplyGeneration supplyGeneration;

  private boolean isImport;

  private boolean isKwh;

  public Channel() {
  }

  public Channel(SupplyGeneration supplyGeneration, boolean isImport,
      boolean isKwh) {
    this.supplyGeneration = supplyGeneration;
    this.isImport = isImport;
    this.isKwh = isKwh;
  }

  public SupplyGeneration getSupplyGeneration() {
    return supplyGeneration;
  }

  void setSupplyGeneration(SupplyGeneration supplyGeneration) {
    this.supplyGeneration = supplyGeneration;
  }

  public boolean getIsImport() {
    return isImport;
  }

  void setIsImport(boolean isImport) {
    this.isImport = isImport;
  }

  public boolean getIsKwh() {
    return isKwh;
  }

  void setIsKwh(boolean isKwh) {
    this.isKwh = isKwh;
  }

  public void siteCheck(HhStartDate from, HhStartDate to)
      throws HttpException {
    if (isKwh) {
      Site site = supplyGeneration.getSiteSupplyGenerations().iterator()
          .next().getSite();
      HhStartDate checkFrom = from.getDate().after(
          supplyGeneration.getStartDate().getDate()) ? from
          : supplyGeneration.getStartDate();
      HhStartDate checkTo = supplyGeneration.getFinishDate() == null
          || to.getDate().before(
              supplyGeneration.getFinishDate().getDate()) ? to
          : supplyGeneration.getFinishDate();
      site.hhCheck(checkFrom, checkTo);
    }
  }

  public ChannelSnags snagsInstance() {
    return new ChannelSnags(this);
  }

  public void addSnag(String description, HhStartDate startDate,
      HhStartDate finishDate) throws HttpException {
    SnagDateBounded
        .addChannelSnag(this, description, startDate, finishDate);
  }

  void deleteSnag(String description, HhStartDate startDate,
      HhStartDate finishDate) throws HttpException {
    SnagDateBounded.deleteChannelSnag(this, description, startDate,
        finishDate);
  }

  public void deleteSnag(String description, HhStartDate date)
      throws HttpException {
    deleteSnag(description, date, date);
  }

  public void deleteData(HhStartDate from, HhStartDate to)
      throws HttpException {
    long numDeleted = Hiber
        .session()
        .createQuery(
            "delete from HhDatum datum where datum.channel = :channel and datum.startDate.date >= :from and datum.startDate.date <= :to")
        .setEntity("channel", this)
        .setTimestamp("from", from.getDate())
        .setTimestamp("to", to.getDate()).executeUpdate();
    if (numDeleted == 0) {
      throw new UserException(
          "There aren't any data to delete for this period.");
    }
    addSnag(ChannelSnag.SNAG_MISSING, from, to);
    siteCheck(from, to);
  }

  public Element toXml(Document doc) throws HttpException {
    Element element = super.toXml(doc, "channel");
    element.setAttribute("is-import", Boolean.toString(isImport));
    element.setAttribute("is-kwh", Boolean.toString(isKwh));
    return element;
  }

  private Document document() throws HttpException {
    Document doc = MonadUtils.newSourceDocument();
    Element source = doc.getDocumentElement();
    source.appendChild(toXml(doc, new XmlTree("supplyGeneration",
        new XmlTree("supply"))));
    return doc;
  }

  public void httpGet(Invocation inv) throws HttpException {
    inv.sendOk(document());
  }

  public void httpPost(Invocation inv) throws HttpException {
    Hiber.setReadWrite();
    try {
      if (inv.hasParameter("delete")) {
        supplyGeneration.deleteChannel(isImport, isKwh);
        Hiber.commit();
        inv.sendSeeOther(supplyGeneration.getChannelsInstance()
            .getEditUri());
      }
    } catch (HttpException e) {
      e.setDocument(document());
      throw e;
    }
  }

  public HhData getHhDataInstance() {
    return new HhData(this);
  }

  public Urlable getChild(UriPathElement uriId) throws HttpException {
    if (HhData.URI_ID.equals(uriId)) {
      return new HhData(this);
    } else if (ChannelSnags.URI_ID.equals(uriId)) {
      return snagsInstance();
    } else {
      return null;
    }
  }

  public MonadUri getEditUri() throws HttpException {
    return supplyGeneration.getChannelsInstance().getEditUri()
        .resolve(getUriId()).append("/");
  }

  public String toString() {
    return "Channel id: " + getId() + "is import: " + getIsImport()
        + " is kWh: " + getIsKwh();
  }

  @SuppressWarnings({ "unchecked", "deprecation" })
  public void addHhData(List<HhDatumRaw> dataRaw) throws HttpException {
    // long now = System.currentTimeMillis();
    HhDatumRaw firstRawDatum = dataRaw.get(0);
    HhDatumRaw lastRawDatum = dataRaw.get(dataRaw.size() - 1);
    // Debug.print("First dr = " + firstRawDatum + " cond dr " +
    // lastRawDatum);
    List<HhDatum> data = (List<HhDatum>) Hiber
        .session()
        .createQuery(
            "from HhDatum datum where datum.channel = :channel and "
                + "datum.startDate.date >= :startDate and datum.startDate.date <= :finishDate order by datum.startDate.date")
        .setEntity("channel", this)
        .setTimestamp("startDate",
            firstRawDatum.getStartDate().getDate())
        .setTimestamp("finishDate",
            lastRawDatum.getStartDate().getDate()).list();
    HhStartDate siteCheckFrom = null;
    HhStartDate siteCheckTo = null;
    HhStartDate notActualFrom = null;
    HhStartDate notActualTo = null;
    HhStartDate deleteMissingFrom = null;
    HhStartDate deleteMissingTo = null;
    HhStartDate lastAdditionDate = null;
    HhStartDate prevStartDate = null;
    int missing = 0;
    BigDecimal originalDatumValue = new BigDecimal(0);
    char originalDatumStatus = Character.UNASSIGNED;
    Connection con = Hiber.session().connection();
    PreparedStatement stmt;
    try {
      stmt = con
          .prepareStatement("INSERT INTO hh_datum VALUES (nextval('hh_datum_id_sequence'), ?, ?, ?, ?)");
    } catch (SQLException e1) {
      throw new InternalException(e1);
    }
    int batchSize = 0;
    for (int i = 0; i < dataRaw.size(); i++) {
      // Debug.print("Start processing hh: " + (System.currentTimeMillis()
      // - now));
      boolean added = false;
      boolean altered = false;
      HhDatumRaw datumRaw = dataRaw.get(i);
      HhDatum datum = null;

      if (i - missing < data.size()) {
        datum = data.get(i - missing);
        if (!datumRaw.getStartDate().equals(datum.getStartDate())) {
          datum = null;
        }
      }
      if (datum == null) {
        // Debug.print("About to save datum: "
        // + (System.currentTimeMillis() - now));
        try {
          stmt.setLong(1, getId());

          stmt.setTimestamp(2, new Timestamp(datumRaw.getStartDate()
              .getDate().getTime()));
          stmt.setBigDecimal(3, datumRaw.getValue());
          stmt.setString(4, Character.toString(datumRaw.getStatus()));
          stmt.addBatch();
          batchSize++;
        } catch (SQLException e) {
          throw new InternalException(e);
        }
        // Debug.print("Saved datum: "
        // + (System.currentTimeMillis() - now));
        // Hiber.flush();
        lastAdditionDate = datumRaw.getStartDate();
        added = true;
        missing++;
        if (deleteMissingFrom == null) {
          deleteMissingFrom = datumRaw.getStartDate();
        }
        deleteMissingTo = datumRaw.getStartDate();
        // Debug.print("Resolved missing: "
        // + (System.currentTimeMillis() - now));
      } else if (datumRaw.getValue().doubleValue() != datum.getValue()
          .doubleValue() || datumRaw.getStatus() != datum.getStatus()) {
        // Debug.print("About to update datum: " + datum + " with " +
        // datumRaw + " "
        // + (System.currentTimeMillis() - now));
        originalDatumValue = datum.getValue();
        originalDatumStatus = datum.getStatus();
        datum.update(datumRaw.getValue(), datumRaw.getStatus());
        Hiber.flush();
        altered = true;
      }
      // Debug.print("About to see if changed: "
      // + (System.currentTimeMillis() - now));
      if (added || altered) {
        if (siteCheckFrom == null) {
          siteCheckFrom = datumRaw.getStartDate();
        }
        siteCheckTo = datumRaw.getStartDate();
        if (datumRaw.getValue().doubleValue() < 0) {
          addSnag(ChannelSnag.SNAG_NEGATIVE, datumRaw.getStartDate(),
              datumRaw.getStartDate());
        } else if (altered && originalDatumValue.doubleValue() < 0) {
          deleteSnag(ChannelSnag.SNAG_NEGATIVE,
              datumRaw.getStartDate());
        }
        if (HhDatum.ACTUAL != datumRaw.getStatus()) {
          if (notActualFrom == null) {
            notActualFrom = datumRaw.getStartDate();
          }
          notActualTo = datumRaw.getStartDate();
        } else if (altered && originalDatumStatus != HhDatum.ACTUAL) {
          deleteSnag(ChannelSnag.SNAG_ESTIMATED,
              datumRaw.getStartDate());
        }
      }
      if (lastAdditionDate != null
          && (lastAdditionDate.equals(prevStartDate) || batchSize > 100)) {
        // Debug.print("About to execute batch "
        // + (System.currentTimeMillis() - now));
        try {
          stmt.executeBatch();
          // Debug.print("Added  lines.");
          batchSize = 0;
        } catch (SQLException e) {
          throw new InternalException(e);
        }
        lastAdditionDate = null;
      }
      if (siteCheckTo != null && siteCheckTo.equals(prevStartDate)) {
        // Debug.print("About to do site check: "
        // + (System.currentTimeMillis() - now));
        siteCheck(siteCheckFrom, siteCheckTo);
        siteCheckFrom = null;
        siteCheckTo = null;
        // Debug.print("Finished site check: "
        // + (System.currentTimeMillis() - now));
      }
      if (notActualTo != null && notActualTo.equals(prevStartDate)) {
        // Debug.print("Started not actual: "
        // + (System.currentTimeMillis() - now));
        addSnag(ChannelSnag.SNAG_ESTIMATED, notActualFrom, notActualTo);
        // Debug.print("Finished not actual: "
        // + (System.currentTimeMillis() - now));
        notActualFrom = null;
        notActualTo = null;
      }
      if (deleteMissingTo != null
          && deleteMissingTo.equals(prevStartDate)) {
        // Debug.print("Starting resolvedMissing: "
        // + (System.currentTimeMillis() - now));
        deleteSnag(ChannelSnag.SNAG_MISSING, deleteMissingFrom,
            deleteMissingTo);
        deleteMissingFrom = null;
        deleteMissingTo = null;
        // Debug.print("Finished resolveMissing: "
        // + (System.currentTimeMillis() - now));
      }
      prevStartDate = datumRaw.getStartDate();
    }
    if (lastAdditionDate != null && lastAdditionDate.equals(prevStartDate)) {
      // Debug.print("About to execute batch 2: "
      // + (System.currentTimeMillis() - now));
      try {
        stmt.executeBatch();
      } catch (SQLException e) {
        throw new InternalException(e);
      }
      lastAdditionDate = null;
    }
    if (siteCheckTo != null && siteCheckTo.equals(prevStartDate)) {
      // Debug.print("About to start site thing 2: "
      // + (System.currentTimeMillis() - now));
      siteCheck(siteCheckFrom, siteCheckTo);
      // Debug.print("About to finish site thing 2: "
      // + (System.currentTimeMillis() - now));
    }
    if (notActualTo != null && notActualTo.equals(prevStartDate)) {
      // Debug.print("About to start not actual 2: "
      // + (System.currentTimeMillis() - now));
      addSnag(ChannelSnag.SNAG_ESTIMATED, notActualFrom, notActualTo);
      // Debug.print("About to finsih not actual 2: "
      // + (System.currentTimeMillis() - now));
    }
    if (deleteMissingTo != null && deleteMissingTo.equals(prevStartDate)) {
      // Debug.print("About to start resolvem 2: "
      // + (System.currentTimeMillis() - now));
      deleteSnag(ChannelSnag.SNAG_MISSING, deleteMissingFrom,
          deleteMissingTo);
      // Debug.print("About to finish resolvem 2: "
      // + (System.currentTimeMillis() - now));
    }
    // Debug.print("Finished method 2: " + (System.currentTimeMillis() -
    // now));
  }

  @SuppressWarnings("unchecked")
  public void onSupplyGenerationChange() throws HttpException {
    List<ChannelSnag> snags = (List<ChannelSnag>) Hiber
        .session()
        .createQuery(
            "from ChannelSnag snag where snag.channel = :channel and snag.startDate.date < snag.channel.supplyGeneration.startDate.date order by snag.startDate.date")
        .setEntity("channel", this).list();
    if (!snags.isEmpty()) {
      HhStartDate startDate = snags.get(0).getStartDate();
      HhStartDate finishDate = supplyGeneration.getStartDate()
          .getPrevious();
      deleteSnag(ChannelSnag.SNAG_MISSING, startDate, finishDate);
      deleteSnag(ChannelSnag.SNAG_DATA_IGNORED, startDate, finishDate);
      deleteSnag(ChannelSnag.SNAG_NEGATIVE, startDate, finishDate);
      deleteSnag(ChannelSnag.SNAG_ESTIMATED, startDate, finishDate);
    }
    if (supplyGeneration.getFinishDate() != null) {
      HhStartDate startDate = supplyGeneration.getFinishDate().getNext();
      deleteSnag(ChannelSnag.SNAG_MISSING, startDate, null);
      deleteSnag(ChannelSnag.SNAG_DATA_IGNORED, startDate, null);
      deleteSnag(ChannelSnag.SNAG_NEGATIVE, startDate, null);
      deleteSnag(ChannelSnag.SNAG_ESTIMATED, startDate, null);
    }

    // find date of first datum
    HhDatum firstDatum = (HhDatum) Hiber
        .session()
        .createQuery(
            "from HhDatum datum where datum.channel = :channel order by datum.startDate.date")
        .setEntity("channel", this).setMaxResults(1).uniqueResult();
    if (firstDatum == null) {
      addSnag(ChannelSnag.SNAG_MISSING, supplyGeneration.getStartDate(),
          supplyGeneration.getFinishDate());
    } else {
      if (firstDatum.getStartDate().getDate()
          .after(supplyGeneration.getStartDate().getDate())) {
        addSnag(ChannelSnag.SNAG_MISSING,
            supplyGeneration.getStartDate(), firstDatum
                .getStartDate().getPrevious());
      }
      HhDatum lastDatum = (HhDatum) Hiber
          .session()
          .createQuery(
              "from HhDatum datum where datum.channel = :channel order by datum.startDate.date desc")
          .setEntity("channel", this).setMaxResults(1).uniqueResult();
      if (supplyGeneration.getFinishDate() == null
          || lastDatum.getStartDate().getDate()
              .before(supplyGeneration.getFinishDate().getDate())) {
        addSnag(ChannelSnag.SNAG_MISSING, lastDatum.getStartDate()
            .getNext(), supplyGeneration.getFinishDate());
      }
    }
  }

  @Override
  public URI getViewUri() throws HttpException {
    // TODO Auto-generated method stub
    return null;
  }
}
TOP

Related Classes of net.sf.chellow.physical.Channel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.