1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.sitegraph.renderers;
23
24 import java.io.IOException;
25 import java.io.Writer;
26 import java.util.ArrayList;
27 import java.util.Comparator;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33
34 import org.apache.struts2.StrutsConstants;
35 import org.apache.struts2.sitegraph.StrutsConfigRetriever;
36 import org.apache.struts2.sitegraph.entities.Target;
37 import org.apache.struts2.sitegraph.entities.View;
38 import org.apache.struts2.sitegraph.model.ActionNode;
39 import org.apache.struts2.sitegraph.model.Graph;
40 import org.apache.struts2.sitegraph.model.IndentWriter;
41 import org.apache.struts2.sitegraph.model.Link;
42 import org.apache.struts2.sitegraph.model.SiteGraphNode;
43 import org.apache.struts2.sitegraph.model.SubGraph;
44 import org.apache.struts2.sitegraph.model.ViewNode;
45
46 import com.opensymphony.xwork2.ActionChainResult;
47 import com.opensymphony.xwork2.config.entities.ActionConfig;
48 import com.opensymphony.xwork2.config.entities.ResultConfig;
49
50 /***
51 * Renders flow diagram to the console at info level
52 */
53 public class DOTRenderer {
54
55 private Writer writer;
56 private List links = new ArrayList();
57
58 public DOTRenderer(Writer writer) {
59 this.writer = writer;
60 }
61
62 public void render(String ns) {
63 Graph graph = new Graph();
64
65 TreeMap viewMap = new TreeMap(new Comparator() {
66 public int compare(Object o1, Object o2) {
67 ViewNode v1 = (ViewNode) o1;
68 ViewNode v2 = (ViewNode) o2;
69
70 return v1.getFullName().compareTo(v2.getFullName());
71 }
72 });
73
74 Set namespaces = StrutsConfigRetriever.getNamespaces();
75 for (Iterator iter = namespaces.iterator(); iter.hasNext();) {
76 String namespace = (String) iter.next();
77
78 if (!namespace.startsWith(ns)) {
79 continue;
80 }
81
82 SubGraph subGraph = graph.create(namespace);
83
84 Set actionNames = StrutsConfigRetriever.getActionNames(namespace);
85 for (Iterator iterator = actionNames.iterator(); iterator.hasNext();) {
86 String actionName = (String) iterator.next();
87 ActionConfig actionConfig = StrutsConfigRetriever.getActionConfig(namespace,
88 actionName);
89
90 ActionNode action = new ActionNode(actionName);
91 subGraph.addNode(action);
92
93 Set resultNames = actionConfig.getResults().keySet();
94 for (Iterator iterator2 = resultNames.iterator(); iterator2.hasNext();) {
95 String resultName = (String) iterator2.next();
96 ResultConfig resultConfig = ((ResultConfig) actionConfig.getResults().get(resultName));
97 String resultClassName = resultConfig.getClassName();
98
99 if (resultClassName.equals(ActionChainResult.class.getName())) {
100
101 } else if (resultClassName.indexOf("Dispatcher") != -1
102 || resultClassName.indexOf("Velocity") != -1
103 || resultClassName.indexOf("Freemarker") != -1) {
104 if (resultConfig.getParams().get("location") == null) {
105 continue;
106 }
107
108 String location = getViewLocation((String) resultConfig.getParams().get("location"), namespace);
109
110 if (location.endsWith("action")) {
111 addTempLink(action, location, Link.TYPE_RESULT, resultConfig.getName());
112 } else {
113 ViewNode view = new ViewNode(stripLocation(location));
114 subGraph.addNode(view);
115
116 addTempLink(action, location, Link.TYPE_RESULT, resultConfig.getName());
117
118 View viewFile = getView(namespace, actionName, resultName, location);
119 if (viewFile != null) {
120 viewMap.put(view, viewFile);
121 }
122 }
123 } else if (resultClassName.indexOf("Jasper") != -1) {
124
125 } else if (resultClassName.indexOf("XSLT") != -1) {
126
127 } else if (resultClassName.indexOf("Redirect") != -1) {
128
129 String locationConfig = (String) resultConfig.getParams().get("location");
130 if (locationConfig == null) {
131 locationConfig = (String) resultConfig.getParams().get("actionName");
132 }
133 String location = getViewLocation(locationConfig, namespace);
134
135 if (location.endsWith("action")) {
136 addTempLink(action, location, Link.TYPE_REDIRECT, resultConfig.getName());
137 } else {
138 ViewNode view = new ViewNode(stripLocation(location));
139 subGraph.addNode(view);
140
141 addTempLink(action, location, Link.TYPE_REDIRECT, resultConfig.getName());
142
143 View viewFile = getView(namespace, actionName, resultName, location);
144 if (viewFile != null) {
145 viewMap.put(view, viewFile);
146 }
147 }
148 }
149 }
150 }
151 }
152
153
154 for (Iterator iterator = viewMap.entrySet().iterator(); iterator.hasNext();) {
155 Map.Entry entry = (Map.Entry) iterator.next();
156 ViewNode view = (ViewNode) entry.getKey();
157 View viewFile = (View) entry.getValue();
158 Set targets = viewFile.getTargets();
159 for (Iterator iterator1 = targets.iterator(); iterator1.hasNext();) {
160 Target target = (Target) iterator1.next();
161 String viewTarget = target.getTarget();
162 addTempLink(view, viewTarget, target.getType(), "");
163 }
164 }
165
166
167 for (Iterator iterator = links.iterator(); iterator.hasNext();) {
168 TempLink temp = (TempLink) iterator.next();
169 String location = temp.location;
170
171
172 if (location.endsWith("action")) {
173 location = location.substring(0, location.indexOf("action") - 1);
174
175 if (location.indexOf('!') != -1) {
176 temp.label = temp.label + "//n(" + location.substring(location.indexOf('!')) + ")";
177 location = location.substring(0, location.indexOf('!'));
178 }
179 }
180 SiteGraphNode to = graph.findNode(location, temp.node);
181 if (to != null) {
182 graph.addLink(new Link(temp.node, to, temp.typeResult, temp.label));
183 }
184 }
185
186 try {
187
188 graph.render(new IndentWriter(writer));
189 writer.flush();
190 writer.close();
191 } catch (IOException e) {
192 e.printStackTrace();
193 }
194 }
195
196 private void addTempLink(SiteGraphNode node, String location, int type, String label) {
197 links.add(new TempLink(node, location, type, label));
198 }
199
200 private String stripLocation(String location) {
201 return location.substring(location.lastIndexOf('/') + 1);
202 }
203
204 private View getView(String namespace, String actionName, String resultName, String location) {
205 int type = View.TYPE_JSP;
206 if (location.endsWith(".fm") || location.endsWith(".ftl")) {
207 type = View.TYPE_FTL;
208 } else if (location.endsWith(".vm")) {
209 type = View.TYPE_VM;
210 }
211 return StrutsConfigRetriever.getView(namespace, actionName, resultName, type);
212 }
213
214 private String getViewLocation(String location, String namespace) {
215 String view = null;
216 if (!location.startsWith("/")) {
217 view = namespace + "/" + location;
218 } else {
219 view = location;
220 }
221
222 if (view.indexOf('?') != -1) {
223 view = view.substring(0, view.indexOf('?'));
224 }
225
226 return view;
227 }
228
229 class TempLink {
230 SiteGraphNode node;
231 String location;
232 int typeResult;
233 String label;
234
235 public TempLink(SiteGraphNode node, String location, int typeResult, String label) {
236 this.node = node;
237 this.location = location;
238 this.typeResult = typeResult;
239 this.label = label;
240 }
241
242 public boolean equals(Object o) {
243 if (this == o) return true;
244 if (!(o instanceof TempLink)) return false;
245
246 final TempLink tempLink = (TempLink) o;
247
248 if (typeResult != tempLink.typeResult) return false;
249 if (label != null ? !label.equals(tempLink.label) : tempLink.label != null) return false;
250 if (location != null ? !location.equals(tempLink.location) : tempLink.location != null) return false;
251 if (node != null ? !node.equals(tempLink.node) : tempLink.node != null) return false;
252
253 return true;
254 }
255
256 public int hashCode() {
257 int result;
258 result = (node != null ? node.hashCode() : 0);
259 result = 29 * result + (location != null ? location.hashCode() : 0);
260 result = 29 * result + typeResult;
261 result = 29 * result + (label != null ? label.hashCode() : 0);
262 return result;
263 }
264 }
265 }