Package org.locationtech.udig.tool.info.internal

Source Code of org.locationtech.udig.tool.info.internal.InfoView2$InfoRequest

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.tool.info.internal;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.geotools.data.FeatureEvent;
import org.geotools.data.FeatureEvent.Type;
import org.geotools.data.FeatureSource;
import org.geotools.data.ows.Layer;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.filter.text.cql2.CQLException;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.locationtech.udig.catalog.IGeoResource;
import org.locationtech.udig.core.internal.FeatureUtils;
import org.locationtech.udig.project.AdaptableFeature;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.ILayerListener;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.IMapCompositionListener;
import org.locationtech.udig.project.Interaction;
import org.locationtech.udig.project.LayerEvent;
import org.locationtech.udig.project.LayerEvent.EventType;
import org.locationtech.udig.project.MapCompositionEvent;
import org.locationtech.udig.project.internal.impl.LayerImpl;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.internal.properties.FeaturePropertySource;
import org.locationtech.udig.tool.info.CoveragePointInfo;
import org.locationtech.udig.tool.info.InfoPlugin;
import org.locationtech.udig.tool.info.InfoTool;
import org.locationtech.udig.tool.info.LayerPointInfo;
import org.locationtech.udig.tool.info.internal.display.BrowserInfoDisplay;
import org.locationtech.udig.tool.info.internal.display.TextInfoDisplay;
import org.locationtech.udig.ui.SearchPart;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.Expression;

/**
* Info recast as a search part.
*
* @author jgarnett
* @since 1.0.0
*/
public class InfoView2 extends SearchPart {
    /** <code>VIEW_ID</code> field */
    public static final String VIEW_ID = "org.locationtech.udig.tool.info.infoView"; //$NON-NLS-1$
    private Text information;
    private TextInfoDisplay textDisplay;
    private BrowserInfoDisplay browserDisplay;
    //private FeatureDisplay featureDisplay;
    private PropertySheetPage featureDisplay;
  private IMapCompositionListener mapListener;
  private ILayerListener layerListener;
  private List<ILayer>  layerList;
  private Thread  fatherThread= null;
    protected ImageRegistry registry;
   
    private class InfoViewLabelProvider extends LabelProvider implements IColorProvider {
       
        private static final String FEATURE_LABEL = "FEATURE_LABEL"; //$NON-NLS-1$
       
        public String getText(Object element) {
            if (element instanceof AdaptableFeature) {
                final AdaptableFeature feature = (AdaptableFeature) element;
                return getFeatureLabel(feature);
            }
            else if (element instanceof LayerPointInfo) {
                LayerPointInfo info = (LayerPointInfo) element;                   
                return info.getLayer().getName();
            }
            else if (element instanceof CoveragePointInfo) {
                CoveragePointInfo info = (CoveragePointInfo) element;                   
                return info.getLayer().getName();
            }
            return super.getText(element);
        }
       
        /**
         * Gets the feature label by running the feature label expression set for the feature.
         *
         * @param feature
         * @return feature label
         */
        private String getFeatureLabel(AdaptableFeature feature) {
           
            final ILayer layer = (ILayer) feature.getAdapter(ILayer.class);
            final IGeoResource resource = layer.getGeoResource();
           
            return getFeatureLabel(resource, feature);
           
        }
       
        /**
         * Gets the feature label by running the feature label expression set for the feature.
         *
         * @param resource
         * @param feature
         * @return feature label
         */
        private String getFeatureLabel(IGeoResource resource, SimpleFeature feature) {
           
            final String labelExpression = (String) resource.getPersistentProperties().get(
                    FEATURE_LABEL);
           
            if (labelExpression != null) {
                try {
                    final Expression exp = ECQL.toExpression(labelExpression);
                    return (String) exp.evaluate(feature);
                } catch (CQLException e) {
                    e.printStackTrace();
                }   
            }
           
            return feature.getID();
           
        }
       
