You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2018/08/15 09:39:20 UTC

svn commit: r1838075 - in /turbine/core/trunk: ./ conf/test/ src/changes/ src/java/org/apache/turbine/ src/java/org/apache/turbine/modules/screens/ src/java/org/apache/turbine/services/avaloncomponent/ src/java/org/apache/turbine/util/ src/test/org/apa...

Author: gk
Date: Wed Aug 15 09:39:20 2018
New Revision: 1838075

URL: http://svn.apache.org/viewvc?rev=1838075&view=rev
Log:
- resolve includes in configuration file relative to configuration base
- resolve log4j relative to provided configuration path (and allowing path to be relative)
- adding tests for TurbineRequiredRole annotation and configuration
- adding MultipartConfig annotation in Turbine.java to allow parser upload
- adding plain JSON screen (TODO: integrate better as "First-class citizen")
- use ArrayList in FormMessages replacing Vector
- downgrading dependency-check version in pom.xml
- adding Jeffrey Painter as dev in pom.xml

Added:
    turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java   (with props)
    turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java   (with props)
Modified:
    turbine/core/trunk/   (props changed)
    turbine/core/trunk/conf/test/CompleteTurbineResources.properties
    turbine/core/trunk/conf/test/ConfigurationBuilder.xml
    turbine/core/trunk/conf/test/TemplateService.properties
    turbine/core/trunk/conf/test/TestFulcrumComponents.properties
    turbine/core/trunk/conf/test/TurbineConfiguration.xml
    turbine/core/trunk/conf/test/TurbineNonPersistentSchedulerServiceTest.properties
    turbine/core/trunk/conf/test/usersettings.properties
    turbine/core/trunk/pom.xml
    turbine/core/trunk/src/changes/changes.xml
    turbine/core/trunk/src/java/org/apache/turbine/Turbine.java
    turbine/core/trunk/src/java/org/apache/turbine/modules/screens/JSONScreen.java
    turbine/core/trunk/src/java/org/apache/turbine/services/avaloncomponent/TurbineYaafiComponentService.java
    turbine/core/trunk/src/java/org/apache/turbine/util/BrowserDetector.java
    turbine/core/trunk/src/java/org/apache/turbine/util/FormMessages.java
    turbine/core/trunk/src/test/org/apache/turbine/ConfigurationTest.java
    turbine/core/trunk/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java
    turbine/core/trunk/src/test/org/apache/turbine/services/LoadingComponentsTest.java

Propchange: turbine/core/trunk/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Aug 15 09:39:20 2018
@@ -1,20 +1,21 @@
-target
-cactus_client.log
-cactus_server.log
-maven.log
-velocity.log*
+*.ser
 *~
 .classpath
-.project
+.deployment
 .externalToolBuilders
-logs
-junit*.properties
-turbine-pom-snapshot-version
-*.ser
+.idea
+.project
 .settings
 Deployment
-.deployment
+cactus_client.log
+cactus_server.log
+junit*.properties
+logs
 maven-eclipse.xml
+maven.log
+target
+turbine-pom-snapshot-version
 turbine.iml
 turbine.ipr
 turbine.iws
+velocity.log*

Modified: turbine/core/trunk/conf/test/CompleteTurbineResources.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/CompleteTurbineResources.properties?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/CompleteTurbineResources.properties (original)
+++ turbine/core/trunk/conf/test/CompleteTurbineResources.properties Wed Aug 15 09:39:20 2018
@@ -23,7 +23,7 @@ pipeline.default.descriptor = /conf/turb
 #
 # -------------------------------------------------------------------
 
-log4j.file = /conf/test/Log4j.properties
+log4j.file = Log4j.properties
 
 # -------------------------------------------------------------------
 #

Modified: turbine/core/trunk/conf/test/ConfigurationBuilder.xml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/ConfigurationBuilder.xml?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/ConfigurationBuilder.xml (original)
+++ turbine/core/trunk/conf/test/ConfigurationBuilder.xml Wed Aug 15 09:39:20 2018
@@ -5,9 +5,9 @@
     <!-- Meta data about the resulting combined configuration -->
   </header>
   <override><!-- only allowed configurations are user and turbine, relative paths   -->
-    <properties config-name="user" fileName="conf/test/usersettings.properties" config-optional="true" config-forceCreate="true"/>
-    <xml fileName="conf/test/TurbineResources.xml"/>
-    <properties config-name="turbine" fileName="conf/test/TemplateService.properties" throwExceptionOnMissing="true"/>
+    <properties config-name="user" fileName="usersettings.properties" config-optional="true" config-forceCreate="true"/>
+    <xml fileName="TurbineResources.xml"/>
+    <properties config-name="turbine" fileName="TemplateService.properties" throwExceptionOnMissing="true"/>
   </override>
   <additional>
     <!-- Configuration declarations that form a union configuration, always provide a unique config-name attribute  -->

