Package org.worldbank.transport.tamt.server.bo

Source Code of org.worldbank.transport.tamt.server.bo.RegionBO

package org.worldbank.transport.tamt.server.bo;

import static org.junit.Assert.assertNull;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.worldbank.transport.tamt.server.bo.RoadBO;
import org.worldbank.transport.tamt.server.bo.TagBO;
import org.worldbank.transport.tamt.server.bo.ZoneBO;
import org.worldbank.transport.tamt.server.dao.GPSTraceDAO;
import org.worldbank.transport.tamt.server.dao.RegionDAO;
import org.worldbank.transport.tamt.server.dao.RoadDAO;
import org.worldbank.transport.tamt.server.dao.TagDAO;
import org.worldbank.transport.tamt.server.dao.ZoneDAO;
import org.worldbank.transport.tamt.shared.DayTypePerYearOption;
import org.worldbank.transport.tamt.shared.DefaultFlow;
import org.worldbank.transport.tamt.shared.GPSTrace;
import org.worldbank.transport.tamt.shared.RoadDetails;
import org.worldbank.transport.tamt.shared.StudyRegion;
import org.worldbank.transport.tamt.shared.TagDetails;
import org.worldbank.transport.tamt.shared.Vertex;
import org.worldbank.transport.tamt.shared.ZoneDetails;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;

public class RegionBO {

  private RegionDAO dao;
  private GPSTraceDAO gpsTraceDAO;
  private TagDAO tagDAO;
  private TagBO tagBO;
  private RoadDAO roadDAO;
  private ZoneDAO zoneDAO;
  private boolean allFlowValuesNull;
  static Logger logger = Logger.getLogger(RegionBO.class);
 
  private static RegionBO singleton = null;
  public static RegionBO get()
  {
    if(singleton == null)
    {
      singleton = new RegionBO();
    }
    return singleton;   
  }
 
  public RegionBO()
  {
    dao = RegionDAO.get();
    gpsTraceDAO = GPSTraceDAO.get();
    tagDAO = TagDAO.get();
    roadDAO = RoadDAO.get();
    zoneDAO = ZoneDAO.get();
    tagBO = TagBO.get();
  }

  public void deleteStudyRegions(ArrayList<String> studyRegionIds) throws Exception {
    try {
      for (Iterator iterator = studyRegionIds.iterator(); iterator
          .hasNext();) {
        String studyRegionId = (String) iterator.next();
        deleteStudyRegion(studyRegionId);
      }
    } catch (SQLException e) {
      logger.error("Could not delete study regions:" + e.getMessage());
      throw new Exception("Could not delete study regions");
    }
  }