        /**
         * @see org.locationtech.udig.project.internal.provider.LayerItemProvider
         */
        public Color getBackground(Object element) {
            if (element instanceof AdaptableFeature) {
                AdaptableFeature feature = (AdaptableFeature) element;
                LayerImpl layer = (LayerImpl) feature.getAdapter(ILayer.class);
                IColorProvider colorProvider = (IColorProvider) layer.getAdapter(IColorProvider.class);
                if (colorProvider == null) return null;
                return colorProvider.getBackground(layer);
            }           
            return null;
        }

        /**
         * @see org.locationtech.udig.project.internal.provider.LayerItemProvider
         */
        public Color getForeground(Object element) {
            if (element instanceof AdaptableFeature) {
                AdaptableFeature feature = (AdaptableFeature) element;
                LayerImpl layer = (LayerImpl) feature.getAdapter(ILayer.class);
                IColorProvider colorProvider = (IColorProvider) layer.getAdapter(IColorProvider.class);
                if (colorProvider == null) return null;
                return colorProvider.getForeground(layer);
            }
            return null;
        }
       
        @Override
        public Image getImage( Object element ) {
            ILayer layer = null;
            if( element instanceof AdaptableFeature){
                AdaptableFeature feature = (AdaptableFeature) element;
                layer = (ILayer) feature.getAdapter(ILayer.class);               
            }
            if( element instanceof LayerPointInfo){
                LayerPointInfo info = (LayerPointInfo) element;
                layer = info.getLayer();
            }
            if( element instanceof CoveragePointInfo){
                CoveragePointInfo info = (CoveragePointInfo) element;
                layer = info.getLayer();
            }
            String key = layer.getID().toExternalForm();               
            Image image = registry.get( key );
            if( image == null ){
                ImageDescriptor icon;
                icon = (ImageDescriptor) layer.getProperties().get("generated icon");
                if( icon == null ){
                    icon = layer.getIcon();
                }
                if( icon == null ){
                    IGeoResource resource = layer.getGeoResource();
                    try {
                        icon = resource.getInfo(null).getImageDescriptor();
                    } catch (IOException e) {
                        // not expecting this to block or throw IO as the layer was available
                        // to be hit by the info tool
                    }                   
                }
                if( icon != null ){
                    registry.put( key, icon );
                    image = registry.get(key);
                }
            }
            return image;
        }
    }

    public static class InfoRequest {
        public ReferencedEnvelope bbox;
        public List<ILayer> layers;
    };
   
    /**
     *
     */
    public InfoView2() {
        super( InfoPlugin.getDefault().getDialogSettings() );
    }
       
  private void initiListeners() {

    this.mapListener = new IMapCompositionListener() {

      public void changed(MapCompositionEvent event) {

        updatedMapLayersActions(event);
      }
    };
   
    this.layerListener = new ILayerListener() {
     
      public void refresh(LayerEvent event) {
       
        updateLayerActions(event);
      }
    };
  }
   
    @Override
    protected Composite createDetails( SashForm splitter ) {
      initiListeners();
      this.fatherThread = Thread.currentThread();
        PageBook book = new PageBook( splitter, SWT.NONE );       
        splitter.setWeights(new int[]{10, 90});

        {
            information = new Text(book, SWT.WRAP );
            information.setText(Messages.InfoView_instructions_text);
            book.showPage(information);           
        }
        {
            textDisplay = new TextInfoDisplay();
            textDisplay.createDisplay(book);
            //textDisplay.getControl().setVisible(false);
        }
        {
            browserDisplay = new BrowserInfoDisplay();
            browserDisplay.createDisplay(book);
            //browserDisplay.getControl().setVisible(false);
        }
        {
            //featureDisplay = new FeatureDisplay();
            //featureDisplay.createDisplay(book);
            featureDisplay = new PropertySheetPage();
            featureDisplay.createControl(book);
            //featureDisplay.getControl().setVisible(false);
        }             
        return book;
    }


