Package org.sintef.umt.systemfamily

Source Code of org.sintef.umt.systemfamily.DefaultVariabilityResolveEngineImpl

//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.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import org.w3c.dom.*;


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

/**
* @author jol
* DefaultVariabilityResolveEngineImpl
* Created 10.nov.2004
*/


public class DefaultVariabilityResolveEngineImpl implements VariabilityResolveEngine {
   
   
   
    private Vector errorList = null;
    private Element rootModel = null;
    private Document doc = null;
           
    private boolean removeCategories;
   
    public Element resolveModel (Element model) {
        System.out.println ("DefaultVariabilityResolveEngineImpl::resolveModel");
        rootModel = model;               
        DocumentBuilderFactory docfac = DocumentBuilderFactory.newInstance();
        DocumentBuilder docbuild = null;
        try {
            docbuild = docfac.newDocumentBuilder();
            doc = docbuild.newDocument();           
        } catch (ParserConfigurationException pcerr) {
            System.out.println ("Could not create document :"  + pcerr);           
            // Have to exit ---
        }       
        errorList = new Vector ();      
       
        // Append root model
               
        // Element derivedModel = doc.createElement(model.getNodeName());
        Element derivedModel = doc.createElement("model");
        Element importModel = (Element) doc.importNode(model, true);
        derivedModel.appendChild(importModel);
        ((Element)importModel).setAttribute("name", model.getAttribute("name") + " UMT Derived Product");
        ((Element)derivedModel).setAttribute("name", model.getAttribute("name") + " UMT Derived Product");       
       
        // Element derivedModel = (Element) doc.importNode(model, true);
       
        ((Element)derivedModel).setAttribute("name", model.getAttribute("name") + " UMT Derived Product");
       
        // doc.appendChild(derivedModel);
       
        // TODO: Need to add attributes ????
       
       
        NodeList children = derivedModel.getChildNodes();
        Node child = null;
        Element element = null;
        for (int i = 0; i < children.getLength(); i++) {
            child = children.item(i);
           
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                element = (Element)child;
                String nodename = element.getNodeName();               
                if (nodename.equalsIgnoreCase("package")) {
                    checkPackage (element, derivedModel);
                } else if (nodename.equalsIgnoreCase("datatype")) {
                    // NOOP
                    // Element datatype = createNewElement(element, true);
                    // derivedModel.appendChild(datatype);
                }
            } else {
               
                // derivedModel.appendChild(child.cloneNode(true));
            }
        }
        checkTypeAlternatives(derivedModel);
        checkDependencies(derivedModel);
        return derivedModel;
       
    }
   
    private Element createNewElement (Element template, boolean deep) {
        Element newElement = doc.createElement(template.getNodeName());       
       
        NodeList children = template.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            short ntype = child.getNodeType();               
            if (ntype == Node.ELEMENT_NODE && deep) {
                Element e = createNewElement ((Element)child, deep);
                newElement.appendChild(e);
            } else if (ntype == Node.ATTRIBUTE_NODE) {
                Attr attribute = doc.createAttribute(((Attr)child).getName());
                attribute.setValue(((Attr)child).getValue());
                newElement.appendChild(attribute);
            } else if (ntype == Node.CDATA_SECTION_NODE) {  
                CDATASection cdata = doc.createCDATASection(((CDATASection)child).getData());
                newElement.appendChild(cdata);
            } else if (ntype == Node.COMMENT_NODE) {
                Comment comment = doc.createComment(((Comment)child).getData());
                newElement.appendChild(comment);
            } else if (ntype == Node.TEXT_NODE) {
                Text t = doc.createTextNode(((Text)child).getData());
                newElement.appendChild(t);
            }
            }
        return newElement;
    }
   
    /**
     * Checks a model element's stereotype - if it matches 'checkType', then swap with 'newType'
     *  Casing ignored
     * @param modelElement
     * @param checkType
     * @param newType
     */
    private void modifyStereoType (Element modelElement, String checkType, String newType) {
        String st = modelElement.getAttribute("stereoType");
        if (st != null && st.equalsIgnoreCase(checkType)) {
            modelElement.setAttribute("stereoType", newType);
        }
    }
   
    /**
     *
     * @param modelElement
     */
    private void family2ProductStereoType (Element modelElement) {
        modifyStereoType (modelElement, "SystemFamily", "Product");
    }
   
    private void checkPackage (Element pElement, Element owner) {
        // Element packageClone = (Element) pElement.cloneNode(false);
        // Element packageClone = createNewElement (pElement, false);
       
        // owner.appendChild(packageClone);   
      
        //
        // Package notation for SystemFamily --- Here: Stereotype "SystemFamily"
        // Remove /  Change Stereotype       
       
        family2ProductStereoType (pElement);
       
        NodeList children = pElement.getChildNodes();
        Node child = null;
        Element child_element = null;
        for (int i = 0; i < children.getLength(); i++) {
            child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                child_element = (Element) child;
                String nodename = child_element.getNodeName();
               
                if (nodename.equalsIgnoreCase("package")){
                    checkPackage (child_element, pElement);
                }
                else if (nodename.equalsIgnoreCase("class")) {
                    checkClass (child_element, pElement);
                }
                else {
                    // NOOP
                }
            }
        }
       
    }
   
    //
    // Check Class
    //
    private void checkClass (Element classElement, Element owner) {
       
        // Append class to owner
        // Element classClone = createNewElement(classElement, false);
        // owner.appendChild(classClone);
       
        this.family2ProductStereoType(classElement);
       
        String name = classElement.getAttribute("name");
        String stereotype = classElement.getAttribute("stereoType");
        String id = classElement.getAttribute("id");
        NodeList attributes = classElement.getElementsByTagName("attribute");
        NodeList associations = classElement.getElementsByTagName("association");
        NodeList operations = classElement.getElementsByTagName("operation");
       
        NodeList children = classElement.getChildNodes();
        Node child = null;
        String childStereoType = "";
        for (int i = 0; i < children.getLength(); i++) {
            child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                childStereoType = ((Element)child).getAttribute("stereoType");               
                if (VariabilityManager.checkVariationPoint(childStereoType)) {
                    checkClassFeature ((Element)child, classElement);
                }
            }
        }  
       
       
        // TODO: REMOVE - HAndled by other means
        if(VariabilityManager.checkVariationPoint(stereotype)) {
           
            //
            // Handle type alternative
            //
            if (stereotype.equalsIgnoreCase("alternative")) {
                String vpvalue = classElement.getAttribute(VariabilityManager.VARIABILITY_INDICATOR);
               
                if (vpvalue == null || vpvalue.equals("")) {
                    // NOOP
                } else {                   
                    classElement.setAttribute("stereoType", "");
                   
                    // get the subclasses and remove all subclasses that are not 'IT'
                   
                    Vector subs = VariabilityManager.getSubclasses(
                            classElement.getOwnerDocument().getDocumentElement(), id);
                   
                    for (Iterator it = subs.iterator(); it.hasNext();) {
                        Element sub = (Element) it.next();
                       
                        String subName = sub.getAttribute("name");
                       
                        if (subName.equalsIgnoreCase(vpvalue)) {
                            // ok, keep this
                        } else {
                            // remove this class...
                           
                            /*
                             * Strategy: Remove all subclasses, rename superclass
                             * to the selected alternative.
                             * Move all properties of the selected alternative to the
                             * original alternative class
                             */
                           
                            classElement.setAttribute("name", subName);
                           
                        }
                    }
                   
                }
            }
        }       
    }
   
    /*
     * checkTypeAlternatives
     */
    protected void checkTypeAlternatives (Element pElement) {
        NodeList allClasses = pElement.getElementsByTagName("class");
       
        for (int i = 0; i < allClasses.getLength(); i++) {
            Element clazz = (Element) allClasses.item(i);
           
            String stereotype = clazz.getAttribute("stereoType");
            if (stereotype.equalsIgnoreCase("alternative")) {
                Vector subClasses = VariabilityManager.getSubclasses(
                        pElement, clazz.getAttribute("id"));               
                NamedNodeMap attributes = clazz.getAttributes();               
                Vector toRemove = new Vector();
                for (int j = 0; j < attributes.getLength(); j++) {
                    Attr attribute = (Attr)attributes.item(j);                   
                    String nodename = attribute.getNodeName();
                    String nodevalue = attribute.getNodeValue();
                   
                    // Need to move associations from alternative class to the alternative
                    if (nodename.startsWith("CLASS-")) {
                        int assocIndex = nodename.lastIndexOf("ASSOC-");
                        String assocId = nodename.substring(assocIndex + 6, nodename.length());
                        // find the assoc and change to the appropriate sub class
                        Element theAssoc = VariabilityManager.getAssociationFromID(
                                pElement, assocId);
                        if (theAssoc != null) {
                            // Change the association target
                           
                            for (Iterator it = subClasses.iterator(); it.hasNext();) {
                                Element subClazz = (Element)it.next();
                                if (subClazz.getAttribute("name").equalsIgnoreCase(nodevalue)) {
                                    // change the assoc to this class
                                    theAssoc.setAttribute("targetClass", subClazz.getAttribute("id"));
                                }
                            }
                        }
                        toRemove.add(attribute);
                        //clazz.removeAttributeNode(attribute);
                    }
                }
               
                // Remove the extra attributes
                for (Iterator it = toRemove.iterator(); it.hasNext();) {
                    Attr attribute = (Attr)it.next();
                    clazz.removeAttributeNode(attribute);
                }
                toRemove.clear();
                toRemove = null;
               
                // Remove stereotype
                clazz.setAttribute("stereoType", "");               
            }           
        }
       
    }
   
    //
    // check attribute, operation, association
    //
   
    private void checkClassFeature (Element feature, Element owner) {
       
        NamedNodeMap attributes = feature.getAttributes();
       
        // Element featureClone = createNewElement(feature, true);       
       
        // VARIABILITY_INDICATOR       
        Element parent = (Element) feature.getParentNode();
        String parentname = parent.getAttribute("name");       
        String vpvalue = feature.getAttribute(VariabilityManager.VARIABILITY_INDICATOR);
        String name = feature.getAttribute("name");
        String id = feature.getAttribute("id");
        String stereotype = feature.getAttribute("stereoType");
       
        String nodename = feature.getNodeName();
       
        if (vpvalue == null || vpvalue.equals("")) {
            // Error: Variability to checker by user
           
            // Include the feature anyway
           
            // owner.appendChild(featureClone);
           
            // Do nothing, element remains here.
           
        } else {
           
            if (stereotype.equalsIgnoreCase("vp") || stereotype.equalsIgnoreCase("optional")) {               
                if (vpvalue.equalsIgnoreCase("false")) {
                    // Do not add the feature.
                    //
                    //                 
                    // Remove the feature
                    owner.removeChild(feature);
                   
                    // TODO: Must also need to check to remove other features or classes....
                   
                } else {
                   
                    // owner.appendChild(featureClone);                   
                    // Remove the variation point indicator
                   
                    feature.setAttribute("stereoType", "");
                }
               
            } else if (stereotype.equalsIgnoreCase("range")) {
                feature.setAttribute("stereoType", "");
                feature.setAttribute("initialValue", vpvalue);
            } else if (stereotype.equalsIgnoreCase("property")) {
                feature.setAttribute("stereoType", "");
                feature.setAttribute("initialValue", vpvalue);
            } else if (stereotype.equalsIgnoreCase("alternative")) {
                feature.setAttribute("stereoType", "");
                feature.setAttribute("initialValue", vpvalue);
            }
            else {
                // add the feature ...
                // owner.appendChild(featureClone);
            }
        }       
    }
   
    private void checkDependencies (Element pElement) {
        NodeList children = pElement.getChildNodes();
        Node child = null;
        Element child_element = null;
        NodeList classlist = pElement.getElementsByTagName("class");
        NodeList associationlist = pElement.getElementsByTagName("association");
       
        Hashtable classes = new Hashtable ();
        Hashtable associations = new Hashtable ();
        Hashtable classesWithAssocs = new Hashtable ();
        Hashtable inheritance = new Hashtable ();
       
       
        for (int i = 0; i < classlist.getLength(); i++) {
            Element clazz = (Element)classlist.item(i);
            classes.put(clazz.getAttribute("id"), clazz);
            String superClass = clazz.getAttribute("superClass");
            if (superClass!=null && !superClass.equals("")) {
                inheritance.put(superClass, clazz.getAttribute("id"));
            }
        }
        for (int i = 0; i < associationlist.getLength(); i++) {
            Element assoc = (Element)associationlist.item(i);
            associations.put(assoc.getAttribute("id"), assoc);
            classesWithAssocs.put(assoc.getAttribute("targetClass"), assoc);
        }
       
       
        for (int i = 0; i < classlist.getLength(); i++) {
            Element clazz = (Element) classlist.item(i);
                       
            String stereotype = clazz.getAttribute("stereoType");
           
            if (stereotype == null || stereotype.equals("") &&
                    (!stereotype.equalsIgnoreCase("SystemFamily")
                            || !stereotype.equalsIgnoreCase("Product"))){
               
               
                // The simplest case: No associations at all exists to this class
               
                Object exists = classesWithAssocs.get(clazz.getAttribute("id"));
                if (exists != null) {
                    // ok, this class has some assoc to it
                } else {
                    // This class does not have any assoc to it, remove the class
                    // Unless another class inherits from this class
                   
                    // Check inheritance
                    Object inherit = inheritance.get(clazz.getAttribute("id"));
                    if (inherit != null) {
                        // Don't remove. This class has inheritance dependencies
                    } else {
                        Node parent = clazz.getParentNode();
                        parent.removeChild(clazz);                       
                    }
                }
               
            }  
        }
       
    }
   
    protected void copyClassProperties (Element toClass, Element fromClass) {
    }
   
    public Vector getErrors () {
        return errorList;
    }
   
   
}
TOP

Related Classes of org.sintef.umt.systemfamily.DefaultVariabilityResolveEngineImpl

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.