All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.languages.parser.DGUtils Maven / Gradle / Ivy

There is a newer version: RELEASE240
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.languages.parser;

import java.util.*;

/**
 *
 * @author Jan Jancura
 */
public class DGUtils {


    public static  DG cloneDG (DG dg, boolean cloneProperties, NodeFactory nodeFactory) {
        DG ndg = DG.createDG ();
        Map oldToNew = new HashMap ();
        Iterator it = dg.getNodes ().iterator ();
        while (it.hasNext ()) {
            N oldNode = it.next ();
            N newNode = oldToNew.get (oldNode); 
            if (newNode == null) {
                newNode = nodeFactory.createNode ();
                ndg.addNode (newNode);
                oldToNew.put (oldNode, newNode);
                if (cloneProperties)
                    ndg.putAllProperties (newNode, dg.getProperties (oldNode));
            }
            Iterator it2 = dg.getEdges (oldNode).iterator ();
            while (it2.hasNext ()) {
                E edge = it2.next ();
                N oldEnd = dg.getNode (oldNode, edge);
                N newEnd = oldToNew.get (oldEnd); 
                if (newEnd == null) {
                    newEnd = nodeFactory.createNode ();
                    ndg.addNode (newEnd);
                    oldToNew.put (oldEnd, newEnd);
                    if (cloneProperties)
                        ndg.putAllProperties (newEnd, dg.getProperties (oldEnd));
                }
                ndg.addEdge (newNode, newEnd, edge);
                if (cloneProperties)
                    ndg.putAllProperties (newNode, edge, dg.getProperties (oldNode, edge));
            }
            if (dg.getEnds ().contains (oldNode))
                ndg.addEnd (newNode);
        }
        N newStart = oldToNew.get (dg.getStartNode ());
        ndg.setStart (newStart);
        return ndg;
    }
    
    
    public static  DG append (DG dg1, DG dg2, E star, NodeFactory nodeFactory) {
        DG ndg = DG.createDG ();
        Set newStart = new HashSet ();
        newStart.add (dg1.getStartNode ());
        if (dg1.getEnds ().contains (dg1.getStartNode ()))
            newStart.add (dg2.getStartNode ());
        Map,N> newToOld = new HashMap,N> ();
        merge (dg1, dg2, newStart, ndg, newToOld, dg1.getEnds (), dg2.getStartNode (), false, true, star, nodeFactory);
        N nnn = newToOld.get (newStart);
        ndg.setStart (nnn);
        return ndg;
    }
    
    public static  DG plus (DG dg, E star, NodeFactory nodeFactory) {
        DG ndg = DG.createDG ();
        N what = dg.getStartNode ();
        Set where = dg.getEnds ();
        Set nn = new HashSet ();
        nn.add (dg.getStartNode ());
        if (where.contains (dg.getStartNode ()))
            nn.add (what);
        Map,N> newToOld = new HashMap,N> ();
        merge (dg, dg, nn, ndg, newToOld, where, what, true, true, star, nodeFactory);
        N nnn = newToOld.get (nn);
        ndg.setStart (nnn);
        return ndg;
    }
    
    private static  void merge (
        DG         dg1,
        DG         dg2,
        Set              nn,
        DG         ndg,
        Map,N>       newToOld,
        Set              where,
        N                   what,
        boolean             setEnds1,
        boolean             setEnds2,
        E                   star,
        NodeFactory      nodeFactory
    ) {
        N nnn = newToOld.get (nn);
        if (nnn != null) return;
        nnn = nodeFactory.createNode ();
        newToOld.put (nn, nnn);
        ndg.addNode (nnn);

        Map> edges = new HashMap> ();
        Map> properties = new HashMap> ();
        Iterator it = nn.iterator ();
        while (it.hasNext ()) {
            N n = it.next ();
            DG cdg = dg1.containsNode (n) ? dg1 : dg2;
            ndg.putAllProperties (nnn, cdg.getProperties (n));
            if (setEnds1 && dg1.getEnds ().contains (n))
                ndg.addEnd (nnn);
            if (setEnds2 && dg2.getEnds ().contains (n))
                ndg.addEnd (nnn);
            Iterator it2 = cdg.getEdges (n).iterator ();
            while (it2.hasNext ()) {
                E edge = it2.next ();
                Set ends = edges.get (edge);
                Map props = properties.get (edge);
                if (ends == null) {
                    ends = new HashSet ();
                    props = new HashMap ();
                    edges.put (edge, ends);
                    properties.put (edge, props);
                }
                N en = cdg.getNode (n, edge);
                ends.add (en);
                props.putAll (cdg.getProperties (n, edge));
                if (where.contains (en))
                    ends.add (what);
            }
        }
        it = nn.iterator ();
        while (it.hasNext ()) {
            N n = it.next ();
            DG cdg = dg1.containsNode (n) ? dg1 : dg2;
            N en = cdg.getNode (n, star);
            if (en == null) continue;
            Iterator it2 = edges.keySet ().iterator ();
            while (it2.hasNext ()) {
                E e = it2.next ();
                if (cdg.getNode (n, e) != null) continue;
                edges.get (e).add (en);
                properties.get (e).putAll (cdg.getProperties (n, e));
                if (where.contains (en))
                    edges.get (e).add (what);
            }
        }
        
        Iterator it2 = edges.keySet ().iterator ();
        while (it2.hasNext ()) {
            E edge = it2.next ();
            Set en = edges.get (edge);
            merge (dg1, dg2, en, ndg, newToOld, where, what, setEnds1, setEnds2, star, nodeFactory);
            N enn = newToOld.get (en);
            ndg.addEdge (nnn, enn, edge);
            ndg.putAllProperties (nnn, edge, properties.get (edge));
        }
    }
    