Modified: turbine/core/trunk/conf/test/TemplateService.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TemplateService.properties?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TemplateService.properties (original)
+++ turbine/core/trunk/conf/test/TemplateService.properties Wed Aug 15 09:39:20 2018
@@ -15,7 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-log4j.file = /conf/test/Log4j.properties
+log4j.file = Log4j.properties
+#log4j.file = none
+# or resolve relatively e.g. 
+#log4j.file = ../../conf/Log4j.properties
 pipeline.default.descriptor = conf/turbine-classic-pipeline.xml
 module.cache=false
 

Modified: turbine/core/trunk/conf/test/TestFulcrumComponents.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TestFulcrumComponents.properties?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TestFulcrumComponents.properties (original)
+++ turbine/core/trunk/conf/test/TestFulcrumComponents.properties Wed Aug 15 09:39:20 2018
@@ -21,7 +21,8 @@
 #
 # -------------------------------------------------------------------
 
-log4j.file = /conf/test/Log4j.properties
+log4j.file = Log4j.properties
+# context path: cft. javax.servlet.ServletContext.getResource(String)
 pipeline.default.descriptor = conf/turbine-classic-pipeline.xml
 
 

Modified: turbine/core/trunk/conf/test/TurbineConfiguration.xml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TurbineConfiguration.xml?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TurbineConfiguration.xml (original)
+++ turbine/core/trunk/conf/test/TurbineConfiguration.xml Wed Aug 15 09:39:20 2018
@@ -19,8 +19,8 @@
 -->
 
 <configuration>
-  <xml fileName="conf/test/TurbineResources.xml"/>
-  <properties fileName="conf/test/TemplateService.properties"/>
+  <xml fileName="TurbineResources.xml"/>
+  <properties fileName="TemplateService.properties"/>
 </configuration>
 
 

Modified: turbine/core/trunk/conf/test/TurbineNonPersistentSchedulerServiceTest.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TurbineNonPersistentSchedulerServiceTest.properties?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TurbineNonPersistentSchedulerServiceTest.properties (original)
+++ turbine/core/trunk/conf/test/TurbineNonPersistentSchedulerServiceTest.properties Wed Aug 15 09:39:20 2018
@@ -21,7 +21,7 @@
 #
 # -------------------------------------------------------------------
 
-log4j.file = /conf/test/Log4j.properties
+log4j.file = Log4j.properties
 
 # resource relative to context
 pipeline.default.descriptor = /conf/turbine-classic-pipeline.xml

Modified: turbine/core/trunk/conf/test/usersettings.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/usersettings.properties?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/usersettings.properties (original)
+++ turbine/core/trunk/conf/test/usersettings.properties Wed Aug 15 09:39:20 2018
@@ -1,3 +1,6 @@
+log4j.file = Log4j.properties
+# or resolve relatively 
+#log4j.file = ../../conf/Log4j.properties
 module.cache=false
-include = conf/test/testinclude.properties
+include = testinclude.properties
 

Modified: turbine/core/trunk/pom.xml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/pom.xml?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/pom.xml (original)
+++ turbine/core/trunk/pom.xml Wed Aug 15 09:39:20 2018
@@ -123,6 +123,14 @@
       <timezone />
     </developer>
     <developer>
+      <id>painter</id>
+      <name>Jeffery Painter</name>
+      <email>jeff@jivecast.com</email>
+      <url />
+      <organization />
+      <timezone />
+    </developer>
+    <developer>
       <id>mpoeschl</id>
       <name>Martin Poeschl</name>
       <email>mpoeschl@marmot.at</email>
@@ -516,7 +524,7 @@
       <plugin>
         <groupId>org.owasp</groupId>
         <artifactId>dependency-check-maven</artifactId>
-        <version>3.3.0</version><!-- requires mvn version > 3.3! For older version try to check v 3.2.1 or 3.1.2 -->
+        <version>3.1.2</version><!-- requires mvn version > 3.3! For older version try to check v 3.2.1 or 3.1.2 -->
         <executions>
            <execution>
                 <goals>

Modified: turbine/core/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/changes/changes.xml?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/changes/changes.xml (original)
+++ turbine/core/trunk/src/changes/changes.xml Wed Aug 15 09:39:20 2018
@@ -25,6 +25,10 @@
 
   <body>
     <release version="5.0" date="in Subversion">
+      <action type="update" dev="gk">
+        Configuration pathes and log4j path are now all relative to base configuration file (included from).
+        Adding screens for plain JSON
+      </action>
       <action type="update" dev="tv">
         Update dependency commons-configuration to 2.2
         Configuration pathes are now all relative to application root.

Modified: turbine/core/trunk/src/java/org/apache/turbine/Turbine.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/Turbine.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/Turbine.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/Turbine.java Wed Aug 15 09:39:20 2018
@@ -24,6 +24,9 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,6 +35,7 @@ import java.util.Properties;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.annotation.MultipartConfig;
 import javax.servlet.annotation.WebInitParam;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
