001: /*
002: * Created on Aug 12, 2004 by mgreer
003: */
004: package com.opensymphony.webwork.sitegraph.renderers;
005:
006: import com.opensymphony.webwork.config.Configuration;
007: import com.opensymphony.webwork.sitegraph.XWorkConfigRetriever;
008: import com.opensymphony.webwork.sitegraph.entities.Target;
009: import com.opensymphony.webwork.sitegraph.entities.View;
010: import com.opensymphony.webwork.sitegraph.model.*;
011: import com.opensymphony.webwork.WebWorkConstants;
012: import com.opensymphony.xwork.ActionChainResult;
013: import com.opensymphony.xwork.config.entities.ActionConfig;
014: import com.opensymphony.xwork.config.entities.ResultConfig;
015:
016: import java.io.IOException;
017: import java.io.Writer;
018: import java.util.*;
019:
020: /**
021: * Renders flow diagram to the console at info level
022: */
023: public class DOTRenderer {
024:
025: private Writer writer;
026: private List links = new ArrayList();
027:
028: public DOTRenderer(Writer writer) {
029: this .writer = writer;
030: }
031:
032: public void render(String ns) {
033: Graph graph = new Graph();
034:
035: TreeMap viewMap = new TreeMap(new Comparator() {
036: public int compare(Object o1, Object o2) {
037: ViewNode v1 = (ViewNode) o1;
038: ViewNode v2 = (ViewNode) o2;
039:
040: return v1.getFullName().compareTo(v2.getFullName());
041: }
042: });
043:
044: Set namespaces = XWorkConfigRetriever.getNamespaces();
045: for (Iterator iter = namespaces.iterator(); iter.hasNext();) {
046: String namespace = (String) iter.next();
047:
048: if (!namespace.startsWith(ns)) {
049: continue;
050: }
051:
052: SubGraph subGraph = graph.create(namespace);
053:
054: Set actionNames = XWorkConfigRetriever
055: .getActionNames(namespace);
056: for (Iterator iterator = actionNames.iterator(); iterator
057: .hasNext();) {
058: String actionName = (String) iterator.next();
059: ActionConfig actionConfig = XWorkConfigRetriever
060: .getActionConfig(namespace, actionName);
061:
062: ActionNode action = new ActionNode(actionName);
063: subGraph.addNode(action);
064:
065: Set resultNames = actionConfig.getResults().keySet();
066: for (Iterator iterator2 = resultNames.iterator(); iterator2
067: .hasNext();) {
068: String resultName = (String) iterator2.next();
069: ResultConfig resultConfig = ((ResultConfig) actionConfig
070: .getResults().get(resultName));
071: String resultClassName = resultConfig
072: .getClassName();
073:
074: if (resultClassName.equals(ActionChainResult.class
075: .getName())) {
076:
077: } else if (resultClassName.indexOf("Dispatcher") != -1
078: || resultClassName.indexOf("Velocity") != -1
079: || resultClassName.indexOf("Freemarker") != -1) {
080: if (resultConfig.getParams().get("location") == null) {
081: continue;
082: }
083:
084: String location = getViewLocation(
085: (String) resultConfig.getParams().get(
086: "location"), namespace);
087: if (location
088: .endsWith((String) Configuration
089: .get(WebWorkConstants.WEBWORK_ACTION_EXTENSION))) {
090: addTempLink(action, location,
091: Link.TYPE_RESULT, resultConfig
092: .getName());
093: } else {
094: ViewNode view = new ViewNode(
095: stripLocation(location));
096: subGraph.addNode(view);
097:
098: addTempLink(action, location,
099: Link.TYPE_RESULT, resultConfig
100: .getName());
101:
102: View viewFile = getView(namespace,
103: actionName, resultName, location);
104: if (viewFile != null) {
105: viewMap.put(view, viewFile);
106: }
107: }
108: } else if (resultClassName.indexOf("Jasper") != -1) {
109:
110: } else if (resultClassName.indexOf("XSLT") != -1) {
111:
112: } else if (resultClassName.indexOf("Redirect") != -1) {
113: // check if the redirect is to an action -- if so, link it
114: String locationConfig = (String) resultConfig
115: .getParams().get("location");
116: if (locationConfig == null) {
117: locationConfig = (String) resultConfig
118: .getParams().get("actionName");
119: }
120: String location = getViewLocation(
121: locationConfig, namespace);
122: if (location
123: .endsWith((String) Configuration
124: .get(WebWorkConstants.WEBWORK_ACTION_EXTENSION))) {
125: addTempLink(action, location,
126: Link.TYPE_REDIRECT, resultConfig
127: .getName());
128: } else {
129: ViewNode view = new ViewNode(
130: stripLocation(location));
131: subGraph.addNode(view);
132:
133: addTempLink(action, location,
134: Link.TYPE_REDIRECT, resultConfig
135: .getName());
136:
137: View viewFile = getView(namespace,
138: actionName, resultName, location);
139: if (viewFile != null) {
140: viewMap.put(view, viewFile);
141: }
142: }
143: }
144: }
145: }
146: }
147:
148: // now look for links in the view
149: for (Iterator iterator = viewMap.entrySet().iterator(); iterator
150: .hasNext();) {
151: Map.Entry entry = (Map.Entry) iterator.next();
152: ViewNode view = (ViewNode) entry.getKey();
153: View viewFile = (View) entry.getValue();
154: Set targets = viewFile.getTargets();
155: for (Iterator iterator1 = targets.iterator(); iterator1
156: .hasNext();) {
157: Target target = (Target) iterator1.next();
158: String viewTarget = target.getTarget();
159: addTempLink(view, viewTarget, target.getType(), "");
160: }
161: }
162:
163: // finally, let's match up these links as real Link objects
164: for (Iterator iterator = links.iterator(); iterator.hasNext();) {
165: TempLink temp = (TempLink) iterator.next();
166: String location = temp.location;
167: if (location.endsWith((String) Configuration
168: .get(WebWorkConstants.WEBWORK_ACTION_EXTENSION))) {
169: location = location
170: .substring(
171: 0,
172: location
173: .indexOf((String) Configuration
174: .get(WebWorkConstants.WEBWORK_ACTION_EXTENSION)) - 1);
175:
176: if (location.indexOf('!') != -1) {
177: temp.label = temp.label + "\\n("
178: + location.substring(location.indexOf('!'))
179: + ")";
180: location = location.substring(0, location
181: .indexOf('!'));
182: }
183: }
184: SiteGraphNode to = graph.findNode(location, temp.node);
185: if (to != null) {
186: graph.addLink(new Link(temp.node, to, temp.typeResult,
187: temp.label));
188: }
189: }
190:
191: try {
192: //writer.write(graph.to_s(true));
193: graph.render(new IndentWriter(writer));
194: writer.flush();
195: writer.close();
196: } catch (IOException e) {
197: e.printStackTrace();
198: }
199: }
200:
201: private void addTempLink(SiteGraphNode node, String location,
202: int type, String label) {
203: links.add(new TempLink(node, location, type, label));
204: }
205:
206: private String stripLocation(String location) {
207: return location.substring(location.lastIndexOf('/') + 1);
208: }
209:
210: private View getView(String namespace, String actionName,
211: String resultName, String location) {
212: int type = View.TYPE_JSP;
213: if (location.endsWith(".fm") || location.endsWith(".ftl")) {
214: type = View.TYPE_FTL;
215: } else if (location.endsWith(".vm")) {
216: type = View.TYPE_VM;
217: }
218: return XWorkConfigRetriever.getView(namespace, actionName,
219: resultName, type);
220: }
221:
222: private String getViewLocation(String location, String namespace) {
223: String view = null;
224: if (!location.startsWith("/")) {
225: view = namespace + "/" + location;
226: } else {
227: view = location;
228: }
229:
230: if (view.indexOf('?') != -1) {
231: view = view.substring(0, view.indexOf('?'));
232: }
233:
234: return view;
235: }
236:
237: class TempLink {
238: SiteGraphNode node;
239: String location;
240: int typeResult;
241: String label;
242:
243: public TempLink(SiteGraphNode node, String location,
244: int typeResult, String label) {
245: this .node = node;
246: this .location = location;
247: this .typeResult = typeResult;
248: this .label = label;
249: }
250:
251: public boolean equals(Object o) {
252: if (this == o)
253: return true;
254: if (!(o instanceof TempLink))
255: return false;
256:
257: final TempLink tempLink = (TempLink) o;
258:
259: if (typeResult != tempLink.typeResult)
260: return false;
261: if (label != null ? !label.equals(tempLink.label)
262: : tempLink.label != null)
263: return false;
264: if (location != null ? !location.equals(tempLink.location)
265: : tempLink.location != null)
266: return false;
267: if (node != null ? !node.equals(tempLink.node)
268: : tempLink.node != null)
269: return false;
270:
271: return true;
272: }
273:
274: public int hashCode() {
275: int result;
276: result = (node != null ? node.hashCode() : 0);
277: result = 29 * result
278: + (location != null ? location.hashCode() : 0);
279: result = 29 * result + typeResult;
280: result = 29 * result
281: + (label != null ? label.hashCode() : 0);
282: return result;
283: }
284: }
285: }
|