    public static  DG merge (DG dg1, DG dg2, E star, NodeFactory  nodeFactory) {
        DG ndg = DG.createDG ();
        Map,N> newToOld = new HashMap,N> ();
        N startNode = merge (
            dg1, dg2, 
            dg1.getStartNode (), 
            dg2.getStartNode (), 
            ndg,
            true, true,
            star,
            nodeFactory,
            newToOld,
            1
        );
        ndg.setStart (startNode);
        return ndg;
    }
    
    private static  N merge (
        DG     dg1,
        DG     dg2,
        N               n1,
        N               n2,
        DG     ndg,
        boolean         addEnds1,
        boolean         addEnds2,
        E               star,
        NodeFactory  nodeFactory,
        Map,N>   newToOld,
        int depth
    ) {
        Set nNode = new HashSet ();
        nNode.add (n1);
        nNode.add (n2);
        if (newToOld.containsKey (nNode)) 
            return newToOld.get (nNode);
        N dnode = nodeFactory.createNode ();
        newToOld.put (nNode, dnode);
        ndg.addNode (dnode);
        ndg.putAllProperties (dnode, dg1.getProperties (n1));
        ndg.putAllProperties (dnode, dg2.getProperties (n2));
        if (addEnds1 && dg1.getEnds ().contains (n1))
            ndg.addEnd (dnode);
        if (addEnds2 && dg2.getEnds ().contains (n2))
            ndg.addEnd (dnode);
        
        Set edges2 = new HashSet (dg2.getEdges (n2));
        Iterator it = dg1.getEdges (n1).iterator ();
        while (it.hasNext ()) {
            E edge = it.next ();
            N nn1 = dg1.getNode (n1, edge);
            N nn2 = dg2.getNode (n2, edge);
            Map properties = null;
            if ( !edge.equals (star) && 
                 edges2.contains (star) &&
                 nn2 == null
            ) {
                nn2 = dg2.getNode (n2, star);
                properties = dg2.getProperties (n2, star);
            } else
            if (nn2 != null)
                properties = dg2.getProperties (n2, edge);
            N nnode = nn2 == null ?
                merge (dg1, nn1, ndg, addEnds1) :
                merge (dg1, dg2, nn1, nn2, ndg, addEnds1, addEnds2, star, nodeFactory, newToOld, depth + 1);
            ndg.addEdge (dnode, nnode, edge);
            ndg.putAllProperties (dnode, edge, dg1.getProperties (n1, edge));
            if (properties != null)
                ndg.putAllProperties (dnode, edge, properties);
            edges2.remove (edge);
        }
        it = edges2.iterator ();
        while (it.hasNext ()) {
            E edge = it.next ();
            N nn2 = dg2.getNode (n2, edge);
            N nnode = null;
            Map properties = null;
            if ( !edge.equals (star) && 
                 dg1.getEdges (n1).contains (star)
            ) {
                nnode = merge (dg1, dg2, dg1.getNode (n1, star), nn2, ndg, addEnds1, addEnds2, star, nodeFactory, newToOld, depth + 1);
                properties = dg1.getProperties (n1, star);
            } else
                nnode = merge (dg2, nn2, ndg, addEnds2);
            ndg.addEdge (dnode, nnode, edge);
            ndg.putAllProperties (dnode, edge, dg2.getProperties (n2, edge));
            if (properties != null)
                ndg.putAllProperties (dnode, edge, properties);
        }
        return dnode;
    }
    