@@ -42,13 +46,13 @@ import javax.xml.bind.Unmarshaller;
 import javax.xml.parsers.FactoryConfigurationError;
 
 import org.apache.commons.configuration2.Configuration;
-import org.apache.commons.configuration2.FileBasedConfiguration;
 import org.apache.commons.configuration2.PropertiesConfiguration;
 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
 import org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder;
 import org.apache.commons.configuration2.builder.fluent.Parameters;
 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
 import org.apache.commons.configuration2.io.HomeDirectoryLocationStrategy;
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.commons.logging.Log;
@@ -117,7 +121,7 @@ import org.apache.turbine.util.uri.URICo
                     value = TurbineConstants.LOGGING_ROOT_DEFAULT),
                  @WebInitParam(name = TurbineConfig.PROPERTIES_PATH_KEY,
                     value = TurbineConfig.PROPERTIES_PATH_DEFAULT) } )
-
+@MultipartConfig
 public class Turbine extends HttpServlet
 {
     /** Serial version */
@@ -184,6 +188,8 @@ public class Turbine extends HttpServlet
     {
         XML,
         PROPERTIES,
+        JSON,
+        YAML,
         UNSET
     }
 
@@ -343,34 +349,44 @@ public class Turbine extends HttpServlet
 
         // now begin loading
         Parameters params = new Parameters();
-        String confPath = new File(getApplicationRoot()).getCanonicalPath();
-
+        File confPath = new File(getApplicationRoot()); //.getCanonicalPath();
+        
+        if (confFile.startsWith( "/" ))
+        {
+            confFile = confFile.substring( 1 ); // cft. RFC2396 should not start with a slash, if not absolute path
+        }
+        
+        Path confFileRelativePath =  Paths.get( confFile );// relative to later join
+        Path targetPath = Paths.get( confPath.toURI() );
+        targetPath = targetPath.resolve( confFileRelativePath );
+        
+        confPath = targetPath.getParent().normalize().toFile();// base part, normally conf folder
+        confFile = targetPath.getFileName().toString();
+        
         switch (confStyle)
         {
             case XML:
-                if (confFile.startsWith( "/" ))
-                {
-                    confFile = confFile.substring( 1 ); // cft. RFC2396 should not start with a slash, if not absolute path
-                }
-
                 // relative base path used for this and child configuration files
                 CombinedConfigurationBuilder combinedBuilder = new CombinedConfigurationBuilder()
                     .configure(params.fileBased()
                         .setFileName(confFile)
                         .setListDelimiterHandler(new DefaultListDelimiterHandler(','))
-                        .setLocationStrategy(new HomeDirectoryLocationStrategy(confPath, false)));
+                        .setLocationStrategy(new HomeDirectoryLocationStrategy(confPath.getCanonicalPath(), false)));
                 configuration = combinedBuilder.getConfiguration();
                 break;
 
             case PROPERTIES:
-                FileBasedConfigurationBuilder<FileBasedConfiguration> propertiesBuilder =
-                    new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
+                FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder =
+                                new FileBasedConfigurationBuilder<>(
+                                                PropertiesConfiguration.class)
                     .configure(params.properties()
                         .setFileName(confFile)
                         .setListDelimiterHandler(new DefaultListDelimiterHandler(','))
-                        .setLocationStrategy(new HomeDirectoryLocationStrategy(confPath, false)));
+                        .setLocationStrategy(new HomeDirectoryLocationStrategy(confPath.getCanonicalPath(), false)));
                 configuration = propertiesBuilder.getConfiguration();
                 break;
+            case JSON: case YAML: 
+                throw new NotImplementedException("JSON or XAML configuration style not yet implemented!");
 
             default:
                 break;
@@ -378,7 +394,7 @@ public class Turbine extends HttpServlet
         //
         // Set up logging as soon as possible
         //
-        configureLogging();
+        configureLogging(targetPath);
 
         // Now report our successful configuration to the world
         log.info("Loaded configuration (" + confStyle + ") from " + confFile + " style: " + configuration.toString());
@@ -436,18 +452,27 @@ public class Turbine extends HttpServlet
 
     /**
      * Configure the logging facilities of Turbine
+     * @param targetPath 
      *
      * @throws IOException if the configuration file handling fails.
      */
