1 /***
2 * UserLayer.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 24.06.2002 ctr 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.layer;
31
32 import org.apache.regexp.RE;
33 import java.awt.event.ActionEvent;
34 import java.awt.event.ActionListener;
35 import java.io.*;
36 import java.util.*;
37 import javax.swing.JMenu;
38 import javax.swing.JMenuItem;
39 import org.apache.log4j.Logger;
40 import att.grappa.*;
41 import ch.elca.dependency.core.RawModel;
42 import ch.elca.dependency.core.Selection;
43 import ch.elca.dependency.exception.BadLayerDefinitionException;
44
45 /***
46 * Class for validate the user proposal for the layer. The
47 * dependencies in the real project are compared to the layer
48 * definitions given by the user. If there is a 'bad' dependency, the
49 * user is warned.
50 *
51 * @author Christoph Trutmann
52 * @version 1.0-beta
53 */
54 public class UserLayer {
55
56 /***
57 * Log4j Logger.
58 */
59 private static final Logger LOG = Logger.getLogger(UserLayer.class);
60
61 /***
62 * Flag for activating special debugging information concerning
63 * the layer definition.
64 */
65 private static final boolean DEBUG = false;
66
67 /***
68 * User layer definitions.
69 */
70 private File m_layerDef;
71
72 /***
73 * Graph for checking the dependencies in the layer definition.
74 */
75 private Graph m_graph;
76
77 /***
78 * Maps to each node (package name String) its layer number (Integer).
79 * With the help of this map the dependencies can be checked easily.
80 */
81 private HashMap m_nodeToLayer;
82
83 /***
84 * Maps to each layer name its package names in an ArrayList.
85 */
86 private HashMap m_layers;
87
88 /***
89 * List of all edges violating the layering.
90 */
91 private ArrayList m_violatingEdges;
92
93 /***
94 * Menu containing the layer list. The sequencing is the same as in the
95 * model.
96 */
97 private JMenu m_listMenu;
98
99 /***
100 * <code>Selection</code> interface.
101 */
102 private Selection m_select;
103
104 /***
105 * Constructor - Initialize the file with theuser definitions.
106 *
107 *
108 * @param layerDef File containing the user layer definitons.
109 * @param model Model for getting the <code>RawModel</code>.
110 * @param menu Menu for the layer list.
111 *
112 * @tbd make UserLayer independent of GUI elements
113 */
114 public UserLayer(File layerDef, RawModel model, JMenu menu){
115 m_layerDef = layerDef;
116 m_graph = model.getRawGraph();
117 m_listMenu = menu;
118 }
119
120 /***
121 * Parses the user defined layer file and compares the layers to the real
122 * dependencies.
123 * Violations are shown in the <code>GraphView</code>.
124 *
125 * @tbd remove hack, use visitor pattern to reuse this method outside DPT-GUI
126 */
127 public void checkLayers(){
128
129 //
130 // TBD: this part belongs aswell to the hack
131 //
132 m_violatingEdges = new ArrayList();
133
134 // parse the layer file
135 parseLayerFile();
136
137 // check all the edges
138 Enumeration edgeEnum = m_graph.edgeElements();
139 while ( edgeEnum.hasMoreElements() ) {
140 Edge edgeTmp = (Edge)edgeEnum.nextElement();
141
142 String headName = edgeTmp.getHead().getName();
143 String tailName = edgeTmp.getTail().getName();
144
145 Integer headObj = (Integer)m_nodeToLayer.get(headName);
146 Integer tailObj = (Integer)m_nodeToLayer.get(tailName);
147
148 // only the dependencies within the project are treated
149 if ( headObj != null && tailObj != null ) {
150 int headLayer = headObj.intValue();
151 int tailLayer = tailObj.intValue();
152
153 if ( headLayer < tailLayer ) {
154 // mark the edge which is responsible for the violation
155 edgeTmp.setAttribute(GrappaConstants.COLOR_ATTR,"cyan");
156 edgeTmp.setAttribute(GrappaConstants.STYLE_ATTR,
157 "lineWidth(3)");
158 //
159 // TBD: this again is a hack: add layering violating edges into a list
160 // to be able to retrieve those edges from the LayeringViolationReportInfo
161 // better: visitor pattern 07-11-2002 PKO
162 //
163 m_violatingEdges.add(edgeTmp);
164 }
165 }
166 }
167 }
168
169 /***
170 * Get an ArrayList of all layering violating edges.
171 *
172 * @return an <code>ArrayList</code> value
173 */
174 public ArrayList getViolatingEdges() {
175 return m_violatingEdges;
176 }
177
178 /***
179 * References the <code>Selection</code> interface for notify the other
180 * views about changing selections.
181 *
182 * @param select Selection interface.
183 */
184 public void reference(Selection select) {
185 m_select = select;
186 }
187
188
189 /***
190 * Selects the nodes of the specified layer.
191 *
192 * @param layer Layer name of the layer to select.
193 */
194 public void selectLayer(String layer) {
195
196 // get list with the nodes to select
197 //
198 ArrayList selectList = (ArrayList)m_layers.get(layer);
199
200 // the layer name is wrong -> no selection
201 //
202 if ( selectList == null ) {
203 return;
204 }
205
206 // create a list with just the names of the nodes for the selction model
207 //
208 ListIterator selectIter = selectList.listIterator();
209 ArrayList selectNameList = new ArrayList();
210 while ( selectIter.hasNext() ) {
211 selectNameList.add(((Node)selectIter.next()).getName());
212 }
213
214 // invoke the select method of the selection model
215 //
216 m_select.selectPackages(selectNameList);
217 }
218
219
220 /***
221 * Parses the user defined layer file.
222 */
223 private void parseLayerFile(){
224 LOG.info("Parsing file with user layer definition.");
225
226 try {
227 // reader for the file with the layer definition
228 BufferedReader reader = new BufferedReader(
229 new InputStreamReader(new FileInputStream(m_layerDef)));
230
231 // maps for each layer name (String) its packages (ArrayList)
232 m_layers = new HashMap();
233
234 // sequencing of the defined layer names
235 ArrayList seqList = new ArrayList();
236
237 // flag for checking if there is only one empty line
238 boolean justOneEmptyLine = true;
239
240 // get all the nodes of the graph into this set
241 // the regular expressions are applied always on this set
242 HashSet nodeSet = new HashSet();
243 Enumeration nodeEnum = m_graph.nodeElements();
244 while ( nodeEnum.hasMoreElements() ) {
245 nodeSet.add((Node)nodeEnum.nextElement());
246 }
247
248 // read each line of the file
249 String inTmp = reader.readLine();
250 while ( inTmp != null ) {
251
252 // layer definition
253 if ( inTmp.indexOf("<-") != -1 ) {
254 // name of the layer
255 String layerName = inTmp.substring(0, inTmp.indexOf("<"));
256
257 // if there is not already a list in the map -> create it
258 ArrayList listTmp = (ArrayList)m_layers.get(layerName);
259 if ( listTmp == null ) {
260 listTmp = new ArrayList();
261 }
262
263 // expression specifying the packages
264 RE regExp = new RE(inTmp.substring( inTmp.indexOf("-")+1,
265 inTmp.length()));
266
267 Enumeration allNodeEnum = m_graph.nodeElements();
268 while ( allNodeEnum.hasMoreElements() ) {
269 Node tmp = (Node)allNodeEnum.nextElement();
270
271 // test if the package matchs the regular expression
272 if ( regExp.match(tmp.getName()) ) {
273 // if the node is left add it to the list
274 if ( nodeSet.remove(tmp) ) {
275 // add the node to the list of this layer
276 listTmp.add(tmp);
277 }
278 }
279 }
280 // put the list of the nodes of this layer in the HashMap
281 m_layers.put(layerName, listTmp);
282
283 LOG.info("definition: " + inTmp);
284
285 // empty line between definition and sequenting
286 //
287 } else if ( inTmp.equals("") ) {
288 // first empty line in the file
289 if ( justOneEmptyLine ) {
290 justOneEmptyLine = false;
291 LOG.info("empty line...");
292
293 // if more than one empty line is in the file
294 //
295 } else {
296 throw new BadLayerDefinitionException();
297 }
298
299 // layer sequencing
300 //
301 } else {
302 seqList.add(inTmp.trim());
303 LOG.info("seq: " + inTmp);
304 }
305 // read next line
306 inTmp = reader.readLine();
307 }
308
309 // fill the rest under the layer name defaul
310 ArrayList defaultList = new ArrayList();
311 Iterator defaultIter = nodeSet.iterator();
312 while ( defaultIter.hasNext() ) {
313 defaultList.add((Node)defaultIter.next());
314
315 }
316 m_layers.put("Default", defaultList);
317
318 // add the name to the list
319 seqList.add("Default");
320
321
322 // ----------- test section ---------------------------
323 if ( DEBUG ) {
324 System.out.println("Layerdefinitions in the HashMap");
325 Iterator testIter = m_layers.keySet().iterator();
326 while ( testIter.hasNext() ) {
327 String key = (String)testIter.next();
328 System.out.println("Layer: " + key);
329 System.out.println("-------");
330
331 ArrayList testListTmp = (ArrayList)m_layers.get(key);
332 ListIterator testListIter = testListTmp.listIterator();
333 while ( testListIter.hasNext() ) {
334 System.out.println("Package: "
335 + ((Node)testListIter.next()).getName());
336 }
337 }
338 }
339 // ----------------------------------------------------
340
341 // create a HashMap which maps each node its level in form of an int
342 int level = 0; // the top level is 0
343 m_nodeToLayer = new HashMap(); // layer-node mapping
344
345 ListIterator seqIter = seqList.listIterator();
346 while ( seqIter.hasNext() ) {
347 String key = (String)seqIter.next();
348
349 // get all the nodes of this layer
350 ArrayList layerNodeList = (ArrayList)m_layers.get(key);
351 ListIterator layerIter = layerNodeList.listIterator();
352 while ( layerIter.hasNext() ) {
353 String nodeName = ((Node)layerIter.next()).getName();
354 m_nodeToLayer.put(nodeName, new Integer(level));
355 }
356 level++;
357 }
358
359 // construct the menu with the layer names
360 constructLayerMenu(seqList);
361
362 } catch ( Exception e) {
363 e.printStackTrace();
364 }
365 }
366
367
368 /***
369 * Helper method for constructing the layer list menu.
370 */
371 private void constructLayerMenu(ArrayList layerList){
372 m_listMenu.removeAll(); // remove the empty menu item
373
374 ListIterator layerIter = layerList.listIterator();
375 while ( layerIter.hasNext() ) {
376 String layer = (String)layerIter.next();
377 JMenuItem itemTmp = new JMenuItem(layer);
378 itemTmp.setActionCommand(layer);
379 itemTmp.addActionListener(new LayerListener());
380 m_listMenu.add(itemTmp);
381 }
382 }
383
384 /***
385 * Class for handling the action events of the layer menu.
386 */
387 class LayerListener implements ActionListener {
388
389 /***
390 * Handle <code>ActionEvent</code>.
391 */
392 public void actionPerformed(ActionEvent e){
393 String comm = e.getActionCommand();
394 LOG.info("Select layer " + comm + ".");
395 selectLayer(comm);
396 }
397 }
398 }
This page was automatically generated by Maven