/* Spatial Operations & Editing Tools for uDig * * Axios Engineering under a funding contract with: * Diputación Foral de Gipuzkoa, Ordenación Territorial * * http://b5m.gipuzkoa.net * http://www.axios.es * * (C) 2006, Diputación Foral de Gipuzkoa, Ordenación Territorial (DFG-OT). * DFG-OT agrees to licence under Lesser General Public License (LGPL). * * 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; version 2.1 of the License. * * 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. */ package es.axios.udig.spatialoperations.internal.processmanager; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.List; import java.util.logging.Logger; import net.refractions.udig.catalog.ICatalog; import net.refractions.udig.catalog.IGeoResource; import net.refractions.udig.project.ILayer; import net.refractions.udig.project.IMap; import net.refractions.udig.project.internal.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.geotools.data.FeatureStore; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.GeometryDescriptor; import com.vividsolutions.jts.geom.Geometry; import es.axios.udig.spatialoperations.internal.i18n.Messages; import es.axios.udig.ui.commons.mediator.AppGISMediator; import es.axios.udig.ui.commons.util.GeometryUtil; public abstract class AbstractProcess implements ISOProcess { private static final Logger LOGGER = Logger.getLogger(AbstractProcess.class.getName()); private IProgressMonitor monitor = null; /** * initialize the process * @throws SOProcessException */ protected void init(IProgressMonitor monitor) throws SOProcessException { if(monitor == null) throw new SOProcessException("the monitor value can not be null"); //$NON-NLS-1$ this.monitor = monitor; } /** * @return Returns the monitor. */ protected final IProgressMonitor getMonitor() { assert this.monitor != null; return this.monitor; } /** * @param monitor The monitor to set. */ protected final void setMonitor( IProgressMonitor monitor ) { this.monitor = monitor; } /** * log the exception and throw to caller * @param exception * @throws SOProcessException */ protected void throwException( SOProcessException exception ) throws SOProcessException { LOGGER.severe(exception.getMessage()); throw exception; } /** * Adds a new layer to map using the georesource of the feature sotre * * @param map * @param geoResource * * @return the new layer */ protected ILayer addLayerToMap(IMap map, IGeoResource geoResource) { int index = map.getMapLayers().size(); List< ? extends ILayer> listLayer = AppGISMediator.addLayersToMap(map, Collections.singletonList(geoResource), index); assert listLayer.size() == 1; // creates only one layer ILayer layer = listLayer.get(0); return layer; } /** * Gets the store required to save the new features. * * @param layer * @return a feature store * @throws SOProcessException if can get the store */ public static FeatureStore<SimpleFeatureType, SimpleFeature> getFeatureStore( final ILayer layer ) throws SOProcessException { SimpleFeatureType featureType = layer.getSchema(); IGeoResource resource = layer.getGeoResource(); FeatureStore<SimpleFeatureType, SimpleFeature> store = getTargetFeatureStore(resource, featureType); return store; } /** * Returns the target FeatureStore<SimpleFeatureType, SimpleFeature> for the operation. * <p> * If it comes from an existing layer, it is returned. If it has to be created because the user * have selected the "create new layer" option, a new temporary IGeoResource is created * </p> * @param resource * @param featureType * @return the FeatureStore<SimpleFeatureType, SimpleFeature> for the generated features, either if it comes from an existing * layer or a new one had to be created * @throws SOProcessException */ private static FeatureStore<SimpleFeatureType, SimpleFeature> getTargetFeatureStore(IGeoResource resource, SimpleFeatureType featureType) throws SOProcessException { try { if (resource == null) { // new resourece is required because new layer was selected final ICatalog catalog = AppGISMediator.getCatalog(); assert catalog != null; resource = catalog.createTemporaryResource(featureType); } final FeatureStore<SimpleFeatureType, SimpleFeature> targetStore; targetStore = resource.resolve(FeatureStore.class, new NullProgressMonitor()); return targetStore; } catch (IOException e) { LOGGER.severe(e.getMessage()); final String msg = Messages.AbstractProcess_failed_getting_feature_store; throw new SOProcessException(msg); } } /** * Returns the muli geometry required by the feature * * @param geometry must be simple geometry (point, polygon, linestring) * @param feature * @return adjusted geometry */ public static Geometry adjustGeometryAttribute( final Geometry geometry, final SimpleFeature feature ) { GeometryDescriptor geoAttr = feature.getFeatureType().getDefaultGeometry(); Class geomClass = geoAttr.getType().getBinding(); Geometry adjustedGeom = GeometryUtil.adapt(geometry, geomClass); return adjustedGeom; } /** * If the user cancel this process throw the InterruptedException * * @throws InterruptedException */ protected void checkCancelation() throws InterruptedException{ if (this.monitor.isCanceled()) { throw new InterruptedException(); } } public abstract void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException ; /** * Presents the result of porcess */ protected void endProcess(final Map map, final ILayer targetLayer) { assert map != null; assert targetLayer != null; // FIXME Hack to solve the target layer refresh // Note: we need confirm the transaction before refresh, the following sentences are a // possible solution try { map.getEditManagerInternal().commitTransaction(); } catch (IOException e) { LOGGER.severe(e.getMessage()); throw (RuntimeException) new RuntimeException().initCause(e); } targetLayer.refresh(null); // I think this don't work for this strategy } }