View Javadoc

    1   /*
    2    * $Id: DOTRenderer.java 474191 2006-11-13 08:30:40Z mrdon $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    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                         //  FIXME: work with new configuration style
    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                         // check if the redirect is to an action -- if so, link it
    128                         String location = getViewLocation((String) resultConfig.getParams().get("location"), namespace);
    129                         //  FIXME: work with new configuration style
    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         // now look for links in the view
    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         // finally, let's match up these links as real Link objects
    162         for (Iterator iterator = links.iterator(); iterator.hasNext();) {
    163             TempLink temp = (TempLink) iterator.next();
    164             String location = temp.location;
    165
    166             // FIXME: work with new configuration style
    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             //writer.write(graph.to_s(true));
    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 }