  public void deleteStudyRegion(String studyRegionId) throws Exception {
   
    // test for null string
    if( studyRegionId == null)
    {
      throw new Exception("Cannot delete a study region with null ID");
    }
   
    //TODO: eventually, this should be wrapped in a transaction
   
    try {
     
      // first, delete the study region
      logger.debug("Deleting study region: " + studyRegionId);
      dao.deleteStudyRegionById(studyRegionId);
     
      // cleans up analysis tables and supporting tables
      dao.deleteAnalysisAndSupportRecords(studyRegionId);
     
      // create a StudyRegion to be used in deleting other entities
      StudyRegion region = new StudyRegion();
      region.setId(studyRegionId);
     
      // delete gps traces (including gpsfiles and gpspoints)
      ArrayList<GPSTrace> gpsTraces = gpsTraceDAO.getGPSTraces(region);
      ArrayList<String> gpsTraceIds = new ArrayList<String>();
      for (Iterator iterator = gpsTraces.iterator(); iterator.hasNext();) {
        GPSTrace gpsTrace = (GPSTrace) iterator.next();
        gpsTraceIds.add(gpsTrace.getId());
      }
      logger.debug("Deleting GPS traces for study region: " + studyRegionId);
      gpsTraceDAO.deleteGPSTraces(gpsTraceIds);
     
      // delete zones
      ArrayList<ZoneDetails> zones = zoneDAO.getZoneDetails(region);
      ArrayList<String> zoneIds = new ArrayList<String>();
      for (Iterator iterator = zones.iterator(); iterator.hasNext();) {
        ZoneDetails zone = (ZoneDetails) iterator.next();
        zoneIds.add(zone.getId());
      }
      logger.debug("Deleting zones for study region: " + studyRegionId);
      zoneDAO.deleteZoneDetails(zoneIds)
     
      // delete roads
      ArrayList<RoadDetails> roads = roadDAO.getRoadDetails(region);
      ArrayList<String> roadIds = new ArrayList<String>();
      for (Iterator iterator = roads.iterator(); iterator.hasNext();) {
        RoadDetails road = (RoadDetails) iterator.next();
        roadIds.add(road.getId());
      }
      logger.debug("Deleting roads for study region: " + studyRegionId);
      roadDAO.deleteRoadDetails(roadIds);
     
      // delete tag
      ArrayList<TagDetails> tags = tagDAO.getTagDetails(region);
      ArrayList<String> tagIds = new ArrayList<String>();
      for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
        TagDetails tag = (TagDetails) iterator.next();
        tagIds.add(tag.getId());
      }
      logger.debug("Deleting tags for study region: " + studyRegionId);
      tagDAO.deleteTagDetails(tagIds);
     

   
    } catch (Exception e)
    {
      logger.error("Error trying to delete a study region: " + e.getMessage());
      throw new Exception("The study region was not completely deleted");
    }
   
   
  }
 
  public ArrayList<StudyRegion> getStudyRegions() throws Exception {
    return dao.getStudyRegions();
  }
 
  public StudyRegion getCurrentStudyRegion() throws Exception {
    ArrayList<StudyRegion> regions = getStudyRegions();
    StudyRegion currentStudyRegion = null;
    for (Iterator iterator = regions.iterator(); iterator.hasNext();) {
      StudyRegion studyRegion = (StudyRegion) iterator.next();
      if( studyRegion.isCurrentRegion())
      {
        currentStudyRegion = studyRegion;
        break;
      }
    }
    return currentStudyRegion;
 

  public StudyRegion saveStudyRegion(StudyRegion studyRegion) throws Exception {
   
    logger.debug("Preparing to save study region:" + studyRegion);
   
    // validate name for comma
    validateStudyRegion(studyRegion);
   
    // we want to store the Vertex array list as a JTS linestring
    ArrayList<Vertex> vertices = studyRegion.getVertices();
    if( vertices == null )
    {
      throw new Exception("Study region does not have an associated shape");
    }
   
    int vertexCount = vertices.size();
    //TODO: handle null vertices
    Coordinate[] coords = new Coordinate[vertexCount];
    for (int i = 0; i < vertexCount; i++) {
      Vertex v = vertices.get(i);
      Coordinate c = new Coordinate(v.getLng(), v.getLat());
      coords[i] = c;
    }
   
    // now create a line string from the coordinates array where null = no holes in the polygon
    LinearRing ring = new GeometryFactory().createLinearRing(coords);
    Geometry geometry = new GeometryFactory().createPolygon(ring, null);
   
    // create a point from the mapCenter vertex
    // TODO: mapCenter is null when creating a new study region.
    Vertex mapCenterVertex = studyRegion.getMapCenter();
    logger.debug("mapCenter=" + studyRegion.getMapCenter());
    Coordinate mapCenterCoord = new Coordinate(mapCenterVertex.getLng(), mapCenterVertex.getLat());
    Geometry mapCenter = new GeometryFactory().createPoint(mapCenterCoord);
   
    StudyRegion savedStudyRegion = null;
   
    try {
      if( studyRegion.getId().indexOf("TEMP") != -1 )
      {
        // create an id, and save it
        studyRegion.setId( UUID.randomUUID().toString() );
        savedStudyRegion = dao.saveStudyRegion(studyRegion, geometry, mapCenter);
       
        // After we save a study region initially, we also want
        // to create 3 special reserved word tags (Issue 67)
        TagDetails resTag = new TagDetails();
        resTag.setName("Residential");
        resTag.setDescription("#RES"); // changing the reserved word from name to description
        resTag.setRegion(studyRegion);
        tagBO.saveTagDetails(resTag);
       
        TagDetails comTag = new TagDetails();
        comTag.setName("Commercial");
        comTag.setDescription("#COM"); // changing the reserved word from name to description
        comTag.setRegion(studyRegion);
        tagBO.saveTagDetails(comTag);
       
        TagDetails indTag = new TagDetails();
        indTag.setName("Industrial");
        indTag.setDescription("#IND"); // changing the reserved word from name to description
        indTag.setRegion(studyRegion);
        tagBO.saveTagDetails(indTag);
       
      } else {
        // use the existing id to update it
        savedStudyRegion = dao.updateStudyRegion(studyRegion, geometry, mapCenter);
      }     
    } catch (SQLException e)
    {
      if( e.getMessage().indexOf("duplicate key value violates unique constraint") != -1 )
      {
        throw new Exception("A study region with that name already exists");
      } else {
        throw new Exception(e.getMessage());
      }
    } catch (Exception e)
    {
      logger.error("An unknown error occured while trying to save a study region");
      throw new Exception("An unknown error occured while trying to save a study region");
    }
   
    return savedStudyRegion;
  }

  public DayTypePerYearOption saveDayTypePerYearOption(DayTypePerYearOption option) throws Exception {
   
    logger.debug("saving option=" + option);
   
    // must have a related study region
    if( option.getRegionId() == "" )
    {
      throw new Exception("Cannot save day type option without study region id");
    }
   
    // if we don't have an ID, this is the first save
    if( option.getId() == null)
    {
      option.setId( UUID.randomUUID().toString() );
      return dao.saveDayTypePerYearOption(option);
    } else {
      // otherwise this is an update
      return dao.updateDayTypePerYearOption(option);
    }
   
  }
 
  public DayTypePerYearOption getDayTypePerYearOption(String studyRegionId) throws Exception {
    DayTypePerYearOption option = dao.getDayTypePerYearOption(studyRegionId);
    return option;
  }

  public DefaultFlow saveDefaultFlow(DefaultFlow defaultFlow) throws Exception {
   
    logger.debug("saving default flow=" + defaultFlow);
   
    // must have a tag id
    if( defaultFlow.getTagDetails() == null || defaultFlow.getTagDetails().getId().equalsIgnoreCase("") )
    {
      throw new Exception("Cannot save default flow without valid tag details");
    }
   
    // must have a study region
    if( defaultFlow.getTagDetails().getRegion() == null && defaultFlow.getTagDetails().getRegion().getId().equalsIgnoreCase("") )
    {
      throw new Exception("Cannot save default flow without valid study region");
    }
   
    /*
     * Check for any non-digit characters. Empty strings are OK, because
     * they will be cleaned next. Throw an exception the user will understand.
     */
    if( !validFlowValues(defaultFlow))
    {
      throw new Exception("Values must be positive integers");
    }
   
    /*
     * Empty form fields in the UI create empty strings. But when we save
     * the default flow, the database is expecting integers or null. So,
     * walk through every integer field. If it is empty, make it null.
     *
     * After this runs, we also know the status of allFlowValuesNull,
     * and can act accordingly. If allFlowValuesNull and first save, don't
     * save it. If allFlowValuesNull and already saved, delete it. Otherwise
     * proceed with save or update.
     */
    cleanDefaultFlowFields(defaultFlow);
   
    // if we don't have an ID, this is the first save
    if( defaultFlow.getId() == null)
    {
      // only save it if not all flow values are null
      if(!allFlowValuesNull)
      {
        defaultFlow.setId( UUID.randomUUID().toString() );
        defaultFlow = dao.saveDefaultFlow(defaultFlow);
      } else
      {
        throw new Exception("All values were empty");
      }
    } else {
      // this is an update
     
      // if all flow values are null, delete it
      //if( allFlowValuesNull )
      //{
      //  dao.deleteDefaultFlow(defaultFlow);
      //  defaultFlow = null;
      // otherwise update it
      //}  else {
        defaultFlow = dao.updateDefaultFlow(defaultFlow);
      //}
    }
   
    // refetch it to make sure weird stuff like '000000' is just '0'
    return dao.getDefaultFlow(defaultFlow);
   
  }
 
  private boolean validFlowValues(DefaultFlow defaultFlow) {

    try {
     
      validFlowValue(defaultFlow.getW2Weekday());
      validFlowValue(defaultFlow.getW2Saturday());
      validFlowValue(defaultFlow.getW2SundayHoliday());
     
      validFlowValue(defaultFlow.getW3Weekday());
      validFlowValue(defaultFlow.getW3Saturday());
      validFlowValue(defaultFlow.getW3SundayHoliday());
     
      validFlowValue(defaultFlow.getPcWeekday());
      validFlowValue(defaultFlow.getPcSaturday());
      validFlowValue(defaultFlow.getPcSundayHoliday());
     
      validFlowValue(defaultFlow.getTxWeekday());
      validFlowValue(defaultFlow.getTxSaturday());
      validFlowValue(defaultFlow.getTxSundayHoliday());
     
      validFlowValue(defaultFlow.getLdvWeekday());
      validFlowValue(defaultFlow.getLdvSaturday());
      validFlowValue(defaultFlow.getLdvSundayHoliday());
     
      validFlowValue(defaultFlow.getLdcWeekday());
      validFlowValue(defaultFlow.getLdcSaturday());
      validFlowValue(defaultFlow.getLdcSundayHoliday());
     
      validFlowValue(defaultFlow.getHdcWeekday());
      validFlowValue(defaultFlow.getHdcSaturday());
      validFlowValue(defaultFlow.getHdcSundayHoliday());
     
      validFlowValue(defaultFlow.getMdbWeekday());
      validFlowValue(defaultFlow.getMdbSaturday());
      validFlowValue(defaultFlow.getMdbSundayHoliday());
     
      validFlowValue(defaultFlow.getHdbWeekday());
      validFlowValue(defaultFlow.getHdbSaturday());
      validFlowValue(defaultFlow.getHdbSundayHoliday());
     
      return true;
     
    } catch (Exception e)
    {
      return false;
    }

  }
 
  private void validFlowValue(String value) throws Exception
  {
    // valid value can be null, empty string, or integer
    // anything else (like string or float) will throw exception
    if( value != null && !value.equalsIgnoreCase(""))
    {
      int v = Integer.parseInt(value);
      if(v < 0)
      {
        throw new Exception("Value cannot be less than zero");
      }
    }
  }

  private void cleanDefaultFlowFields(DefaultFlow defaultFlow) {
   
    allFlowValuesNull = true;
   
    defaultFlow.setW2Weekday( swapEmptyStringsForZero(defaultFlow.getW2Weekday()) );
    defaultFlow.setW2Saturday( swapEmptyStringsForZero(defaultFlow.getW2Saturday()) );
    defaultFlow.setW2SundayHoliday( swapEmptyStringsForZero(defaultFlow.getW2SundayHoliday()) );
   
    defaultFlow.setW3Weekday( swapEmptyStringsForZero(defaultFlow.getW3Weekday()) );
    defaultFlow.setW3Saturday( swapEmptyStringsForZero(defaultFlow.getW3Saturday()) );
    defaultFlow.setW3SundayHoliday( swapEmptyStringsForZero(defaultFlow.getW3SundayHoliday()) );
   
    defaultFlow.setPcWeekday( swapEmptyStringsForZero(defaultFlow.getPcWeekday()) );
    defaultFlow.setPcSaturday( swapEmptyStringsForZero(defaultFlow.getPcSaturday()) );
    defaultFlow.setPcSundayHoliday( swapEmptyStringsForZero(defaultFlow.getPcSundayHoliday()) );
   
    defaultFlow.setTxWeekday( swapEmptyStringsForZero(defaultFlow.getTxWeekday()) );
    defaultFlow.setTxSaturday( swapEmptyStringsForZero(defaultFlow.getTxSaturday()) );
    defaultFlow.setTxSundayHoliday( swapEmptyStringsForZero(defaultFlow.getTxSundayHoliday()) );
   
    defaultFlow.setLdvWeekday( swapEmptyStringsForZero(defaultFlow.getLdvWeekday()) );
    defaultFlow.setLdvSaturday( swapEmptyStringsForZero(defaultFlow.getLdvSaturday()) );
    defaultFlow.setLdvSundayHoliday( swapEmptyStringsForZero(defaultFlow.getLdvSundayHoliday()) );
   
    defaultFlow.setLdcWeekday( swapEmptyStringsForZero(defaultFlow.getLdcWeekday()) );
    defaultFlow.setLdcSaturday( swapEmptyStringsForZero(defaultFlow.getLdcSaturday()) );
    defaultFlow.setLdcSundayHoliday( swapEmptyStringsForZero(defaultFlow.getLdcSundayHoliday()) );
   
    defaultFlow.setHdcWeekday( swapEmptyStringsForZero(defaultFlow.getHdcWeekday()) );
    defaultFlow.setHdcSaturday( swapEmptyStringsForZero(defaultFlow.getHdcSaturday()) );
    defaultFlow.setHdcSundayHoliday( swapEmptyStringsForZero(defaultFlow.getHdcSundayHoliday()) );
   
    defaultFlow.setMdbWeekday( swapEmptyStringsForZero(defaultFlow.getMdbWeekday()) );
    defaultFlow.setMdbSaturday( swapEmptyStringsForZero(defaultFlow.getMdbSaturday()) );
    defaultFlow.setMdbSundayHoliday( swapEmptyStringsForZero(defaultFlow.getMdbSundayHoliday()) );
   
    defaultFlow.setHdbWeekday( swapEmptyStringsForZero(defaultFlow.getHdbWeekday()) );
    defaultFlow.setHdbSaturday( swapEmptyStringsForZero(defaultFlow.getHdbSaturday()) );
    defaultFlow.setHdbSundayHoliday( swapEmptyStringsForZero(defaultFlow.getHdbSundayHoliday()) );
   
    logger.debug("allFlowValuesNull=" + allFlowValuesNull);
   
  }
 
  private String swapEmptyStringsForZero(String field) {
    if( field.equalsIgnoreCase(""))
    {
      return null;
    } else {
      allFlowValuesNull = false;
      return field;
    }
  }

  public DefaultFlow getDefaultFlow(DefaultFlow defaultFlow) throws Exception {
    // TODO: validate tagDetails.id and StudyRegion.id
    return dao.getDefaultFlow(defaultFlow);
  }
 
  public void deleteDefaultFlow(DefaultFlow defaultFlow) throws Exception
  {
    dao.deleteDefaultFlow(defaultFlow);
  }

  public void copyStudyRegion(StudyRegion studyRegion) throws Exception {
   
    logger.debug("Copy studyregion=" + studyRegion);
    try {
      // we only validate the name on copy
      validateStudyRegionName(studyRegion);
    } catch (Exception e) {
      logger.error(e.getLocalizedMessage());
      throw e;
    }
   
    // if we did not error out, keep going
    dao.copyStudyRegion(studyRegion);
   
  }

  protected void validateStudyRegionName(StudyRegion studyRegion) throws Exception
  {
    if( studyRegion.getName().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a name");
    }   
    if( !studyRegion.getName().matches("[a-zA-Z0-9]*") )
    {
        throw new Exception("Study region cannot contain spaces or special characters");
   
 
  }
  protected void validateStudyRegion(StudyRegion studyRegion) throws Exception {
     
    // validate the name
    validateStudyRegionName(studyRegion);
   
    // commercial block length
    if( studyRegion.getUtcOffset().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a UTC offset");
    }
   
    if( !studyRegion.getUtcOffset().matches("^-{0,1}[0-9]*") )
    {
        throw new Exception("UTC offset must be an integer (in hours)");
    }
   
    // commercial block length
    if( studyRegion.getCommercialZoneBlockLength().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a commerical zone block length");
    }
   
    if( !studyRegion.getCommercialZoneBlockLength().matches("[0-9]*") )
    {
        throw new Exception("Commercial zone block length must be an integer (in meters)");
    }
   
    // residential  block length
    if( studyRegion.getResidentialZoneBlockLength().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a residential zone block length");
    }
   
    if( !studyRegion.getResidentialZoneBlockLength().matches("[0-9]*") )
    {
        throw new Exception("Residential zone block length must be an integer (in meters)");
   
   
    // industrial  block length
    if( studyRegion.getIndustrialZoneBlockLength().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a industrial zone block length");
    }
   
    if( !studyRegion.getIndustrialZoneBlockLength().matches("[0-9]*") )
    {
        throw new Exception("Industrial zone block length must be an integer (in meters)");
    }     
   
    // minimum soak interval
    if( studyRegion.getMinimumSoakInterval().equalsIgnoreCase(""))
    {
      throw new Exception("Study region must have a minimum soak interval");
    }
   
    if( !studyRegion.getMinimumSoakInterval().matches("[0-9]*") )
    {
        throw new Exception("Minimum soak interval must be an integer (in seconds)");
    }   
   
  }
}
TOP

Related Classes of org.worldbank.transport.tamt.server.bo.RegionBO

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.