Package org.sintef.umt.systemfamily

Source Code of org.sintef.umt.systemfamily.VariabilityManager$VariabilityCellEditor

//UML Model Transformation Tool (UMT)
//Copyright (C) 2003, 2004, 2005 SINTEF
//Authors:  jon.oldevik at sintef.no | roy.gronmo at sintef.no | tor.neple at sintef.no | fredrik.vraalsen at sintef.no
//Webpage: http://umt.sourceforge.net
//Deloped in the projects:  ACEGIS (EU project - IST-2002-37724),
// CAFE (EUREKA/ITEA - ip00004), FAMILIES (ITEA project ip02009)
//
//This program 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 program 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 program; if not, write to the Free
//Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
//02111-1307 USA


package org.sintef.umt.systemfamily;


import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.*;

import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

import org.sintef.umt.transformer.XMLUtility;
import org.sintef.umt.umtmain.UMTMain;
import org.w3c.dom.*;



/**
* @author jol
* VariabilityManager
* Created Aug 20, 2004
*/

import javax.swing.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import java.awt.event.*;

public class VariabilityManager extends JPanel implements ActionListener {

    public static final String SYSTEM_FAMILY_VARIABILITY_FILE = "context.system_family_gen.html";
    public static final String SYSTEM_FAMILY_INITIAL_STATE = "context.system_family.initial.html";
   
  public final static Color bgColor = Color.white;
    public final static Color altBackground = Color.lightGray;
  public final static Color deactivatedBackground = Color.blue;
    public final static Color fgColor = Color.black;
    public final static Color varChecked = Color.green.brighter().brighter().brighter();
    public final static Color varNotChecked = Color.pink;
    public static Font defaultFont = null;
    public static Font rendererFont1 = null;
    public static Font rendererFont2 = null
 
    private int variationPointCounter = 0;
    private static TitledBorder templateBorder;

   
    private Element modelRoot = null;
    public static final String VARIABILITY_INDICATOR = "vpvalue";
  public static final String VARIABILITY_CLASS_ACTIVE = "variability_active";
   
    private JComboBox exportSelectorBox = null;
    private boolean viewDerivedModel = false;
   
   
    private Hashtable idManager = new Hashtable ();
    private Vector variabilityListeners = new Vector();
  private Hashtable classPanels = new Hashtable ();
   
    private VariabilityChecker variabilityChecker = null;
    private VariabilityResolver variabilityResolver = null;
   
    // private final static String VP_OPTIONAL = ""
     
    // private Font h1,h2;
   
    public VariabilityManager () {
        templateBorder = new TitledBorder ("");
        defaultFont = templateBorder.getTitleFont();
        rendererFont1 = defaultFont.deriveFont(defaultFont.getStyle(), defaultFont.getSize() + 6);
        rendererFont2 = defaultFont.deriveFont(defaultFont.getStyle(), defaultFont.getSize() + 4);
        idManager.clear();
    classPanels.clear();
    }
   
    public void addVariabilityEventListener (VariabilityEventListener listener) {
        variabilityListeners.add(listener);
    }
   
    private void notifyVariabilityEventListeners (Object changedObject) {
        for (Iterator it = variabilityListeners.iterator(); it.hasNext();) {
            VariabilityEventListener listener = (VariabilityEventListener)it.next();
            listener.variabilityModelChanged(changedObject);
        }
    }
   
