diff --git a/plugins/convention/design.txt b/plugins/convention/design.txt
new file mode 100644
index 000000000..397956e45
--- /dev/null
+++ b/plugins/convention/design.txt
@@ -0,0 +1,39 @@
+Design
+
+Action with no annotations (all the default handlings)
+--------------------------
+
+Action name is class name.
+Action package is based on the either any Namespace annotations on the class or Java package the
+ action class is defined in or the Java package name and the root Java package, which is determined
+ based on the package locators or the action package list. In either case, a root package is
+ identified and the namespace is the packages below the root up to and including the package that
+ contains the action class.
+Action method is execute in all cases.
+Results are built first from the Result annotations at the class level. Next, they are built from
+ the resources available in the web application and in the classpath based on the result location,
+ namespace of the action and action name (not anything to do with the code element names). Results
+ are found for common result codes including, success, error, input, failure, etc. If a specific
+ result doesn't exist using the result code then just the action namespace and action name are used to
+ locate results. If there are still no results found, than a redirect is added back to the index
+ action for the namespace, if one exists.
+
+Action with Action(s) annotations
+---------------------------------
+
+If the annotation is located on any method other than execute, than the action configuration built
+ from the annotation is in addition to the action configuration built using the default. Unless there
+ is an annotation that contains no value, in which case, the method that annotation is defined for
+ becomes the default action method. If the annotation is defined on the execute method, regardless of
+ the value of the annotation, no default configuration is built for the class.
+If multiple annotations have no value, an error should occur.
+If multiple annotations have the same value, an error should occur.
+
+Action name is taken from the annotation value. If the value is empty, the default action name
+ is used.
+Action package is taken from the annotation value. If the annotation value doesn't start with a slash
+ character, the default action namespace is used.
+Action method is always the method that the annotation is defined on.
+Results are built first from the array of Results on the Action annotation. Next, they are built
+ from the class level Result annotations. Lastly, all default results are created. All Results already
+ created during this process should not be overridden later in the process.
diff --git a/plugins/convention/pom.xml b/plugins/convention/pom.xml
new file mode 100644
index 000000000..c330c73d0
--- /dev/null
+++ b/plugins/convention/pom.xml
@@ -0,0 +1,91 @@
+
+
+
+ * This interface defines how the action configurations for the current + * web application can be constructed. This must find all actions that + * are not specifically defined in the struts XML files or any plugins. + * Furthermore, it must make every effort to locate all action results + * as well. + *
+ */ +public interface ActionConfigBuilder { + /** + * Builds all the action configurations and stores them into the XWork configuration instance + * via XWork dependency injetion. + */ + void buildActionConfigs(); +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/ActionNameBuilder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/ActionNameBuilder.java new file mode 100644 index 000000000..89444053d --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/ActionNameBuilder.java @@ -0,0 +1,37 @@ +/* + * $Id$ + * + * 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.convention; + +/** + *+ * This interface defines the method that is used to create action + * names based on the name of a class. + *
+ */ +public interface ActionNameBuilder { + /** + * Given the name of the class, this method should build an action name. + * + * @param className The class name. + * @return The action name and never null. + */ + String build(String className); +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/ClasspathConfigurationProvider.java b/plugins/convention/src/main/java/org/apache/struts2/convention/ClasspathConfigurationProvider.java new file mode 100644 index 000000000..bc67e708f --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/ClasspathConfigurationProvider.java @@ -0,0 +1,81 @@ +/* + * $Id$ + * + * 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.convention; + +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.util.location.LocatableProperties; + +/** + *+ * This class is a configuration provider for the XWork configuration + * system. This is really the only way to truly handle loading of the + * packages, actions and results correctly. This doesn't contain any + * logic and instead delegates to the configured instance of the + * {@link ActionConfigBuilder} interface. + *
+ */ +public class ClasspathConfigurationProvider implements ConfigurationProvider { + private ActionConfigBuilder actionConfigBuilder; + + @Inject + public ClasspathConfigurationProvider(ActionConfigBuilder actionConfigBuilder) { + this.actionConfigBuilder = actionConfigBuilder; + } + + /** + * Not used. + */ + public void destroy() { + } + + /** + * Not used. + */ + public void init(Configuration configuration) { + } + + /** + * Does nothing. + */ + public void register(ContainerBuilder containerBuilder, LocatableProperties locatableProperties) + throws ConfigurationException { + } + + /** + * Loads the packages using the {@link ActionConfigBuilder}. + * + * @throws ConfigurationException + */ + public void loadPackages() throws ConfigurationException { + actionConfigBuilder.buildActionConfigs(); + } + + /** + * @return Always false. + */ + public boolean needsReload() { + return false; + } +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java b/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java new file mode 100644 index 000000000..56af1d640 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java @@ -0,0 +1,418 @@ +/* + * $Id$ + * + * 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.convention; + +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.apache.struts2.util.ClassLoaderUtils; + +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.ConfigurationException; +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.inject.Inject; +import com.opensymphony.xwork2.util.logging.Logger; +import com.opensymphony.xwork2.util.logging.LoggerFactory; + +/** + *+ * This class is the default unknown handler for all of the Convention + * plugin integration with XWork. This handles instances when a URL doesn't + * have an action associated with it but does a viable result and also the + * instance where an action returns a result code that isn't already + * configured but there is a viable result for the code. + *
+ * + *+ * This class also handles all of the index actions using redirects + * and actions in nested packages. For example, if there is an action + * /foo/index and the URL /foo is used, + * this will render the index action in the /foo namespace. + *
+ */ +public class ConventionUnknownHandler implements UnknownHandler { + private static final Logger LOG = LoggerFactory.getLogger(ConventionUnknownHandler.class); + protected Configuration configuration; + protected ObjectFactory objectFactory; + protected ServletContext servletContext; + protected ResultMapBuilder resultMapBuilder; + protected String defaultParentPackageName; + protected PackageConfig parentPackage; + + private boolean redirectToSlash; + private ConventionsService conventionsService; + private String nameSeparator; + + /** + * Constructs the unknown handler. + * + * @param configuration The XWork configuration. + * @param objectFactory The XWork object factory used to create result instances. + * @param servletContext The servlet context used to help build the action configurations. + * @param resultMapBuilder The result map builder that is used to create results. + * @param conventionsService The conventions service used to get all the conventions and + * configurations. + * @param defaultParentPackageName The default XWork package that the unknown handler will use as + * the parent package for new actions and results. + * @param redirectToSlash A boolean parameter that controls whether or not this will handle + * unknown actions in the same manner as Apache, Tomcat and other web servers. This + * handling will send back a redirect for URLs such as /foo to /foo/ if there doesn't + * exist an action that responds to /foo. + * @param nameSeparator The character used as word separator in the action names. "-" by default + */ + @Inject + public ConventionUnknownHandler(Configuration configuration, ObjectFactory objectFactory, + ServletContext servletContext, ResultMapBuilder resultMapBuilder, + ConventionsService conventionsService, + @Inject("struts.convention.default.parent.package") String defaultParentPackageName, + @Inject("struts.convention.redirect.to.slash") String redirectToSlash, + @Inject("struts.convention.action.name.separator") String nameSeparator) { + this.configuration = configuration; + this.objectFactory = objectFactory; + this.servletContext = servletContext; + this.resultMapBuilder = resultMapBuilder; + this.conventionsService = conventionsService; + this.defaultParentPackageName = defaultParentPackageName; + this.nameSeparator = nameSeparator; + + this.parentPackage = configuration.getPackageConfig(defaultParentPackageName); + if (parentPackage == null) { + throw new ConfigurationException("Unknown default parent package [" + defaultParentPackageName + "]"); + } + + this.redirectToSlash = Boolean.parseBoolean(redirectToSlash); + } + + public ActionConfig handleUnknownAction(String namespace, String actionName) + throws XWorkException { + // Strip the namespace if it is just a slash + if (namespace == null || "/".equals(namespace)) { + namespace = ""; + } + + Map+ * This interface defines the conventions that are used by the convention plugin. + * In most cases the methods on this class will provide the best default for any + * values and also handle locating overrides of the default via the annotations + * that are part of the plugin. + *
+ */ +public interface ConventionsService { + /** + * Locates the result location from annotations on the action class or the package or returns the + * default if no annotations are present. + * + * @param actionClass The action class. + * @return The result location if it is set in the annotations. Otherwise, the default result + * location is returned. + */ + String determineResultPath(Class> actionClass); + + /** + * Delegates to the other method but first looks up the Action's class using the given class name. + * + * @param actionConfig (Optional) The configuration for the action that the result is being + * built for or null if the default result path is needed. + * @return The result location if it is set in the annotations for the class of the ActionConfig. + * Otherwise, the default result location is returned. If null is passed in, the default + * is returned, + */ + String determineResultPath(ActionConfig actionConfig); + + /** + * Returns a mapping between the result type strings and the {@link ResultTypeConfig} instances + * based on the {@link PackageConfig} given. + * + * @param packageConfig The PackageConfig to get the result types for. + * @return The result types or an empty Map of nothing is configured. + */ + Map+ * This class is the implementation of the {@link ConventionsService} + * interface and provides all of the defaults and annotation handling. + *
+ */ +public class ConventionsServiceImpl implements ConventionsService { + private String resultPath; + + /** + * Constructs a new instance. + * + * @param resultPath The result path that is configured in the Struts configuration files using + * the constant name of struts.convention.result.path. + */ + @Inject + public ConventionsServiceImpl(@Inject("struts.convention.result.path") String resultPath) { + this.resultPath = resultPath; + } + + /** + * {@inheritDoc} + */ + public String determineResultPath(Class> actionClass) { + String localResultPath = resultPath; + ResultPath resultPathAnnotation = AnnotationTools.findAnnotation(actionClass, ResultPath.class); + if (resultPathAnnotation != null) { + if (resultPathAnnotation.value().equals("") && resultPathAnnotation.property().equals("")) { + throw new ConfigurationException("The ResultPath annotation must have either" + + " a value or property specified."); + } + + String property = resultPathAnnotation.property(); + if (property.equals("")) { + localResultPath = resultPathAnnotation.value(); + } else { + try { + ResourceBundle strutsBundle = ResourceBundle.getBundle("struts"); + localResultPath = strutsBundle.getString(property); + } catch (Exception e) { + throw new ConfigurationException("The action class [" + actionClass + "] defines" + + " a @ResultPath annotation and a property definition however the" + + " struts.properties could not be found in the classpath using ResourceBundle" + + " OR the bundle exists but the property [" + property + "] is not defined" + + " in the file.", e); + } + } + } + + return localResultPath; + } + + /** + * {@inheritDoc} + */ + public String determineResultPath(ActionConfig actionConfig) { + if (actionConfig == null) { + return resultPath; + } + + try { + return determineResultPath(Class.forName(actionConfig.getClassName())); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Invalid action class configuration that references an unknown " + + "class named [" + actionConfig.getClassName() + "]", e); + } + } + + /** + * {@inheritDoc} + */ + public Map+ * This class strips the word Action from the end of the class name + * and possibly lowercases the name as well depending on the value of the + * constant struts.convention.action.name.lowercase. If the + * constant is set to true, this class will lowercase all + * action names. + *
+ */ +public class DefaultActionNameBuilder implements ActionNameBuilder { + private String actionSuffix = "Action"; + private boolean lowerCase; + + @Inject + public DefaultActionNameBuilder(@Inject(value="struts.convention.action.name.lowercase") String lowerCase) { + this.lowerCase = Boolean.parseBoolean(lowerCase); + } + + /** + * @param actionSuffix (Optional) Classes that end with these value will be mapped as actions + * (defaults to "Action") + */ + @Inject(value = "struts.convention.action.suffix", required = false) + public void setActionSuffix(String actionSuffix) { + if (!StringTools.isTrimmedEmpty(actionSuffix)) { + this.actionSuffix = actionSuffix; + } + } + + public String build(String className) { + String actionName = className; + + // Truncate Action suffix if found + if (actionName.endsWith(actionSuffix)) { + actionName = actionName.substring(0, actionName.length() - actionSuffix.length()); + } + + // Force initial letter of action to lowercase, if desired + if ((lowerCase) && (actionName.length() > 1)) { + int lowerPos = actionName.lastIndexOf('/') + 1; + StringBuilder sb = new StringBuilder(); + sb.append(actionName.substring(0, lowerPos)); + sb.append(Character.toLowerCase(actionName.charAt(lowerPos))); + sb.append(actionName.substring(lowerPos + 1)); + actionName = sb.toString(); + } + + return actionName; + } +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultInterceptorMapBuilder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultInterceptorMapBuilder.java new file mode 100644 index 000000000..0eed1ea2a --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultInterceptorMapBuilder.java @@ -0,0 +1,109 @@ +/* + * $Id$ + * + * 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.convention; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.AnnotationTools; +import org.apache.struts2.convention.annotation.InterceptorRef; +import org.apache.struts2.convention.annotation.InterceptorRefs; + +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.entities.InterceptorMapping; +import com.opensymphony.xwork2.config.entities.PackageConfig; +import com.opensymphony.xwork2.config.providers.InterceptorBuilder; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.util.AnnotationUtils; +import com.opensymphony.xwork2.util.logging.Logger; +import com.opensymphony.xwork2.util.logging.LoggerFactory; + +/** + *+ * Builds interceptor mappings from annotations. + *
+ */ +public class DefaultInterceptorMapBuilder implements InterceptorMapBuilder { + private static final Logger LOG = LoggerFactory + .getLogger(DefaultInterceptorMapBuilder.class); + + private Configuration configuration; + + public List+ * This class implements the ResultMapBuilder and traverses the web + * application content directory looking for reasonably named JSPs and + * other result types as well as annotations. This naming is in this + * form: + *
+ * + *+ * /resultPath/namespace/action-<result>.jsp + *+ * + *
+ * If there are any files in these locations than a result is created + * for each one and the result names is the last portion of the file + * name up to the . (dot). + *
+ * + *+ * When results are found, new ResultConfig instances are created. The + * result config that is created has a number of thing to be aware of: + *
+ * + *+ * After loading the files in the web application, this class will then + * use any annotations on the action class to override what was found in + * the web application files. These annotations are the {@link Result} + * and {@link Results} annotations. These two annotations allow an action + * to supply different or non-forward based results for specific return + * values of an action method. + *
+ * + *+ * The result path used by this class for locating JSPs and other + * such result files can be set using the Struts2 constant named + * struts.convention.result.path or using the + * {@link org.apache.struts2.convention.annotation.ResultPath} + * annotation. + *
+ * + *+ * This class will also locate and configure Results in the classpath, + * including velocity and FreeMarker templates inside the classpath. + *
+ * + *+ * All results that are conigured from resources are given a type corresponding + * to the resources extension. The extensions and types are given in the + * table below: + *
+ * + *| Extension | Type |
|---|---|
| .jsp | dispatcher | + *
| .html | dispatcher | + *
| .htm | dispatcher | + *
| .vm | velocity | + *
| .ftl | freemarker | + *
/resultPath/actionName.
+ * @param actionName The action name which is used only for logging in this implementation.
+ * @param packageConfig The package configuration which is passed along in order to determine
+ * @param resultsByExtension The map of extensions to result type configuration instances.
+ */
+ protected void createFromResources(Class> actionClass, Map+ * This interface defines how interceptors are built from + * annotations. + *
+ */ +public interface InterceptorMapBuilder { + /** + * Builds the interceptor configurations given the action information. + * + * @param actionClass The class of the action. + * @param annotation The action annotation. + * @param actionName The action name. + * @param builder The package configuration builder. + * @return The mapping of the interceptors. If there were none found + * then this should return an empty List. + */ + List+ * This class implements the ActionConfigBuilder interface. + *
+ */ +public class PackageBasedActionConfigBuilder implements ActionConfigBuilder { + private static final Logger LOG = LoggerFactory.getLogger(PackageBasedActionConfigBuilder.class); + private final Configuration configuration; + private final ActionNameBuilder actionNameBuilder; + private final ResultMapBuilder resultMapBuilder; + private final InterceptorMapBuilder interceptorMapBuilder; + private final ObjectFactory objectFactory; + private final String defaultParentPackage; + private final boolean redirectToSlash; + private String[] actionPackages; + private String[] excludePackages; + private String[] packageLocators; + private String[] excludeJars; + private String packageLocatorsBasePackage; + private boolean disableJarScanning = true; + private boolean disableActionScanning = false; + private boolean disablePackageLocatorsScanning = false; + private String actionSuffix = "Action"; + private boolean checkImplementsAction = true; + private boolean mapAllMatches = false; + + /** + * Constructs actions based on a list of packages. + * + * @param configuration The XWork configuration that the new package configs and action configs + * are added to. + * @param actionNameBuilder The action name builder used to convert action class names to action + * names. + * @param resultMapBuilder The result map builder used to create ResultConfig mappings for each + * action. + * @param interceptorMapBuilder The interceptor map builder used to create InterceptorConfig mappings for each + * action. + * @param objectFactory The ObjectFactory used to create the actions and such. + * @param redirectToSlash A boolean parameter that controls whether or not this will create an + * action for indexes. If this is set to true, index actions are not created because + * the unknown handler will redirect from /foo to /foo/. The only action that is created + * is to the empty action in the namespace (e.g. the namespace /foo and the action ""). + * @param defaultParentPackage The default parent package for all the configuration. + */ + @Inject + public PackageBasedActionConfigBuilder(Configuration configuration, ActionNameBuilder actionNameBuilder, + ResultMapBuilder resultMapBuilder, InterceptorMapBuilder interceptorMapBuilder, ObjectFactory objectFactory, + @Inject("struts.convention.redirect.to.slash") String redirectToSlash, + @Inject("struts.convention.default.parent.package") String defaultParentPackage) { + + // Validate that the parameters are okay + this.configuration = configuration; + this.actionNameBuilder = actionNameBuilder; + this.resultMapBuilder = resultMapBuilder; + this.interceptorMapBuilder = interceptorMapBuilder; + this.objectFactory = objectFactory; + this.redirectToSlash = Boolean.parseBoolean(redirectToSlash); + + if (LOG.isTraceEnabled()) { + LOG.trace("Setting action default parent package to [#0]", defaultParentPackage); + } + + this.defaultParentPackage = defaultParentPackage; + } + + /** + * @param disableActionScanning Disable scanning for actions + */ + @Inject(value = "struts.convention.action.disableScanning", required = false) + public void setDisableActionScanning(String disableActionScanning) { + this.disableActionScanning = "true".equals(disableActionScanning); + } + + /** + * @param exlcudeJars Comma separated list of regular expressions of jars to be exluded. + * Ignored if "struts.convention.action.disableJarScanning" is true + */ + @Inject(value = "struts.convention.action.excludeJars", required = false) + public void setExcludeJars(String excludeJars) { + this.excludeJars = excludeJars.split("\\s*[,]\\s*");; + } + + /** + * @param disableJarScanning Disable scanning jar files for actions + */ + @Inject(value = "struts.convention.action.disableJarScanning", required = false) + public void setDisableJarScanning(String disableJarScanning) { + this.disableJarScanning = "true".equals(disableJarScanning); + } + + /** + * @param disableActionScanning If set to true, only the named packages will be scanned + */ + @Inject(value = "struts.convention.package.locators.disable", required = false) + public void setDisablePackageLocatorsScanning(String disablePackageLocatorsScanning) { + this.disablePackageLocatorsScanning = "true".equals(disablePackageLocatorsScanning); + } + + /** + * @param actionPackages (Optional) An optional list of action packages that this should create + * configuration for. + */ + @Inject(value = "struts.convention.action.packages", required = false) + public void setActionPackages(String actionPackages) { + if (!StringTools.isTrimmedEmpty(actionPackages)) { + this.actionPackages = actionPackages.split("\\s*[,]\\s*"); + } + } + + /** + * @param actionPackages (Optional) Map classes that implement com.opensymphony.xwork2.Action + * as actions + */ + @Inject(value = "struts.convention.action.checkImplementsAction", required = false) + public void setCheckImplementsAction(String checkImplementsAction) { + this.checkImplementsAction = "true".equals(checkImplementsAction); + } + + /** + * @param actionSuffix (Optional) Classes that end with these value will be mapped as actions + * (defaults to "Action") + */ + @Inject(value = "struts.convention.action.suffix", required = false) + public void setActionSuffix(String actionSuffix) { + if (!StringTools.isTrimmedEmpty(actionSuffix)) { + this.actionSuffix = actionSuffix; + } + } + + /** + * @param excludePackages (Optional) A list of packages that should be skipped when building + * configuration. + */ + @Inject(value = "struts.convention.exclude.packages", required = false) + public void setExcludePackages(String excludePackages) { + if (!StringTools.isTrimmedEmpty(excludePackages)) { + this.excludePackages = excludePackages.split("\\s*[,]\\s*"); + } + } + + /** + * @param packageLocators (Optional) A list of names used to find action packages. + */ + @Inject(value = "struts.convention.package.locators", required = false) + public void setPackageLocators(String packageLocators) { + this.packageLocators = packageLocators.split("\\s*[,]\\s*"); + } + + /** + * @param packageLocatorsBasePackage (Optional) If set, only packages that start with this + * name will be scanned for actions. + */ + @Inject(value = "struts.convention.package.locators.basePackage", required = false) + public void setPackageLocatorsBase(String packageLocatorsBasePackage) { + this.packageLocatorsBasePackage = packageLocatorsBasePackage; + } + + /** + * @param mapAllMatches (Optional) Map actions that match the "*${Suffix}" pattern + * even if they don't have a default method. The mapping from + * the url to the action will be delegated the action mapper. + */ + @Inject(value = "struts.convention.action.mapAllMatches", required = false) + public void setMapAllMatches(String mapAllMatches) { + this.mapAllMatches = "true".equals(mapAllMatches); + } + + /** + * Builds the action configurations by loading all classes in the packages specified by the + * property struts.convention.action.packages and then figuring out which classes implement Action + * or have Action in their name. Next, if this class is in a Java package that hasn't been + * inspected a new PackageConfig (XWork) is created for that Java package using the Java package + * name. This will contain all the ActionConfigs for all the Action classes that are discovered + * within that Java package. Next, each class is inspected for the {@link ParentPackage} + * annotation which is used to control the parent package for a specific action. Lastly, the + * {@link ResultMapBuilder} is used to create ResultConfig instances of the action. + */ + public void buildActionConfigs() { + if (!disableActionScanning ) { + if (actionPackages == null && packageLocators == null) { + throw new ConfigurationException("At least a list of action packages or action package locators " + + "must be given using one of the properties [struts.convention.action.packages] or " + + "[struts.convention.package.locators]"); + } + + if (LOG.isTraceEnabled()) { + LOG.trace("Loading action configurations"); + if (actionPackages != null) { + LOG.trace("Actions being loaded from action packages " + Arrays.asList(actionPackages)); + } + if (packageLocators != null) { + LOG.trace("Actions being loaded using package locators " + Arrays.asList(packageLocators)); + } + if (excludePackages != null) { + LOG.trace("Excluding actions from packages " + Arrays.asList(excludePackages)); + } + } + + Set+ * This class has some reflection helpers. + *
+ */ +public class ReflectionTools { + /** + * Determines if the class given contains the method. + * + * @param klass The class to check for the method. + * @param method The method name. + * @param parameterTypes The parameter types of the method. + * @return True if the method exists, false if not. + */ + public static boolean containsMethod(Class> klass, String method, Class>... parameterTypes) { + try { + klass.getMethod(method, parameterTypes); + return true; + } catch (NoSuchMethodException e) { + return false; + } + } + + /** + * Retrieves the annotation from the given method in the given class. + * + * @param klass The class. + * @param methodName The method. + * @param annotationClass The annotation to get. + * @return The annotation or null if it doesn't exist. + */ + public static+ * This interface defines how results are constructed for an Action. + * The action information is supplied and the result is a mapping of + * ResultConfig instances to the result name. + *
+ */ +public interface ResultMapBuilder { + /** + * Builds the result configurations given the action information. + * + * @param actionClass The class of the action. + * @param annotation The action annotation. + * @param actionName The action name. + * @param packageConfig The package configuration that the action will be added to. + * @return The mapping of the result names to the result configurations. If there were none found + * than this should return an empty Map. + */ + Map+ * This class converts the class name into a SEO friendly name by recognizing + * camel casing and inserting dashes. This also converts everything to + * lower case if desired. And this will also strip off the word Action + * from the class name. + *
+ */ +public class SEOActionNameBuilder implements ActionNameBuilder { + private static final Logger LOG = LoggerFactory.getLogger(SEOActionNameBuilder.class); + private String actionSuffix = "Action"; + private boolean lowerCase; + private String separator; + + @Inject + public SEOActionNameBuilder(@Inject(value="struts.convention.action.name.lowercase") String lowerCase, + @Inject(value="struts.convention.action.name.separator") String separator) { + this.lowerCase = Boolean.parseBoolean(lowerCase); + this.separator = separator; + } + + /** + * @param actionSuffix (Optional) Classes that end with these value will be mapped as actions + * (defaults to "Action") + */ + @Inject(value = "struts.convention.action.suffix", required = false) + public void setActionSuffix(String actionSuffix) { + if (!StringTools.isTrimmedEmpty(actionSuffix)) { + this.actionSuffix = actionSuffix; + } + } + + public String build(String className) { + String actionName = className; + + // Truncate Action suffix if found + if (actionName.endsWith(actionSuffix)) { + actionName = actionName.substring(0, actionName.length() - actionSuffix.length()); + } + + // Convert to underscores + char[] ca = actionName.toCharArray(); + StringBuilder build = new StringBuilder("" + ca[0]); + boolean lower = true; + for (int i = 1; i < ca.length; i++) { + char c = ca[i]; + if (Character.isUpperCase(c) && lower) { + build.append(separator); + lower = false; + } else if (!Character.isUpperCase(c)) { + lower = true; + } + + build.append(c); + } + + actionName = build.toString(); + if (lowerCase) { + actionName = actionName.toLowerCase(); + } + + if (LOG.isTraceEnabled()) { + LOG.trace("Changed action name from [#0] to [#1]", className, actionName); + } + + return actionName; + } +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/StringTools.java b/plugins/convention/src/main/java/org/apache/struts2/convention/StringTools.java new file mode 100644 index 000000000..336d9fea9 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/StringTools.java @@ -0,0 +1,86 @@ +/* + * $Id$ + * + * 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.convention; + +import java.util.HashMap; +import java.util.Map; + +import com.opensymphony.xwork2.config.ConfigurationException; + +/** + *+ * This class is a String helper. + *
+ */ +public class StringTools { + public static boolean isTrimmedEmpty(String s) { + return s == null || s.trim().length() == 0; + } + + public static String lastToken(String str, String s) { + int index = str.lastIndexOf(s); + if (index >= 0) { + return str.substring(index + 1); + } + + return str; + } + + public static boolean contains(String[] strings, String value, boolean ignoreCase) { + if (strings != null) { + for (String string : strings) { + if (string.equals(value) || (ignoreCase && string.equalsIgnoreCase(value))) + return true; + } + } + + return false; + } + + public static String upToLastToken(String str, String s) { + int index = str.lastIndexOf(s); + if (index >= 0) { + return str.substring(0, index); + } + + return ""; + } + + public static Map+ * This annotation can be used to control the URL that maps to + * a specific method in an Action class. By default, the method + * that is invoked is the execute method of the action and the + * URL is based on the package and class names. This annotation + * allows developers to change the URL or invoke a different + * method. This also allows developers to specify multiple URLs + * that will be handled by a single class or a single method. + *
+ *+ * This can also be used via the {@link Actions} annotation + * to associate multiple URLs with a single method. + *
+ *+ * Here's an example: + *
+ * + *
+ * public class MyAction implements Action {
+ * {@code @Action("/foo/bar")}
+ * public String execute() {}
+ * }
+ *
+ *
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Action {
+ String DEFAULT_VALUE = "DEFAULT_VALUE";
+
+ /**
+ * Allows actions to specify different URLs rather than the default that is based on the package
+ * and action name. This also allows methods other than execute() to be invoked or multiple URLs
+ * to map to a single class or a single method to handle multiple URLs.
+ *
+ * @return The action URL.
+ */
+ String value() default DEFAULT_VALUE;
+
+ /**
+ * Allows action methods to specifically control the results for specific return values. These
+ * results are not used for other method/URL invocations on the action. These are only used for
+ * the URL that this action is associated with.
+ *
+ * @return The results for the action.
+ */
+ Result[] results() default {};
+
+ /**
+ * Allows action methods to specify what interceptors must be applied to it.
+ * @return Interceptors to be applied to the action
+ */
+ InterceptorRef[] interceptorRefs() default {};
+
+ /**
+ * @return The parameters passed to the action. This is a list of strings that form a name/value
+ * pair chain since creating a Map for annotations is not possible. An example would be:
+ * {"key", "value", "key2", "value2"}.
+ */
+ String[] params() default {};
+
+ /**
+ * @return Maps return codes to exceptions. The "exceptions" interceptor must be applied to the action.
+ */
+ ExceptionMapping[] exceptionMappings() default {};
+}
\ No newline at end of file
diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java
new file mode 100644
index 000000000..d32549e42
--- /dev/null
+++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * 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.convention.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * + * This annotation allows for multiple {@link Action} annotations + * to be used on a single method. + *
+ * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Actions { + Action[] value() default {}; +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/AnnotationTools.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/AnnotationTools.java new file mode 100644 index 000000000..cab649fb0 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/AnnotationTools.java @@ -0,0 +1,51 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import java.lang.annotation.Annotation; + +/** + *+ * This class provides helper methods for dealing with annotations. + *
+ */ +public class AnnotationTools { + + /** + * Returns the annotation on the given class or the package of the class. This searchs up the + * class hierarchy and the package hierarchy. + * + * @param klass The class to search for the annotation. + * @param annotationClass The Class of the annotation. + * @return The annotation or null. + */ + public static+ * Adds an exception mapping to an action + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ExceptionMapping { + /** + * @return Result name + */ + String result(); + + /** + * @return Class name of the exception to be thrown + */ + String exception(); + + /** + * @return The parameters passed to the exception. This is a list of strings that form a name/value + * pair chain since creating a Map for annotations is not possible. An example would be: + *{"key", "value", "key2", "value2"}.
+ */
+ String[] params() default {};
+}
diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ExceptionMappings.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ExceptionMappings.java
new file mode 100644
index 000000000..a517b9276
--- /dev/null
+++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ExceptionMappings.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * 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.convention.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * + * This annotation allows a class to define more than one {@link ExceptionMapping} + * annotations. These exception mappings will be on all actions defined in the annotated + * class, they are not global exception mappings. + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ExceptionMappings { + /** + * @return Exception mappings + */ + ExceptionMapping[] value(); +} diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRef.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRef.java new file mode 100644 index 000000000..d427dfc89 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRef.java @@ -0,0 +1,52 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + *+ * This annotation allows an interceptor to be applied to an action. If + * this annotation is used at the class level, then the interceptor + * will be applied to all actions defined on that class, and will be applied + * before the ones defined at the method level. + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface InterceptorRef { + /** + * @return name of the interceptor or interceptor stack + */ + String value(); + + /** + * @return The parameters passed to the interceptor. This is a list of strings that form a name/value + * pair chain, since creating a Map for annotations is not possible. An example would be: + *{"key", "value", "key2", "value2"}.
+ */
+ String[] params() default {};
+}
diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRefs.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRefs.java
new file mode 100644
index 000000000..c878760ea
--- /dev/null
+++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/InterceptorRefs.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * 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.convention.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * + * This annotation allows a class to define more than one {@link InterceptorRef} + * annotations. + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface InterceptorRefs { + InterceptorRef[] value(); +} diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Namespace.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Namespace.java new file mode 100644 index 000000000..a0c4739c4 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Namespace.java @@ -0,0 +1,93 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * + *+ * This annotation defines how actions can modify the namespace + * that they are added to. This overrides the behavior of the + * Convention plugin which by default uses the package names for + * namespaces. Since XWork packages are created by the Convention + * plugin via the Java packages that the actions exist in, there + * is some tricky handling of XWork parent packages and namespaces + * of the XWork packages for the Convention plugin discovered + * actions so that two actions in the same package can specify + * different parents and namespaces without collision. + *
+ * + *+ * In order to handle this correctly, the name of the XWork + * package that actions are placed into is built using this + * format: + *
+ * + *+ * <java-package>#<parent-xwork-package>#<namespace> + *+ * + *
+ * This mechanism will guarantee that two actions in the same + * Java package can specify different parent packages (using the + * {@link org.apache.struts2.convention.annotation.ParentPackage} annotation) + * and namespaces (using this annotation). + *
+ * + *+ * The value of a Namespace annotation should specify the portion of + * the action URL between the context path and the action name. For + * example: + *
+ *
+ * @Namespace("/careers/job-postings-overview/job-postings")
+ *
+ *
+ * + * This annotation can also be placed inside the special Java file + * named package-info.java, which allows package + * level annotations. If this is used in this manner it changes the + * default namespace for all actions within that Java package. The + * search order for the namespace of a particular class is therefore: + *
+ * + *+ * This annotation allows actions to be defined in more than one {@link Namespace} + *
+ * + */ +@Target({ElementType.PACKAGE, ElementType.TYPE}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Namespaces { + Namespace[] value(); +} diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ParentPackage.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ParentPackage.java new file mode 100644 index 000000000..7a2c6f81b --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ParentPackage.java @@ -0,0 +1,78 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + *+ * This annotation allows actions to modify the parent package + * that they are using. Since XWork packages are created by + * the Convention plugin via the Java packages that the actions + * exist in, there is some tricky handling of XWork parent packages + * and namespaces of the XWork packages for discovered + * actions so that two actions in the same package can specify + * different parents and namespaces without collision. + *
+ * + *+ * In order to handle this correctly, the name of the XWork + * package that actions are placed into is built using this + * format: + *
+ * + *+ * <java-package>#<parent-xwork-package>#<namespace> + *+ * + *
+ * This mechanism will guarantee that two actions in the same + * Java package can specify different parent packages (using this + * annotation) and namespaces (using the {@link Namespace} annotation). + *
+ * + *+ * This annotation can be used directly on Action classes or + * in the package-info.java class in order + * to specify the default XWork parent package for all actions + * in the Java package. The search order for XWork parent packages + * is therefore: + *
+ * + *+ * This annotation is used to specify non-convention based results for + * the Struts convention handling. This annotation is added to a class + * and can be used to specify the result location for a specific result + * code from an action method. Furthermore, this can also be used to + * handle results only for specific action methods within an action class + * (if there are multiple). + *
+ * + *+ * When this annotation is used on an action class, it generates results + * that are applicable to all of the actions URLs defined in the class. + * These are considered global results for that class. Here is an example + * of a global result: + *
+ * + *
+ * {@code @Result(name="fail", location="failed.jsp")}
+ * public class MyAction {
+ * }
+ *
+ *
+ * + * This annotation can also be used inside an {@link Action} annotation + * on specific methods. This usage will define results for that specific + * action URL. Here is an example of an action URL specific result: + *
+ * + *
+ * {@code @Action(results={@Result(name="success", location="/", type="redirect")})}
+ * public String execute() {
+ * }
+ *
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface Result {
+ /**
+ * @return The name of the result mapping. This is the value that is returned from the action
+ * method and is used to associate a location with a return value.
+ */
+ String name();
+
+ /**
+ * @return The location of the result within the web application or anywhere on disk. This location
+ * can be relative if the type of this result is one of the pre-defined relative result
+ * types (these default to dispatcher, velocity and freemarker). Or this location can be
+ * absolute relative to the root of the web application or the classpath (since velocity
+ * and freemarker templates can be loaded via the classpath).
+ */
+ String location() default "";
+
+ /**
+ * @return The type of the result. This is usually setup in the struts.xml or struts-plugin.xml
+ * and is a simple name that is mapped to a result Class.
+ */
+ String type() default "";
+
+ /**
+ * @return The parameters passed to the result. This is a list of strings that form a name/value
+ * pair chain since creating a Map for annotations is not possible. An example would be:
+ * {"key", "value", "key2", "value2"}.
+ */
+ String[] params() default {};
+}
\ No newline at end of file
diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ResultPath.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ResultPath.java
new file mode 100644
index 000000000..320fdc72a
--- /dev/null
+++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/ResultPath.java
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * 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.convention.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * + * This annotation allows the path to the results be to changed on a class + * by class basis. This will favor the property name setting and then the + * value. + *
+ * + *+ * This is used when locating results for an action. In most cases a result + * is a JSP or some type of template (Velocity for example). In order to + * figure out which results are associated with an action, this class can be + * used to set the base directory that the Convention plugin looks at when + * trying to figure out the correct results. For example, if there is an action: + *
+ * + *+ * com.example.foo.DoSomething + *+ * + *
+ * The Convention plugin might find that the namespace is foo and the action
+ * name is do-something and will need to find the results. Using this annotation
+ * you can set the base path of the results to something like
+ * /WEB-INF/jsps so that the Convention plugin will look in the
+ * web application for files of this pattern:
+ *
+ * /WEB-INF/jsps/foo/do-something-<resultCode>.ext + *+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.PACKAGE}) +public @interface ResultPath { + /** + * @return The result path to use for this action, instead of the default. + */ + String value() default ""; + + /** + * @return The name of the property from the struts.properties file that contains the result + * path for the action that contains this annotation. This property must be set + * and the struts.properties file must exist in the root of the classpath. + */ + String property() default ""; +} \ No newline at end of file diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Results.java b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Results.java new file mode 100644 index 000000000..156ef9af5 --- /dev/null +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Results.java @@ -0,0 +1,40 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + *
+ * This annotation allows a class to define more than one {@link Result} + * annotations. + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface Results { + Result[] value(); +} \ No newline at end of file diff --git a/plugins/convention/src/main/resources/LICENSE.txt b/plugins/convention/src/main/resources/LICENSE.txt new file mode 100644 index 000000000..dd5b3a58a --- /dev/null +++ b/plugins/convention/src/main/resources/LICENSE.txt @@ -0,0 +1,174 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/plugins/convention/src/main/resources/NOTICE.txt b/plugins/convention/src/main/resources/NOTICE.txt new file mode 100644 index 000000000..cd13ec449 --- /dev/null +++ b/plugins/convention/src/main/resources/NOTICE.txt @@ -0,0 +1,5 @@ +Apache Struts +Copyright 2000-2007 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/plugins/convention/src/main/resources/struts-plugin.xml b/plugins/convention/src/main/resources/struts-plugin.xml new file mode 100644 index 000000000..4fc42efd0 --- /dev/null +++ b/plugins/convention/src/main/resources/struts-plugin.xml @@ -0,0 +1,60 @@ + + + + + ++ * This class tests the simple result map builder. + *
+ */ +public class DefaultResultMapBuilderTest extends TestCase { + public void testBuild() throws Exception { + ServletContext context = mockServletContext("/WEB-INF/location"); + + // Test with a slash + PackageConfig packageConfig = createPackageConfigBuilder("/namespace"); + DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, new ConventionsServiceImpl("/WEB-INF/location"), "dispatcher,velocity,freemarker"); + Map+ * This is a test for the package based name builder. + *
+ */ +public class PackageBasedActionConfigBuilderTest extends TestCase { + public void testActionPackages() throws MalformedURLException { + run("org.apache.struts2.convention.actions", null, null); + } + + public void testPackageLocators() throws MalformedURLException { + run(null, "actions,dontfind", null); + } + + private void run(String actionPackages, String packageLocators, String excludePackages) throws MalformedURLException { + //setup interceptors + List+ * This tests the reflection tools. + *
+ */ +public class ReflectionToolsTest extends TestCase { + public void testContainsMethod() { + assertTrue(ReflectionTools.containsMethod(this.getClass(), "testContainsMethod")); + assertFalse(ReflectionTools.containsMethod(this.getClass(), "badMethod")); + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/SEOActionNameBuilderTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/SEOActionNameBuilderTest.java new file mode 100644 index 000000000..2d9a4de22 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/SEOActionNameBuilderTest.java @@ -0,0 +1,46 @@ +/* + * $Id$ + * + * 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.convention; + +import junit.framework.TestCase; + +/** + *+ * This class tests the SEO name builder. + *
+ */ +public class SEOActionNameBuilderTest extends TestCase { + public void testBuild() throws Exception { + SEOActionNameBuilder builder = new SEOActionNameBuilder("true", "_"); + assertEquals("foo", builder.build("Foo")); + assertEquals("foo", builder.build("FooAction")); + assertEquals("foo_bar", builder.build("FooBarAction")); + assertEquals("foo_bar_baz", builder.build("FooBarBazAction")); + } + + public void testDash() throws Exception { + SEOActionNameBuilder builder = new SEOActionNameBuilder("true", "-"); + assertEquals("foo", builder.build("Foo")); + assertEquals("foo", builder.build("FooAction")); + assertEquals("foo-bar", builder.build("FooBarAction")); + assertEquals("foo-bar-baz", builder.build("FooBarBazAction")); + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/StringToolsTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/StringToolsTest.java new file mode 100644 index 000000000..811d4b8ea --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/StringToolsTest.java @@ -0,0 +1,51 @@ +/* + * $Id$ + * + * 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.convention; + +import junit.framework.TestCase; + +/** + *+ * This class tests the string tools. + *
+ */ +public class StringToolsTest extends TestCase { + public void testEmpty() { + assertTrue(StringTools.isTrimmedEmpty(null)); + assertTrue(StringTools.isTrimmedEmpty("")); + assertTrue(StringTools.isTrimmedEmpty(" ")); + assertFalse(StringTools.isTrimmedEmpty("f")); + assertFalse(StringTools.isTrimmedEmpty(" f ")); + } + + public void testLastToken() { + assertEquals("bar", StringTools.lastToken("/foo/bar", "/")); + assertEquals("baz", StringTools.lastToken("/foo/bar/baz", "/")); + assertEquals("baz", StringTools.lastToken("baz", "/")); + } + + public void testUpToLastToken() { + assertEquals("/foo", StringTools.upToLastToken("/foo/bar", "/")); + assertEquals("/foo/bar", StringTools.upToLastToken("/foo/bar/baz", "/")); + assertEquals("", StringTools.upToLastToken("/foo", "/")); + assertEquals("", StringTools.upToLastToken("foo", "/")); + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/TestInterceptor.java b/plugins/convention/src/test/java/org/apache/struts2/convention/TestInterceptor.java new file mode 100644 index 000000000..92b9fe724 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/TestInterceptor.java @@ -0,0 +1,21 @@ +package org.apache.struts2.convention; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.interceptor.AbstractInterceptor; + +public class TestInterceptor extends AbstractInterceptor { + private String string1; + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + return null; + } + + public String getString1() { + return string1; + } + + public void setString1(String string1) { + this.string1 = string1; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/DefaultResultPathAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/DefaultResultPathAction.java new file mode 100644 index 000000000..636953e43 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/DefaultResultPathAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions; + +/** + *+ * This class is a test action with the default result path. + *
+ */ +public class DefaultResultPathAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/NoAnnotationAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/NoAnnotationAction.java new file mode 100644 index 000000000..224987e03 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/NoAnnotationAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions; + +/** + *+ * This is a struts action with no annotations. + *
+ */ +public class NoAnnotationAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/Skip.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/Skip.java new file mode 100644 index 000000000..3e7e517c5 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/Skip.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * 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.convention.actions; + +import com.opensymphony.xwork2.Action; + +public class Skip implements Action { + public String execute() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNameAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNameAction.java new file mode 100644 index 000000000..5071586de --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNameAction.java @@ -0,0 +1,40 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +import org.apache.struts2.convention.annotation.Action; + +/** + *+ * This is a test action. + *
+ */ +public class ActionNameAction { + @Action("action1") + public String run1() { + return null; + } + + @Action("action2") + public String run2() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNamesAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNamesAction.java new file mode 100644 index 000000000..bded4e037 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ActionNamesAction.java @@ -0,0 +1,39 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.Actions; + +/** + *+ * This class is a test action. + *
+ */ +public class ActionNamesAction { + @Actions({ + @Action("actions1"), + @Action("actions2") + }) + public String run() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/SingleActionNameAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/SingleActionNameAction.java new file mode 100644 index 000000000..699bad1a2 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/SingleActionNameAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +import org.apache.struts2.convention.annotation.Action; + +/** + *+ * This is a test action. + *
+ */ +public class SingleActionNameAction { + @Action("action") + public String run() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestAction.java new file mode 100644 index 000000000..cfd90e40b --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +/** + *+ * This is a test action. + *
+ */ +public class TestAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestBase.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestBase.java new file mode 100644 index 000000000..3b7d83ce6 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestBase.java @@ -0,0 +1,27 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +import com.opensymphony.xwork2.ActionSupport; + +public abstract class TestBase extends ActionSupport { + +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestExtends.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestExtends.java new file mode 100644 index 000000000..074d60d5c --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/TestExtends.java @@ -0,0 +1,25 @@ +/* + * $Id$ + * + * 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.convention.actions.action; + +public class TestExtends extends TestBase { + +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/chain/ChainedAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/chain/ChainedAction.java new file mode 100644 index 000000000..f481c40d7 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/chain/ChainedAction.java @@ -0,0 +1,35 @@ +/* + * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.actions.chain; + +import org.apache.struts2.convention.annotation.Action; + +public class ChainedAction { + @Action("foo") + public String foo() { + return "bar"; + } + + @Action("foo-bar") + public String bar() { + return null; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/SingleActionNameAction2.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/SingleActionNameAction2.java new file mode 100644 index 000000000..703ba9898 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/SingleActionNameAction2.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.defaultinterceptor; + +import org.apache.struts2.convention.annotation.Action; + +/** + *+ * This is a test action. + *
+ */ +public class SingleActionNameAction2 implements com.opensymphony.xwork2.Action{ + @Action("action345") + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/package-info.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/package-info.java new file mode 100644 index 000000000..fc05e762a --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/defaultinterceptor/package-info.java @@ -0,0 +1,22 @@ +/* + * $Id$ + * + * 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. + */ +@org.apache.struts2.convention.annotation.DefaultInterceptorRef("validationWorkflowStack") +package org.apache.struts2.convention.actions.defaultinterceptor; \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsActionLevelAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsActionLevelAction.java new file mode 100644 index 000000000..4e7fc49c5 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsActionLevelAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.exception; + +import org.apache.struts2.convention.annotation.ExceptionMapping; +import org.apache.struts2.convention.annotation.ExceptionMappings; + +@ExceptionMappings({ + @ExceptionMapping(exception = "NPE1", result = "success"), + @ExceptionMapping(exception = "NPE2", result = "success", params = {"param1", "val1"}) +}) +public class ExceptionsActionLevelAction { + + public String execute() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsMethodLevelAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsMethodLevelAction.java new file mode 100644 index 000000000..925cf8f1e --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/exception/ExceptionsMethodLevelAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.exception; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.ExceptionMapping; + +public class ExceptionsMethodLevelAction { + + @Action(value = "exception1", exceptionMappings = { + @ExceptionMapping(exception = "NPE1", result = "success"), + @ExceptionMapping(exception = "NPE2", result = "success", params = {"param1", "val1"}) + }) + public String run1() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/Index.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/Index.java new file mode 100644 index 000000000..124306a91 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/Index.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * 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.convention.actions.idx; + +import com.opensymphony.xwork2.Action; + +public class Index implements Action { + public String execute() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/idx2/Index.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/idx2/Index.java new file mode 100644 index 000000000..e4388bd10 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/idx/idx2/Index.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * 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.convention.actions.idx.idx2; + +import com.opensymphony.xwork2.Action; + +public class Index implements Action { + public String execute() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor2Action.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor2Action.java new file mode 100644 index 000000000..80705942a --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor2Action.java @@ -0,0 +1,42 @@ +/* + * $Id: ActionLevelResultAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.actions.interceptor; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.InterceptorRef; +import org.apache.struts2.convention.annotation.InterceptorRefs; + +/** + *+ * This is a test action with 2 interceptors at the action level. + *
+ */ +@InterceptorRefs({ + @InterceptorRef("interceptor-1"), + @InterceptorRef("interceptor-2") +}) +public class ActionLevelInterceptor2Action { + + @Action(value = "action800") + public String run1() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor3Action.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor3Action.java new file mode 100644 index 000000000..37f429ca9 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptor3Action.java @@ -0,0 +1,42 @@ +/* + * $Id: ActionLevelResultAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.actions.interceptor; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.InterceptorRef; +import org.apache.struts2.convention.annotation.InterceptorRefs; + +/** + *+ * This is a test action with 1 interceptor and 1 stack at the action level. + *
+ */ +@InterceptorRefs({ + @InterceptorRef("interceptor-1"), + @InterceptorRef("stack-1") +}) +public class ActionLevelInterceptor3Action { + + @Action(value = "action900") + public String run1() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptorAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptorAction.java new file mode 100644 index 000000000..474fc62c4 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/ActionLevelInterceptorAction.java @@ -0,0 +1,48 @@ +/* + * $Id: ActionLevelResultAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.actions.interceptor; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.InterceptorRef; + +/** + *+ * This is a test action with one interceptor at the action level. + *
+ */ +@InterceptorRef("interceptor-1") +public class ActionLevelInterceptorAction { + + @Action(value = "action500") + public String run1() throws Exception { + return null; + } + + @Action(value = "action600", interceptorRefs = @InterceptorRef("interceptor-2")) + public String run2() throws Exception { + return null; + } + + @Action(value = "action700", interceptorRefs = @InterceptorRef("stack-1")) + public String run3() throws Exception { + return null; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/InterceptorsAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/InterceptorsAction.java new file mode 100644 index 000000000..40150e6d4 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/interceptor/InterceptorsAction.java @@ -0,0 +1,51 @@ +/* + * $Id: ActionLevelResultAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.actions.interceptor; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.InterceptorRef; + +/** + *+ * This is a test action with multiple interceptors. + *
+ */ +public class InterceptorsAction { + @Action(value = "action100", interceptorRefs = @InterceptorRef("interceptor-1")) + public String run1() { + return null; + } + + @Action(value = "action200", interceptorRefs = @InterceptorRef("stack-1")) + public String run2() { + return null; + } + + @Action(value = "action300", interceptorRefs = {@InterceptorRef("interceptor-1"), @InterceptorRef("interceptor-2")}) + public String run3() { + return null; + } + + @Action(value = "action400", interceptorRefs = {@InterceptorRef("interceptor-1"), @InterceptorRef("stack-1")}) + public String run4() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ActionLevelNamespaceAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ActionLevelNamespaceAction.java new file mode 100644 index 000000000..908c8cec5 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ActionLevelNamespaceAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace; + +import org.apache.struts2.convention.annotation.Action; + +/** + *+ * This class uses the action level annotation override. + *
+ */ +public class ActionLevelNamespaceAction { + @Action("/action-level/action") + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ClassLevelNamespaceAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ClassLevelNamespaceAction.java new file mode 100644 index 000000000..e73e4078c --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/ClassLevelNamespaceAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace; + +import org.apache.struts2.convention.annotation.Namespace; + +/** + *+ * This class uses the class level annotation override. + *
+ */ +@Namespace("/class-level") +public class ClassLevelNamespaceAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/PackageLevelNamespaceAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/PackageLevelNamespaceAction.java new file mode 100644 index 000000000..88447a39a --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/PackageLevelNamespaceAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace; + +/** + *+ * This class uses the package level annotation. + *
+ */ +public class PackageLevelNamespaceAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/package-info.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/package-info.java new file mode 100644 index 000000000..e90de8e05 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace/package-info.java @@ -0,0 +1,22 @@ +/* + * $Id$ + * + * 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. + */ +@org.apache.struts2.convention.annotation.Namespace("/package-level") +package org.apache.struts2.convention.actions.namespace; \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace2/DefaultNamespaceAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace2/DefaultNamespaceAction.java new file mode 100644 index 000000000..153246362 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace2/DefaultNamespaceAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace2; + +/** + *+ * This class uses the package level annotation. + *
+ */ +public class DefaultNamespaceAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace3/ActionLevelNamespacesAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace3/ActionLevelNamespacesAction.java new file mode 100644 index 000000000..1d1d0b956 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace3/ActionLevelNamespacesAction.java @@ -0,0 +1,34 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace3; + +import org.apache.struts2.convention.annotation.Namespace; +import org.apache.struts2.convention.annotation.Namespaces; + +@Namespaces({ + @Namespace("/namespaces1"), + @Namespace("/namespaces2") +}) +public class ActionLevelNamespacesAction { + public String execute() { + return null; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/ActionAndPackageLevelNamespacesAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/ActionAndPackageLevelNamespacesAction.java new file mode 100644 index 000000000..61ac8d76c --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/ActionAndPackageLevelNamespacesAction.java @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * 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.convention.actions.namespace4; + +import org.apache.struts2.convention.annotation.Namespace; +import org.apache.struts2.convention.annotation.Namespaces; + +@Namespaces({ + @Namespace("/namespaces3") +}) +public class ActionAndPackageLevelNamespacesAction { + public String execute() { + return null; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/package-info.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/package-info.java new file mode 100644 index 000000000..07407a7f0 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/namespace4/package-info.java @@ -0,0 +1,22 @@ +/* + * $Id$ + * + * 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. + */ +@org.apache.struts2.convention.annotation.Namespace("/namespaces4") +package org.apache.struts2.convention.actions.namespace4; \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/params/ActionParamsMethodLevelAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/params/ActionParamsMethodLevelAction.java new file mode 100644 index 000000000..3ee2dbecb --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/params/ActionParamsMethodLevelAction.java @@ -0,0 +1,49 @@ +/* + * $Id$ + * + * 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.convention.actions.params; + +import org.apache.struts2.convention.annotation.Action; + +public class ActionParamsMethodLevelAction { + private String param1; + private String param2; + + @Action(value = "actionParam1", params = {"param1", "val1", "param2", "val2"}) + public String run1() throws Exception { + return null; + } + + public String getParam1() { + return param1; + } + + public void setParam1(String param1) { + this.param1 = param1; + } + + public String getParam2() { + return param2; + } + + public void setParam2(String param2) { + this.param2 = param2; + } +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/ClassLevelParentPackageAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/ClassLevelParentPackageAction.java new file mode 100644 index 000000000..bcabeb942 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/ClassLevelParentPackageAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.parentpackage; + +import org.apache.struts2.convention.annotation.ParentPackage; + +/** + *+ * This is a parent package usage action. + *
+ */ +@ParentPackage("class-level") +public class ClassLevelParentPackageAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/PackageLevelParentPackageAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/PackageLevelParentPackageAction.java new file mode 100644 index 000000000..ebe3f1706 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/PackageLevelParentPackageAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions.parentpackage; + +/** + *+ * This is a parent package usage action. + *
+ */ +public class PackageLevelParentPackageAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/package-info.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/package-info.java new file mode 100644 index 000000000..434b24d28 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/parentpackage/package-info.java @@ -0,0 +1,23 @@ +/* + * $Id$ + * + * 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. + */ +@org.apache.struts2.convention.annotation.ParentPackage("package-level") +package org.apache.struts2.convention.actions.parentpackage; + diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultAction.java new file mode 100644 index 000000000..bf188cf9a --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultAction.java @@ -0,0 +1,38 @@ +/* + * $Id$ + * + * 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.convention.actions.result; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.Result; + +/** + *+ * This is a test action with multiple results. + *
+ */ +public class ActionLevelResultAction { + @Action(results = { + @Result(name="success", location="/WEB-INF/location/namespace/action-success.jsp") + }) + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultsAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultsAction.java new file mode 100644 index 000000000..27d1a5ad3 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ActionLevelResultsAction.java @@ -0,0 +1,41 @@ +/* + * $Id$ + * + * 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.convention.actions.result; + +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.Result; + +/** + *+ * This is a test action with multiple results. + *
+ */ +public class ActionLevelResultsAction { + @Action(results = { + @Result(name="error", location="error.jsp"), + @Result(name="input", location="foo.action", type="redirectAction"), + @Result(name="success", location="/WEB-INF/location/namespace/action-success.jsp"), + @Result(name="failure", location="/WEB-INF/location/namespace/action-failure.jsp") + }) + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultAction.java new file mode 100644 index 000000000..91fe4debc --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.result; + +import org.apache.struts2.convention.annotation.Result; + +/** + *+ * This is a test action with multiple results. + *
+ */ +@Result(name="error", location="error.jsp", params={"key", "value", "key1", "value1"}) +public class ClassLevelResultAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultsAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultsAction.java new file mode 100644 index 000000000..8e28f04e4 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/ClassLevelResultsAction.java @@ -0,0 +1,41 @@ +/* + * $Id$ + * + * 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.convention.actions.result; + +import org.apache.struts2.convention.annotation.Result; +import org.apache.struts2.convention.annotation.Results; + +/** + *+ * This is a test action with multiple results. + *
+ */ +@Results({ + @Result(name="error", location="error.jsp", params={"key", "ann-value", "key1", "ann-value1"}), + @Result(name="input", location="foo.action", type="redirectAction"), + @Result(name="success", location="/WEB-INF/location/namespace/action-success.jsp"), + @Result(name="failure", location="/WEB-INF/location/namespace/action-failure.jsp") +}) +public class ClassLevelResultsAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/ClassLevelResultPathAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/ClassLevelResultPathAction.java new file mode 100644 index 000000000..67d4d16ea --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/ClassLevelResultPathAction.java @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * 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.convention.actions.resultpath; + +import org.apache.struts2.convention.annotation.ResultPath; + +/** + *+ * This class is a test action with the default result path. + *
+ */ +@ResultPath("/class-level") +public class ClassLevelResultPathAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/PackageLevelResultPathAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/PackageLevelResultPathAction.java new file mode 100644 index 000000000..473eeac8e --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/PackageLevelResultPathAction.java @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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.convention.actions.resultpath; + +/** + *+ * This class is a test action with the default result path. + *
+ */ +public class PackageLevelResultPathAction { + public String execute() { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/package-info.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/package-info.java new file mode 100644 index 000000000..b4af5a0a2 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/resultpath/package-info.java @@ -0,0 +1,23 @@ +/* + * $Id$ + * + * 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. + */ +@org.apache.struts2.convention.annotation.ResultPath("/package-level") +package org.apache.struts2.convention.actions.resultpath; + diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/skip/Index.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/skip/Index.java new file mode 100644 index 000000000..987be9358 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/skip/Index.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * 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.convention.actions.skip; + +import com.opensymphony.xwork2.Action; + +public class Index implements Action { + public String execute() throws Exception { + return null; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/annotation/AnnotationToolsTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/annotation/AnnotationToolsTest.java new file mode 100644 index 000000000..94b307ed0 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/annotation/AnnotationToolsTest.java @@ -0,0 +1,45 @@ +/* + * $Id$ + * + * 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.convention.annotation; + +import junit.framework.TestCase; + +import org.apache.struts2.convention.actions.namespace.PackageLevelNamespaceAction; +import org.apache.struts2.convention.actions.resultpath.ClassLevelResultPathAction; + +/** + *+ * This class tests the annotation tools. + *
+ */ +public class AnnotationToolsTest extends TestCase { + public void testFindAnnotationOnClass() { + ResultPath rl = AnnotationTools.findAnnotation(ClassLevelResultPathAction.class, ResultPath.class); + assertNotNull(rl); + assertEquals("/class-level", rl.value()); + } + + public void testFindAnnotationOnPackage() { + Namespace ns = AnnotationTools.findAnnotation(PackageLevelNamespaceAction.class, Namespace.class); + assertNotNull(ns); + assertEquals("/package-level", ns.value()); + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/dontfind/DontFindMeAction.java b/plugins/convention/src/test/java/org/apache/struts2/convention/dontfind/DontFindMeAction.java new file mode 100644 index 000000000..11baeaba2 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/dontfind/DontFindMeAction.java @@ -0,0 +1,31 @@ +/* + * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $ + * + * 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.convention.dontfind; + +import org.apache.struts2.convention.annotation.Action; + +//should never be found by the scanner +public class DontFindMeAction { + @Action("foo") + public String foo() { + return "bar"; + } +} \ No newline at end of file diff --git a/plugins/convention/src/test/resources/WEB-INF/component/no-annotation-foo.ftl b/plugins/convention/src/test/resources/WEB-INF/component/no-annotation-foo.ftl new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/convention/src/test/resources/WEB-INF/component/no-annotation.ftl b/plugins/convention/src/test/resources/WEB-INF/component/no-annotation.ftl new file mode 100644 index 000000000..e69de29bb