-    protected void configureLogging() throws IOException
+    protected void configureLogging(Path targetPath) throws IOException
     {
         String log4jFile = configuration.getString(TurbineConstants.LOG4J_CONFIG_FILE,
                 TurbineConstants.LOG4J_CONFIG_FILE_DEFAULT);
+        
+        if (log4jFile.startsWith( "/" ))
+        {
+            log4jFile = log4jFile.substring( 1 );
+        }
+        // log4j must either share path with configuration path or resolved relatively
+        Path log4jTarget = targetPath.getParent().resolve( log4jFile ).normalize();
 
         if (StringUtils.isNotEmpty(log4jFile) &&
-                !log4jFile.equalsIgnoreCase("none"))
+                !log4jFile.equalsIgnoreCase("none") && Files.exists( log4jTarget ))
         {
-            log4jFile = getRealPath(log4jFile);
+            log4jFile = log4jTarget.toFile().getAbsolutePath();
+            
             boolean success = false;
 
             if (log4jFile.endsWith(".xml"))

Modified: turbine/core/trunk/src/java/org/apache/turbine/modules/screens/JSONScreen.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/modules/screens/JSONScreen.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/modules/screens/JSONScreen.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/modules/screens/JSONScreen.java Wed Aug 15 09:39:20 2018
@@ -99,7 +99,7 @@ public class JSONScreen extends RawScree
     /**
      * Output the dynamic content.
      *
-     * Encodign is UTF-8. @{@link #JSONRPC_CONTENT_TYPE}: {@value #JSONRPC_CONTENT_TYPE}.
+     * Encoding is UTF-8. @{@link #JSONRPC_CONTENT_TYPE}: {@value #JSONRPC_CONTENT_TYPE}.
      *
      * @param pipelineData The PipelineData object.
      */

Added: turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java?rev=1838075&view=auto
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java (added)
+++ turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java Wed Aug 15 09:39:20 2018
@@ -0,0 +1,99 @@
+package org.apache.turbine.modules.screens;
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.turbine.pipeline.PipelineData;
+import org.apache.turbine.util.RunData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Screen class for dealing with JSON requests.  Typically you would
+ * extend this class and override the doOutput() method to use it by setting the JSON output into
+ * rundata.setMessage( serialized ).
+ * As convenience you may use inject in your extended class the Turbine service JsonService
+ * Use {@link PlainJSONSecureAnnotatedScreen} if you need the user to be
+ * logged in or having a special role in prior to executing the functions you provide.
+ *
+ * <p>Here is an example from a subclass:
+ *
+ * <code>
+ * 
+ *
+ * public void doOutput(PipelineData pipelineData) throws Exception
+ * {
+ *     RunData data = getRunData(pipelineData);
+ *     JSONStrategy strategy = null;
+ *     
+ *     try
+ *     {
+ *        strategy = new XYStrategy();
+ *        // the result goes into rundata.message
+ *        strategy.execute(data, jsonService);
+ *     }
+ *       catch ( Exception e )
+ *       {
+ *          log.error( "init failed for "+strategy , e);
+ *          String msg = new JSONObject().put("error", e.getMessage()).toString();
+ *          data.setMessage( msg );
+ *       }
+ *     
+ *     super.doOutput(data);
+ * }
+ * </code>
+ *
+ *
+ * @author gk
+ * @version $Id$
+ */
+public class PlainJSONScreen extends RawScreen
+{
+    protected static final String JSON_TYPE = "application/json;charset=utf-8";
+
+    protected final static int BUFFER_SIZE = 4096;
+    
+    static final Logger log = LoggerFactory.getLogger(PlainJSONScreen.class);
+
+    /** Injected service instance */
+    //@TurbineService
+    //protected JsonService jsonService;
+
+    /**
+     * @see org.apache.turbine.modules.screens.RawScreen#getContentType(org.apache.turbine.pipeline.PipelineData)
+     */
+    @Override
+    protected String getContentType(PipelineData pipelineData)
+    {
+        return JSON_TYPE;
+    }
+
+    /**
+     * Output JSON content set into {@link RunData#getMessage()}.
+     *
+     * Encoding is UTF-8. @{@link #JSON_TYPE}: {@value #JSON_TYPE}.
+     *
+     * @param pipelineData The PipelineData object.
+     */
+    @Override
+    protected void doOutput(PipelineData pipelineData) throws Exception
+    {
+        RunData data = getRunData(pipelineData);
+       
+        HttpServletRequest request = data.getRequest();
+        // read in json!
+        String charset =  "UTF-8"; //request.getCharacterEncoding();
+        
+        String json_res =data.getMessage();
+
+        log.debug( "json_res output:" +json_res );
+        PrintWriter out = new PrintWriter(
+                new OutputStreamWriter(data.getResponse().getOutputStream(),charset));
+        out.print(json_res.toString());
+        out.flush();
+        out.close();
+    }
+}

Propchange: turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONScreen.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java?rev=1838075&view=auto
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java (added)
+++ turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java Wed Aug 15 09:39:20 2018
@@ -0,0 +1,51 @@
+package org.apache.turbine.modules.screens;
+
+import java.lang.reflect.Method;
+
+import org.apache.fulcrum.security.model.turbine.TurbineAccessControlList;
+import org.apache.turbine.annotation.AnnotationProcessor;
+import org.apache.turbine.annotation.AnnotationProcessor.ConditionType;
+import org.apache.turbine.annotation.TurbineRequiredRole;
+import org.apache.turbine.pipeline.PipelineData;
+import org.apache.turbine.util.RunData;
+
+public class PlainJSONSecureAnnotatedScreen extends PlainJSONScreen
+{
+    
+    /**
+     * This method overrides the method in JSONScreen to perform a security
+     * check prior to producing the output.
+     *
+     * @param pipelineData Turbine information.
+     * @throws Exception a generic exception.
+     */
+    @Override
+    public void doOutput(PipelineData pipelineData) throws Exception
+    {
+        if (isAuthorized(pipelineData))
+        {
+            super.doOutput(pipelineData);
+        }
+    }
+
+    /**
+     * Use this method to perform the necessary security check with Turbine annotations {@link TurbineRequiredRole} in 
+     * a newly overridden {@link #doOutput(PipelineData)} method.
+     *
+     * @param pipelineData Turbine information.
+     * @return <code>true</code> if the user is authorized to access the screen, by default it is required ACL is populated.
+     * If {@link TurbineRequiredRole} is not set, it is allowed by default 
+     * @throws Exception A generic exception.
+     */
+    protected boolean isAuthorized(PipelineData pipelineData) throws Exception {
+        RunData data = getRunData(pipelineData);
+        Method[] methods = getClass().getMethods();
+        for (Method m : methods) {
+            if (m.getName().equals( "doOutput" )) {
+                if ((TurbineAccessControlList)data.getACL() == null) return false;
+                return AnnotationProcessor.isAuthorized( m, (TurbineAccessControlList)data.getACL(), ConditionType.ANY );
+            }
+        }
+        return false;
+    }
+}

Propchange: turbine/core/trunk/src/java/org/apache/turbine/modules/screens/PlainJSONSecureAnnotatedScreen.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: turbine/core/trunk/src/java/org/apache/turbine/services/avaloncomponent/TurbineYaafiComponentService.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/services/avaloncomponent/TurbineYaafiComponentService.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/services/avaloncomponent/TurbineYaafiComponentService.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/services/avaloncomponent/TurbineYaafiComponentService.java Wed Aug 15 09:39:20 2018
@@ -135,6 +135,7 @@ public class TurbineYaafiComponentServic
             this.container = ServiceContainerFactory.create(
                 config
                 );
+            //this.container .service( manager );
         }
         catch (Exception e)
         {

Modified: turbine/core/trunk/src/java/org/apache/turbine/util/BrowserDetector.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/util/BrowserDetector.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/util/BrowserDetector.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/util/BrowserDetector.java Wed Aug 15 09:39:20 2018
@@ -1,14 +1,5 @@
 package org.apache.turbine.util;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import net.sf.uadetector.OperatingSystem;
-import net.sf.uadetector.ReadableUserAgent;
-import net.sf.uadetector.UserAgentStringParser;
-import net.sf.uadetector.VersionNumber;
-import net.sf.uadetector.service.UADetectorServiceFactory;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -28,6 +19,14 @@ import net.sf.uadetector.service.UADetec
  * under the License.
  */
 
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.uadetector.OperatingSystem;
+import net.sf.uadetector.ReadableUserAgent;
+import net.sf.uadetector.UserAgentStringParser;
+import net.sf.uadetector.VersionNumber;
+import net.sf.uadetector.service.UADetectorServiceFactory;
 /**
  * This class parses the user agent string and provides getters for
  * its parts. It uses UADetector (http://uadetector.sourceforge.net/)

Modified: turbine/core/trunk/src/java/org/apache/turbine/util/FormMessages.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/util/FormMessages.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/util/FormMessages.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/util/FormMessages.java Wed Aug 15 09:39:20 2018
@@ -1,6 +1,5 @@
 package org.apache.turbine.util;
 
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,97 +19,89 @@ package org.apache.turbine.util;
  * under the License.
  */
 
-
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Vector;
+import java.util.ArrayList;
 
 /**
- * Used for adding and accessing messages that relate to a specific
- * form and field.  Allows to query for messages by form name and
- * field name.  Used together with FormMessage class.
+ * Used for adding and accessing messages that relate to a specific form and field. Allows to query for messages by form
+ * name and field name. Used together with FormMessage class.
  *
  * @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
  * @version $Id$
  */
 public class FormMessages
 {
-    private final Hashtable<String, Vector<String>> forms_messages;
-    private final Hashtable<String, Vector<String>> fields_messages;
-    private final Hashtable<String, Vector<String>> messages_fields;
-    private final Hashtable<String, Vector<String>> forms_fields;
+    private final Hashtable<String, List<String>> forms_messages;
+
+    private final Hashtable<String, List<String>> fields_messages;
+
+    private final Hashtable<String, List<String>> messages_fields;
+
+    private final Hashtable<String, List<String>> forms_fields;
 
     /**
      * Constructor.
      */
     public FormMessages()
     {
-        forms_messages = new Hashtable<String, Vector<String>>();
-        fields_messages = new Hashtable<String, Vector<String>>();
-        messages_fields = new Hashtable<String, Vector<String>>();
-        forms_fields = new Hashtable<String, Vector<String>>();
+        forms_messages = new Hashtable<String, List<String>>();
+        fields_messages = new Hashtable<String, List<String>>();
+        messages_fields = new Hashtable<String, List<String>>();
+        forms_fields = new Hashtable<String, List<String>>();
     }
 
     /**
-     * Sets a message for a field of a form.  The message is given as
-     * a long representing a return code.
+     * Sets a message for a field of a form. The message is given as a long representing a return code.
      *
      * @param formName A String with the form name.
      * @param fieldName A String with the field name.
      * @param returnCode A long with the return code.
      */
-    public void setMessage(String formName,
-                           String fieldName,
-                           long returnCode)
+    public void setMessage( String formName, String fieldName, long returnCode )
     {
-        setMessage(formName, fieldName, String.valueOf(returnCode));
+        setMessage( formName, fieldName, String.valueOf( returnCode ) );
     }
 
     /**
-     * Sets a message for a field of a form.  The message is given as
-     * a String.
+     * Sets a message for a field of a form. The message is given as a String.
      *
      * @param formName A String with the form name.
      * @param fieldName A String with the field name.
      * @param messageName A String with the message.
      */
-    public void setMessage(String formName,
-                           String fieldName,
-                           String messageName)
+    public void setMessage( String formName, String fieldName, String messageName )
     {
         fieldName = formName + "-" + fieldName;
-        addValue(forms_messages, formName, messageName);
-        addValue(fields_messages, fieldName, messageName);
-        addValue(messages_fields, messageName, fieldName);
-        addValue(forms_fields, formName, fieldName);
+        addValue( forms_messages, formName, messageName );
+        addValue( fields_messages, fieldName, messageName );
+        addValue( messages_fields, messageName, fieldName );
+        addValue( forms_fields, formName, fieldName );
     }
 
     /**
-     * Adds a pair key/value to a table, making sure not to add
-     * duplicate keys.
+     * Adds a pair key/value to a table, making sure not to add duplicate keys.
      *
      * @param table A Hashtable.
      * @param key A String with the key.
      * @param value A String with value.
      */
-    private void addValue(Hashtable<String, Vector<String>> table,
-                          String key,
-                          String value)
+    private void addValue( Hashtable<String, List<String>> table, String key, String value )
     {
-        Vector<String> values;
+        List<String> values;
 
-        if (!table.containsKey(key))
+        if ( !table.containsKey( key ) )
         {
-            values = new Vector<String>();
-            values.addElement(value);
-            table.put(key, values);
+            values = new ArrayList<String>();
+            values.add( value );
+            table.put( key, values );
         }
         else
         {
-            values = table.get(key);
-            if (!values.contains(value))
-                values.addElement(value);
+            values = table.get( key );
+            if ( !values.contains( value ) )
+                values.add( value );
         }
     }
 
@@ -119,11 +110,11 @@ public class FormMessages
      *
      * @param table A Hashtable.
      * @param key A String with the key.
-     * @return A Vector with the pair key/value, or null.
+     * @return A List with the pair key/value, or null.
      */
-    private final Vector<String> getValues(Hashtable<String, Vector<String>> table, String key)
+    private final List<String> getValues( Hashtable<String, List<String>> table, String key )
     {
-        return table.get(key);
+        return table.get( key );
     }
 
     /**
@@ -132,26 +123,26 @@ public class FormMessages
      * @param formName A String with the form name.
      * @return A FormMessage[].
      */
-    public FormMessage[] getFormMessages(String formName)
+    public FormMessage[] getFormMessages( String formName )
     {
-        Vector<String> messages, fields;
+        List<String> messages, fields;
         String messageName, fieldName;
-        messages = getValues(forms_messages, formName);
-        if (messages != null)
+        messages = getValues( forms_messages, formName );
+        if ( messages != null )
         {
             FormMessage[] result = new FormMessage[messages.size()];
-            for (int i = 0; i < messages.size(); i++)
+            for ( int i = 0; i < messages.size(); i++ )
             {
-                result[i] = new FormMessage(formName);
-                messageName = messages.elementAt(i);
-                result[i].setMessage(messageName);
-                fields = getValues(messages_fields, messageName);
-                for (int j = 0; j < fields.size(); j++)
+                result[i] = new FormMessage( formName );
+                messageName = messages.get( i );
+                result[i].setMessage( messageName );
+                fields = getValues( messages_fields, messageName );
+                for ( int j = 0; j < fields.size(); j++ )
                 {
-                    fieldName = fields.elementAt(j);
-                    if (formHasField(formName, fieldName))
+                    fieldName = fields.get( j );
+                    if ( formHasField( formName, fieldName ) )
                     {
-                        result[i].setFieldName(fieldName);
+                        result[i].setFieldName( fieldName );
                     }
                 }
             }
@@ -167,21 +158,21 @@ public class FormMessages
      * @param fieldName A String with the field name.
      * @return A FormMessage[].
      */
-    public FormMessage[] getFormMessages(String formName, String fieldName)
+    public FormMessage[] getFormMessages( String formName, String fieldName )
     {
         String key = formName + "-" + fieldName;
 
-        Vector<String> messages = getValues(fields_messages, key);
+        List<String> messages = getValues( fields_messages, key );
         String messageName;
 
-        if (messages != null)
+        if ( messages != null )
         {
             FormMessage[] result = new FormMessage[messages.size()];
-            for (int i = 0; i < messages.size(); i++)
+            for ( int i = 0; i < messages.size(); i++ )
             {
-                result[i] = new FormMessage(formName, fieldName);
-                messageName = messages.elementAt(i);
-                result[i].setMessage(messageName);
+                result[i] = new FormMessage( formName, fieldName );
+                messageName = messages.get( i );
+                result[i].setMessage( messageName );
             }
             return result;
         }
@@ -195,13 +186,12 @@ public class FormMessages
      * @param fieldName A String with the field name.
      * @return True if form has the field.
      */
-    private boolean formHasField(String formName,
-                                 String fieldName)
+    private boolean formHasField( String formName, String fieldName )
     {
-        List<String> fields = getValues(forms_fields, formName);
-        for (Iterator<String> iter = fields.iterator(); iter.hasNext();)
+        List<String> fields = getValues( forms_fields, formName );
+        for ( Iterator<String> iter = fields.iterator(); iter.hasNext(); )
         {
-            if (fieldName.equals(iter.next().toString()))
+            if ( fieldName.equals( iter.next().toString() ) )
             {
                 return true;
             }

Modified: turbine/core/trunk/src/test/org/apache/turbine/ConfigurationTest.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/ConfigurationTest.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/ConfigurationTest.java (original)
+++ turbine/core/trunk/src/test/org/apache/turbine/ConfigurationTest.java Wed Aug 15 09:39:20 2018
@@ -34,6 +34,7 @@ import org.apache.commons.configuration2
 import org.apache.turbine.test.BaseTestCase;
 import org.apache.turbine.util.TurbineConfig;
 import org.apache.turbine.util.TurbineXmlConfig;
+import org.junit.After;
 import org.junit.Test;
 
 /**
@@ -55,6 +56,12 @@ public class ConfigurationTest extends B
 
     private TurbineConfig tc = null;
     private TurbineXmlConfig txc = null;
+    
+    @After
+    public void close() {
+        if (tc != null) tc.dispose();
+        if (txc != null) txc.dispose();
+    }
 
     @Test
     public void testCreateTurbineWithConfigurationXML() throws Exception
@@ -114,7 +121,7 @@ public class ConfigurationTest extends B
     }
 
     @Test
-    public void testCreateTurbineWithIncludedConfiguration() throws Exception
+    public void testCreateConfigurationWithIncludedConfiguration() throws Exception
     {
         String confPath = Turbine.getRealPath( "/conf/test/usersettings.properties" );
         try
@@ -133,6 +140,32 @@ public class ConfigurationTest extends B
             throw e;
         }
     }
+    
+    @Test
+    public void testCreateTurbineWithIncludedConfiguration() throws Exception
+    {
+        tc = new TurbineConfig(".", "/conf/test/usersettings.properties");
+        try
+        {
+            tc.initialize();
+            
+            Configuration configuration = Turbine.getConfiguration();
+            assertNotNull("No Configuration Object found!", configuration);
+            assertFalse("Make sure we have values", configuration.isEmpty());
+
+            String key = "scheduledjob.cache.size";
+            assertEquals("Read a config value " + key + ", received:" + configuration.getString(key), "100", configuration.getString(key));
+            String key2 ="module.cache";
+            assertEquals("Read a config value " + key2 + ", received:" + configuration.getString(key2), "false", configuration.getString(key2));
+        }
+        catch (Exception e)
+        {
+            throw e;
+        } finally
+        {
+            tc.dispose();
+        }
+    }
 
     @SuppressWarnings("boxing")
     @Test

Modified: turbine/core/trunk/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java (original)
+++ turbine/core/trunk/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java Wed Aug 15 09:39:20 2018
@@ -18,21 +18,31 @@ package org.apache.turbine.annotation;
  * specific language governing permissions and limitations
  * under the License.
  */
-
+import static org.hamcrest.CoreMatchers.any;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import java.lang.reflect.Method;
 import java.util.List;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.fulcrum.factory.FactoryService;
+import org.apache.fulcrum.security.entity.Group;
+import org.apache.fulcrum.security.entity.Role;
+import org.apache.fulcrum.security.model.turbine.TurbineAccessControlList;
+import org.apache.turbine.annotation.AnnotationProcessor.ConditionType;
 import org.apache.turbine.modules.Screen;
 import org.apache.turbine.modules.ScreenLoader;
 import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
+import org.apache.turbine.util.RunData;
 import org.apache.turbine.util.TurbineConfig;
 import org.apache.turbine.util.TurbineException;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -89,9 +99,14 @@ public class AnnotationProcessorTest
     {
         tc.dispose();
     }
+    
+    @Before
+    public void setUpBefore() throws Exception
+    {
+    }
 
     @Test
-    public void testProcess() throws TurbineException
+    public void testProcess() throws Exception
     {
         AnnotationProcessor.process(this);
 
@@ -112,6 +127,80 @@ public class AnnotationProcessorTest
         assertNotNull(screenLoader);
         assertNotNull(asb);
         assertNotNull(factory);
+        
+    }
+    
+    @TurbineRequiredRole({"user","admin"})
+    public void guardedMethoded() {
+        
+    }
+    
+    @Test
+    public void testRequiredRoleMethodProcess() throws Exception
+    {
+        RunData data = mock(RunData.class);
+        TurbineAccessControlList acl = mock(TurbineAccessControlList.class);
+        Role role = mock(Role.class);
+        when(role.getName()).thenReturn( "user" );
+        Group group = mock(Group.class);
+        when(acl.hasRole( role.getName() )).thenReturn( true );
+        when(data.getACL()).thenReturn(acl );
+                                       
+        Method[] methods = getClass().getMethods();
+        for (Method m : methods) {
+            if (m.getName().equals( "guardedMethoded" )) {
+                assertTrue( AnnotationProcessor.isAuthorized( m, (TurbineAccessControlList)data.getACL(), ConditionType.ANY ));
+                assertFalse( AnnotationProcessor.isAuthorized( m, (TurbineAccessControlList)data.getACL(), ConditionType.COMPOUND ));
+            }
+        }
+    }
+    
+    @TurbineRequiredRole({"admin"})
+    public void guardedMethodedAdmin() {
+        
+    }
+    
+    @Test
+    public void testRequiredRoleAdminMethodProcess() throws Exception
+    {
+        RunData data = mock(RunData.class);
+        TurbineAccessControlList acl = mock(TurbineAccessControlList.class);
+        Role role = mock(Role.class);
+        when(role.getName()).thenReturn( "user" );
+        Group group = mock(Group.class);
+        when(acl.hasRole( role.getName() )).thenReturn( true );
+        when(data.getACL()).thenReturn(acl );
+                                       
+        Method[] methods = getClass().getMethods();
+        for (Method m : methods) {
+            if (m.getName().equals( "guardedMethodedAdmin" )) {
+                assertFalse( AnnotationProcessor.isAuthorized( m, (TurbineAccessControlList)data.getACL(), ConditionType.ANY ));
+            }
+        }
+    }
+    
+    public void unguardedMethoded() {
+        
+    }
+    
+    @Test
+    public void testUnguardedMethodWProcessDefault() throws Exception
+    {
+        RunData data = mock(RunData.class);
+        TurbineAccessControlList acl = mock(TurbineAccessControlList.class);
+        Role role = mock(Role.class);
+        when(role.getName()).thenReturn( "user" );
+        Group group = mock(Group.class);
+        when(acl.hasRole( role.getName() )).thenReturn( false );
+        when(data.getACL()).thenReturn(acl );
+                                       
+        Method[] methods = getClass().getMethods();
+        for (Method m : methods) {
+            if (m.getName().equals( "unguardedMethoded" )) {
+                // default is true, if not annotated
+                assertTrue( AnnotationProcessor.isAuthorized( m, (TurbineAccessControlList)data.getACL(), ConditionType.ANY ));
+            }
+        }
     }
 
     @Ignore("For performance tests only") @Test

Modified: turbine/core/trunk/src/test/org/apache/turbine/services/LoadingComponentsTest.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/services/LoadingComponentsTest.java?rev=1838075&r1=1838074&r2=1838075&view=diff
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/services/LoadingComponentsTest.java (original)
+++ turbine/core/trunk/src/test/org/apache/turbine/services/LoadingComponentsTest.java Wed Aug 15 09:39:20 2018
@@ -51,6 +51,20 @@ public class LoadingComponentsTest exten
 {
     private static TurbineConfig tc = null;
 
+    @BeforeClass
+    public static void setUp() throws Exception
+    {
+        tc = new TurbineConfig(".", "/conf/test/TestFulcrumComponents.properties");
+        tc.initialize();
+    }
+    @AfterClass
+    public static void tearDown() throws Exception
+    {
+        if (tc != null)
+        {
+            tc.dispose();
+        }
+    }
 
     /**
      * Test to load a couple of Avalon services directly by the
@@ -149,19 +163,4 @@ public class LoadingComponentsTest exten
         assertEquals("ISO-8859-1", s);
     }
 
-    @BeforeClass
-    public static void setUp() throws Exception
-    {
-        tc = new TurbineConfig(".", "/conf/test/TestFulcrumComponents.properties");
-        tc.initialize();
-    }
-    @AfterClass
-    public static void tearDown() throws Exception
-    {
-        if (tc != null)
-        {
-            tc.dispose();
-        }
-    }
-
 }