    public void variabilityPanel (Element rootelement) {
        idManager.clear();
    classPanels.clear();
   
        modelRoot = rootelement;
        setLayout(new BorderLayout ());       
        NodeList packages = rootelement.getElementsByTagName("package");
        if (packages.getLength() > 0) {
            JPanel pPanel = handlePackage((Element)packages.item(0), true);
            TitledBorder border = new TitledBorder("ProductLine " + ((Element)packages.item(0)).getAttribute("name"));           
            Font f1 = defaultFont.deriveFont(defaultFont.getStyle(), defaultFont.getSize() + 10);           
            border.setTitleFont(f1);
            pPanel.setBorder(border);
            add(new JScrollPane(pPanel), BorderLayout.CENTER);           
        }
       
        ImageIcon checkIcon = null;
        ImageIcon resolveIcon = null;
        ImageIcon storeConfigIcon = null;
        ResourceBundle bundle = SystemFamilyTreeCellRenderer.getResourceBundle();
        if (bundle != null) {           
            checkIcon = new ImageIcon (UMTMain.family_img_dir + bundle.getString("family.action.check"));
            resolveIcon = new ImageIcon (UMTMain.family_img_dir + bundle.getString("family.action.resolve"));
            storeConfigIcon = new ImageIcon (UMTMain.family_img_dir + bundle.getString("family.action.storeConfig"));
        }
       
       
        JButton check = new JButton ("Check");
        JButton resolve = new JButton ("Resolve");
        check.setContentAreaFilled(false);
        resolve.setContentAreaFilled(false);
        check.setIcon(checkIcon);
        resolve.setIcon(resolveIcon);
        check.setToolTipText("Check Product Line Model");
        resolve.setToolTipText("Resolve Product Line Model - Generate System Model");
        check.addActionListener(this);
        resolve.addActionListener(this);
       
        String[] data = {"UMT XMIL", "XMI1.0/UML 1.3","UML2"};
        exportSelectorBox = new JComboBox (data);
        exportSelectorBox.setFont(defaultFont);
       
        JCheckBox viewDerivedChecker = new JCheckBox ("View result");
        viewDerivedChecker.setSelected(false);
        viewDerivedChecker.setToolTipText("Tick to view the resulting resolved model. ");
        viewDerivedChecker.addItemListener(new ItemListener() {
           public void itemStateChanged(ItemEvent e) {
               if (e.getStateChange() == ItemEvent.DESELECTED)
                 viewDerivedModel = false;
               else if (e.getStateChange() == ItemEvent.SELECTED)
                   viewDerivedModel = true;
           }
        });
       
        JButton saveConfig = new JButton ("");
        saveConfig.setActionCommand("save_configuration");
        saveConfig.setFont(defaultFont);
        saveConfig.setIcon(storeConfigIcon);
        saveConfig.setContentAreaFilled(false);
        saveConfig.setToolTipText("Save Configuration as a new Family Model");
        saveConfig.addActionListener(this);
               
        JPanel actionPanel = new JPanel (new FlowLayout(FlowLayout.LEFT));
        actionPanel.setBackground(bgColor);
        actionPanel.add(check); actionPanel.add(resolve);
        actionPanel.add(exportSelectorBox);
        actionPanel.add(saveConfig);
        actionPanel.add(viewDerivedChecker);       
        // actionPanel.add(exportBox); actionPanel.add(exportButton);       
       
        variabilityChecker = new VariabilityChecker ();       
        variabilityResolver = new VariabilityResolver ();
        JPanel varPanel = new JPanel (new GridLayout(2,1));       
        varPanel.add(variabilityChecker);
        varPanel.add(variabilityResolver);
        actionPanel.add(varPanel);
       
        add(actionPanel, BorderLayout.NORTH);
       
       
        // setSize(300,200);
        // setVisible(true);
        repaint ();
    }
       