    private static  N merge (
        DG     dg,
        N               n,
        DG     ndg,
        boolean         addEnds
    ) {
        if (ndg.containsNode (n)) return n;
        ndg.addNode (n);
        ndg.putAllProperties (n, dg.getProperties (n));
        if (addEnds && dg.getEnds ().contains (n))
            ndg.addEnd (n);
        
        Iterator it = dg.getEdges (n).iterator ();
        while (it.hasNext ()) {
            E edge = it.next ();
            N nn = dg.getNode (n, edge);
            N endN = merge (dg, nn, ndg, addEnds);
            ndg.addEdge (n, endN, edge);
            ndg.putAllProperties (n, edge, dg.getProperties (n, edge));
        }
        return n;
    }
    
    static  DG reduce (DG dg, NodeFactory nodeFactory) {
        Map,Set> ends = new HashMap,Set> ();
        Set other = new HashSet ();
        Iterator it = dg.getNodes ().iterator ();
        while (it.hasNext ()) {
            N node = it.next ();
            if (!dg.getEnds ().contains (node))
                other.add (node);
            else {
                Set e = ends.get (dg.getProperties (node));
                if (e == null) {
                    e = new HashSet ();
                    ends.put (dg.getProperties (node), e);
                }
                e.add (node);
            }
        }
        Set> newNodes = new HashSet> ();
        if (other.size () > 0) newNodes.add (other);
        newNodes.addAll (ends.values ());
        Map,Map>> ng = reduce (dg, newNodes);

        DG ndg = DG.createDG ();
        Map,N> oldToNewNode = new HashMap,N> ();
        Iterator> it2 = ng.keySet ().iterator ();
        while (it2.hasNext ()) {
            Set node = it2.next ();
            N newNode = oldToNewNode.get (node);
            if (newNode == null) {
                newNode = nodeFactory.createNode ();
                oldToNewNode.put (node, newNode);
                ndg.addNode (newNode);
            }
            Map> edgeToNode = ng.get (node);
            Iterator it3 = edgeToNode.keySet ().iterator ();
            while (it3.hasNext ()) {
                E edge = it3.next ();
                Set end = edgeToNode.get (edge);
                N newNode2 = oldToNewNode.get (end);
                if (newNode2 == null) {
                    newNode2 = nodeFactory.createNode ();
                    oldToNewNode.put (end, newNode2);
                    ndg.addNode (newNode2);
                }
                ndg.addEdge (newNode, newNode2, edge);
            }
        }
        ndg.setEnds (new HashSet ());
        it2 = ng.keySet ().iterator ();
        while (it2.hasNext ()) {
            Set node = it2.next ();
            N newNode = oldToNewNode.get (node);
            Iterator it3 = node.iterator ();
            while (it3.hasNext ()) {
                N n = it3.next ();
                if (dg.containsNode (n) && dg.getProperties (n) != null)
                    ndg.putAllProperties (newNode, dg.getProperties (n));
                Iterator it4 = ndg.getEdges (newNode).iterator ();
                while (it4.hasNext ()) {
                    E edge = it4.next ();
                    if (dg.containsNode (n) && dg.getProperties (n, edge) != null)
                        ndg.putAllProperties (newNode, edge, dg.getProperties (n, edge));
                }
                if (dg.getEnds ().contains (n))
                    ndg.addEnd (newNode);
                if (dg.getStartNode ().equals (n))
                    ndg.setStart (newNode);
            }
        }
        return ndg;
    }
    
    private static  Map,Map>> reduce (DG dg, Set> s) {
        Map> m = new HashMap> ();
        Iterator> it = s.iterator ();
        while (it.hasNext ()) {
            Set nnode = it.next ();
            Iterator it2 = nnode.iterator ();
            while (it2.hasNext ()) {
                N node = it2.next ();
                m.put (node, nnode);
            }
        }
        
        Map,Map>> nnodes = new HashMap,Map>> ();
        it = s.iterator ();
        while (it.hasNext ()) {
            Set nnode = it.next ();
            Map>,Set> nodes = new HashMap>,Set> ();
            Iterator it2 = nnode.iterator ();
            while (it2.hasNext ()) {
                N node = it2.next ();
                Map> edges = new HashMap> ();
                Iterator it3 = dg.getEdges (node).iterator ();
                while (it3.hasNext ()) {
                    E edge = it3.next ();
                    N endNode = dg.getNode (node, edge);
                    edges.put (edge, m.get (endNode));
                }
                Set n = nodes.get (edges);
                if (n == null) {
                    n = new HashSet ();
                    nodes.put (edges, n);
                }
                n.add (node);
            }
            Iterator>> it3 = nodes.keySet ().iterator ();
            while (it3.hasNext ()) {
                Map> edges = it3.next ();
                Set newState = nodes.get (edges);
                nnodes.put (newState, edges);
            }
        }
        if (nnodes.size () > s.size ())
            return reduce (dg, nnodes.keySet ());
        return nnodes;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy