Commits

plightbo  committed 7671d4a

* WebFlow utility mostly complete
* Fixed JSP taglibs when used in Velocity to use the correct Writer

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@539573baa09-0c28-0410-bef9-dab3c582ae83

  • Participants
  • Parent commits c49d328

Comments (0)

Files changed (10)

File src/etc/example/xwork.xml

 
         <default-interceptor-ref name="defaultStack"/>
 
+    </package>
+
+    <package name="examples" extends="default">
+
         <action name="SimpleCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter">
             <result name="success" type="dispatcher">
                 <param name="location">/success.jsp</param>

File src/java/com/opensymphony/webwork/views/jsp/ui/template/VelocityTemplateEngine.java

 package com.opensymphony.webwork.views.jsp.ui.template;
 
+import com.opensymphony.webwork.views.velocity.AbstractTagDirective;
 import com.opensymphony.webwork.views.velocity.VelocityManager;
+import com.opensymphony.xwork.ActionContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.velocity.Template;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.context.Context;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
                 (HttpServletRequest) pageContext.getRequest(),
                 (HttpServletResponse) pageContext.getResponse());
 
-        Writer outputWriter = pageContext.getOut();
+        Writer outputWriter = (Writer) ActionContext.getContext().get(AbstractTagDirective.VELOCITY_WRITER);
 
         // Make the OGNL stack available to the velocityEngine templates.
         // todo Consider putting all the VelocityServlet Context values in

File src/java/com/opensymphony/webwork/views/velocity/AbstractTagDirective.java

 
     protected static Log log = LogFactory.getLog(AbstractTagDirective.class);
 
+    public static final String VELOCITY_WRITER = "com.opensymphony.webwork.views.velocity.AbstractTagDirective.VELOCITY_WRITER";
+
     /**
      * a params of tagname to tagclass that provides faster lookup that searching through the tagpath.  for example,
      * <pre>#tag( TextField )</pre>
                 }
 
                 try {
+                    ActionContext.getContext().put(VELOCITY_WRITER, writer);
                     return this.processTag(pageContext, (Tag) object, subContextAdapter, writer, node, bodyNode);
                 } catch (Exception e) {
                     log.error("Error processing tag: " + e, e);

File src/test/com/opensymphony/webwork/views/jsp/AbstractTagTest.java

 
 import com.opensymphony.webwork.TestAction;
 import com.opensymphony.webwork.config.Configuration;
+import com.opensymphony.webwork.views.velocity.AbstractTagDirective;
 import com.opensymphony.xwork.Action;
+import com.opensymphony.xwork.ActionContext;
 import com.opensymphony.xwork.util.OgnlValueStack;
 import junit.framework.TestCase;
 
         writer = new StringWriter();
 
         JspWriter jspWriter = new WebWorkMockJspWriter(writer);
+        context.put(AbstractTagDirective.VELOCITY_WRITER, writer);
 
         pageContext = new WebWorkMockPageContext();
         pageContext.setRequest(request);
 
         session = new HashMap();
 
+        ActionContext.setContext(new ActionContext(context));
+
         Configuration.setConfiguration(null);
     }
 

File src/webflow/com/opensymphony/webwork/webFlow/WebFlow.java

 
     public static void main(String[] args) {
         LOG.info("WebFlow starting...");
-        String configFilePath = null;//"/Users/mgreer/Sandbox/martin2/"
-        if (args.length > 0) {
-            configFilePath = (String) args[0];
-            LOG.info("configFilePath=" + configFilePath);
-        }/*else{
-            File file = new File("xwork.xml");
-            configFilePath = file.getParent();
-        }*/
-        if (configFilePath != null) {
-            XWorkConfigRetriever.setBasePath(configFilePath);
-            Renderer renderer = new DOTRenderer();
-            renderer.render();
+
+        String configDir = getArg(args, "config");
+        String views = getArg(args, "views");
+
+        XWorkConfigRetriever.setConfiguration(configDir, views.split("[, ]+"));
+        Renderer renderer = new DOTRenderer("temp");
+        renderer.render();
+    }
+
+    private static String getArg(String[] args, String arg) {
+        for (int i = 0; i < args.length; i++) {
+            if (("-" + arg).equals(args[i]) && ((i + 1) < args.length)) {
+                return args[i + 1];
+            }
         }
+
+        return "";
     }
 }

