1 /***
2 * RawModel.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 20.01.2003 pko modification
9 * 18.04.2002 ctr modification
10 * 22.01.2002 ctr modification
11 * 08.01.2002 ctr creation
12 *
13 * Copyright 2003 ELCA Informatique SA
14 * Av. de la Harpe 22-24, 1000 Lausanne 13, Switzerland
15 * www.elca.ch
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public License
19 * as published by the Free Software Foundation; either version 2.1 of
20 * the License, or (at your option) any later version.
21 *
22 * This library is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 * USA
31 */
32
33 package ch.elca.dependency.core;
34
35 import java.io.File;
36 import java.util.*;
37
38 import org.apache.log4j.Logger;
39
40 import ch.elca.dependency.adapter.grappa.EdgeFactory;
41 import ch.elca.dependency.adapter.grappa.GraphFactory;
42 import ch.elca.dependency.core.classinfo.ClassInfo;
43 import ch.elca.dependency.exception.AnalyseException;
44 import ch.elca.dependency.layer.UserLayer;
45
46 import att.grappa.GrappaConstants;
47 import att.grappa.Node;
48 import att.grappa.Edge;
49 import att.grappa.Graph;
50
51 /***
52 * The <code>RawModel</code> is the data model created after the
53 * initialisation. Only the "loadFilter" is applied to that model.<br>
54 * That means this model contains all the informations which are extracted out
55 * of the class structure without any modifications.<br>
56 * The model is used to compare with the <code>DependencyModel</code> when another
57 * filter is applied during run time. So it is not necessary to perform another
58 * parsing for applying a filter.
59 *
60 * @see Analyzer
61 * @see ch.elca.dependency.gui.MainFrame
62 * @see Graph
63 *
64 * @author Christoph Trutmann
65 * @author Pawel Kowalski
66 * @version 1.0-beta
67 */
68 public class RawModel {
69
70 /***
71 * Log4j category to invoke the log statements.
72 */
73 private static final Logger LOG = Logger.getLogger(RawModel.class);
74
75 /***
76 * The graph component of the <code>RawModel</code>.
77 */
78 private Graph m_rawGraph;
79
80 /***
81 * The statistic component of the <code>RawModel</code>.
82 */
83 private Statistic m_rawStatistic;
84
85 /***
86 * List containing all the <code>ClassInfo</code> objects.
87 */
88 private HashMap m_classInfos;
89
90 /***
91 * For each package string a list with all its needed packages is mapped.
92 */
93 private HashMap m_packDepend;
94
95 /***
96 * Reads the java .class file structure into the <code>RawModel</code>.
97 */
98 private Analyzer m_analyzer;
99
100 /***
101 * A <code>UserLayer</code> associated with this <code>RawModel</code>.
102 */
103 private UserLayer m_userLayer = null;
104
105 /***
106 * Creates a new <code>RawModel</code> instance.
107 *
108 * @param analyzer an <code>Analyzer</code> value
109 * @exception AnalyseException if an error occurs
110 */
111 public RawModel(Analyzer analyzer) throws AnalyseException {
112 m_analyzer = analyzer;
113 createModel();
114 }
115
116 /***
117 * Creates the graph with the information in the hash table. Also the
118 * statistic data are generated.
119 * Each package that contains a class of the inquired tree, is mapped to all
120 * the packages, the classes of it needs.
121 *
122 * @exception AnalyseException if an error occurs
123 */
124 public void createModel() throws AnalyseException {
125
126 // create the graph object for the raw model
127 m_rawGraph = GraphFactory.createNewGraph("Dependency Graph", // graph name
128 true, // directed
129 false); // strict (no loops allowed)
130 // there are no loops anyway!!
131
132 // tool tip of graph
133 m_rawGraph.setAttribute(GrappaConstants.TIP_ATTR, "");
134
135 // hashtable containing all the nodes (Node objects) and its name
136 HashMap nodes = new HashMap();
137
138 // perform the analyse on the specified project
139 m_analyzer.analyse();
140
141 // get the list with the ClassInfo objects
142 m_classInfos = m_analyzer.getClassInfos();
143
144 // create the statistic object for the RawModel
145 m_rawStatistic = m_analyzer.getStatistics();
146
147 // hash map with all the packages of the project as keys and all the
148 // needed internal and external packages in the mapped list object
149 m_packDepend = m_analyzer.getDependencies();
150
151 // all the package names (String) that will be a node
152 ArrayList packages = getNodeList(m_packDepend);
153 LOG.info("Got the data from the analysis.");
154
155 // set the number of nodes in the statistic
156 m_rawStatistic.setAnalyzedVertices(packages.size());
157
158 ListIterator iterator = packages.listIterator();
159
160 // create the nodes representing the packages
161 while ( iterator.hasNext() ) {
162 String packageTmp = (String)iterator.next();
163
164 Node nodeTmp = new Node(m_rawGraph, packageTmp);
165 nodeTmp.setAttribute("style", "filled");
166 nodeTmp.setAttribute("color", "palegoldenrod");
167
168 int chars = packageTmp.length();
169 nodeTmp.setAttribute(GrappaConstants.WIDTH_ATTR,
170 new Double (chars * 0.110d));
171
172 // map the nodes to its name
173 nodes.put(packageTmp, nodeTmp);
174
175 LOG.debug("The following node is put in the hashtable: '"
176 + packageTmp + "'");
177 }
178
179 // create the edges representing the dependencies
180 Iterator keyIter = m_packDepend.keySet().iterator();
181
182 while ( keyIter.hasNext() ) {
183 String key = (String)keyIter.next();
184
185 ArrayList toList = (ArrayList)m_packDepend.get(key);
186 ListIterator toIter = toList.listIterator();
187
188 Node fromNode = (Node)nodes.get(key);
189 int i = 0;
190 while ( toIter.hasNext() ) {
191 Node toNode = (Node)nodes.get((String)toIter.next());
192 String toName = toNode.getName();
193
194 if ( ! fromNode.equals(toNode) ) {
195 Edge edge = EdgeFactory.createNewEdge(m_rawGraph, fromNode, toNode);
196
197 boolean finish = false;
198 boolean ext = false, impl = false, uses = false;
199
200 // determine the types of dependencies
201 ListIterator fromInfoIter
202 = ((ArrayList)m_classInfos.get(fromNode.getName()))
203 .listIterator();
204 while ( fromInfoIter.hasNext() && ! finish ) {
205 ClassInfo infoTmp = (ClassInfo)fromInfoIter.next();
206
207 // checks uses dependency type
208 if ( infoTmp.getNeededPackages().contains(toName)
209 && ! uses) {
210 uses = true;
211 }
212 // get package of the super class if it is not Object
213 String superTmp = infoTmp.getSuperClass();
214 if ( ! superTmp.equals("java.lang.Object") && ! ext ) {
215 int index = 0;
216 if ((index = superTmp.lastIndexOf(".")) == -1) {
217 index = superTmp.length();
218 }
219 if ( superTmp.substring(0, index).equals(toName) ) {
220 ext = true;
221 }
222 }
223 // get implemented interfaces of the current class
224 Iterator interIter
225 = infoTmp.getImplInterfaces().iterator();
226 while ( interIter.hasNext() && ! impl ) {
227 String interTmp = (String)interIter.next();
228 int index = 0;
229 if ((index = interTmp.lastIndexOf(".")) == -1) {
230 index = interTmp.length();
231 }
232 if ( interTmp.substring(0, index).equals(toName) ) {
233 impl = true;
234 }
235 }
236 // try to finish the loop
237 if ( (uses && ext) && impl ) {
238 finish = true;
239 }
240 }
241
242 // construct the string with the dependency types
243 StringBuffer depTypes = new StringBuffer();
244
245 if ( uses ) {
246 depTypes.append("uses");
247 }
248 if ( ext ) {
249 if ( depTypes.length() != 0 ) {
250 depTypes.append(", ");
251 }
252 depTypes.append("ext");
253 }
254 if ( impl ) {
255 if ( depTypes.length() != 0 ) {
256 depTypes.append(", ");
257 }
258 depTypes.append("impl");
259 }
260 // set the types for that edge
261 String depTypeStr = depTypes.toString();
262
263 edge.setAttribute(GrappaConstants.TIP_ATTR,
264 "'" + fromNode.getName() + "' -> '" + toName
265 + "' (" + depTypeStr + ")");
266 }
267
268 LOG.debug("The edge from node '" + fromNode.getName()
269 + "' to node '" + toNode.getName() + "' created."
270 );
271 i++;
272 }
273 }
274 LOG.info("The RawModel is initialized.\n");
275 }
276
277 /***
278 * Helper method that extracts the nodes which have to be created in the
279 * graph. Each node is only once in this list because it has to be unique
280 * in the graph.
281 * In other words all packages (String) existing in the directory tree are
282 * in this list.
283 *
284 * @param deps All the encountered dependencies of the class structure.
285 * @return List containing all the existing packages passed through the load
286 * filter.
287 */
288 private ArrayList getNodeList(HashMap deps) {
289
290 // all the packages (String) except the keys
291 Iterator objIter = deps.values().iterator();
292
293 // all the keys
294 Iterator keyIter = deps.keySet().iterator();
295
296 // all the packages for beeing a node in the graph
297 ArrayList nodes = new ArrayList();
298
299 while ( objIter.hasNext() ) {
300 ArrayList packStr = (ArrayList)objIter.next();
301 ListIterator iterator = packStr.listIterator();
302 while ( iterator.hasNext() ) {
303 String tmp = (String)iterator.next();
304
305 if ( !nodes.contains(tmp) ) {
306 nodes.add(tmp);
307 }
308 }
309 }
310
311 while ( keyIter.hasNext() ) {
312 String tmp = (String)keyIter.next();
313
314 if ( !nodes.contains(tmp) ) {
315 nodes.add(tmp);
316 }
317 }
318 return nodes;
319 }
320
321 /***
322 * Helper method that extracts the nodes which have to be created in the
323 * graph. Each node is only once in this list because it has to be unique
324 * in the graph.
325 * In other words all packages (String) existing in the directory tree are
326 * in this list.
327 *
328 * @return an <code>ArrayList</code> value
329 */
330 public ArrayList getNodeList() {
331 return getNodeList(m_packDepend);
332 }
333
334 /***
335 * Gets the <code>ClassInfo</code> objects which passed the load filter.
336 *
337 * @return Map containing all the <code>ClassInfo</code> objects.
338 */
339 public HashMap getRawClassInfos(){
340 return m_classInfos;
341 }
342
343 /***
344 * Gets the <code>Graph</code> with the raw data.
345 *
346 * @return Graph with the raw data.
347 */
348 public Graph getRawGraph() {
349 return m_rawGraph;
350 }
351
352 /***
353 * Gets the <code>Statistic</code> with the raw data.
354 *
355 * @return Statistic with the raw data.
356 */
357 public Statistic getRawStatistic() {
358 return m_rawStatistic;
359 }
360
361 /***
362 * Gets the <code>HashMap</code> with all the package dependencies of the
363 * packages which passed the load filter.<br>
364 * The key is the full qualified name string of the package. For each one
365 * of these keys, a list with all the needed packages is mapped.
366 *
367 * @return HashMap with all the package dependencies.
368 */
369 public HashMap getPackDepend() {
370 return m_packDepend;
371 }
372
373 /***
374 * Get the project root file.
375 *
376 * @return a <code>File</code> value
377 */
378 public File getProjectRoot() {
379 return m_analyzer.getProjectRoot();
380 }
381
382 /***
383 * Get the <code>UserLayer</code>.
384 *
385 * @return an <code>UserLayer</code> value
386 */
387 public UserLayer getUserLayer() {
388 return m_userLayer;
389 }
390
391 /***
392 * Set a <code>UserLayer</code>.
393 *
394 * @param userLayer an <code>UserLayer</code> value
395 */
396 public void setUserLayer(UserLayer userLayer) {
397 m_userLayer = userLayer;
398 }
399 }
This page was automatically generated by Maven