/*---------------- 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.views.swing.addlayer; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.ListCellRenderer; import org.deegree.datatypes.QualifiedName; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.utils.SwingUtils; import org.deegree.framework.xml.NamespaceContext; import org.deegree.framework.xml.XMLFragment; import org.deegree.framework.xml.XMLParsingException; import org.deegree.framework.xml.XMLTools; import org.deegree.igeo.ApplicationContainer; import org.deegree.igeo.commands.model.AddWFSLayerCommand; import org.deegree.igeo.i18n.Messages; import org.deegree.igeo.mapmodel.MapModel; import org.deegree.igeo.views.DialogFactory; import org.deegree.kernel.CommandProcessedEvent; import org.deegree.kernel.CommandProcessedListener; import org.deegree.kernel.ProcessMonitor; import org.deegree.kernel.ProcessMonitorFactory; import org.deegree.ogcbase.CommonNamespaces; import org.deegree.ogcwebservices.wfs.XMLFactory; import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType; import org.w3c.dom.Node; /** * <code>JAddWFSChooseFeature</code> * * @author <a href="mailto:buesching@lat-lon.de">Lyn Buesching</a> * @author last edited by: $Author$ * * @version $Revision$, $Date$ * */ public class AddWFSChooseFeature extends WizardDialog implements ActionListener, ItemListener { private static final long serialVersionUID = -3149417521102716483L; private static final ILogger LOG = LoggerFactory.getLogger( AddWFSChooseFeature.class ); private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); private MapModel mapModel; private WFSCapabilities wfsCapabilities; private JComboBox featureTypeChooser = new JComboBox(); private JComboBox geomPropChooser = new JComboBox(); private JTextArea descriptionArea = new JTextArea(); /** * * @param frame * the previous frame * @param mapModel * tha map model to add the new layer * @param appContainer * the application container * @param wfsCapabilities * the requested capabilities */ public AddWFSChooseFeature( JFrame frame, MapModel mapModel, ApplicationContainer<Container> appContainer, WFSCapabilities wfsCapabilities ) { super( frame ); this.wfsCapabilities = wfsCapabilities; this.mapModel = mapModel; this.appContainer = appContainer; this.setSize( 500, 600 ); this.setResizable( false ); this.setTitle( Messages.getMessage( Locale.getDefault(), "$MD10128" ) ); infoPanel.setInfoText( Messages.getMessage( Locale.getDefault(), "$MD10129" ) ); buttonPanel.registerActionListener( this ); this.geomPropChooser.setRenderer( new QualifiedNameRenderer() ); this.geomPropChooser.setPreferredSize( new Dimension( 100, 20 ) ); initFeatureTypeChooser(); setFeatureTypeDescription(); super.init(); } /** * fills the combo box with all featureTypes of the requested WFS */ private void initFeatureTypeChooser() { // add an item listener to update the featureType description this.featureTypeChooser.addItemListener( this ); this.featureTypeChooser.setPreferredSize( new Dimension( 200, 20 ) ); this.featureTypeChooser.setRenderer( new FeatureTypeRenderer() ); WFSFeatureType[] featureTypes = this.wfsCapabilities.getFeatureTypeList().getFeatureTypes(); featureTypes = sort( featureTypes ); for ( int i = 0; i < featureTypes.length; i++ ) { this.featureTypeChooser.addItem( featureTypes[i] ); } } /** * @param featureTypes * @return */ private WFSFeatureType[] sort( WFSFeatureType[] featureTypes ) { WFSFeatureType temp; for ( int i = 0; i < featureTypes.length; i++ ) { for ( int j = 0; j < featureTypes.length - 1; j++ ) { if ( featureTypes[j + 1].getTitle().compareTo( featureTypes[j].getTitle() ) < 0 ) { temp = featureTypes[j]; featureTypes[j] = featureTypes[j + 1]; featureTypes[j + 1] = temp; } } } return featureTypes; } /** * updates the comboBox with the list of geometrie properties * * @param geomProps * the geometrie properties to insert in the comboBox */ private void updateGeomPropsChooser( List<QualifiedName> geomProps ) { this.geomPropChooser.removeAllItems(); this.geomPropChooser.validate(); if ( geomProps.size() > 0 ) { this.geomPropChooser.setEnabled( true ); for ( QualifiedName name : geomProps ) { this.geomPropChooser.addItem( name ); } } else { this.geomPropChooser.setEnabled( false ); } } /** * @param text * the text to write in the descriptionArea */ private void updateDescriptionArea( String text ) { this.descriptionArea.setText( text ); } /** * updates all components depends of the description of the selected featureType * * @throws XMLParsingException */ private void setFeatureTypeDescription() { // the selected feature type WFSFeatureType featureType = (WFSFeatureType) this.featureTypeChooser.getSelectedItem(); FeatureTypeWrapper ftWrapper = null; String wfsUrl = null; try { XMLFragment xml = XMLFactory.export( wfsCapabilities ); Node n = XMLTools.getNode( xml.getRootElement(), "ows:OperationsMetadata/ows:Operation[@name='DescribeFeatureType']/ows:DCP/ows:HTTP/ows:Get", nsContext ); wfsUrl = XMLTools.getAttrValue( n, CommonNamespaces.XLNNS, "href", null ); int index = wfsUrl.indexOf( '?' ); if ( index > -1 ) { wfsUrl = wfsUrl.substring( 0, index ); } ftWrapper = new FeatureTypeWrapper( new URL( wfsUrl ), wfsCapabilities, featureType.getName(), appContainer ); } catch ( MalformedURLException e ) { // should never happen this.dispose(); LOG.logError( Messages.get( "$DG10068", wfsUrl, e.getMessage() ) ); DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, getClass().getSimpleName(), Messages.get( "$DG10013", wfsUrl ), e ); } catch ( IOException e ) { LOG.logError( Messages.get( "$DG10013", wfsUrl ), e ); this.dispose(); DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, getClass().getSimpleName(), Messages.get( "$DG10013", wfsUrl ), e ); } catch ( XMLParsingException e ) { LOG.logError( Messages.get( "$DG10013", wfsUrl ), e ); this.dispose(); DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, getClass().getSimpleName(), Messages.get( "$DG10013", wfsUrl ), e ); } catch ( Exception e ) { LOG.logError( Messages.get( "$DG10013", wfsUrl ), e ); this.dispose(); DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, getClass().getSimpleName(), Messages.get( "$DG10013", wfsUrl ), e ); } try { if ( ftWrapper != null ) { // update description area updateDescriptionArea( ftWrapper.getFeatureTypeDescriptionAsXML().getAsPrettyString() ); // and the combobox with geometries of the selected featuretype updateGeomPropsChooser( ftWrapper.getGeometryProperties() ); } } catch ( Exception e ) { LOG.logError( Messages.get( "$DG10101", wfsUrl ), e ); this.dispose(); DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, getClass().getSimpleName(), Messages.get( "$DG10101", wfsUrl, ftWrapper.getFeatureTypeDescriptionAsXML().getAsPrettyString() ), e ); } } /** * * The <code>FeatureTypeRenderer</code> shows a WFSFeatureType as an entry in a JComboBox. * * @author <a href="mailto:buesching@lat-lon.de">Lyn Buesching</a> * @author last edited by: $Author$ * * @version $Revision$, $Date$ * */ private class FeatureTypeRenderer extends JLabel implements ListCellRenderer { private static final long serialVersionUID = -7255425959231493183L; public FeatureTypeRenderer() { setPreferredSize( new Dimension( 300, 18 ) ); setBorder( BorderFactory.createEmptyBorder( 0, 2, 0, 0 ) ); } /* * (non-Javadoc) * * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, * boolean, boolean) */ public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) { WFSFeatureType ft = (WFSFeatureType) value; String displayName = ft.getTitle(); if ( displayName == null || !( displayName.length() > 0 ) ) { displayName = ft.getName().getLocalName(); } setText( displayName ); setToolTipText( ft.getAbstract() ); return this; } } // ///////////////////////////////////////////////////////////////////////////////// // WizardDialog // ///////////////////////////////////////////////////////////////////////////////// /* * (non-Javadoc) * * @see org.deegree.igeo.views.swing.addlayer.WizardDialog#getMainPanel() */ @Override public JPanel getMainPanel() { JPanel chooseFeaturePanel = new JPanel(); chooseFeaturePanel.setVisible( true ); GridBagConstraints gbc = SwingUtils.initPanel( chooseFeaturePanel ); // show the decription of the selected feature type Dimension descDim = new Dimension( 400, 225 ); JScrollPane descriptionScroll = new JScrollPane( this.descriptionArea ); descriptionScroll.setPreferredSize( descDim ); descriptionScroll.setMinimumSize( descDim ); descriptionScroll.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED ); descriptionScroll.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED ); // add components to the main panel gbc.anchor = GridBagConstraints.LINE_START; chooseFeaturePanel.add( new JLabel( Messages.getMessage( Locale.getDefault(), "$MD10131" ) ), gbc ); ++gbc.gridy; chooseFeaturePanel.add( this.featureTypeChooser, gbc ); ++gbc.gridy; gbc.insets = new Insets( 5, 2, 2, 2 ); chooseFeaturePanel.add( new JLabel( Messages.getMessage( Locale.getDefault(), "$MD10132" ) ), gbc ); ++gbc.gridy; gbc.insets = new Insets( 2, 2, 2, 2 ); chooseFeaturePanel.add( this.geomPropChooser, gbc ); ++gbc.gridy; gbc.insets = new Insets( 10, 2, 2, 2 ); chooseFeaturePanel.add( new JLabel( Messages.getMessage( Locale.getDefault(), "$MD10130" ) ), gbc ); ++gbc.gridy; gbc.insets = new Insets( 2, 2, 2, 2 ); chooseFeaturePanel.add( descriptionScroll, gbc ); return chooseFeaturePanel; } // ///////////////////////////////////////////////////////////////////////////////// // ActionListener // ///////////////////////////////////////////////////////////////////////////////// /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed( ActionEvent event ) { if ( event.getSource() instanceof JButton ) { JButton srcButton = (JButton) event.getSource(); if ( srcButton.getName().equals( ButtonPanel.CANCEL_BT ) ) { this.dispose(); } else if ( srcButton.getName().equals( ButtonPanel.PREVIOUS_BT ) ) { if ( this.previousFrame != null ) { this.previousFrame.setVisible( true ); } this.close(); } else if ( srcButton.getName().equals( ButtonPanel.NEXT_BT ) ) { WFSFeatureType featureType = (WFSFeatureType) this.featureTypeChooser.getSelectedItem(); QualifiedName geometryProp = (QualifiedName) this.geomPropChooser.getSelectedItem(); AddWFSCreateFilter nextStep = null; try { nextStep = new AddWFSCreateFilter( this, this.mapModel, this.appContainer, this.wfsCapabilities, featureType, geometryProp ); } catch ( Exception e ) { return; } nextStep.setLocation( this.getX(), this.getY() ); nextStep.setVisible( true ); this.setVisible( false ); } else if ( srcButton.getName().equals( ButtonPanel.FINISH_BT ) ) { // adds the new layer and closes the current window WFSFeatureType featureType = (WFSFeatureType) this.featureTypeChooser.getSelectedItem(); QualifiedName geometryProp = (QualifiedName) this.geomPropChooser.getSelectedItem(); AddWFSLayerCommand command = new AddWFSLayerCommand( this.mapModel, this.wfsCapabilities, featureType, geometryProp, null ); final ProcessMonitor pm = ProcessMonitorFactory.createDialogProcessMonitor( appContainer.getViewPlatform(), Messages.get( "$MD11270" ), Messages.get( "$MD11271", featureType.getTitle() ), 0, -1, command ); command.setProcessMonitor( pm ); command.addListener( new CommandProcessedListener() { public void commandProcessed( CommandProcessedEvent event ) { try { pm.cancel(); } catch ( Exception e ) { e.printStackTrace(); } } } ); appContainer.getCommandProcessor().executeASychronously( command ); this.dispose(); } } } // ///////////////////////////////////////////////////////////////////////////////// // ItemListener // ///////////////////////////////////////////////////////////////////////////////// /* * (non-Javadoc) * * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) */ public void itemStateChanged( ItemEvent event ) { // update the decription of the selected feature type, when state of the check box changed // or selected fetaure type changed. Methode will be called two timed when selection of the // combo box changed, so avoid not required multiple updates of the description area. if ( !( event.getSource() instanceof JComboBox && event.getStateChange() == ItemEvent.DESELECTED ) ) { try { setFeatureTypeDescription(); } catch ( Exception e ) { DialogFactory.openErrorDialog( appContainer.getViewPlatform(), null, e.getMessage(), getClass().getSimpleName(), e ); this.dispose(); } } } }