  @Override   
    protected void fillActionBars() {
        IActionBars actionBars = getViewSite().getActionBars();
        IToolBarManager toolBar = actionBars.getToolBarManager();
    
        IAction infoTool = ApplicationGIS.getToolManager().getToolAction(InfoTool.ID, InfoTool.CATEGORY_ID);
        assert( infoTool != null );
        if( toolBar != null ){
            toolBar.add( infoTool );
        }
        super.fillActionBars();
       
    }
   
    @Override
    protected PageBook getDetails() {
        return (PageBook) super.getDetails();
    }
    @Override
    protected void showDetail( Object selection ) {
        if (selection == null ) {
            getDetails().showPage(information);
            return;
        }
        if( selection instanceof SimpleFeature ) {
            getDetails().showPage(featureDisplay.getControl());
            FeaturePropertySource source = new FeaturePropertySource( (SimpleFeature)selection, false, false);
            StructuredSelection sel = new StructuredSelection(source);
            featureDisplay.selectionChanged(null, sel);
            //featureDisplay.setInfo( (SimpleFeature) selection );
        }
        if (selection instanceof LayerPointInfo) {
            LayerPointInfo info = (LayerPointInfo) selection;
            if (info.getMimeType() == null) {
                getDetails().showPage(information);
            } else if (info.getMimeType().startsWith(LayerPointInfo.GML)) {
                getDetails().showPage(featureDisplay.getControl());
                try {
                    SimpleFeature feature = (SimpleFeature) info.acquireValue();
                    FeaturePropertySource src = new FeaturePropertySource(feature);
                    StructuredSelection sel = new StructuredSelection(src);
                    featureDisplay.selectionChanged(null, sel);
                } catch(IOException ex) {
                    InfoPlugin.log("GML value could not be acquired.", ex); //$NON-NLS-1$
                }
                //featureDisplay.setInfo(info);
            } else if (info.getRequestURL() != null &&
                       info.getMimeType().startsWith(LayerPointInfo.HTML)) {
                getDetails().showPage( browserDisplay.getControl() );
                browserDisplay.setInfo(info);       
            } else if (info.getRequestURL() != null && info.getMimeType().startsWith(LayerPointInfo.XML)) {
                getDetails().showPage( browserDisplay.getControl() );
                browserDisplay.setInfo(info);
            } else if (info.getRequestURL() != null && info.getMimeType().startsWith(LayerPointInfo.ERROR)) {
                getDetails().showPage( browserDisplay.getControl() );
                browserDisplay.setInfo(info);       
            } else if (info.getRequestURL() != null && info.getMimeType().startsWith(LayerPointInfo.TEXT)) {
                getDetails().showPage( browserDisplay.getControl() );
                browserDisplay.setInfo(info);
            } else {
                    getDetails().showPage(information);
            }
        }       
        if (selection instanceof CoveragePointInfo) {
            CoveragePointInfo info = (CoveragePointInfo) selection;
            information.setText(info.getInfo());
            getDetails().showPage(information);
        }       
   
    }
   
    @Override
    public void createPartControl( Composite aParent ) {
        super.createPartControl(aParent);
        ApplicationGIS.getToolManager().registerActionsWithPart(this);
        registry = new ImageRegistry( aParent.getDisplay() );       
    }
   
