/******************************************************************************* * Gisgraphy Project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * * Copyright 2008 Gisgraphy project * David Masclet <davidmasclet@gisgraphy.com> * * *******************************************************************************/ package com.gisgraphy.webapp.action; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Required; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import com.gisgraphy.domain.geoloc.entity.Country; import com.gisgraphy.domain.geoloc.entity.OpenStreetMap; import com.gisgraphy.domain.repository.CountryDao; import com.gisgraphy.domain.repository.IIdGenerator; import com.gisgraphy.domain.repository.IOpenStreetMapDao; import com.gisgraphy.domain.repository.ISolRSynchroniser; import com.gisgraphy.helper.GeolocHelper; import com.gisgraphy.helper.StringHelper; import com.gisgraphy.service.IInternationalisationService; import com.gisgraphy.street.StreetType; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.Preparable; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; /** * Edit Street (openstreetMap entity) action * * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> */ public class EditStreetAction extends BaseAction implements Preparable { private static final long serialVersionUID = 4785676484073350068L; private static Logger logger = LoggerFactory .getLogger(EditStreetAction.class); private IOpenStreetMapDao openStreetMapDao; private OpenStreetMap openstreetmap; private IInternationalisationService internationalisationService; private CountryDao countryDao; private IIdGenerator IdGenerator; /** * The transaction manager */ private PlatformTransactionManager transactionManager; private TransactionStatus txStatus = null; private DefaultTransactionDefinition txDefinition; private ISolRSynchroniser solRSynchroniser; /* * Those specific fields needs to be process separately because of decimal * separator or enum type */ private String latitude; private String longitude; private Float latitudeAsFloat = null; private Float longitudeAsFloat = null; private String streettype; private Long id; private String errorMessage; private String stackTrace; public String getStreettype() { return streettype; } public void setStreettype(String streettype) { this.streettype = streettype; } private String shape; /** * @return the available countries */ public List<Country> getCountries() { return countryDao.getAllSortedByName(); } public StreetType[] getStreetTypes() { return StreetType.values(); } public void prepare() { // we have to test httpparameter because prepare is called before the // setters are called HttpServletRequest request = (HttpServletRequest) ActionContext .getContext().get(ServletActionContext.HTTP_REQUEST); String parameter = request.getParameter("gid"); if (parameter != null && !parameter.equals("")) { Long idAsLong = null; try { idAsLong = Long.parseLong(parameter); } catch (NumberFormatException e) { errorMessage="gid should be numeric"; logger.error(errorMessage); } id = idAsLong; } if (openstreetmap != null && openstreetmap.getId() != null) { openstreetmap = openStreetMapDao.get(openstreetmap.getId()); } else if (id != null) { openstreetmap = openStreetMapDao.getByGid(getId()); } } public String input() { return INPUT; } public String save() { return doSave(); } public String doSave() { if (openstreetmap != null) { checkMissingRequiredfields(); //we sync the idgenerator in case an import is in progress //or several person add street simultaneously IdGenerator.sync(); if(openstreetmap.getGid()==null){ openstreetmap.setGid(generateGid()); } openstreetmap.setLocation(processPoint()); LineString shapeProcessed = processShape(); openstreetmap.setShape(shapeProcessed); openstreetmap.setStreetType(processStreettype()); openstreetmap.setLength(processLength(shapeProcessed)); if (getFieldErrors().keySet().size() > 0) { return INPUT; } else { startTransaction(); try { StringHelper.updateOpenStreetMapEntityForIndexation(openstreetmap); openStreetMapDao.save(openstreetmap); } catch (Exception e) { rollbackTransaction(); errorMessage="could not save street " + e.getMessage(); stackTrace= StringHelper.getStackTraceAsString(e); logger.error(errorMessage, e); return ERROR; } commitTransaction(); return SUCCESS; } } else { errorMessage="There is no street to save"; logger.error(errorMessage); return ERROR; } } private void checkMissingRequiredfields() { if (getLatitude()==null){ addFieldError("latitude",internationalisationService.getString("errors.required", new String[]{"latitude"}) ); } if (getLongitude()==null){ addFieldError("longitude",internationalisationService.getString("errors.required", new String[]{"longitude"}) ); } if (openstreetmap!=null && (openstreetmap.getCountryCode()==null || openstreetmap.getCountryCode().trim().equals(""))){ addFieldError("country",internationalisationService.getString("errors.required", new String[]{"country"}) ); } } protected Double processLength(LineString lineString) { Double lengthAsDouble = null; if (lineString != null) { lengthAsDouble = lineString.getLength(); } return lengthAsDouble; } private void commitTransaction() { transactionManager.commit(txStatus); solRSynchroniser.commit(); } private void rollbackTransaction() { transactionManager.rollback(txStatus); } private void startTransaction() { txDefinition = new DefaultTransactionDefinition(); txDefinition .setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txDefinition.setReadOnly(false); txStatus = transactionManager.getTransaction(txDefinition); } protected StreetType processStreettype() { if (getStreettype() != null) { StreetType type; try { type = StreetType.valueOf(getStreettype()); return type; } catch (Exception e) { logger.warn("can not determine streetType for " + getStreettype() + " : " + e); } } return null; } protected LineString processShape() { LineString lineString; if ((shape == null || "".equals(shape)) && latitudeAsFloat != null && longitudeAsFloat != null) { try { lineString = GeolocHelper.createLineString("LINESTRING (" + longitudeAsFloat + " " + latitudeAsFloat + "," + longitudeAsFloat + " " + latitudeAsFloat + ")"); } catch (Exception e) { logger.warn("can not createlinestring with lat/long " + latitudeAsFloat + "/" + longitudeAsFloat); addFieldError( "shape", internationalisationService .getString("error.wrong.lat.long.for.linestring")); return null; } } else { try { lineString = GeolocHelper.createLineString(shape); } catch (Exception e) { logger.warn("Can not determine shape for " + shape); addFieldError("shape", internationalisationService .getString("errors.invalid",new String[]{"shape"})); return null; } } return lineString; } protected Point processPoint() { try { if (latitude != null) { try { latitudeAsFloat = GeolocHelper .parseInternationalDouble(latitude); if (latitudeAsFloat < -90 || latitudeAsFloat > 90) { addFieldError("latitude", internationalisationService .getString("error.latitude.outOfRange")); } } catch (Exception e) { logger.warn("latitude : " + latitude + "is not a number"); addFieldError("latitude", internationalisationService.getString( "error.notANumber", new String[] { "latitude" })); } } if (longitude != null) { try { longitudeAsFloat = GeolocHelper .parseInternationalDouble(longitude); if (longitudeAsFloat < -180 || longitudeAsFloat > 180) { addFieldError( "longitude", internationalisationService .getString("error.longitude.outOfRange")); } } catch (Exception e) { logger.warn("longitude : " + longitude + "is not a number"); addFieldError("longitude", internationalisationService.getString( "error.notANumber", new String[] { "longitude" })); } } Point point = null; if (latitudeAsFloat != null && longitudeAsFloat != null) { point = GeolocHelper.createPoint(longitudeAsFloat, latitudeAsFloat); return point; } else { return null; } } catch (Exception e) { logger.warn("can not determine point for lat/long : " + latitude + "/" + longitude); addFieldError("latitude", internationalisationService .getString("error.not.gps.point")); return null; } } protected long generateGid() { return IdGenerator.getNextGId(); } public Long getId() { return id; } public void setId(Long id) { this.id = id; } /** * @return the max openstreetmap id found in the Datastore + an increment */ public String doDelete() { if (openstreetmap!=null){ startTransaction(); try{ openStreetMapDao.remove(openstreetmap); } catch (Exception e){ logger.error("Can not delete the street : "+e.getMessage(),e); stackTrace= StringHelper.getStackTraceAsString(e); rollbackTransaction(); return ERROR; } commitTransaction(); return SUCCESS; } else { errorMessage="there is no entity to delete"; return ERROR; } } public OpenStreetMap getOpenstreetmap() { return openstreetmap; } public String getLatitude() { return latitude; } public void setLatitude(String latitude) { this.latitude = latitude; } public String getLongitude() { return longitude; } public void setLongitude(String longitude) { this.longitude = longitude; } public String getShape() { return shape; } public void setShape(String shape) { this.shape = shape; } public void setOpenstreetmap(OpenStreetMap openstreetmap) { this.openstreetmap = openstreetmap; } public void setopenstreetmaps(OpenStreetMap openstreetmap) { this.openstreetmap = openstreetmap; } /** * @return the errorMessage */ public String getErrorMessage() { return errorMessage; } /** * @param errorMessage the errorMessage to set */ public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } /** * @return the stackTrace */ public String getStackTrace() { return stackTrace; } /** * @param stackTrace the stackTrace to set */ public void setStackTrace(String stackTrace) { this.stackTrace = stackTrace; } @Required public void setOpenStreetMapDao(IOpenStreetMapDao openStreetMapDao) { this.openStreetMapDao = openStreetMapDao; } @Required public void setCountryDao(CountryDao countryDao) { this.countryDao = countryDao; } @Required public void setTransactionManager( PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } @Required public void setInternationalisationService( IInternationalisationService internationalisationService) { this.internationalisationService = internationalisationService; } @Required public void setIdGenerator(IIdGenerator idGenerator) { IdGenerator = idGenerator; } @Required public void setSolRSynchroniser(ISolRSynchroniser solRSynchroniser) { this.solRSynchroniser = solRSynchroniser; } }