1 /***
2 * Aggregator.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 10.12.2002 pko creation
9 *
10 * Copyright 2003 ELCA Informatique SA
11 * Av. de la Harpe 22-24, 1000 Lausanne 13, Switzerland
12 * www.elca.ch
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public License
16 * as published by the Free Software Foundation; either version 2.1 of
17 * the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 * USA
28 */
29
30 package ch.elca.dependency.graph;
31
32 import java.util.Enumeration;
33
34 import java.util.regex.PatternSyntaxException;
35 import java.util.regex.Pattern;
36 import java.util.regex.Matcher;
37
38 import org.apache.log4j.Logger;
39
40 import att.grappa.*;
41
42 /***
43 * This class is responsible for aggregating nodes in a graph
44 * accordingly to a regexp.
45 *
46 * @author Pawel Kowalski
47 * @version 1.0-beta
48 */
49 public class Aggregator extends AbstractGraphProcessor {
50
51 /***
52 * Log4j Logger.
53 */
54 private static final Logger LOG = Logger.getLogger(Aggregator.class);
55
56 /***
57 * A <code>regexp String</code> associated with this
58 * <code>Aggregator</code>.
59 */
60 protected String m_regexpString = null;
61
62 /***
63 * A precompiled regexp matcher.
64 */
65 protected Pattern m_regexp = null;
66
67 /***
68 * A flag, telling whether the specified regular expression could
69 * be successfully used for building a <code>RE</code> Program.
70 */
71 protected boolean m_noRegexp = false;
72
73 /***
74 * Creates a new <code>Aggregator</code> instance.
75 */
76 public Aggregator() {
77 }
78
79 /***
80 * Creates a new <code>Aggregator</code> with a name and a String
81 * used to be used for building a RE (regular expression program).
82 *
83 * @param name a <code>String</code> value
84 * @param regexpString a <code>String</code> value
85 */
86 public Aggregator(String name, String regexpString) {
87 super(name);
88 setRegexp(regexpString);
89 }
90
91 /***
92 * Set a regular expression for aggregating nodes.
93 *
94 * @param regexpString a <code>String</code> value
95 */
96 public void setRegexp(String regexpString) {
97 m_regexpString = regexpString;
98 try {
99 m_regexp = Pattern.compile(regexpString);
100 } catch (PatternSyntaxException e) {
101 LOG.error("Syntax error in regexp: " + regexpString);
102 m_noRegexp = true;
103 }
104 }
105
106 /***
107 * Get the regexp used to aggregate nodes.
108 *
109 * @return a <code>String</code> value
110 */
111 public String getRegexp() {
112 return m_regexpString;
113 }
114
115 /***
116 * Returns the Pattern (Regexp) used by this Aggregator.
117 *
118 * @return a <code>Pattern</code> value
119 */
120 public Pattern getPattern() {
121 return m_regexp;
122 }
123
124 /***
125 * Aggregate nodes accordingl to a regexp. The aggregate node
126 * will have the name associated with this class. This is an
127 * Implementation of the abstract method inherited from the
128 * <code>AbstractGraphProcessor</code>.
129 *
130 * @param graph a <code>Graph</code> value
131 * @return a <code>Graph</code> value
132 */
133 public Graph process(Graph graph) {
134
135 // syntax error in regexp, ignore this aggregation
136 //
137 if (m_noRegexp) {
138 return graph;
139 }
140
141 LOG.debug("Process graph: " + graph.getName());
142
143 Node node = null;
144 String nodeName = "";
145 Node newNode = null;
146 Node tailNode = null;
147 Node headNode = null;
148 Edge edge = null;
149 Edge newEdge = null;
150
151 // enumerate over all nodes
152 //
153 for (Enumeration enum = graph.nodeElements(); enum.hasMoreElements(); ) {
154 node = (Node)enum.nextElement();
155 nodeName = node.getName();
156
157 // does the node match the regexp
158 //
159 Matcher matcher = m_regexp.matcher(nodeName);
160 if (matcher.matches() && !nodeName.equals(m_name)) {
161
162 // create new aggregate node, or reuse an existing one
163 //
164 if (newNode == null) {
165 if ((newNode = graph.findNodeByName(m_name)) == null) {
166 newNode = new Node(graph, m_name);
167 }
168 newNode.setAttribute(GrappaConstants.STYLE_ATTR, "filled");
169 newNode.setAttribute(GrappaConstants.COLOR_ATTR, "powderblue");
170 }
171
172 // process in-edges
173 //
174 for (Enumeration inEnum = node.inEdgeElements(); inEnum.hasMoreElements(); ) {
175 edge = (Edge)inEnum.nextElement();
176
177 // no multiple edges
178 //
179 if (!(Edge.findEdgesByEnds(newNode, edge.getTail()).hasMoreElements())) {
180
181 // no edges showing on self
182 //
183 if (!(edge.getTail() == newNode)) {
184 newEdge = new Edge(graph, edge.getTail(), newNode);
185 }
186 }
187
188 tailNode = edge.getTail();
189
190 // remove edge from graph and head/tail nodes
191 //
192 node.removeEdge(edge, true);
193 tailNode.removeEdge(edge, false);
194 graph.removeEdge(edge.getName());
195 }
196
197 // process out-edges
198 //
199 for (Enumeration outEnum = node.outEdgeElements(); outEnum.hasMoreElements(); ) {
200 edge = (Edge)outEnum.nextElement();
201
202 // no multiple edges
203 //
204 if (!(Edge.findEdgesByEnds(edge.getHead(), newNode).hasMoreElements())) {
205
206 // no edges showing on self
207 //
208 if (!(edge.getHead() == newNode)) {
209 newEdge = new Edge(graph, newNode, edge.getHead());
210 }
211 }
212
213 headNode = edge.getHead();
214
215 // remove edge from graph and head/tail nodes
216 //
217 node.removeEdge(edge, false);
218 headNode.removeEdge(edge, true);
219 graph.removeEdge(edge.getName());
220 }
221
222 // remove node
223 //
224 graph.removeNode(nodeName);
225 LOG.debug("Removed node: " + nodeName);
226 }
227 }
228 return graph;
229 }
230 }
This page was automatically generated by Maven