    /**
     * Called by search( Object filter ) in a job to get stuff done.
     * <p>
     * Resulting like is provided to the viewer via setInput.
     * </p>
     */
    @Override
    protected void searchImplementation( Object filter, IProgressMonitor monitor, ResultSet set ) {
        InfoRequest request = (InfoRequest) filter;

        if( monitor != null ) {
            monitor.beginTask( Messages.InfoView2_information_request, request.layers.size() );
        }
        //add listener to the current map
        addMapListener();
        layerList = new LinkedList<ILayer>();
        int work = 0;
        for( int i = request.layers.size()-1; i > -1; i-- ) {
            ILayer layer = request.layers.get(i); //navigate the list backwards
            monitor.subTask( layer.getName() );
            monitor.worked( ++work );
          List<ILayer> currentLayerList = ApplicationGIS.getActiveMap().getMapLayers();
          if (!currentLayerList.contains(layer)) continue;
            if( !layer.isVisible() ) continue;
            if( !layer.getInteraction(Interaction.INFO)) continue;
           
            //if( !layer.isApplicable( "information" )) continue;
            //add listener to the current layer and add that layer to be processed.
            addLayerListener(layer);
            layerList.add(layer);
            if( layer.hasResource( FeatureSource.class ) ) {
                try {
                    List<SimpleFeature> more = DataStoreDescribeLayer.info2( layer, request.bbox, monitor );
                    if( !more.isEmpty() ) {
                        set.addAll( more );
                    }
                }
                catch( Throwable t ) {
                    InfoPlugin.log( "Information request "+layer.getName()+" failed "+t, t ); //$NON-NLS-1$ //$NON-NLS-2$
                }
                continue;
            }           
            if( layer.hasResource( GridCoverage.class ) ) {
                try {
                    CoveragePointInfo hit = CoverageDescribeLayer.info2( layer, request.bbox, monitor );
                    if( hit != null ) set.add( hit );
                }
                catch( Throwable t ) {
                    InfoPlugin.log( "Information request "+layer.getName()+" failed "+t, t ); //$NON-NLS-1$ //$NON-NLS-2$
                }
                continue;
            }           
            if( layer.hasResource( Layer.class ) ) {
                try {
                    Layer wmsLayer = layer.getResource(Layer.class, new NullProgressMonitor());
                    if( wmsLayer.isQueryable()){
                        LayerPointInfo hit = WMSDescribeLayer.info2( layer, request.bbox );
                        if( hit != null ) {
                            set.add( hit );
                        }
                    }
                }
                catch( Throwable t ) {
                    InfoPlugin.log( "Information request "+layer.getName()+" failed "+t, t ); //$NON-NLS-1$ //$NON-NLS-2$
                    t.printStackTrace();
                }
                continue;
            }
        }
    }
    @Override
    protected IBaseLabelProvider createLabelProvider() {
        return new InfoViewLabelProvider();
    }
 
    @Override
    protected StructuredViewer createViewer( Composite parent ) {
        TreeViewer viewer = new TreeViewer(parent);
        return viewer;
    }

    @Override
    protected ISelection getSelection( List<Object> results ) {

        for( Object object : results ) {
            ILayer layer=null ;
            if( object instanceof LayerPointInfo ){
                LayerPointInfo info=(LayerPointInfo) object;
                layer = info.getLayer();
            }
            if (object instanceof CoveragePointInfo) {
                CoveragePointInfo info = (CoveragePointInfo) object;
                layer = info.getLayer();
            }
            if( object instanceof AdaptableFeature ){
                AdaptableFeature feature=(AdaptableFeature) object;
                layer=(ILayer) feature.getAdapter(ILayer.class);
            }
            if( layer==ApplicationGIS.getActiveMap().getEditManager().getSelectedLayer() ){
                return new StructuredSelection(object);
            }
        }
        if( results.isEmpty() )
            return new StructuredSelection();
       
        return new StructuredSelection(results.get(0));
    }