File src/webflow/com/opensymphony/webwork/webFlow/XWorkConfigRetriever.java

 public class XWorkConfigRetriever {
 
     private static final Log LOG = LogFactory.getLog(XWorkConfigRetriever.class);
-    private static String basePath = "";
+    private static String configDir;
+    private static String[] views;
     private static boolean isXWorkStarted = false;
     private static Map viewCache = new HashMap();
 
     }
 
     private static void initXWork() {
-        String configFilePath = basePath + "WEB-INF/classes/xwork.xml";
+        String configFilePath = configDir + "/xwork.xml";
         File configFile = new File(configFilePath);
         try {
             ConfigurationProvider configProvider = new ArbitraryXMLConfigurationProvider(configFile.getCanonicalPath());
     }
 
     public static File getViewFile(String namespace, String actionName, String resultName) {
-        File viewFile = null;
         ResultConfig result = getResultConfig(namespace, actionName, resultName);
-        if (result != null) {
-            String location = (String) result.getParams().get("location");
-            //TODO make sure to follow chaining and redirection to other
-            // actions
-            if (location != null && !location.matches(".*action.*")) {
-                StringBuffer filePath = new StringBuffer(basePath);
-                if (!location.startsWith("/"))
-                    filePath.append(namespace + "/");
-                filePath.append(location);
-                viewFile = new File(filePath.toString());
+        String location = (String) result.getParams().get("location");
+        for (int i = 0; i < views.length; i++) {
+            String viewRoot = views[i];
+            File viewFile = getViewFileInternal(viewRoot, location, namespace);
+            if (viewFile != null) {
+                return viewFile;
             }
         }
-        return viewFile;
+
+        return null;
+    }
+
+    private static File getViewFileInternal(String root, String location, String namespace) {
+        StringBuffer filePath = new StringBuffer(root);
+        if (!location.startsWith("/")) {
+            filePath.append(namespace + "/");
+        }
+        filePath.append(location);
+        File viewFile = new File(filePath.toString());
+        if (viewFile.exists()) {
+            return viewFile;
+        } else {
+            return null;
+        }
     }
 
     public static View getView(String namespace, String actionName, String resultName) {
         String viewId = namespace + "/" + actionName + "/" + resultName;
         View view = (View) viewCache.get(viewId);
         if (view == null) {
-            File viewFile = XWorkConfigRetriever.getViewFile(namespace, actionName,
-                    resultName);
-            if (viewFile != null && viewFile.exists()) {
+            File viewFile = XWorkConfigRetriever.getViewFile(namespace, actionName, resultName);
+            if (viewFile != null) {
                 view = new XworkView(viewFile);
                 viewCache.put(viewId, view);
             }
         return view;
     }
 
-    public static void setBasePath(final String newBasePath) {
-        basePath = newBasePath;
+    public static void setConfiguration(String configDir, String[] views) {
+        XWorkConfigRetriever.configDir = configDir;
+        XWorkConfigRetriever.views = views;
         isXWorkStarted = false;
         viewCache = new HashMap();
     }
-
-    public static String getBasePath() {
-        return basePath;
-    }
 }

File src/webflow/com/opensymphony/webwork/webFlow/collectors/ArbitraryXMLConfigurationProvider.java

  */
 package com.opensymphony.webwork.webFlow.collectors;
 
+import com.opensymphony.util.FileManager;
 import com.opensymphony.xwork.config.providers.XmlConfigurationProvider;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
         try {
             is = new FileInputStream(this.basePathString + fileName);
         } catch (FileNotFoundException e) {
-            LOG.error("FileNotFoundException", e);
+            // ok, try to check the ClassLoader
+            is = FileManager.loadFile(fileName, this.getClass());
         }
-        //InputStream is = FileManager.loadFile(fileName, this.getClass());
+
         return is;
     }
 }

File src/webflow/com/opensymphony/webwork/webFlow/entities/XworkView.java

  */
 package com.opensymphony.webwork.webFlow.entities;
 
+import com.opensymphony.webwork.config.Configuration;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
     private static final Log LOG = LogFactory.getLog(XworkView.class);
     private File file = null;
     private Set targets = null;
-    private static String actionRegex = "([a-zA-Z]+)\\.action";
+    private static String actionRegex = "([A-Za-z0-9\\._\\-]+\\." + Configuration.get("webwork.action.extension") + ")";
     private static Pattern actionPattern = Pattern.compile(actionRegex);
 
     public XworkView() {
             this.targets = new HashSet();
             try {
                 BufferedReader input = new BufferedReader(new FileReader(getFile()));
-                String line = null; //not declared within while loop
+                String line = null;
                 while ((line = input.readLine()) != null) {
                     List actionNameList = findActionLinks(line);
                     if (actionNameList.size() > 0) {

File src/webflow/com/opensymphony/webwork/webFlow/renderers/DOTRenderer.java

  */
 package com.opensymphony.webwork.webFlow.renderers;
 
+import com.opensymphony.webwork.config.Configuration;
+import com.opensymphony.webwork.dispatcher.ServletDispatcherResult;
+import com.opensymphony.webwork.dispatcher.ServletRedirectResult;
+import com.opensymphony.webwork.dispatcher.VelocityResult;
+import com.opensymphony.webwork.views.freemarker.FreemarkerResult;
+import com.opensymphony.webwork.views.jasperreports.JasperReportsResult;
+import com.opensymphony.webwork.views.xslt.XSLTResult;
 import com.opensymphony.webwork.webFlow.XWorkConfigRetriever;
 import com.opensymphony.webwork.webFlow.entities.View;
+import com.opensymphony.xwork.ActionChainResult;
 import com.opensymphony.xwork.config.entities.ActionConfig;
+import com.opensymphony.xwork.config.entities.ResultConfig;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 /**
 public class DOTRenderer implements Renderer {
 
     private static final Log LOG = LogFactory.getLog(DOTRenderer.class);
+    private String output;
 
-    /**
-     * Default constructor
-     */
-    public DOTRenderer() {
+    public DOTRenderer(String output) {
+        this.output = output;
     }
 
     public void render() {
+        DotGraph graph = new DotGraph();
+        graph.attribute("action", "color", "coral1");
+        graph.attribute("view", "color", "darkseagreen2");
+        graph.attribute("start", "color", "gold");
+        graph.attribute("start", "shape", "octagon");
+
+        HashMap viewMap = new HashMap();
+
         Set namespaces = XWorkConfigRetriever.getNamespaces();
         for (Iterator iter = namespaces.iterator(); iter.hasNext();) {
             String namespace = (String) iter.next();
-            String fileName = "default";
-            if (namespace.length() > 0)
-                fileName = namespace.substring(1);
-            LOG.info("fileName=" + fileName);
-            File namespaceFile = new File(XWorkConfigRetriever.getBasePath() + fileName + ".dot");
-            FileWriter out = null;
-            try {
-                out = new FileWriter(namespaceFile);
-                out.write("graph " + fileName + "{\n");
-                Set actionNames = XWorkConfigRetriever.getActionNames(namespace);
-                for (Iterator iterator = actionNames.iterator(); iterator.hasNext();) {
-                    String actionName = (String) iterator.next();
-                    ActionConfig actionConfig = XWorkConfigRetriever.getActionConfig(namespace,
-                            actionName);
-                    //out.write( actionName + " -- " );
-                    Set resultNames = actionConfig.getResults().keySet();
-                    for (Iterator iterator2 = resultNames.iterator(); iterator2.hasNext();) {
-                        String resultName = (String) iterator2.next();
-                        View view = XWorkConfigRetriever
-                                .getView(namespace, actionName, resultName);
-                        if (resultName != "login" && resultName != "access" && view != null) {
-                            //out.write( actionName + " -- " + view +" [label="+resultName+"];\n");
-//							out.write( "\t\t-> " + resultName + "\t-> " + view + "\t-> "
-//									+ view.getTargets() + "\n" );
-                            Set targetActions = view.getTargets();
-                            for (Iterator iterator3 = targetActions.iterator(); iterator3.hasNext();) {
-                                String targetAction = (String) iterator3.next();
-                                out.write(actionName + " -- " + targetAction + ";\n");
-                            }
+
+            Set actionNames = XWorkConfigRetriever.getActionNames(namespace);
+            for (Iterator iterator = actionNames.iterator(); iterator.hasNext();) {
+                String actionName = (String) iterator.next();
+                ActionConfig actionConfig = XWorkConfigRetriever.getActionConfig(namespace,
+                        actionName);
+                String action = namespace + "/" + actionName + "." + Configuration.get("webwork.action.extension");
+
+                graph.add_node("action", action, actionName);
+
+                Set resultNames = actionConfig.getResults().keySet();
+                for (Iterator iterator2 = resultNames.iterator(); iterator2.hasNext();) {
+                    String resultName = (String) iterator2.next();
+                    ResultConfig resultConfig = ((ResultConfig) actionConfig.getResults().get(resultName));
+                    String resultClassName = resultConfig.getClassName();
+
+                    if (resultClassName.equals(ActionChainResult.class.getName())) {
+
+                    } else if (resultClassName.equals(ServletDispatcherResult.class.getName())
+                            || resultClassName.equals(VelocityResult.class.getName())
+                            || resultClassName.equals(FreemarkerResult.class.getName())) {
+                        String location = (String) resultConfig.getParams().get("location");
+                        String view = getViewLocation(location, namespace);
+                        graph.add_node("view", view, null);
+                        graph.add_link(action, view, resultConfig.getName());
+
+                        View viewFile = XWorkConfigRetriever.getView(namespace, actionName, resultName);
+                        if (viewFile != null) {
+                            viewMap.put(view, viewFile);
                         }
+                    } else if (resultClassName.equals(JasperReportsResult.class.getName())) {
+
+                    } else if (resultClassName.equals(XSLTResult.class.getName())) {
+
+                    } else if (resultClassName.equals(ServletRedirectResult.class.getName())) {
+
                     }
                 }
-                out.write("}");
-                out.close();
-            } catch (IOException e) {
-                LOG.error("Error writing to " + namespace, e);
             }
         }
+
+        for (Iterator iterator = viewMap.entrySet().iterator(); iterator.hasNext();) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            String view = (String) entry.getKey();
+            View viewFile = (View) entry.getValue();
+            Set targets = viewFile.getTargets();
+            for (Iterator iterator1 = targets.iterator(); iterator1.hasNext();) {
+                String viewTarget = (String) iterator1.next();
+                graph.add_link(view, "/" + viewTarget, null);
+            }
+        }
+
+        try {
+            FileWriter out = new FileWriter(output + "/out.dot");
+            out.write(graph.to_s(true));
+            out.flush();
+            out.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
 
+    private String getViewLocation(String location, String namespace) {
+        String view = null;
+        if (!location.startsWith("/")) {
+            view = namespace + "/" + location;
+        } else {
+            view = location;
+        }
+        return view;
+    }
+
+    /**
+     * @author Joe Walnes <joe@truemesh.com>
+     */
+    static class DotGraph {
+        Map clusters; // Map of String -> (Map of String -> Object[] { Map attrs, String type })
+        Map links; // Map of Link->Map of params
+        Map attributes;
+
+        public DotGraph() {
+            clusters = new HashMap();
+            clusters.put("default", new HashMap());
+            links = new HashMap();
+            attributes = new HashMap();
+        }
+
+        public void add_node(String type, String name, String label) {
+
+            String[] ret = split_cluster(name);
+            String cluster = ret[0];
+            name = ret[1];
+
+            Map nodes = (Map) clusters.get(cluster);
+            if (nodes == null) {
+                nodes = new HashMap();
+                clusters.put(cluster, nodes);
+            }
+
+            if (label == null) {
+                label = name;
+            }
+
+            Map nodeParams = new HashMap(1);
+            nodes.put(name, new Object[]{type, nodeParams});
+            nodeParams.put("label", label);
+        }
+
+        public void add_link(String source, String dest, String label) {
+            Map attrs = new HashMap();
+            attrs.put("label", label);
+
+            links.put(new String[]{x(source), x(dest)}, new Object[]{"link", attrs});
+        }
+
+        public String x(String y) {
+            String[] cluster = split_cluster(y);
+            return cluster[0] + "/" + cluster[1];
+        }
+
+        public void attribute(String type, String name, String value) {
+            Map params = null;
+            if (attributes.get(type) == null) {
+                params = new HashMap();
+                attributes.put(type, params);
+            } else {
+                params = (Map) attributes.get(type);
+            }
+
+            params.put(name, value);
+        }
+
+        public String to_s(boolean include_attributes) {
+            StringBuffer result = new StringBuffer();
+
+            result.append("digraph mygraph {\n");
+            if (include_attributes) {
+                //result << "  rankdir=LR;\n"
+                result.append("  fontsize=10;\n");
+                result.append("  fontname=helvetica;\n");
+                result.append("  node [fontsize=10, fontname=helvetica, style=filled, shape=rectangle]\n");
+                result.append("  edge [fontsize=10, fontname=helvetica]\n");
+            }
+
+            Map defaultCluster = (Map) clusters.get("default");
+            for (Iterator iterator = defaultCluster.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String name = (String) entry.getKey();
+                Object[] attributes = (Object[]) entry.getValue();
+
+                result.append("  default_" + c(name) + " ");
+                if (include_attributes) {
+                    result.append(write_attributes((Map) attributes[1], (String) attributes[0]));
+                }
+                result.append(";\n");
+            }
+
+            for (Iterator iterator = clusters.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String cluster = (String) entry.getKey();
+                Map nodes = (Map) entry.getValue();
+
+                if (!"default".equals(cluster)) {
+                    result.append("  subgraph cluster_" + c(cluster) + " {\n");
+                    if (include_attributes) {
+                        result.append("    color=grey;\n");
+                        result.append("    fontcolor=grey;\n");
+                        result.append("    label=\"" + cluster + "\";\n");
+                    }
+
+                    for (Iterator iterator1 = nodes.entrySet().iterator(); iterator1.hasNext();) {
+                        Map.Entry entry1 = (Map.Entry) iterator1.next();
+                        String name = (String) entry1.getKey();
+                        Object[] attributes = (Object[]) entry1.getValue();
+
+                        result.append("    " + c(cluster) + "_" + c(name) + " ");
+                        if (include_attributes) {
+                            result.append(write_attributes((Map) attributes[1], (String) attributes[0]));
+                        }
+                        result.append(";\n");
+                    }
+
+                    result.append("  }\n");
+                }
+            }
+
+            for (Iterator iterator = links.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String[] link = (String[]) entry.getKey();
+                Object[] attributes = (Object[]) entry.getValue();
+
+                result.append("  " + c(link[0]) + " -> " + c(link[1]) + " ");
+                if (include_attributes) {
+                    result.append(write_attributes((Map) attributes[1], (String) attributes[0]));
+                }
+                result.append(";\n");
+            }
+
+            result.append("}\n");
+
+            return result.toString();
+        }
+
+        String[] split_cluster(String name) {
+            String[] cluster = new String[2];
+
+            // name[/\//]
+            if (name.startsWith("/")) {
+                name = name.substring(1);
+            }
+
+            if (name.matches(".*\\/.*")) {
+                cluster = name.split("\\/", 2);
+            } else {
+                cluster[0] = "default";
+                cluster[1] = name;
+            }
+
+            return cluster;
+        }
+
+        String c(String str) { // replace dot unfriendly chars
+            return str.replaceAll("[\\.\\/\\-\\$\\{\\}]", "_");
+        }
+
+        String write_attributes(Map attributes, String type) {
+            StringBuffer result = new StringBuffer();
+            result.append('[');
+
+            for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String key = (String) entry.getKey();
+                String value = (String) entry.getValue();
+
+                if (value != null) {
+                    result.append(key + "=\"" + value + "\",");
+                }
+            }
+
+            Map extra_attributes = (Map) this.attributes.get(type);
+            if (extra_attributes != null) {
+                for (Iterator iterator = extra_attributes.entrySet().iterator(); iterator.hasNext();) {
+                    Map.Entry entry = (Map.Entry) iterator.next();
+                    String key = (String) entry.getKey();
+                    String value = (String) entry.getValue();
+
+                    if (value != null) {
+                        result.append(key + "=\"" + value + "\",");
+                    }
+                }
+            }
+
+            result.deleteCharAt(result.length() - 1);
+            result.append(']');
+            String toString = result.toString();
+
+            if (toString.equals("]")) {
+                toString = "";
+            }
+
+            return toString;
+        }
+    }
 }

File src/webflow/com/opensymphony/webwork/webFlow/renderers/TextRenderer.java

             if (namespace.length() > 0)
                 fileName = namespace.substring(1) + ".txt";
             LOG.info("fileName=" + fileName);
-            File namespaceFile = new File(XWorkConfigRetriever.getBasePath() + fileName);
+            File namespaceFile = new File(fileName);
             FileWriter out = null;
             try {
                 out = new FileWriter(namespaceFile);