Return-Path: Delivered-To: apmail-struts-commits-archive@locus.apache.org Received: (qmail 72265 invoked from network); 19 Nov 2006 05:03:47 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 Nov 2006 05:03:47 -0000 Received: (qmail 19421 invoked by uid 500); 19 Nov 2006 05:03:55 -0000 Delivered-To: apmail-struts-commits-archive@struts.apache.org Received: (qmail 19380 invoked by uid 500); 19 Nov 2006 05:03:55 -0000 Mailing-List: contact commits-help@struts.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@struts.apache.org Delivered-To: mailing list commits@struts.apache.org Received: (qmail 19371 invoked by uid 99); 19 Nov 2006 05:03:55 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 Nov 2006 21:03:55 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 Nov 2006 21:03:44 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 7A69E1A9846; Sat, 18 Nov 2006 21:03:11 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r476709 - in /struts/struts2/trunk/plugins: ./ codebehind/ codebehind/src/ codebehind/src/main/ codebehind/src/main/java/ codebehind/src/main/java/org/ codebehind/src/main/java/org/apache/ codebehind/src/main/java/org/apache/struts2/ codebe... Date: Sun, 19 Nov 2006 05:03:11 -0000 To: commits@struts.apache.org From: mrdon@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061119050311.7A69E1A9846@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mrdon Date: Sat Nov 18 21:03:10 2006 New Revision: 476709 URL: http://svn.apache.org/viewvc?view=rev&rev=476709 Log: Adding the codebehind plugin, which minimizes the amount of configuration needed for common cases (default results and templates with no Action) WW-1515 Added: struts/struts2/trunk/plugins/codebehind/ struts/struts2/trunk/plugins/codebehind/pom.xml struts/struts2/trunk/plugins/codebehind/src/ struts/struts2/trunk/plugins/codebehind/src/main/ struts/struts2/trunk/plugins/codebehind/src/main/java/ struts/struts2/trunk/plugins/codebehind/src/main/java/org/ struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/ struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/ struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/ struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/CodebehindUnknownHandler.java struts/struts2/trunk/plugins/codebehind/src/main/resources/ struts/struts2/trunk/plugins/codebehind/src/main/resources/struts-plugin.xml struts/struts2/trunk/plugins/codebehind/src/test/ struts/struts2/trunk/plugins/codebehind/src/test/java/ struts/struts2/trunk/plugins/codebehind/src/test/java/org/ struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/ struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/ struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/ struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/CodebehindUnknownHandlerTest.java Modified: struts/struts2/trunk/plugins/pom.xml Added: struts/struts2/trunk/plugins/codebehind/pom.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/pom.xml?view=auto&rev=476709 ============================================================================== --- struts/struts2/trunk/plugins/codebehind/pom.xml (added) +++ struts/struts2/trunk/plugins/codebehind/pom.xml Sat Nov 18 21:03:10 2006 @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.apache.struts + struts2-plugins + 2.0.2-SNAPSHOT + + org.apache.struts + struts2-codebehind-plugin + jar + Struts 2 Codebehind Plugin + + + scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/codebehind/ + scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/codebehind/ + http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/plugins/codebehind/ + + + + + junit + junit + test + 3.8.1 + + + mockobjects + mockobjects-core + 0.09 + test + + + org.springframework + spring-mock + 1.2.8 + test + + + org.springframework + spring-core + 1.2.8 + test + + + javax.servlet + servlet-api + 2.4 + provided + + + + javax.servlet + jsp-api + 2.0 + provided + + + + + + + + Added: struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/CodebehindUnknownHandler.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/CodebehindUnknownHandler.java?view=auto&rev=476709 ============================================================================== --- struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/CodebehindUnknownHandler.java (added) +++ struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/codebehind/CodebehindUnknownHandler.java Sat Nov 18 21:03:10 2006 @@ -0,0 +1,212 @@ +/* + * $Id: DWRValidator.java 476642 2006-11-18 22:40:18Z mrdon $ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.codebehind; + +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionSupport; +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.UnknownHandler; +import com.opensymphony.xwork2.XWorkException; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.config.entities.PackageConfig; +import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.config.entities.ResultTypeConfig; +import com.opensymphony.xwork2.config.providers.InterceptorBuilder; +import com.opensymphony.xwork2.inject.Inject; + +public class CodebehindUnknownHandler implements UnknownHandler { + + protected String defaultPackageName = "codebehind-default"; + protected ServletContext servletContext; + protected Map resultsByExtension = new HashMap(); + protected String templatePathPrefix = "/"; + protected Configuration configuration; + protected ObjectFactory objectFactory; + + protected static final Log LOG = LogFactory.getLog(CodebehindUnknownHandler.class); + + @Inject("struts.codebehind.defaultPackage") + public void setDefaultPackage(String pkg) { + this.defaultPackageName = pkg; + } + + @Inject + public void setConfiguration(Configuration config) { + this.configuration = config; + } + + @Inject + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + @Inject + public void setObjectFactory(ObjectFactory objectFactory) { + this.objectFactory = objectFactory; + } + + protected Map loadResultTypes(Configuration config) { + Map resultTypes = new LinkedHashMap(); + PackageConfig parentPackage = config.getPackageConfig(defaultPackageName); + Map results = parentPackage.getAllResultTypeConfigs(); + + resultTypes.put("jsp", results.get("dispatcher")); + resultTypes.put("vm", results.get("velocity")); + resultTypes.put("ftl", results.get("freemarker")); + return resultTypes; + } + + public ActionConfig handleUnknownAction(String namespace, String actionName) + throws XWorkException { + if (resultsByExtension == null) { + resultsByExtension = loadResultTypes(configuration); + } + String pathPrefix = determinePath(templatePathPrefix, namespace); + ActionConfig actionConfig = null; + for (String ext : resultsByExtension.keySet()) { + if (LOG.isDebugEnabled()) { + LOG.debug("Trying to locate unknown action template with extension ."+ext+" in directory "+pathPrefix); + } + String path = string(pathPrefix, actionName, "." , ext); + try { + if (servletContext.getResource(path) != null) { + actionConfig = buildActionConfig(path, namespace, actionName, resultsByExtension.get(ext)); + break; + } + } catch (MalformedURLException e) { + LOG.warn("Unable to parse template path: "+path+", skipping..."); + } + } + return actionConfig; + } + + protected ActionConfig buildActionConfig(String path, String namespace, String actionName, ResultTypeConfig resultTypeConfig) { + if (resultsByExtension == null) { + resultsByExtension = loadResultTypes(configuration); + } + Map results = new HashMap(); + HashMap params = new HashMap(); + if (resultTypeConfig.getParams() != null) { + params.putAll(resultTypeConfig.getParams()); + } + params.put(resultTypeConfig.getDefaultResultParam(), path); + + PackageConfig pkg = configuration.getPackageConfig(defaultPackageName); + List interceptors = InterceptorBuilder.constructInterceptorReference(pkg, pkg.getFullDefaultInterceptorRef(), + Collections.EMPTY_MAP, null, objectFactory); + ResultConfig config = new ResultConfig(Action.SUCCESS, resultTypeConfig.getClazz(), params); + results.put(Action.SUCCESS, config); + return new ActionConfig("execute", ActionSupport.class.getName(), defaultPackageName, new HashMap(), results, interceptors); + } + + public Result handleUnknownResult(ActionContext actionContext, String actionName, + ActionConfig actionConfig, String resultCode) throws XWorkException { + + Result result = null; + PackageConfig pkg = configuration.getPackageConfig(actionConfig.getPackageName()); + String ns = pkg.getNamespace(); + String pathPrefix = determinePath(templatePathPrefix, ns); + + for (String ext : resultsByExtension.keySet()) { + if (LOG.isDebugEnabled()) { + LOG.debug("Trying to locate result with extension ."+ext+" in directory "+pathPrefix); + } + String path = string(pathPrefix, actionName, "-", resultCode, "." , ext); + try { + if (servletContext.getResource(path) != null) { + result = buildResult(path, resultCode, resultsByExtension.get(ext), actionContext); + break; + } + } catch (MalformedURLException e) { + LOG.warn("Unable to parse template path: "+path+", skipping..."); + } + + path = string(pathPrefix, actionName, "." , ext); + try { + if (servletContext.getResource(path) != null) { + result = buildResult(path, resultCode, resultsByExtension.get(ext), actionContext); + break; + } + } catch (MalformedURLException e) { + LOG.warn("Unable to parse template path: "+path+", skipping..."); + } + } + + return result; + } + + protected Result buildResult(String path, String resultCode, ResultTypeConfig config, ActionContext invocationContext) { + String resultClass = config.getClazz(); + + Map params = new LinkedHashMap(); + if (config.getParams() != null) { + params.putAll(config.getParams()); + } + params.put(config.getDefaultResultParam(), path); + + ResultConfig resultConfig = new ResultConfig(resultCode, resultClass, params); + try { + return objectFactory.buildResult(resultConfig, invocationContext.getContextMap()); + } catch (Exception e) { + throw new XWorkException("Unable to build codebehind result", e, resultConfig); + } + } + + protected String string(String... parts) { + StringBuilder sb = new StringBuilder(); + for (String part : parts) { + sb.append(part); + } + return sb.toString(); + } + + protected String determinePath(String prefix, String ns) { + if (ns == null || "/".equals(ns)) { + ns = ""; + } + if (ns.length() > 0) { + if (ns.charAt(0) == '/') { + ns = ns.substring(1); + } + if (ns.charAt(ns.length() - 1) != '/') { + ns += "/"; + } + } + return prefix + ns; + } + +} Added: struts/struts2/trunk/plugins/codebehind/src/main/resources/struts-plugin.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/main/resources/struts-plugin.xml?view=auto&rev=476709 ============================================================================== --- struts/struts2/trunk/plugins/codebehind/src/main/resources/struts-plugin.xml (added) +++ struts/struts2/trunk/plugins/codebehind/src/main/resources/struts-plugin.xml Sat Nov 18 21:03:10 2006 @@ -0,0 +1,12 @@ + + + + + + + + + + Added: struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/CodebehindUnknownHandlerTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/CodebehindUnknownHandlerTest.java?view=auto&rev=476709 ============================================================================== --- struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/CodebehindUnknownHandlerTest.java (added) +++ struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/codebehind/CodebehindUnknownHandlerTest.java Sat Nov 18 21:03:10 2006 @@ -0,0 +1,90 @@ +/* + * $Id: DWRValidator.java 476642 2006-11-18 22:40:18Z mrdon $ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.codebehind; + +import java.util.HashMap; + +import javax.servlet.ServletContext; + +import org.apache.struts2.StrutsTestCase; +import org.apache.struts2.config.NullResult; +import org.apache.struts2.dispatcher.ServletDispatcherResult; + +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.VoidResult; +import com.opensymphony.xwork2.config.entities.ResultTypeConfig; + +public class CodebehindUnknownHandlerTest extends StrutsTestCase { + + CodebehindUnknownHandler handler; + Mock mockServletContext; + + public void setUp() throws Exception { + super.setUp(); + mockServletContext = new Mock(ServletContext.class); + handler = new CodebehindUnknownHandler(); + handler.setConfiguration(configuration); + handler.setObjectFactory(container.getInstance(ObjectFactory.class)); + handler.setServletContext((ServletContext)mockServletContext.proxy()); + + } + + public void testBuildResult() { + ActionContext ctx = new ActionContext(new HashMap()); + ResultTypeConfig config = new ResultTypeConfig("null", SomeResult.class.getName(), "location"); + + Result result = handler.buildResult("/foo.jsp", "success", config, ctx); + assertNotNull(result); + assertTrue(result instanceof SomeResult); + assertEquals("/foo.jsp", ((SomeResult) result).location); + + } + + public void testString() { + assertEquals("foo.bar.jim", handler.string("foo", ".", "bar", ".", "jim")); + } + + public void testDeterminePath() { + assertEquals("/", handler.determinePath("/", "")); + assertEquals("/", handler.determinePath("/", null)); + assertEquals("/", handler.determinePath("/", "/")); + assertEquals("/foo/", handler.determinePath("/", "/foo")); + assertEquals("/foo/", handler.determinePath("/", "/foo/")); + assertEquals("/foo/", handler.determinePath("/", "foo")); + } + + public static class SomeResult implements Result { + + public String location; + public void setLocation(String loc) { + this.location = loc; + } + + public void execute(ActionInvocation invocation) throws Exception { + } + + } + +} Modified: struts/struts2/trunk/plugins/pom.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/pom.xml?view=diff&rev=476709&r1=476708&r2=476709 ============================================================================== --- struts/struts2/trunk/plugins/pom.xml (original) +++ struts/struts2/trunk/plugins/pom.xml Sat Nov 18 21:03:10 2006 @@ -19,6 +19,7 @@ + codebehind config-browser jasperreports jfreechart