    @Override
    protected IStructuredContentProvider createContentProvider() {
        return new ITreeContentProvider() {
            @SuppressWarnings("unchecked")
            public Object[] getElements( Object inputElement ) {
                if( inputElement instanceof List ) {
                    return ((List)inputElement).toArray();
                }
                return null;
            }
            public void dispose() {
            }
            public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) {
                //assert( newInput instanceof List );
                // lists don't have events for us to watch
            }
            public Object[] getChildren( Object parentElement ) {
                return null;
            }
            public Object getParent( Object element ) {
                return null;
            }
            public boolean hasChildren( Object element ) {
                return false;
            }           
        };
    }
   
    /**
     * If the layer is removed then removed all the items from the tree because they won't be
     * accessible anymore.
     *
     * @param event
     */
    private void updatedMapLayersActions( MapCompositionEvent event ) {

        MapCompositionEvent.EventType eventType = event.getType();

        switch( eventType ) {
        case REMOVED:
        case MANY_REMOVED:

            // if the layer was removed, then it isn't in the list anymore, so the feature/s showed
            // on the tree could be removed.
            List<ILayer> currentLayerList = ApplicationGIS.getActiveMap().getMapLayers();
            for( ILayer layer : layerList ) {
                if (!currentLayerList.contains(layer)) {
                    removeItemsFromTree();
                    break;
                }
            }
            break;
        default:
            break;
        }
    }

    /**
     * If the feature is deleted and also it's contained on the tree, remove it.
     *
     * @param event
     */
    private void updateLayerActions( LayerEvent event ) {

        EventType eventType = event.getType();

        switch( eventType ) {
        case EDIT_EVENT:
            FeatureEvent featureEvent = (FeatureEvent) event.getNewValue();

            if (featureEvent.getType() == Type.REMOVED) {
                removeFeatureFromTree();
            }
            break;
        default:
            break;
        }
    }

    /**
     * With each entry from the tree, creates a FidFilter, retrieves from the store that query. If
     * a feature is returned, then this feature still exist, if not, then remove the associated treeItem.
     */
    private void removeFeatureFromTree() {

        Display.findDisplay(fatherThread).asyncExec(new Runnable(){

            public void run() {
               
                Tree tree = ((TreeViewer) viewer).getTree();
                TreeItem[] treeItems = tree.getItems();
                TreeItem removedItem = null;
                for( int i = 0; i < treeItems.length; i++ ) {
                    TreeItem item = treeItems[i];

                    if (item.getData() instanceof SimpleFeature) {
                        SimpleFeature feature = (SimpleFeature) item.getData();
                        Filter id = createFidFiler(feature.getID());
                        if (!isFeatureOnStore(id)) {
                            // this feature was removed, so remove from tree.
                            removedItem = treeItems[i];
                            break;
                        }
                    }
                }
                if (removedItem != null) {
                    // if a feature is deleted, show the initial style
                    getDetails().showPage(information);
                    tree.deselectAll();
                    tree.getItem(tree.indexOf(removedItem)).dispose();
                }
            }
            /**
             * Check if the feature is on the store.
             * @param id
             * @return True if the feature is in the store.
             */
            private boolean isFeatureOnStore( Filter id ) {

                SimpleFeatureCollection collection = null;
                SimpleFeatureIterator iter = null;
                try {
                    collection = layerList.get(0).getResource(SimpleFeatureSource.class, null).getFeatures(id);
                    iter = collection.features();
                    if (iter.hasNext()) {
                        return true;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(iter != null) iter.close();
                }
                return false;
            }
        });
    }

    private Filter createFidFiler( String id ) {
        FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(GeoTools
                .getDefaultHints());
        Filter filterId = filterFactory.id(FeatureUtils.stringToId(filterFactory, id));
        return filterId;
    }

    private void removeItemsFromTree() {

        Display.findDisplay(fatherThread).asyncExec(new Runnable(){

            public void run() {
                getDetails().showPage(information);
                Tree tree = ((TreeViewer) viewer).getTree();
                if (tree != null && !tree.isDisposed()) {
                    tree.removeAll();
                }
            }
        });
    }

    private void addMapListener() {
        IMap map = ApplicationGIS.getActiveMap();
        map.addMapCompositionListener(mapListener);
    }

    private void addLayerListener( ILayer layer ) {
        layer.addListener(layerListener);
    }
   
    @Override
    public void dispose() {
        if( registry != null ){
            registry.dispose();
            registry = null;
        }
        super.dispose();
    }
}
TOP

Related Classes of org.locationtech.udig.tool.info.internal.InfoView2$InfoRequest

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.