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