view src/MPipeline/src/mpipeline/MSubsystem.java @ 46:ca0b8d4dcdb6 database-connection-manager

Fix
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Tue, 06 Dec 2011 19:07:27 +0100
parents f0afece42f48
children
line wrap: on
line source

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mpipeline;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.border.BevelBorder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * A view of a block diagram that can be placed on a canvas.
 * 
 * @author hewitson
 */
public class MSubsystem extends MElementWithPorts {

    private String parentDiagTitle = "";
    private String myDiagTitle = "";

    /**
     * Empty constructor for MSubsystem elements.
     */
    public MSubsystem() {
        setName("subsystem");
        setupMSubsystem();
    }

    /**
     * Construct a subsystem with the given parent diagram.
     * @param diag
     */
    public MSubsystem(BlockDiagram diag) {
        this.parentDiagTitle = diag.getTitle();
        setName("subsystem");
        setupMSubsystem();
    }

    /**
     * Construct a subsystem with the given parent diagram and with the
     * given name.
     * 
     * @param diag parent diagram for this subsystem
     * @param name name for this subsystem
     */
    public MSubsystem(BlockDiagram diag, String name) {
        this.parentDiagTitle = diag.getTitle();
        setName(name);
        setupMSubsystem();
    }


    /**
     *
     * @param sn
     * @param x
     * @param y
     */
    public MSubsystem(String sn, int x, int y) {
        position.x = x;
        position.y = y;
        setName(sn);
        setupMSubsystem();
    }

    /**
     *
     * @param sn
     */
    public MSubsystem(String sn) {
        setName(sn);
        setupMSubsystem();
    }


    /**
     * Attach this subsystem to the given DOM node.
     * @param doc
     * @param docnode
     */
    @Override
    public void attachToDom(Document doc, Element docnode) {
        // start new document node
        Element tnode = doc.createElement("subsystem");
        tnode.setAttribute("name", this.getName());
        tnode.setAttribute("bounds", "" + position.x + " " + position.y + " " + mySize.width + " " + mySize.height + "");
        String ips = getPortNumberString(inputs);
        String ops = getPortNumberString(outputs);
        tnode.setAttribute("inputs", "" + ips);
        tnode.setAttribute("outputs", "" + ops);
        tnode.setAttribute("parentDiag", "" + parentDiagTitle);
        tnode.setAttribute("myDiag", "" + myDiagTitle);

        // write connections
        Iterator it = outputs.iterator();
        while (it.hasNext()) {
            MPort o = (MPort) it.next();
            o.attachToDom(doc, tnode);
        }
        // attach to the DOM
        docnode.appendChild(tnode);
    }

    /**
     * Get the block that is the source of given output port. This bypasses the
     * terminal that joins the block inside the subsystem to the port on the subsystem.
     * @param port
     * @return
     */
    public MElementWithPorts getSourceBlockForOutputPort(int port) {
//        System.out.println("Getting source block for output port " + port + " of subsystem " + getMyDiagTitle());
        MPort op = outputs.get(port);
        MTerminal ot = op.getMyTerm();
        return ot.getSourceBlock(0);
    }

    /**
     * Get the port number on the block that is the source of given output port.
     * This bypasses the terminal that joins the block inside the subsystem to
     * the port on the subsystem.
     * @param port
     * @return
     */
    public int getSourceBlockPortForOutputPort(int port) {
//        System.out.println("Getting source block port number for output port " + port + " of subsystem " + getMyDiagTitle());
        MPort op = outputs.get(port);
        MTerminal ot = op.getMyTerm();
//        System.out.println("$$$ got terminal: follow on to source block.");
        return ot.getSourceBlockPortNumber(0);
    }


    /**
     * Count the number of blocks that can be executed inside this subsystem. This
     * works recursively and counts all the blocks inside subsystems of this subsystem.
     * @return
     */
    private int countBlocksToExecute(){
        
        BlockDiagram diag = getMyDiagram();
        MCanvas c = diag.getCanvas();

        ArrayList<MBlock> blocks = c.getBlocklist();
        int count = blocks.size();

        // now go through all subsystems
        ArrayList<MSubsystem> sss = c.getSubsystems();
        Iterator it = sss.iterator();
        while (it.hasNext()){
            MSubsystem ss = (MSubsystem)it.next();
            count += ss.countBlocksToExecute();
        }

        return count;
    }

    /**
     * Cound the number of blocks that have been executed inside this subsystem. This
     * works recursively and counts all the blocks inside subsystems of this one.
     * @return
     */
    private int countBlocksExecuted(){

        BlockDiagram diag = getMyDiagram();
        MCanvas c = diag.getCanvas();

        int count = 0;
        ArrayList<MBlock> blocks = c.getBlocklist();
        Iterator it = blocks.iterator();
        while(it.hasNext()){
            MBlock b = (MBlock) it.next();
            if (b.hasExecuted()){
                count ++;
            }
        }

        // now go through all subsystems
        ArrayList<MSubsystem> sss = c.getSubsystems();
        it = sss.iterator();
        while (it.hasNext()){
            MSubsystem ss = (MSubsystem)it.next();
            count += ss.countBlocksExecuted();
        }

        return count;
    }