    private JPanel handlePackage (Element element, boolean isRoot) {
        NodeList children = element.getChildNodes();
        Element childelement = null;       
        JPanel pPanel = new JPanel (new BorderLayout());
        pPanel.setBackground(bgColor);
      
        // If there are sub packages, these should be placed in a new tab.
        JTabbedPane containerTab = new JTabbedPane ();
        containerTab.setFont(rendererFont1);
        containerTab.setBackground(bgColor);
        pPanel.add(containerTab);
       
        if (isRoot) {
           
            // add the category classes
                       
            NodeList classes = element.getElementsByTagName("class");
            for (int i = 0; i < classes.getLength(); i++) {
                Element e = (Element) classes.item(i);
                String stereotype = e.getAttribute("stereoType");
                String eid = e.getAttribute("id");
                if (stereotype.equalsIgnoreCase("category")) {
                    idManager.put(eid, e);                   
                    JTabbedPane catTab = new JTabbedPane ();
                    //// FONT
                    catTab.setFont(rendererFont2);
                   
                    containerTab.add(e.getAttribute("name"), catTab);
          int index = containerTab.indexOfComponent(catTab);
          containerTab.setIconAt(index, SystemFamilyTreeCellRenderer.categoryClass);
          containerTab.setToolTipTextAt(index, "Category (group) '" + e.getAttribute("name") + "'");

                    JPanel cPanel= handleClass (e);
                    if (cPanel != null) {
                        catTab.addTab(e.getAttribute("name"), cPanel);
                    }
                   
                    NodeList assocs = e.getElementsByTagName("association");
                    for (int j = 0; j < assocs.getLength(); j++) {
                        Element assoc = (Element) assocs.item(j);
                        String targetClass = assoc.getAttribute("targetClass");
                       
                        // get the class
                        Object gotId = idManager.get(targetClass);
                        if (gotId == null) {
                          Element clazz = VariabilityManager.getClassElementWithID(assoc.getOwnerDocument().getDocumentElement(), targetClass);
                          if (clazz != null) {
                              cPanel= handleClass (clazz);
                              if (cPanel != null) {
                                  catTab.addTab(clazz.getAttribute("name"), cPanel);
                              }
                          }
                        }
                    }                       
                } else if (stereotype.equalsIgnoreCase("ProductLine")) {
                    idManager.put(eid, e);
          JPanel cPanel = handleClass(e);
          if (cPanel != null) {
            containerTab.add(cPanel, "Attributes");
            int index = containerTab.indexOfComponent(cPanel);
            containerTab.setToolTipTextAt(index, "Attribute properties for the product line '" + e.getAttribute("name") + "'");
          }
         
                }
            }
           
        }
        boolean hasPackages = false;
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);           
            if (child.getNodeName().equalsIgnoreCase("package")) {
                hasPackages = true;
                break;
            }           
        }
       
        if (hasPackages) {           
            JTabbedPane packageTab = new JTabbedPane ();
            containerTab.add("Packages", packageTab);           
            for (int i = 0; i < children.getLength(); i++) {
                Node child = children.item(i);
                if (child.getNodeName().equalsIgnoreCase("package")){
                    JPanel childPanel = handlePackage ((Element) child, false);
                    // pPanel.setFont(h2);
                    // Font f1 = defaultFont.deriveFont(defaultFont.getStyle(), defaultFont.getSize() + 6);
                    // currentPackageTab.setFont(f1);               
                    packageTab.addTab("Package " + ((Element)child).getAttribute("name"), childPanel);               
                }                       
            }
           
        }

        return pPanel;       
    }   
   
   
    private JPanel handleClass (Element element) {       
        variationPointCounter = 0;
        boolean has_variability = checkClassVariability (element);
        JPanel cPanel = null;
        idManager.put(element.getAttribute("id"), element);
        if (has_variability) {
            // cPanel = new JPanel (new FlowLayout(FlowLayout.LEFT));
            cPanel = new JPanel (new BorderLayout());
            cPanel.setBackground(bgColor);
            // cPanel.setBackground(bgColor);
            // TitledBorder border = new TitledBorder("Class " + element.getAttribute("name"));
            // border.setTitleFont(defaultFont.deriveFont(defaultFont.getStyle(), defaultFont.getSize() + 2));          
            // cPanel.setBorder (border);
            variationPointCounter++;
           
            ClassPropertyTableModel tablemodel = new ClassPropertyTableModel (element);
            JTable table = new JTable (tablemodel) {
                public TableCellRenderer getCellRenderer(int row, int column) {
                      return new VariabilityCellRenderer ();
                }               
            };
            table.setBackground(bgColor);
            TableColumn vpColumn = table.getColumnModel().getColumn(2);
            vpColumn.setCellEditor(new VariabilityCellEditor());
            JScrollPane scroll = new JScrollPane (table);
            scroll.setBackground(bgColor);
            cPanel.add(scroll);
      if (cPanel != null)
        classPanels.put(element.getAttribute("id"), cPanel);
        } else {           
        }
        return cPanel;
    }   
   
   
   
    private int handleAttributes (NodeList attributes, JPanel vPanel) {
        int count = 0;
        for (int i = 0; i< attributes.getLength();i++)
            count += handleAttribute ((Element)attributes.item(i), vPanel);
        return count;
    }
    private void handleAssociations (NodeList associations, JPanel vPanel) {
        for (int i = 0; i< associations.getLength();i++)
            handleAssociation ((Element)associations.item(i), vPanel);       
    }
    private void handleOperations (NodeList operations, JPanel vPanel) {
        for (int i = 0; i< operations.getLength();i++)
            handleOperation ((Element)operations.item(i), vPanel);       
    }
   
    private int handleAttribute (Element element, JPanel vPanel) {
        String stereotype = element.getAttribute("stereoType");
        String name = element.getAttribute("name");
        String type_id = element.getAttribute("type");       
        boolean is_vp = checkVariationPoint (stereotype);
       
        if (is_vp) {
            addCheckBox (vPanel, name, "Attribute <i>" + name + "</i>");
            return 1;
        }
        return 0;
    }
    private void handleAssociation(Element element, JPanel vPanel) {
        String stereotype = element.getAttribute("stereoType");
        String name = element.getAttribute("name");
        String otherEnd = element.getAttribute("otherEnd");       
        boolean is_vp = checkVariationPoint (stereotype);
       
        if (is_vp) {
            addCheckBox (vPanel, name, "Association <i>" + name + "</i>");
        } else if (stereotype.equalsIgnoreCase("conflicts")) {
            // body (pw, "Association <i>" + name + "</i> in conflict");
        } else if (stereotype.equalsIgnoreCase("requires")) {
            // body (pw, "Association <i>" + name + "</i> requires");
        }
    }
   
    private void handleOperation(Element element, JPanel vPanel) {
        String stereotype = element.getAttribute("stereoType");
        String name = element.getAttribute("name");       
        boolean is_vp = checkVariationPoint (stereotype);
       
        if (is_vp) {           
            addCheckBox (vPanel, name, "Operation " + name);
        }       
    }
   
    private void addCheckBox (JPanel vPanel, String name, String value) {
        JCheckBox check = new JCheckBox ();
        check.setBackground(bgColor);
        check.setText(name);
        check.setSelected(true);
        check.setToolTipText("Optional variation point " + name);
        vPanel.add(check);
    }
   
     
    /**
     *
     * @param element
     * @return
     */
    protected boolean checkClassVariability (Element element) {
        boolean has_variability = false;
        // has_variability = VariabilityManager.checkVariationPoint(element.getAttribute("stereoType"));
        // if (has_variability) return true;
        NodeList list = element.getElementsByTagName("attribute");
        has_variability = checkVariationPointForList(list);
        if (has_variability)
            return true;
        list = element.getElementsByTagName("operation");
        has_variability = checkVariationPointForList(list);
        if (has_variability) return true;       
        list = element.getElementsByTagName("association");
        has_variability = checkVariationPointForList(list);
        if (has_variability)
            return true;
        // check extra for association going to 'alternative classes'
        for (int i = 0; i < list.getLength(); i++) {
            Element assoc = (Element) list.item(i);
            Element targetClazz = VariabilityManager.getClassElementWithID(
                    assoc.getOwnerDocument().getDocumentElement(), assoc.getAttribute("targetClass"));
            has_variability = VariabilityManager.checkVariationPoint(targetClazz.getAttribute("stereoType"));
        }       
        return has_variability;       
    }
   
    //
    // Utils
    //
   
    protected boolean checkVariationPointForList (NodeList list) {
        boolean has_variability = false;
        for (int i = 0; i< list.getLength();i++) {
            String st = ((Element)list.item(i)).getAttribute("stereoType");
            has_variability = checkVariationPoint(st);
            if (has_variability)
                return true;
        }       
        return has_variability;
    }
   
    public static Vector getVariationPoints (NodeList list) {
        Vector v = new Vector ();
        boolean has_variability = false;
        for (int i = 0; i< list.getLength();i++) {
            String st = ((Element)list.item(i)).getAttribute("stereoType");
            has_variability = checkVariationPoint(st);
            if (has_variability)
                v.add(list.item(i));
        }               
        return v;
    }
   
    /**
     * Static method that decides if a stereotype actually represents a variability
     * @param stereotype
     * @return
     */
    public static boolean checkVariationPoint (String stereotype) {
        if (stereotype == null)
            return false;
        else if (stereotype.equalsIgnoreCase("vp") || stereotype.equalsIgnoreCase("optional") || stereotype.equalsIgnoreCase("variationpoint"))
            return true;
        else if (stereotype.equalsIgnoreCase("range") || stereotype.equalsIgnoreCase("property"))
            return true;
        else if (stereotype.equalsIgnoreCase("conflicts") || stereotype.equalsIgnoreCase("requires"))
            return true;
        else if (stereotype.equalsIgnoreCase("alternative"))
            return true;
        return false;
    }
   
    //
    // ActionListener
    //
   
    public void actionPerformed (java.awt.event.ActionEvent ae) {
        Object source = ae.getSource();
        String action = ae.getActionCommand();
        if (action.equalsIgnoreCase("resolve")) {
            resolveSystemFamily ();
        } else if (action.equalsIgnoreCase("check")) {
            checkSystemFamily ();
        } else if (action.equalsIgnoreCase("save_configuration")) {
            saveSystemFamilyConfiguration ();
        }
    }
   
    private void checkSystemFamily () {
        // System.out.println ("Check System Family ");       
        variabilityChecker.setModel(modelRoot);
        variabilityChecker.startCheck();
    }
   
    private void resolveSystemFamily () {
        // System.out.println ("Resolve System Family ");
 
        variabilityResolver.setModel (modelRoot);
        String selected = (String) exportSelectorBox.getSelectedItem();       
        variabilityResolver.startResolving(selected, true, viewDerivedModel);
    }
   
    /**
     * Stores the current variability specification
     * as a "new" System Family Model
     */
    private void saveSystemFamilyConfiguration() {
        System.out.println ("saveSystemFamilyConfiguration");
       
        // Store the current model with variability settings       
       
        System.out.println ("DefaultVariabilityResolveEngineImpl::resolveModel");
                      
        DocumentBuilderFactory docfac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docbuild = null;
        Document doc = null;
        try {
            docbuild = docfac.newDocumentBuilder();
            doc = docbuild.newDocument();           
        } catch (ParserConfigurationException pcerr) {
            System.out.println ("Could not create document :"  + pcerr);           
            // Have to exit ---
        }                      
        Element newModelRoot = doc.createElement("model");
        Element importModel = (Element) doc.importNode(modelRoot, true);
        newModelRoot.appendChild(importModel);       
        storeModel(newModelRoot, "UMT");       
    }

   
   
    private class VariabilityCellRenderer extends DefaultTableCellRenderer  {
        public VariabilityCellRenderer (){
            super ();
        }
       
        public Component getTableCellRendererComponent(JTable table,
                Object obj,
                boolean isSelected,
                boolean hasFocus,
                int row,
                int column)
        {
            // System.out.println ("RenderObject:" + obj.getClass().getName());           
            JComponent renderer = null;
            String toolTipText = "";
            if (obj instanceof Element) {
                Element element = (Element)obj;
                String stereotype = element.getAttribute("stereoType");
                String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);
                boolean is_variation_point = checkVariationPoint(stereotype);
                if (stereotype.equalsIgnoreCase("vp") || stereotype.equalsIgnoreCase("optional")) {                   
                    JCheckBox checker = new JCheckBox ();
                  toolTipText = "OPTIONAL variation point.";       
                  checker.setSelected(vpvalue.equalsIgnoreCase("false")?false:true)
                  renderer = checker;     
                } else if (stereotype.equalsIgnoreCase("range")) {
                    // range variation points only for attributes                   
                    // Get range values                   
                    String[] ranges = VariabilityManager.getRangeValues(element);
                    JTextField tf = new JTextField (vpvalue);
                    tf.setEditable(false);                   
                    // MyLabel l = new MyLabel (vpvalue);
                    toolTipText = "RANGE variation point (Valid range: " + ranges[0] + " - " + ranges[1] + ")";
                    renderer = tf;
                } else if (stereotype.equalsIgnoreCase("property")) {
                    // Property variation points only for attributes
                    JTextField tf = new JTextField (vpvalue);
                    tf.setEditable(false);
                    renderer = tf;
                    toolTipText = "PROPERTY variation point. " + vpvalue;
                    if (element.getNodeName().equalsIgnoreCase("attribute")) {
                        String typeid = element.getAttribute("type");
                        // Need to find type of this attribute
                    }
                } else if (stereotype.equalsIgnoreCase("alternative")) {
                    JComboBox combo = null;
                    if (element.getNodeName().equalsIgnoreCase("attribute")) {
                        String data[] = {vpvalue};                   
                        combo = new JComboBox (data);
                        toolTipText = "Alternative variation point: " + vpvalue;                       
                    } else {
                        String sourceAssociation = element.getAttribute("sourceAssociation");
                        String id = element.getAttribute("id");
                        String key = getTypeAlternativeKey(id, sourceAssociation);
                        String vpvalueAssoc = ((Element)idManager.get(id)).getAttribute(key);                   
                        String data[] = {vpvalueAssoc};                   
                        combo = new JComboBox (data);
                        toolTipText = "Type Alternative variation point: " + vpvalueAssoc;
                        vpvalue = vpvalueAssoc;
                    }                    
                    /*
                     JTextField tf = null;                   
                    if (vpvalue != null)
                        tf = new JTextField (vpvalue);
                    else
                        tf = new JTextField ("alternative...");
                        */                   
                    renderer = combo;
                    combo.setEditable(false);                   
                } else {
                    JTextField tf = new JTextField (vpvalue);
                    tf.setEditable(false);
                    renderer = tf;
                    toolTipText = "Unhandled variation point type: " + stereotype;                   
                }
                if (is_variation_point && vpvalue.equals("")) {
                    renderer.setBackground(varNotChecked);
                    toolTipText = renderer.getToolTipText() + "  # Not checked by user #";
                } else if (is_variation_point) {
                    renderer.setBackground(varChecked);
                    // send update event to tree viewer
                   
                } else {
                    // renderer.setBackground(bgColor);
                    renderer.setBackground(Color.yellow);
                }
        /*
                if (renderer instanceof JComboBox)
                    renderer.setFont(defaultFont);
                else
                    renderer.setFont(rendererFont1);
                    */               
              renderer.setToolTipText(toolTipText);
        renderer.setFont(defaultFont);
                return renderer;
            } else {
                JLabel label = new JLabel ((String)obj);
                renderer = label;
                renderer.setBackground(bgColor);
            }
      renderer.setFont(defaultFont);
            return renderer;
        }       
    }
       
   
    private class VariabilityCellEditor extends AbstractCellEditor implements TableCellEditor,
      ChangeListener  {

        Object editorvalue = null;
        public Object getCellEditorValue() {
            return editorvalue;
        }
       
        public Component getTableCellEditorComponent(JTable table,
                Object value,
                boolean isSelected,
                int row,
                int column) {
            JComponent editor = null;
            editorvalue = value;
            // System.out.println ("getTableCellEditorComponent: " + value);
            boolean is_variation_point = false;
            String vpvalue = "";
            if (value instanceof Element) {                              
                Element element = (Element)value;
                vpvalue = element.getAttribute(VARIABILITY_INDICATOR);
                String stereotype = element.getAttribute("stereoType");
                is_variation_point = checkVariationPoint(stereotype);
                if (stereotype.equalsIgnoreCase("vp") || stereotype.equalsIgnoreCase("optional")) {
                    JCheckBox check = new JCheckBox ();
                    check.addChangeListener(this);
                    editor = check;
                } else if (stereotype.equalsIgnoreCase("range")) {
                    NumberRangeVariabilityCellEditor rangeeditor = new NumberRangeVariabilityCellEditor (element);
                    rangeeditor.addChangeListener(this);
                    editor = rangeeditor;
                } else if (stereotype.equalsIgnoreCase("property")) {
                    // the editor handles the actions
                    PropertyVariabilityCellEditor propertycelleditor = new PropertyVariabilityCellEditor (element);
                    editor = propertycelleditor;
                } else if (stereotype.equalsIgnoreCase("alternative")) {
                    // The editor handles the actions
                    AlternativeVariabilityCellEditor altEditor = new AlternativeVariabilityCellEditor (element);
                    editor = altEditor;
                }
                else {
                    editor = new JTextField ((String) value);
                }               
            } else {
                JLabel label = new JLabel ((String)value);
                editor = label;
            }
           
            if (is_variation_point){
                editor.setBackground(varChecked);
            }
            if (editor instanceof JComboBox)               
                editor.setFont(rendererFont2);
            else
                editor.setFont(rendererFont1);
            return editor;
        }
       
        public void stateChanged (ChangeEvent ce) {
            Object source = ce.getSource();
            Element element = null;           
            if (ce.getSource() instanceof JCheckBox) {               
                JCheckBox box = (JCheckBox)ce.getSource();
                element = (Element)editorvalue;
                String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);
                vpvalue = box.isSelected()?"true":"false";
                element.setAttribute(VARIABILITY_INDICATOR, vpvalue);
       
        checkOptionalVariabilityChange(element);
       
            } else if (source instanceof NumberRangeVariabilityCellEditor) {
                NumberRangeVariabilityCellEditor editor = (NumberRangeVariabilityCellEditor) source;
                Object val = editor.getValue();
                String strVal = val.toString();
                element = (Element)editorvalue;               
                String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);
                vpvalue.toString();
                element.setAttribute(VARIABILITY_INDICATOR, strVal);
            }
            notifyVariabilityEventListeners(editorvalue);
        }
       
     }
 
 
  /**
   * check OptionalVariabilityChange
   * @param element
   */
  protected void checkOptionalVariabilityChange (Element element) {   
    String varIndicator = element.getAttribute(VARIABILITY_INDICATOR);
    if (element.getNodeName().equalsIgnoreCase("association")) {
      String targetClassId = element.getAttribute("targetClass");
      Collection assocs = getAssociationsToClass(this.modelRoot, targetClassId);
      Element assoc = null;
      boolean someIsTrue = false;
      for (Iterator it = assocs.iterator(); it.hasNext();) {
        assoc = (Element) it.next();
        varIndicator = assoc.getAttribute(VARIABILITY_INDICATOR);       
        if (varIndicator.equals("false")) {         
        } else if (varIndicator.equals("true")){
          someIsTrue = true;
          break;
        }
      }
     
      if (someIsTrue) {
        // activate the pane containing this class.
        variabilityActivation(targetClassId, true);
      } else {
        // deactivate the pane containing this class.
        variabilityActivation(targetClassId, false);
      }
    }   
  }
 
  protected void variabilityActivation (String classId, boolean activate) {
    JPanel clazzPanel = (JPanel) classPanels.get(classId);
    Container c = null;
    Element clazzElement = null;
    int index = 0;
    if (clazzPanel != null){
      c = clazzPanel.getParent();
      if (c instanceof JTabbedPane) {
        index = ((JTabbedPane)c).indexOfComponent(clazzPanel);
        // ((JTabbedPane)c).setIconAt()
        ((JTabbedPane)c).setEnabledAt(index, activate);
        //set activation property for the class element
        clazzElement = getClassElementWithID(modelRoot, classId);
        if (clazzElement != null) {
          // set the VARIABILITY_CLASS_ACTIVE property
          clazzElement.setAttribute(VARIABILITY_CLASS_ACTIVE, "" + activate);
        }
      }
    }
  }
   
    /**
     *  Fetches the range values from a model element (attribute)
     *  For now, uses the initialValue property on the form value: int = 4{3-10},
     *  where 4 is the default, 3, is the lower and 10 the upper range value
     *
     *  For now: Only returns low and high range values, not default value
     */
    public static String[] getRangeValues (Element element) {
        String[] ranges = new String [2];
        ranges[0] = "2"; ranges[1] = "16";

        String initialValue = element.getAttribute ("initialValue");
        String[] valueSplit = initialValue.split(", ");
        int beginindex = initialValue.indexOf('{');
        int nextindex = initialValue.indexOf('-', beginindex);
        int endindex = initialValue.indexOf('}', nextindex);       
        try {
            ranges[0] = initialValue.substring(beginindex+1, nextindex).trim();
            ranges[1] = initialValue.substring(nextindex+1, endindex).trim();
        } catch (Exception ex) {
           
        }
        return ranges;
    }
   
    /**
     * Fetches the alternative values from a model element (attribute)
     * For now, uses the initialValue property on the form: {3,100, 2000, 200}
     * @param element
     * @return
     */
    public static Object [] getAlternativeValuesForAttribute (Element element) {
        Vector alts = new Vector ();
        String initialValue = element.getAttribute ("initialValue");
        String[] valueSplit = initialValue.split("[,\\{\\}]");       
        for (int i = 0; i < valueSplit.length; i++) {
            if (!valueSplit[i].trim().equals(""))
               alts.add(valueSplit[i].trim());
        }       
        return alts.toArray();
    }
   
    /**
     * Fetches the type alternatives for a class - determined by its subclasses
     * @param element
     * @return
     */
    public static Object [] getAlternativeValuesForClass (Element element) {
        Vector alts = new Vector ();
        Vector subs = VariabilityManager.getSubclasses(element.getOwnerDocument().getDocumentElement(), element.getAttribute("id"));
       
        for (Iterator it = subs.iterator(); it.hasNext();) {
            Element sub = (Element) it.next();
            alts.add(sub.getAttribute("name"));
        }       
        return alts.toArray();
    }   
   
    private class NumberRangeVariabilityCellEditor extends JSpinner implements ChangeListener, KeyListener {
        private Element editorvalue = null;
        public NumberRangeVariabilityCellEditor (Element element) {
            // Get the range values
      addKeyListener(this);
            editorvalue = element;
            String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);           
           
            String[] ranges = VariabilityManager.getRangeValues(element);
            String minval = ranges[0], maxval = ranges[1];
            setToolTipText("Legal range values: {" + minval + " - " + maxval + "}");               
           
            // Must fetch type
            // element.getAttribute("type");        
            String type = "int";
            if (minval.indexOf('.') > -1 || maxval.indexOf('.') > -1)
                type = "double";
                       
            if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("integer") || type.equalsIgnoreCase("short") || type.equalsIgnoreCase("long")){               
                int val = 4, min = 4, max = 20, step = 1;
                min = Integer.parseInt(minval); max = Integer.parseInt(maxval);
                val = min;
                if (vpvalue != null && !vpvalue.equals("")) {
                    val = Integer.parseInt(vpvalue);
                }
                SpinnerNumberModel model = new SpinnerNumberModel (val, min, max, step);
                setModel(model);               
            } else if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("double")) {
                // values currently defined by substring of initialValue property e.g. {2-15}
                double val = 2.0, min = 2.0, max = 14.4, step = 0.1;
                min = Double.parseDouble(minval); max = Double.parseDouble(maxval);
                val = min;
                if (vpvalue != null && !vpvalue.equals("")) {
                    val = Double.parseDouble(vpvalue);
                }
                SpinnerNumberModel model = new SpinnerNumberModel (val, min, max, step);
                setModel(model);
            } else {
                // TODO: What to do here?
                // Type could also be an enumeration
                //
                SpinnerListModel model = new SpinnerListModel ();
                setModel (model);
            }
            this.setBackground(varNotChecked);
            addChangeListener(this);
        }
       
        public void stateChanged (ChangeEvent ce) {
            System.out.println ("NumberRangeCellEditor::stateChanged");
            JSpinner spin = (JSpinner) ce.getSource();
            Object value = spin.getValue();           
            editorvalue.setAttribute(VARIABILITY_INDICATOR, value.toString());
        }
   
    public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB) {
        System.out.println ("Enter | tab");
      }
    }
   
    public void keyReleased(KeyEvent e) {
    }
   
    public void keyTyped(KeyEvent e) {
    }
    }

   
    private class PropertyVariabilityCellEditor extends JTextField implements ActionListener, KeyListener {
        private Element editorvalue = null;
        public PropertyVariabilityCellEditor (Element element) {
            editorvalue = element;
            String type = element.getAttribute("type");
            String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);                       
            setToolTipText("Select value for property: (Type...)");
      setText (editorvalue.getAttribute(VARIABILITY_INDICATOR));
            // addCaretListener(this);           
            addActionListener(this);
      addKeyListener(this);
        }
       
        public void actionPerformed (ActionEvent ae) {
            // System.out.println ("PropertyCellEditor::actionPerformed: " + ae.getActionCommand());
            editorvalue.setAttribute(VARIABILITY_INDICATOR, ae.getActionCommand());
        }
   
    public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB) {
        editorvalue.setAttribute(VARIABILITY_INDICATOR, getText());
      }
    }   
    public void keyReleased(KeyEvent e) {
    }
   
    public void keyTyped(KeyEvent e) {
    }   
   
    }
   
    private class AlternativeVariabilityCellEditor extends JComboBox implements ActionListener {
        private Element editorvalue = null;
        public AlternativeVariabilityCellEditor (Element element) {
            editorvalue = element;
            Object[] alternativeValues = null;
            if (element.getNodeName().equalsIgnoreCase("attribute")) {
                alternativeValues = VariabilityManager.getAlternativeValuesForAttribute(editorvalue);
                setToolTipText("Select value for Alternative vp.");               
            }
            else if (element.getNodeName().equalsIgnoreCase("class")) {
                alternativeValues = VariabilityManager.getAlternativeValuesForClass(editorvalue);
                setToolTipText("Select type alternative for " + element.getAttribute("name"));
            }
            String vpvalue = element.getAttribute(VARIABILITY_INDICATOR);
           
            if (alternativeValues == null || alternativeValues.length == 0) {
                alternativeValues = new String[1];
                alternativeValues[0] = "No alternatives";
            }
            setModel(new DefaultComboBoxModel(alternativeValues));
            addActionListener(this);
        }
       
        public void actionPerformed (ActionEvent ae) {
            // System.out.println ("PropertyCellEditor::actionPerformed: " + ae.getActionCommand());
            String action = ae.getActionCommand();
            String selected = (String) getSelectedItem();
            if (editorvalue.getNodeName().equalsIgnoreCase("attribute")) {
                editorvalue.setAttribute(VARIABILITY_INDICATOR, selected);
            } else if (editorvalue.getNodeName().equalsIgnoreCase("class")) {
                String sourceAssociation = editorvalue.getAttribute("sourceAssociation");
                String id = editorvalue.getAttribute("id");
                String key = getTypeAlternativeKey(id, sourceAssociation);
                Element orgClazz = (Element)idManager.get(id);
                orgClazz.setAttribute(key, selected);               
                editorvalue.setAttribute(key, selected);
            }
            notifyVariabilityEventListeners(editorvalue);           
        }       
    }
   
              

   

    public static void storeModel (Element model, String exportType) {
        Writer writer = null;           
        if (exportType.startsWith("UMT")) {
            writer = getStoreWriter(model, exportType, "xml");
            if (writer != null) {
                XMLUtility.streamToXML(model, writer);
                try {
                    writer.close();
                } catch (IOException ioex) {
                }
            }   
        }
    }
   
    public  static void storeTextModel (Element orgModel, StringBuffer model, String exportType) {
        Writer writer = null;
        String ext = exportType.startsWith("UML2")? "uml2": "xmi";
        writer = getStoreWriter(orgModel, exportType, ext);
        if (writer != null) {
          PrintWriter printer = new PrintWriter(writer);
          printer.print(model.toString());
          printer.close();
        }
    }
   
    protected static Writer getStoreWriter (Element orgModel, String modelType, String extension) {
        JFileChooser savedialog = new JFileChooser ("Save product model(" + modelType + ")");           
    savedialog.setCurrentDirectory (new java.io.File (org.sintef.umt.umtmain.UMTMain.getCurrentStoreDir()));
    String name = orgModel.getAttribute("name");
    if (name == null) name = "DerivedModel";
    savedialog.setSelectedFile(new File (name + "." + extension));
    int ret = savedialog.showSaveDialog(null);
    if(ret == JFileChooser.APPROVE_OPTION) {     
      File f = savedialog.getSelectedFile();
            java.io.FileWriter writer = null;
            try {
                writer = new java.io.FileWriter (f);
                return writer;
            } catch (java.io.IOException ex) {
                System.out.println ("VariabilityResolver::getStoreWriter- " + ex);
            }         
    }
    return null;
    }   
   
   
    /**
     *
     * @param rootDoc
     * @param id
     * @return
     */
  public static Element getClassElementWithID (Element rootDoc, String id) {     
      NodeList classes = rootDoc.getElementsByTagName("class");
      for (int i = 0; i < classes.getLength(); i++) {
          Element clazz =  (Element)classes.item(i);
          if (clazz.getAttribute("id").equalsIgnoreCase(id))
              return clazz;         
      }     
      return null;
  }
 
  /**
   *
   * @param rootDoc
   * @param superClassID
   * @return
   */
  public static Vector getSubclasses (Element rootDoc, String superClassID) {
      Vector subClasses = new Vector ();     
      String scID = null;
      NodeList classes = rootDoc.getElementsByTagName("class");
      for (int i = 0; i < classes.getLength(); i++) {
          Element clazz =  (Element)classes.item(i);
          scID = clazz.getAttribute("superClass");
          if (scID.equalsIgnoreCase(superClassID))
              subClasses.add(clazz)
      }           
      return subClasses;
  }
 
  public static Collection getAssociationsToClass (Element rootDoc, String classId) {
    ArrayList assocsForClass = new ArrayList();
    NodeList assocs = rootDoc.getElementsByTagName ("association");
    String targetClass = null;
      for (int i = 0; i < assocs.getLength(); i++) {     
          Element assoc = (Element) assocs.item(i);
      targetClass = assoc.getAttribute("targetClass");
      if (targetClass.equals(classId))
        assocsForClass.add(assoc);
      }
    return assocsForClass;
  }
 
  public static Element getAssociationFromID (Element rootDoc, String id) {
      NodeList assocs = rootDoc.getElementsByTagName("association");
      for (int i = 0; i < assocs.getLength(); i++) {
          Element assoc = (Element) assocs.item(i);
          if (assoc.getAttribute("id").equals(id))
              return assoc;
      }
      return null;
  }
 
  public static String getTypeAlternativeKey (String classId, String assocId) {
      return "CLASS-" + classId + "ASSOC-" + assocId;     
  }
       
}
TOP

Related Classes of org.sintef.umt.systemfamily.VariabilityManager$VariabilityCellEditor

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.