/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2007 by:
Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.igeo.commands.model;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.sf.ehcache.Cache;
import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.util.HttpUtils;
import org.deegree.graphics.sld.UserStyle;
import org.deegree.igeo.config.DirectStyleType;
import org.deegree.igeo.config.OnlineResourceType;
import org.deegree.igeo.config.Util;
import org.deegree.igeo.config.WFSDatasourceType;
import org.deegree.igeo.config.ServiceDatasourceType.CapabilitiesURL;
import org.deegree.igeo.config.WFSDatasourceType.GetFeatureRequest;
import org.deegree.igeo.dataadapter.DataAccessException;
import org.deegree.igeo.mapmodel.AuthenticationInformation;
import org.deegree.igeo.mapmodel.Datasource;
import org.deegree.igeo.mapmodel.Layer;
import org.deegree.igeo.mapmodel.LayerGroup;
import org.deegree.igeo.mapmodel.MapModel;
import org.deegree.igeo.mapmodel.NamedStyle;
import org.deegree.igeo.mapmodel.WFSDatasource;
import org.deegree.igeo.settings.Settings;
import org.deegree.igeo.views.DialogFactory;
import org.deegree.kernel.AbstractCommand;
import org.deegree.kernel.Command;
import org.deegree.model.Identifier;
import org.deegree.model.filterencoding.Filter;
import org.deegree.ogcwebservices.OWSUtils;
import org.deegree.ogcwebservices.getcapabilities.GetCapabilities;
import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
import org.deegree.ogcwebservices.wfs.XMLFactory;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
import org.deegree.ogcwebservices.wfs.operation.GetFeature;
import org.deegree.ogcwebservices.wfs.operation.Query;
/**
* {@link Command} implementation for adding a layer based on a WFS feature type to a {@link MapModel}
*
* @author <a href="mailto:buesching@lat-lon.de">Lyn Buesching</a>
* @author last edited by: $Author$
*
* @version $Revision$, $Date$
*
*/
public class AddWFSLayerCommand extends AbstractCommand {
public static final QualifiedName commandName = new QualifiedName( "add layer from WFS command" );
private MapModel mapModel;
private WFSCapabilities wfsCapabilities;
private URL capabilitiesURL;
private WFSFeatureType featureType;
private QualifiedName geometryProp;
private String serviceName;
private String serviceTitle;
private String serviceAbstract;
private List<org.deegree.igeo.config.LayerType.MetadataURL> metadataURLs = new ArrayList<org.deegree.igeo.config.LayerType.MetadataURL>();
private String dsName;
private double minScaleDenominator = 0;
private double maxScaleDenominator = 9E99;
private Filter filter;
private Layer newLayer;
private boolean performed = false;
private boolean lazyLoading = false;
/**
*
* @param mapModel
* the mapModel to add the new layer
* @param wfsCapabilities
* the capabilities of the new data source
* @param featureType
* the featureType to add as new layer
* @param geometryProp
* the geometry of the featureType to add as new layer
* @param filter
* the filter
*/
public AddWFSLayerCommand( MapModel mapModel, WFSCapabilities wfsCapabilities, WFSFeatureType featureType,
QualifiedName geometryProp, Filter filter ) {
this.mapModel = mapModel;
try {
String s = OWSUtils.getHTTPGetOperationURL( wfsCapabilities, GetCapabilities.class ).toExternalForm();
s = OWSUtils.validateHTTPGetBaseURL( s );
this.capabilitiesURL = new URL( s + "version=" + wfsCapabilities.getVersion()
+ "&service=WFS&request=GetCapabilities" );
} catch ( MalformedURLException e ) {
throw new DataAccessException( e );
}
this.wfsCapabilities = wfsCapabilities;
this.featureType = featureType;
this.geometryProp = geometryProp;
this.serviceName = UUID.randomUUID().toString();
String title;
if ( featureType.getTitle() != null && featureType.getTitle().length() > 0 ) {
title = featureType.getTitle();
} else {
title = featureType.getName().getLocalName();
}
this.serviceTitle = title;
this.serviceAbstract = featureType.getAbstract();
String dsName = featureType.getName().getLocalName();
if ( wfsCapabilities.getServiceIdentification() != null
&& wfsCapabilities.getServiceIdentification().getName() != null ) {
dsName = dsName + " " + wfsCapabilities.getServiceIdentification().getName();
}
this.dsName = dsName;
this.filter = filter;
}
/**
*
* @param mapModel
* the mapModel to add the new layer
* @param wfsCapabilities
* the capabilities of the new datasource
* @param featureType
* the featureType to add as new layer
* @param geometryProp
* the geometry of the featureType to add as new layer
* @param filter
* the filter
* @param serviceName
* the name of the new layer
* @param serviceTitle
* the title of the new layer
* @param serviceAbstract
* the abstract of the new layer
* @param dsName
* the name of the new data source
* @param minScaleDenominator
* the minScaleDenominator of the new data source
* @param maxScaleDenominator
* the maxScaleDenominator of the new data source
*/
public AddWFSLayerCommand( MapModel mapModel, WFSCapabilities wfsCapabilities, WFSFeatureType featureType,
QualifiedName geometryProp, Filter filter, String serviceName, String serviceTitle,
String serviceAbstract, String dsName, double minScaleDenominator,
double maxScaleDenominator, boolean lazyLoading ) {
this.mapModel = mapModel;
try {
String s = HttpUtils.normalizeURL( OWSUtils.getHTTPGetOperationURL( wfsCapabilities, GetCapabilities.class ) );
s = OWSUtils.validateHTTPGetBaseURL( s );
this.capabilitiesURL = new URL( s + "version=" + wfsCapabilities.getVersion()
+ "&service=WFS&request=GetCapabilities" );
} catch ( MalformedURLException e ) {
throw new DataAccessException( e );
}
this.wfsCapabilities = wfsCapabilities;
this.featureType = featureType;
this.geometryProp = geometryProp;
this.serviceName = serviceName;
this.serviceTitle = serviceTitle;
this.serviceAbstract = serviceAbstract;
this.dsName = dsName;
// read meatadataURLs out of the featureType
MetadataURL[] metadataUrls = this.featureType.getMetadataUrls();
for ( int i = 0; i < metadataUrls.length; i++ ) {
org.deegree.igeo.config.LayerType.MetadataURL mu = new org.deegree.igeo.config.LayerType.MetadataURL();
OnlineResourceType ort = new OnlineResourceType();
ort.setHref( metadataUrls[i].getOnlineResource().toExternalForm() );
mu.setOnlineResource( ort );
this.metadataURLs.add( mu );
}
this.minScaleDenominator = minScaleDenominator;
this.maxScaleDenominator = maxScaleDenominator;
this.filter = filter;
this.lazyLoading = lazyLoading;
}
/*
* (non-Javadoc)
*
* @see org.deegree.kernel.Command#execute()
*/
public void execute()
throws Exception {
try {
List<Datasource> datasources = new ArrayList<Datasource>();
AuthenticationInformation authenticationInformation = null;
Cache cache = null;
QualifiedName qn = featureType.getName();
Query query = Query.create( null, null, null, null, null, new QualifiedName[] { qn }, null, null,
this.filter, -1, 1, GetFeature.RESULT_TYPE.RESULTS );
GetFeature getFeature = GetFeature.create( this.wfsCapabilities.getVersion(), "addLayer",
GetFeature.RESULT_TYPE.RESULTS, GetFeature.FORMAT_GML3, "", -1,
0, -1, -1, new Query[] { query } );
WFSDatasourceType dsType = new WFSDatasourceType();
dsType.setName( this.dsName );
dsType.setMinScaleDenominator( minScaleDenominator );
dsType.setMaxScaleDenominator( maxScaleDenominator );
dsType.setEditable( true );
dsType.setQueryable( true );
dsType.setLazyLoading( lazyLoading );
dsType.setSupportToolTips( true );
dsType.setGeometryProperty( Util.convertQualifiedName( this.geometryProp ) );
dsType.setNativeCRS( featureType.getDefaultSRS().toASCIIString() );
CapabilitiesURL cu = new CapabilitiesURL();
OnlineResourceType ort = new OnlineResourceType();
ort.setHref( this.capabilitiesURL.toExternalForm() );
cu.setOnlineResource( ort );
dsType.setCapabilitiesURL( cu );
GetFeatureRequest value = new GetFeatureRequest();
value.setValue( XMLFactory.export( getFeature ).getAsString() );
value.setVersion( getFeature.getVersion() );
dsType.setGetFeatureRequest( value );
datasources.add( new WFSDatasource( dsType, authenticationInformation, cache ) );
// avoid double layer name/id
Identifier id = new Identifier( this.serviceName );
int i = 0;
String tmp = this.serviceTitle;
while ( mapModel.exists( id ) ) {
tmp = this.serviceTitle + "_" + i;
id = new Identifier( this.serviceName + "_" + i++ );
}
newLayer = new Layer( mapModel, id, tmp, this.serviceAbstract, datasources, this.metadataURLs );
List<NamedStyle> styles = new ArrayList<NamedStyle>();
Settings settings = mapModel.getApplicationContainer().getSettings();
DirectStyleType dst = new DirectStyleType();
dst.setCurrent( true );
UserStyle us = settings.getWFSDefaultStyle().getDefaultStyle();
dst.setName( us.getName() );
dst.setTitle( us.getTitle() );
dst.setAbstract( us.getAbstract() );
dst.setCurrent( true );
// styles.add( new DirectStyle( dst, us, newLayer ) );
styles.add( new NamedStyle( dst, newLayer ) );
newLayer.setStyles( styles );
newLayer.setMinScaleDenominator( minScaleDenominator );
newLayer.setMaxScaleDenominator( maxScaleDenominator );
newLayer.setEditable( true );
newLayer.setVisible( true );
if ( mapModel.getLayerGroups().size() == 0 ) {
LayerGroup layerGroup = new LayerGroup( mapModel, new Identifier(), "LayerGroup", "" );
mapModel.insert( layerGroup, null, null, false );
}
mapModel.insert( newLayer, mapModel.getLayerGroups().get( 0 ), null, false );
} catch ( Exception e ) {
if ( processMonitor != null ) {
processMonitor.cancel();
}
String s = mapModel.getApplicationContainer().getViewPlatform();
DialogFactory.openErrorDialog( s, null, "LOAD WFS Layer", "can not load data from WFS", e );
throw e;
} finally {
fireCommandProcessedEvent();
}
performed = true;
}
/*
* (non-Javadoc)
*
* @see org.deegree.kernel.Command#getName()
*/
public QualifiedName getName() {
return commandName;
}
/*
* (non-Javadoc)
*
* @see org.deegree.kernel.Command#getResult()
*/
public Object getResult() {
return newLayer;
}
/*
* (non-Javadoc)
*
* @see org.deegree.kernel.Command#isUndoSupported()
*/
public boolean isUndoSupported() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.deegree.kernel.Command#undo()
*/
public void undo()
throws Exception {
if ( performed ) {
mapModel.remove( newLayer );
performed = false;
}
}
}