1 /***
2 * LayeringViolationReportInfo.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 07.11.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.report;
31
32 import att.grappa.Edge;
33
34 import ch.elca.dependency.core.DependencyContext;
35 import ch.elca.dependency.core.classinfo.ClassInfo;
36 import ch.elca.dependency.graph.Aggregator;
37 import ch.elca.dependency.graph.LayerOrder;
38 import ch.elca.dependency.graph.LayeringListener;
39 import ch.elca.dependency.graph.LayeringEvent;
40 import ch.elca.dependency.graph.Perspective;
41 import ch.elca.dependency.graph.PerspectiveManager;
42
43 import java.io.File;
44 import java.util.ArrayList;
45 import java.util.Iterator;
46 import java.util.ListIterator;
47 import java.util.HashMap;
48 import java.util.regex.Matcher;
49 import java.util.regex.Pattern;
50 import javax.swing.tree.DefaultMutableTreeNode;
51
52 /***
53 * Class <code>LayeringViolationReportInfo</code> used to create
54 * information about layering violations. This only makes sense if a
55 * file with layer information were specified before analysis.
56 *
57 * @author Pawel Kowalski
58 * @version 1.0-beta
59 */
60 public class LayeringViolationReportInfo extends ReportInfo implements LayeringListener {
61
62 /***
63 * Code identifying this ReportInfo
64 */
65 private static final String CODE_REPORT_INFO_NAME = "layering-violation";
66
67 /***
68 * Text identifying this ReportInfo
69 */
70 private static final String TEXT_REPORT_INFO_NAME = "layering violation";
71
72 /***
73 * Code identifying a violating edge.
74 */
75 private static final String CODE_LAYER_VIOLATING_EDGE = "violating-edge";
76
77 /***
78 * Text identifying a violating edge.
79 */
80 private static final String TEXT_LAYER_VIOLATING_EDGE = "layer violating edge";
81
82 /***
83 * Message String: <code>NO_LAYERING_SPECIFIED</code>.
84 */
85 private static final String NO_LAYERING_SPECIFIED = "no layering specified";
86
87 private static final String INVALID_LAYERING_CONFIG = "invalid layering config";
88
89 /***
90 * An <code>ARROW</code> used by Plain Text Formatters.
91 */
92 private static final String ARROW = " --> ";
93
94 private Perspective m_perspective = null;
95
96 /***
97 * Create Information tree containing all layering
98 * violations. This will only make sense with a layering file
99 * specified before the analysis.
100 */
101 void report() {
102
103 ReportObject reportObject = null;
104
105 reportObject = new ReportObject(CODE_REPORT_INFO_NAME, TEXT_REPORT_INFO_NAME);
106 reportObject.put(Report.INDENT, new Integer(1));
107 reportObject.put(Report.IS_HEADER, Report.IS_HEADER);
108 m_rootNode.setUserObject(reportObject);
109
110 // no layer definition specified
111 //
112 File perspConfig = (File)m_dependencyModel.getDependencyContext().get(DependencyContext.PERSPECTIVES_KEY);
113 if (perspConfig == null) {
114 reportObject.setNodeValue(NO_LAYERING_SPECIFIED);
115 return;
116 }
117
118 m_perspective = PerspectiveManager.loadFirstPerspective(perspConfig);
119
120 // invalid perspective config
121 //
122 if (m_perspective == null) {
123 reportObject.setNodeValue(INVALID_LAYERING_CONFIG);
124 return;
125 }
126
127 // no layer definition specified
128 //
129 LayerOrder layerOrder = m_perspective.getLayerOrder();
130 if (layerOrder == null) {
131 reportObject.setNodeValue(NO_LAYERING_SPECIFIED);
132 return;
133 }
134
135 reportObject.setNodeValue("Perspective used: " + m_perspective.getName());
136
137 layerOrder.addLayeringListener(this);
138 m_perspective.process(m_dependencyModel.getFilteredGraph());
139 }
140
141
142 public void layeringViolated(LayeringEvent event) {
143
144 DefaultMutableTreeNode treeNode = null;
145 ReportObject reportObject = null;
146 Object tmpObject = null;
147
148 Edge edge = event.getEdge();
149 String headName = edge.getHead().getName();
150 String tailName = edge.getTail().getName();
151
152 reportObject = new ReportObject(CODE_LAYER_VIOLATING_EDGE,
153 TEXT_LAYER_VIOLATING_EDGE,
154 tailName + ARROW + headName,
155 false);
156
157 reportObject.put(Report.INDENT, new Integer(2));
158 treeNode = new DefaultMutableTreeNode(reportObject);
159 m_rootNode.add(treeNode);
160
161 // get the map with the filtered class informations
162 //
163 HashMap infos = m_dependencyModel.getFilteredClassInfos();
164 ArrayList headz = new ArrayList();
165
166 // perhaps the node is an aggregate: find correspondent nodes
167 //
168 if ((ArrayList)infos.get(headName) != null) {
169 headz.add(headName);
170 } else {
171 Aggregator aggregator = null;
172 if ((aggregator = m_perspective.findAggregatorForName(headName)) != null) {
173 Pattern regexp = aggregator.getPattern();
174 for (Iterator iter = infos.keySet().iterator(); iter.hasNext();) {
175 String keyString = (String)iter.next();
176 Matcher matcher = regexp.matcher(keyString);
177 if (matcher.matches()) {
178 headz.add(keyString);
179 }
180 }
181 }
182 }
183
184 // get all the class infos of this from package
185 //
186 ArrayList fromInfoList = (ArrayList)infos.get(tailName);
187 if (fromInfoList == null) {
188 fromInfoList = new ArrayList();
189 Aggregator aggregator = null;
190 if ((aggregator = m_perspective.findAggregatorForName(tailName)) != null) {
191 Pattern regexp = aggregator.getPattern();
192 for (Iterator iter = infos.keySet().iterator(); iter.hasNext(); ) {
193 String keyString = (String)iter.next();
194 Matcher matcher = regexp.matcher(keyString);
195 if (matcher.matches()) {
196 fromInfoList.addAll((ArrayList)infos.get(keyString));
197 }
198 }
199 }
200 }
201
202 // iterate over the class infos of the from package
203 //
204 ListIterator fromListIter = fromInfoList.listIterator();
205 while ( fromListIter.hasNext() ) {
206 ClassInfo fromInfoTmp = (ClassInfo)fromListIter.next();
207
208 // iterate over all headz
209 //
210 for (Iterator iter = headz.iterator(); iter.hasNext();) {
211 headName = (String)iter.next();
212
213 // check interfaces
214 //
215 Iterator interIter = fromInfoTmp.getImplInterfaces().iterator();
216 while ( interIter.hasNext() ) {
217 String interTmp = (String)interIter.next();
218 String interPack = interTmp.substring(0, interTmp.lastIndexOf("."));
219
220 // interface belongs to the target package
221 //
222 if ( interPack.equals(headName) ) {
223 String from = fromInfoTmp.getFullName().substring(fromInfoTmp.getFullName().lastIndexOf(".") + 1);
224 String to = interTmp.substring(interTmp.lastIndexOf(".") + 1);
225 reportObject = new ReportObject(CODE_LAYER_VIOLATING_EDGE,
226 TEXT_LAYER_VIOLATING_EDGE,
227 from + " >-impl-> " + to, false);
228 reportObject.put(Report.INDENT, new Integer(3));
229 treeNode = new DefaultMutableTreeNode(reportObject);
230 m_rootNode.add(treeNode);
231 }
232 }
233
234 // check super class
235 //
236 String superClass = fromInfoTmp.getSuperClass();
237 String superPack = superClass.substring(0, superClass.lastIndexOf("."));
238 if ( ! superClass.equals("java.lang.Object") && superPack.equals(headName) ) {
239 String from = fromInfoTmp.getFullName().substring(fromInfoTmp.getFullName().lastIndexOf(".") + 1);
240 String to = superClass.substring(superClass.lastIndexOf(".") + 1);
241 reportObject = new ReportObject(CODE_LAYER_VIOLATING_EDGE,
242 TEXT_LAYER_VIOLATING_EDGE,
243 from + " >-ext-> " + to, false);
244 reportObject.put(Report.INDENT, new Integer(3));
245 treeNode = new DefaultMutableTreeNode(reportObject);
246 m_rootNode.add(treeNode);
247 }
248
249 // check used classes
250 //
251 ListIterator usedIter = fromInfoTmp.getNeededClasses().listIterator();
252 while ( usedIter.hasNext() ) {
253 String usedTmp = (String)usedIter.next();
254 String usedPack = usedTmp.substring(0, usedTmp.lastIndexOf("."));
255
256 // used class belongs to the target package
257 //
258 if ( usedPack.equals(headName) ) {
259 String from = fromInfoTmp.getFullName().substring(fromInfoTmp.getFullName().lastIndexOf(".") + 1);
260 String to = usedTmp.substring(usedTmp.lastIndexOf(".") + 1);
261 reportObject = new ReportObject(CODE_LAYER_VIOLATING_EDGE,
262 TEXT_LAYER_VIOLATING_EDGE,
263 from + " >-uses-> " + to, false);
264 reportObject.put(Report.INDENT, new Integer(3));
265 treeNode = new DefaultMutableTreeNode(reportObject);
266 m_rootNode.add(treeNode);
267 }
268 }
269 }
270 }
271 }
272 }
This page was automatically generated by Maven