1 /*
2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 package com.sun.hotspot.igv.filter;
25 
26 import com.sun.hotspot.igv.data.Properties;
27 import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
28 import com.sun.hotspot.igv.graph.*;
29 import java.util.ArrayList;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Set;
33 
34 /**
35  *
36  * @author Thomas Wuerthinger
37  */
38 public class CombineFilter extends AbstractFilter {
39 
40     private List<CombineRule> rules;
41     private String name;
42 
CombineFilter(String name)43     public CombineFilter(String name) {
44         this.name = name;
45         rules = new ArrayList<>();
46     }
47 
48     @Override
getName()49     public String getName() {
50         return name;
51     }
52 
53     @Override
apply(Diagram diagram)54     public void apply(Diagram diagram) {
55 
56         Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
57         for (CombineRule r : rules) {
58 
59             List<Figure> list = selector.selectMultiple(r.getFirstMatcher());
60             Set<Figure> figuresToRemove = new HashSet<>();
61             for (Figure f : list) {
62 
63                 List<Figure> successors = new ArrayList<>(f.getSuccessors());
64                 if (r.isReversed()) {
65                     if (successors.size() == 1) {
66                         Figure succ = successors.get(0);
67                         InputSlot slot = null;
68 
69                         for (InputSlot s : succ.getInputSlots()) {
70                             for (Connection c : s.getConnections()) {
71                                 if (c.getOutputSlot().getFigure() == f) {
72                                     slot = s;
73                                 }
74                             }
75                         }
76 
77                         slot.getSource().addSourceNodes(f.getSource());
78                         if (r.getShortProperty() != null) {
79                             String s = f.getProperties().get(r.getShortProperty());
80                             if (s != null && s.length() > 0) {
81                                 slot.setShortName(s);
82                                 slot.setText(s);
83                                 slot.setColor(f.getColor());
84                             }
85                         } else {
86                             assert slot != null;
87                             slot.setText(f.getProperties().get("dump_spec"));
88                             if (f.getProperties().get("short_name") != null) {
89                                 slot.setShortName(f.getProperties().get("short_name"));
90                             } else {
91                                 String s = f.getProperties().get("dump_spec");
92                                 if (s != null && s.length() <= 5) {
93                                     slot.setShortName(s);
94                                 }
95                             }
96                         }
97 
98                         for (InputSlot s : f.getInputSlots()) {
99                             for (Connection c : s.getConnections()) {
100                                 Connection newConn = diagram.createConnection(slot, c.getOutputSlot(), c.getLabel(), c.getType());
101                                 newConn.setColor(c.getColor());
102                                 newConn.setStyle(c.getStyle());
103                             }
104                         }
105 
106                         figuresToRemove.add(f);
107                     }
108                 } else {
109 
110                     for (Figure succ : successors) {
111                         if (succ.getPredecessors().size() == 1 && succ.getInputSlots().size() == 1) {
112                             if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) {
113 
114 
115                                 OutputSlot oldSlot = null;
116                                 for (OutputSlot s : f.getOutputSlots()) {
117                                     for (Connection c : s.getConnections()) {
118                                         if (c.getInputSlot().getFigure() == succ) {
119                                             oldSlot = s;
120                                         }
121                                     }
122                                 }
123 
124                                 assert oldSlot != null;
125 
126                                 OutputSlot nextSlot = succ.getOutputSlots().get(0);
127                                 int pos = 0;
128                                 if (succ.getProperties().get("con") != null) {
129                                     pos = Integer.parseInt(succ.getProperties().get("con"));
130                                 }
131                                 OutputSlot slot = f.createOutputSlot(pos);
132                                 slot.getSource().addSourceNodes(succ.getSource());
133                                 if (r.getShortProperty() != null) {
134                                     String s = succ.getProperties().get(r.getShortProperty());
135                                     if (s != null && s.length() > 0) {
136                                         slot.setShortName(s);
137                                         slot.setText(s);
138                                         slot.setColor(succ.getColor());
139                                     }
140                                 } else {
141                                     slot.setText(succ.getProperties().get("dump_spec"));
142                                     if (succ.getProperties().get("short_name") != null) {
143                                         slot.setShortName(succ.getProperties().get("short_name"));
144                                     } else {
145                                         String s = succ.getProperties().get("dump_spec");
146                                         if (s != null && s.length() <= 2) {
147                                             slot.setShortName(s);
148                                         } else {
149                                             String tmpName = succ.getProperties().get("name");
150                                             if (tmpName != null && tmpName.length() > 0) {
151                                                 slot.setShortName(tmpName.substring(0, 1));
152                                             }
153                                         }
154                                     }
155                                 }
156                                 for (Connection c : nextSlot.getConnections()) {
157                                     Connection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel(), c.getType());
158                                     newConn.setColor(c.getColor());
159                                     newConn.setStyle(c.getStyle());
160                                 }
161 
162 
163                                 figuresToRemove.add(succ);
164 
165                                 if (oldSlot.getConnections().size() == 0) {
166                                     f.removeSlot(oldSlot);
167                                 }
168                             }
169                         }
170                     }
171                 }
172             }
173 
174             diagram.removeAllFigures(figuresToRemove);
175         }
176     }
177 
addRule(CombineRule combineRule)178     public void addRule(CombineRule combineRule) {
179         rules.add(combineRule);
180     }
181 
182     public static class CombineRule {
183 
184         private PropertyMatcher first;
185         private PropertyMatcher second;
186         private boolean reversed;
187         private String shortProperty;
188 
CombineRule(PropertyMatcher first, PropertyMatcher second)189         public CombineRule(PropertyMatcher first, PropertyMatcher second) {
190             this(first, second, false);
191 
192         }
193 
CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed)194         public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) {
195             this(first, second, reversed, null);
196         }
197 
CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty)198         public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty) {
199             this.first = first;
200             this.second = second;
201             this.reversed = reversed;
202             this.shortProperty = shortProperty;
203         }
204 
isReversed()205         public boolean isReversed() {
206             return reversed;
207         }
208 
getFirstMatcher()209         public PropertyMatcher getFirstMatcher() {
210             return first;
211         }
212 
getSecondMatcher()213         public PropertyMatcher getSecondMatcher() {
214             return second;
215         }
216 
getShortProperty()217         public String getShortProperty() {
218             return shortProperty;
219         }
220     }
221 }
222