SelectionModel.java :  » IDE-Netbeans » soa » org » netbeans » modules » soa » mappercore » Java Open Source

Java Open Source » IDE Netbeans » soa 
soa » org » netbeans » modules » soa » mappercore » SelectionModel.java
/*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.soa.mappercore;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreePath;
import org.netbeans.modules.soa.mappercore.event.MapperSelectionEvent;
import org.netbeans.modules.soa.mappercore.event.MapperSelectionListener;
import org.netbeans.modules.soa.mappercore.model.Graph;
import org.netbeans.modules.soa.mappercore.model.GraphItem;
import org.netbeans.modules.soa.mappercore.model.GraphListener;
import org.netbeans.modules.soa.mappercore.model.GraphSubset;
import org.netbeans.modules.soa.mappercore.model.Link;
import org.netbeans.modules.soa.mappercore.model.MapperModel;
import org.netbeans.modules.soa.mappercore.model.Vertex;
import org.netbeans.modules.soa.mappercore.model.VertexItem;
import org.netbeans.modules.soa.mappercore.utils.MapperTreePath;
import org.netbeans.modules.soa.mappercore.utils.Utils;

/**
 *
 * @author anjeleevich
 */
public class SelectionModel extends MapperPropertyAccess {
    
    private MapperModel model = null;
    
    private TreePath selectedPath = null;
    private Graph selectedGraph = null;
    
    private List<GraphItem> selected = new ArrayList<GraphItem>();
    
    private ListenersImpl listenersImpl;
    private List<MapperSelectionListener> listeners 
            = new ArrayList<MapperSelectionListener>();
    
    
    public SelectionModel(Mapper mapper) {
        super(mapper);
        listenersImpl = new ListenersImpl();
        
        updateMapperModel();
        
        mapper.addPropertyChangeListener(listenersImpl);
        mapper.addRightTreeExpansionListener(listenersImpl);
    }
    
    
    public void addSelectionListener(MapperSelectionListener listener) {
        listeners.add(listener);
    }
    
    
    public void removeSelectionListener(MapperSelectionListener listener) {
        int index = listeners.lastIndexOf(listener);
        if (index >= 0) {
            listeners.remove(index);
        }
    }
    
    
    private void fireSelectionChanged() {
        int size = listeners.size();
        if (size > 0) {
            MapperSelectionEvent event = new MapperSelectionEvent(this);
            for (MapperSelectionListener l : listeners
                    .toArray(new MapperSelectionListener[size])) 
            {
                l.mapperSelectionChanged(event);
            }
        }
    }
    
    
    public GraphSubset getSelectedSubset() {
        if (selectedPath != null && selectedGraph != null) {
            return new GraphSubset(selectedPath, selectedGraph,
                    getSelectedVerteces(), getSelectedLinks());
        } 
        return null;
    }
    
    
    public List<Vertex> getSelectedVerteces() {
        return getSelectedImpl(Vertex.class);
    }
    
    
    public List<Link> getSelectedLinks() {
        return getSelectedImpl(Link.class);
    }
    
    
    public TreePath getSelectedPath() {
        return selectedPath;
    }
    
    
    public Graph getSelectedGraph() {
        return selectedGraph;
    }
    
    
    public VertexItem getSelectedVertexItem() {
        if (selected.size() == 1) {
            GraphItem graphItem = selected.get(0);
            if (graphItem instanceof VertexItem) {
                return (VertexItem) graphItem;
            }
        }
        return null;
    }
    
   
    public void setSelected(TreePath treePath) {
        if (setSelectedPathImpl(treePath)) {
            fireSelectionChanged();
        }
    }
    
    
    public void setSelected(TreePath treePath, GraphItem graphItem) {
        boolean changed = setSelectedPathImpl(treePath);
        
        if (selected.size() != 1 || selected.get(0) != graphItem) {
            selected.clear();
            selected.add(graphItem);
            changed = true;
        }
        
        if (changed) {
            fireSelectionChanged();
        }
    }
    
    
    public void switchSelected(TreePath treePath, GraphItem graphItem) {
        boolean changed = setSelectedPathImpl(treePath);
        
        if (graphItem instanceof VertexItem) {
            graphItem = ((VertexItem) graphItem).getVertex();
        }
        
        if (selected.contains(graphItem)) {
            selected.remove(graphItem);
            changed = true;
        } else {
            selected.add(graphItem);
            changed = true;
        }
        
        changed |= removeVertexItemsImpl();
        
        if (changed) {
            fireSelectionChanged();
        }
    }
    
    
    public void clearSelection(TreePath treePath) {
        boolean changed = setSelectedPathImpl(treePath);
        
        if (!selected.isEmpty()) {
            selected.clear();
            changed = true;
        }
        
        if (changed) {
            fireSelectionChanged();
        }
    }
    
    
    public void selectAll(TreePath treePath) {
        boolean changed = setSelectedPathImpl(treePath);
        
        if (selectedGraph != null) {
            Set<GraphItem> select = new HashSet<GraphItem>();
            for (int i = selectedGraph.getLinkCount() - 1; i >= 0; i--) {
                select.add(selectedGraph.getLink(i));
            }

            for (int i = selectedGraph.getVertexCount() - 1; i >= 0; i--) {
                select.add(selectedGraph.getVertex(i));
            }
            
            select.removeAll(selected);
            
            if (!select.isEmpty()) {
                selected.addAll(0, select);
                changed = true;
            }
            
            changed |= removeVertexItemsImpl();
        }
        
        if (changed) {
            fireSelectionChanged();
        }
    }
    
    
    private boolean removeVertexItemsImpl() {
        boolean changed = false;
        
        for (int i = selected.size() - 1; i >= 0; i--) {
            if (selected.get(i) instanceof VertexItem) {
                selected.remove(i);
                changed = true;
            }
        }
        
        return changed;
    }
    
    