    /**
     * Update the execution progress through this subsystem.
     */
    public void updateProgress(){

        int bce = countBlocksToExecute();
        if (bce > 0){
            float prog = ((1.0f * countBlocksExecuted()) / (1.0f * bce));
//            System.out.println("Setting progress to: " + prog);
            blockCore.setProgress(prog);
            repaint();
        }
    }

    /**
     * Set up this subsystem.
     */
    private void setupMSubsystem() {
        myMinWidth = 30;
        myMinHeight = 25;
        this.mySize = new Dimension(100, 60);
        this.defaultSize = new Dimension(100, 60);
        this.setLocation(0, 0);
        this.setVisible(true);
        this.setLayout(null);
        this.setOpaque(false);
        // set my border
        this.setBorder(notSelectedBorder);
        scaleElement();
        setupHandles();
        setBlockCoreBounds();
        blockCore.setDefaultBackgroundColor(Color.yellow);
        setIdleColor(Color.yellow);
        blockCore.setMyBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED,
                Color.LIGHT_GRAY, Color.darkGray));
        this.add(blockCore);
        blockCore.setupBlockContextMenu();
        setupBlockNameView();
        this.add(nameView);
        addMouseListener(new MyMouseEvents());
        addMouseMotionListener(new MyMouseEvents());
        revalidate();
        repaint();
    }

    /**
     * Get the next free avaialable input port. If no free input port is found,
     * -1 is returned.
     * 
     * @return
     */
    @Override
    public int getNextFreeInput() {
        Iterator it = inputs.iterator();
        int n = 0;
        while (it.hasNext()) {
            MPort p = (MPort) it.next();
            if (p.getNode() == null) {
                return n;
            }
            n++;
        }

        return -1;
    }


    /**
     * Add an input port to this subsystem. A new input terminal is placed on the
     * canvas of this subsystem.
     */
    @Override
    public void addInput() {
        if (getMyDiagram() != null) {
            MCanvas ssc = this.getMyDiagram().getCanvas();
            MTerminal term = ssc.createTerminal(MTerminal.INPUT);
            ssc.autoPlace(term);
            MCanvas c = (MCanvas) getParent();
            if (c != null) {
                c.setNotSaved("Added subsystem input");
            }
        }
//        else {
//            super.createInput();
//        }
    }

    /**
     * Add an output port to this subsystem. A new output terminal is placed on the
     * canvas of this subsystem.
     */
    @Override
    public void addOutput() {
        if (getMyDiagram() != null) {
            MCanvas ssc = this.getMyDiagram().getCanvas();
            MTerminal term = ssc.createTerminal(MTerminal.OUTPUT);
            ssc.autoPlace(term);
            MCanvas c = (MCanvas) getParent();
            if (c != null) {
                c.setNotSaved("Added subsystem output");
            }
        }
//        else {
//            super.addOutput();
//        }
    }

    /**
     * Add an input port to this subsystem and associate it with the given
     * terminal.
     * @param term the terminal to associate to this new input port
     */
    public void addInput(MTerminal term) {
        MPort p = new MPort(0);
        p.setMyElement(this);
        // find the first free port number
        int pnum = getFirstFreePortNumber(inputs);
        p.setNumber(pnum);
        p.setMyTerm(term);
        term.setRefPort(p);
        inputs.add(p);
        setupPorts(inputs);
        this.add(p, 0);
        revalidate();
        MCanvas c = (MCanvas) getParent();
        if (c != null) {
            c.setNotSaved("Added subsystem input from terminal");
        }
    }

    /**
     * Add an input port to this subsystem with the given number and
     * associate it with the given terminal.
     * @param term the terminal to associate to this new input port
     * @param num
     */
    public void addInput(MTerminal term, int num) {
        boolean portExists = false;
        Iterator it = inputs.iterator();
        while(it.hasNext()){
            MPort p = (MPort) it.next();
            if (p.getNumber() == num){
                portExists = true;
                break;
            }
        }
        if (!portExists){
            MPort p = new MPort(0);
            p.setMyElement(this);
            p.setNumber(num);
            p.setMyTerm(term);
            term.setRefPort(p);
            inputs.add(p);
            setupPorts(inputs);
            this.add(p, 0);
            revalidate();
            MCanvas c = (MCanvas) getParent();
            if (c != null) {
                c.setNotSaved("Added subsystem input from terminal and port number");
            }
        }
    }

    /**
     * Add an output port to this subsystem and associate it with the given
     * terminal.
     * @param term the terminal to associate to this new output port
     */
    public void addOutput(MTerminal term) {
        MPort p = new MPort(1);
        p.setMyElement(this);
        int pnum = getFirstFreePortNumber(outputs);
        p.setNumber(pnum);
        p.setMyTerm(term);
        term.setRefPort(p);
        outputs.add(p);
        setupPorts(outputs);
        this.add(p, 0);
        revalidate();
        MCanvas c = (MCanvas) getParent();
        if (c != null) {
            c.setNotSaved("Added subsystem output from terminal");
        }
    }

    /**
     * Add an output port to this subsystem with the given number and
     * associate it with the given terminal.
     * @param term the terminal to associate to this new output port
     * @param num
     */
    public void addOutput(MTerminal term, int num) {
        boolean portExists = false;
        Iterator it = outputs.iterator();
        while(it.hasNext()){
            MPort p = (MPort) it.next();
            if (p.getNumber() == num){
                portExists = true;
                break;
            }
        }
        if (!portExists){
            MPort p = new MPort(1);
            p.setMyElement(this);
            p.setNumber(num);
            p.setMyTerm(term);
            term.setRefPort(p);
            outputs.add(p);
            setupPorts(outputs);
            this.add(p, 0);
            revalidate();
            MCanvas c = (MCanvas) getParent();
            if (c != null) {
                c.setNotSaved("Added subsystem output from terminal and port number");
            }
        }
    }


    /**
     * Make a deep copy of this subsystem element.
     * 
     * @param b
     * @return
     * @throws java.io.IOException
     * @throws java.lang.ClassNotFoundException
     */
    public static MSubsystem copy(MSubsystem b) throws IOException, ClassNotFoundException {
        return (MSubsystem) MElement.copy(b);
    }

    /**
     * Get the block diagram associated with this subsystem.
     * 
     * @return
     */
    public BlockDiagram getMyDiagram() {
        MCanvas mc = (MCanvas) getParent();
        if (mc != null){
            MainWindow mw = mc.getMainWindow();
            if (mw != null){
                BlockDiagram diag = mw.getDiagramByTitle(getMyDiagTitle());
                return diag;
            } else {
                System.err.println("mpipeline:MSubsystem:getMyDiagram: main window is null");
                return null;
            }
        } else {
            System.err.println("mpipeline:MSubsystem:getMyDiagram: parent canvas is null");
            return null;
        }
    }




    @Override
    public void display(){
        String header = "-------" + getName() + "--------";
        String footer = "-";
        while (footer.length() < header.length()) {
            footer += "-";
        }

        System.out.println(header);
        System.out.println(" num inputs: " + inputs.size());
        System.out.println("num outputs: " + outputs.size());
        System.out.println(" my diagram: " + getMyDiagTitle());
        System.out.println(" my parent diagram: " + parentDiagTitle);
        System.out.println(footer);
        
    }

    private class MyMouseEvents implements MouseListener, MouseMotionListener, Serializable {

        public void mouseClicked(MouseEvent me) {
            if (me.getClickCount() == 2) {

                BlockDiagram diag = getMyDiagram();
                if (diag != null) {
                    System.out.println("Bringing up diagram: " + diag.getTitle());
                    diag.setVisible(true);
                    diag.requestFocus();
                    diag.moveToFront();
                    try {
                        diag.setSelected(true);
                    } catch (PropertyVetoException ex) {
                        System.err.println("Couldn't select diagram: " + diag.getTitle());
                    }
                }
            } else {
                // pass to canvas
                Point pt = me.getPoint(); // the point that was clicked
                MCanvas c = (MCanvas) getParent(); // get canvas
                int newX = getX() + pt.x; // transform to canvas coords
                int newY = getY() + pt.y; // transform to canvas coords
                // create a new mouse event...
                MouseEvent transformed = new MouseEvent(c,
                        MouseEvent.MOUSE_CLICKED, me.getWhen(),
                        me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                        me.getButton());
                // ... and pass it to the canvas
                c.dispatchEvent(transformed);
            }
        }

        public void mousePressed(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_PRESSED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }

        public void mouseReleased(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_RELEASED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }

        public void mouseEntered(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_ENTERED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }

        public void mouseExited(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_EXITED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }

        public void mouseDragged(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_DRAGGED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }

        public void mouseMoved(MouseEvent me) {
            // pass to canvas
            Point pt = me.getPoint(); // the point that was clicked
            MCanvas c = (MCanvas) getParent(); // get canvas
            int newX = getX() + pt.x; // transform to canvas coords
            int newY = getY() + pt.y; // transform to canvas coords
            // create a new mouse event...
            MouseEvent transformed = new MouseEvent(c,
                    MouseEvent.MOUSE_MOVED, me.getWhen(),
                    me.getModifiers(), newX, newY, me.getClickCount(), me.isPopupTrigger(),
                    me.getButton());
            // ... and pass it to the canvas
            c.dispatchEvent(transformed);
        }
    }

    /**
     * Get the title of the diagram that is associated with this subsystem.
     * @return
     */
    public String getMyDiagTitle() {
        return parentDiagTitle + " / " + getName();
    }

    /**
     * Set the title of the diagram associated with this subsystem.
     * @param myDiagTitle
     */
    public void setMyDiagTitle(String myDiagTitle) {
        this.myDiagTitle = myDiagTitle;
    }

    /**
     *
     * @param parentDiagTitle
     */
    public void setParentDiagTitle(String parentDiagTitle) {
        System.out.println(" set parent diagram title to " + parentDiagTitle);
        this.parentDiagTitle = parentDiagTitle;
    }


}