View Javadoc

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