    private <T extends GraphItem> List<T> getSelectedImpl(Class<T> type) {
        List<T> result = new ArrayList<T>(selected.size());
        for (Object o : selected) {
            if (type.isInstance(o)) {
                result.add(type.cast(o));
            }
        }
        return result;
    }
    
    
    private boolean setSelectedPathImpl(TreePath treePath) {
        if (!Utils.equal(this.selectedPath, treePath)) {
            selected.clear();
            
            this.selectedPath = treePath;

            updateGraph(false);
            
            return true;
        }
        
        return false;
    }

    

    public boolean isSelected(TreePath treePath) {
        return Utils.equal(selectedPath, treePath);
    }
    
    
    public boolean isSelected(TreePath treePath, GraphItem graphItem) {
        return isSelected(treePath) && selected.contains(graphItem);
    }
    
    
    private void updateMapperModel() {
        MapperModel oldModel = this.model;
        MapperModel newModel = getMapperModel();
        
        if (oldModel != newModel) {
            if (oldModel != null) {
                oldModel.removeTreeModelListener(listenersImpl);
            }
            
            if (newModel != null) {
                newModel.addTreeModelListener(listenersImpl);
            }
            
            this.model = newModel;
    
            setSelectedPathImpl(null);
        }
    }
    
    
    private void updateGraph(boolean fireEvent) {
        Graph oldGraph = selectedGraph;
        Graph newGraph = (model != null && selectedPath != null) 
                ? model.getGraph(selectedPath) : null;
        
        if (oldGraph != newGraph) {
            if (oldGraph != null) {
                oldGraph.removeGraphListener(listenersImpl);
            }
            
            if (newGraph != null) {
                newGraph.addGraphListener(listenersImpl);
            }
            
            selectedGraph = newGraph;
            selected.clear();
            
            if (fireEvent) {
                fireSelectionChanged();
            }
        }
    }
    
    
    private void updateSelectedItems() {
        boolean changed = false;
        
        if (selectedGraph != null && !selected.isEmpty()) {
            Set<GraphItem> difference = new HashSet<GraphItem>(selected);
            
            for (int i = selectedGraph.getVertexCount() - 1; i >= 0; i--) {
                difference.remove(selectedGraph.getVertex(i));
            }

            for (int i = selectedGraph.getLinkCount() - 1; i >= 0; i--) {
                difference.remove(selectedGraph.getLink(i));
            }
            
            for (GraphItem item : difference) {
                if (item instanceof VertexItem) {
                    VertexItem vertexItem = (VertexItem) item;
                    Vertex vertex = vertexItem.getVertex();
                    
                    if (vertex.getItemIndex(vertexItem) < 0) {
                        selected.remove(item);
                        changed = true;
                    } else if (vertex.getGraph() != selectedGraph) {
                        selected.remove(item);
                        changed = true;
                    }
                } else {
                    selected.remove(item);
                    changed = true;
                }
            }
        }
        
        if (changed) {
            fireSelectionChanged();
        }
    }

    
    private class ListenersImpl implements GraphListener, TreeModelListener, 
            PropertyChangeListener, TreeExpansionListener 
    {
        public void graphBoundsChanged(Graph graph) {
            updateSelectedItems();
        }

        public void graphLinksChanged(Graph graph) {
            updateSelectedItems();
        }

        public void graphContentChanged(Graph graph) {
            updateSelectedItems();
        }

        
        public void treeNodesChanged(TreeModelEvent e) {
            TreePath parentPath = e.getTreePath();
            Object[] children = e.getChildren();
            
            for (int i = 0; i < children.length; i++) {
                TreePath changedPath = new MapperTreePath(parentPath, 
                        children[i]);
                if (Utils.equal(changedPath, selectedPath)) {
                    updateGraph(true);
                }
            }
        }
        

        public void treeNodesInserted(TreeModelEvent e) {}
        

        public void treeNodesRemoved(TreeModelEvent e) {
            TreePath parentPath = e.getTreePath();
            Object parent = parentPath.getLastPathComponent();
            
            Object[] children = e.getChildren();
            
            for (int i = 0; i < children.length; i++) {
                Object removedChild = children[i];
                TreePath removedPath = new MapperTreePath(parentPath, 
                        removedChild);

                boolean changeSelection = false;

                for (TreePath path = selectedPath; path != null; 
                        path = path.getParentPath())
                {
                    if (Utils.equal(path, removedPath)) {
                        changeSelection = true;
                        break;
                    }
                }
                
                if (changeSelection) {
                    MapperModel model = getMapperModel();
                    int count = model.getChildCount(parent);
                    int newSelectedIndex = Math.min(e.getChildIndices()[i], 
                            count - 1);
                    
                    if (newSelectedIndex < 0) {
                        setSelected(parentPath);
                    } else {
                        setSelected(new MapperTreePath(parentPath, 
                                model.getChild(parent, newSelectedIndex)));
                    }
                }
            }
        }
        

        public void treeStructureChanged(TreeModelEvent e) {
//            validateSelection();
        }
        

        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getSource() == getMapper()
                    && evt.getPropertyName() == Mapper.MODEL_PROPERTY)
            {
                updateMapperModel();
            }
        }

        
        public void treeExpanded(TreeExpansionEvent event) {}

        
        public void treeCollapsed(TreeExpansionEvent event) {
            TreePath path = event.getPath();
            TreePath selectedPath = SelectionModel.this.selectedPath;
            
            if (selectedPath != null) {
                selectedPath = selectedPath.getParentPath();
                while (selectedPath != null) {
                    if (Utils.equal(selectedPath, path)) {
                        setSelectedPathImpl(path);
                        return;
                    }
                    selectedPath = selectedPath.getParentPath();
                }
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.