Hi all, i have had the same problem as the user in the forwarded message, and found out that the problem ist within village and the different handling of sql timestamps between mysql 4.0 and 4.1. So I have modified the torque-security-schema.xml file to have default values for modified, created and last_login to be set to 01.01.1970 00:00:00.
Another modification is to the Intake Service. I have found that the handling of default validators is wrong, if no rules are defined for a specific field. I.e. Fields of Type boolean should get the BooleanValidator as the default validator. This is just the case if you have more than one rule assigned to it, which is a bug in my eyes. Another bug was within TurbineURI which set the String "null" if the String was "", which is in most cases unwanted behavior. I have added tests to all my modifications plus I have created a test to test the intake validators. Hopefully correctly. The patch is against the TURBINE_2_3_2 Branch, because I don't know in which State HEAD is at the moment. Kind regards Juergen Hoffmann
--- Begin Message --- We have seen this problem since migrating the mysql driver to the com.mysql version. In our case, changes to the application logic took care of the problem. Specifically, we would need to call setDateCreated() on the user object.The problem may actually be in torque rather than turbine since the default (not specified in the schema) is set to '0000-00-00 00:00:00' for both the CREATED and the LAST_LOGIN columns in TURBINE_USER.cheers, h. On Jun 9, 2006, at 2:38 AM, Wohlschlaeger, Fabian wrote:5h work and i found the error.Turbine setted some timestamps in the turbine-user table 0000-00-00 00:00:00 and this couldn't be converted to a timestamp, so Torque, which is used by TurbineSecurity, throws an exception. I hope u are able to fix the bug withmy explanation. Nice Greetings Fabian Wohlschlänger--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] !EXCUBATOR:1,4489896d37021813263684!
--- End Message ---
Index: /home/buddy/workspace/TURBINE_2_3_2/conf/test/TurbineResourcesWithIntake.properties =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/conf/test/TurbineResourcesWithIntake.properties (revision 0) +++ /home/buddy/workspace/TURBINE_2_3_2/conf/test/TurbineResourcesWithIntake.properties (revision 0) @@ -0,0 +1,710 @@ +# ------------------------------------------------------------------- +# $Id: TurbineResources.properties 278819 2005-09-05 21:24:56 +0200 (Mo, 05 Sep 2005) henning $ +# +# This is the configuration file for Turbine. +# +# Note that strings containing "," (comma) characters must backslash +# escape the comma (i.e. '\,') +# +# ------------------------------------------------------------------- + +# Copyright 2001-2005 The Apache Software Foundation. +# +# Licensed 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. + +# ------------------------------------------------------------------- +# +# L O G 4 J - L O G G I N G +# +# ------------------------------------------------------------------- + +log4j.file = conf/test/Log4j.properties + +# ------------------------------------------------------------------- +# +# M A I L S E R V E R +# +# ------------------------------------------------------------------- +# Your mail server for outgoing email. +# +# Default: null +# ------------------------------------------------------------------- + +mail.server= + +# ------------------------------------------------------------------- +# SMTP-From header for your outgoing messages +# +# All failed delivery messages will be returned to this address. +# If unset, these messages will be sent to the address in the +# From header (standard behaviour) +# +# Default: null +# ------------------------------------------------------------------- + +mail.smtp.from= + +# ------------------------------------------------------------------- +# +# M O D U L E C A C H I N G +# +# ------------------------------------------------------------------- +# This determines whether or not to cache the modules in memory. For +# development, turn this off. For production, turn this on. +# +# Default: false +# ------------------------------------------------------------------- + +module.cache=false + +# If module.cache=true, then how large should we make the hashtables +# by default. + +action.cache.size=20 +layout.cache.size=10 +navigation.cache.size=10 +page.cache.size=5 +screen.cache.size=50 +scheduledjob.cache.size=10 + +# ------------------------------------------------------------------- +# +# M O D U L E P A C K A G E S +# +# ------------------------------------------------------------------- +# This is the "classpath" for Turbine. In order to locate your own +# modules, you should add them to this path. For example, if you have +# com.company.actions, com.company.screens, com.company.navigations, +# then this setting would be "com.company,org.apache.turbine.modules". +# This path is searched in order. For example, Turbine comes with a +# screen module named "Login". If you wanted to have your own screen +# module named "Login", then you would specify the path to your +# modules before the others. +# +# Note: org.apache.turbine.modules will always be added to the search +# path. If it is not explictly added here, it will be added to the +# end. +# +# Default: org.apache.turbine.modules +# ------------------------------------------------------------------- + +module.packages=org.apache.turbine.modules + +# ------------------------------------------------------------------- +# +# F R A M E W O R K S E T T I N G S +# +# ------------------------------------------------------------------- +# These are settings that control the behaviour of the framework, +# such as determining whether a template system is in use, what +# the default templates and screens are and session handling settings. +# ------------------------------------------------------------------- + +# Used to set the template homepage if you are using a template +# layout. This is the template that will be displayed to the user +# when no specific template is requested. This is normally executed +# as the first template the user sees when they access the system. +# +# Default: Index.vm + +template.homepage=Index.vm + +# This is the default screen to show to people when they first access +# the system. This is only used if there is no value for +# template.homepage. This is for use when you are not using a +# templating system such as Velocity or JSP. +# +# Default: Login + +screen.homepage= + +# This is the template that is shown on an incorrect login attempt. +# Setting this property will override any value of screen.login specfied +# below. +# +# Default: Login.vm + +template.login=Login.vm + +# This is the page that is shown on an incorrect login attempt. It is +# referenced in the LoginUser action. This is only used if there is no value +# for template.login. This is for use when you are not using a +# templating system such as Velocity or JSP. +# +# Default: Login + +screen.login= + +# This is the template that is used by the respective Template based +# ErrorScreen for displaying the error. If you are not using a Template based +# ErrorScreen, then this is ignored. +# +# Default: Error.vm + +template.error=Error.vm + +# This is the default error screen. +# +# Default: VelocityErrorScreen + +screen.error=VelocityErrorScreen + +# This is the screen that is displayed when the user's web page is in +# an invalid state. +# +# Default: error.InvalidState + +screen.invalidstate=error.InvalidState + +# Set the default Doctype. The default Doctype can be set by using +# the single strings: Html40Strict, Html40Transitional, or +# Html40Frameset. Additionally the default can be supplied as two +# strings separated by a comma giving the DTD and URI. +# +# Default: ignored if not set to some value. + +default.doctype=Html40Transitional + +# This is the default action to log a user in. If you write your own +# implementation of the login action, make sure that you change this +# to reflect the new name. + +action.login=LoginUser + +# This is the default action to log a user out. If you write your own +# implementation of the logout action, make sure that you change this +# to reflect the new name. + +action.logout=LogoutUser + +# This is the default action to validate whether or not a session is +# valid. For example, if you want to make sure if a user has already +# logged in or not. +# +# Default: SessionValidator + +# action.sessionvalidator=sessionvalidator.TemplateSessionValidator +# +# Use this setting if you want your application to display the Login Screen +# as first action and does not allow any operation before the user has +# logged in +# +action.sessionvalidator=sessionvalidator.TemplateSecureSessionValidator + +# This is the timeout in seconds for sessions. If left commented out, the +# servlet container's default timeout will be left as is. + +# session.timeout=1800 + +# This is the default action that builds up the AccessControlList for +# the individual users session. + +action.accesscontroller=AccessController + +# +# Set this value to true if you want to be able to submit multiple +# events to an Action by doing eventSubmit_do<action> and consider +# only events that have a non-empty, non-zero value. This is useful +# if you submit your form with JavaScript +# +action.eventsubmit.needsvalue = true + +# ------------------------------------------------------------------- +# +# J N D I C O N T E X T S +# +# ------------------------------------------------------------------- + +# This indicates whether Turbine should try to create JNDI contexts. +# +# Default: false +# +# contexts=true + +# These are the JNDI context properties. Each context's properties +# are defined by the properties beginning with context.name. +# +# Default: none +# +# Example: The following will create a JNDI context named "name" in +# the data.contexts Hashtable. It will point at the RMI registry on +# localhost running on port 1099, and will use +# com.sun.jndi.rmi.registry.RegistryContextFactory as the initial +# context factory: +# +# context.name.java.naming.provider.url=rmi://localhost:1099 +# context.name.java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory + +# ------------------------------------------------------------------- +# +# S E C U R E S O C K E T S L A Y E R +# +# ------------------------------------------------------------------- +# Whether the web server is able to use SSL. Links in Turbine can +# check this property to determine if SSL can be used. +# +# Default: true +# ------------------------------------------------------------------- + +use.ssl=false + +# ------------------------------------------------------------------- +# +# S E R V I C E S +# +# ------------------------------------------------------------------- +# Classes for Turbine Services should be defined here. +# Format: services.[name].classname=[implementing class] +# +# To specify properties of a service use the following syntax: +# service.[name].[property]=[value] +# +# The order that these services is listed is important! The +# order that is stated here is the order in which the services +# will be initialized. Keep this is mind if you have services +# that depend on other services during initialization. +# ------------------------------------------------------------------- +services.AvalonComponentService.classname=org.apache.turbine.services.avaloncomponent.TurbineAvalonComponentService +services.CryptoService.classname=org.apache.turbine.services.crypto.TurbineCryptoService +# services.ComponentService.classname=org.apache.turbine.services.component.TurbineComponentService +services.FactoryService.classname=org.apache.turbine.services.factory.TurbineFactoryService +services.PoolService.classname=org.apache.turbine.services.pool.TurbinePoolService +services.RunDataService.classname=org.apache.turbine.services.rundata.TurbineRunDataService +services.ServletService.classname=org.apache.turbine.services.servlet.TurbineServletService +services.AssemblerBrokerService.classname=org.apache.turbine.services.assemblerbroker.TurbineAssemblerBrokerService +services.GlobalCacheService.classname=org.apache.turbine.services.cache.TurbineGlobalCacheService +services.PullService.classname=org.apache.turbine.services.pull.TurbinePullService +services.IntakeService.classname=org.apache.turbine.services.intake.TurbineIntakeService +services.TemplateService.classname=org.apache.turbine.services.template.TurbineTemplateService +services.VelocityService.classname=org.apache.turbine.services.velocity.TurbineVelocityService +services.UploadService.classname=org.apache.turbine.services.upload.TurbineUploadService +services.SecurityService.classname=org.apache.turbine.services.security.torque.TorqueSecurityService + + +# ------------------------------------------------------------------- +# +# R U N D A T A S E R V I C E +# +# ------------------------------------------------------------------- +# Default implementations of base interfaces for request processing. +# Additional configurations can be defined by using other keys +# in the place of the <default> key. +# ------------------------------------------------------------------- + +services.RunDataService.default.run.data=org.apache.turbine.services.rundata.DefaultTurbineRunData +services.RunDataService.default.parameter.parser=org.apache.turbine.util.parser.DefaultParameterParser +services.RunDataService.default.cookie.parser=org.apache.turbine.util.parser.DefaultCookieParser + +# ------------------------------------------------------------------- +# +# C A C H E S E R V I C E +# +# ------------------------------------------------------------------- + +# Interval at which the cache will be checked. The default is +# 5000ms or 5 seconds. + +services.GlobalCacheService.cache.check.frequency = 5000 + +# ------------------------------------------------------------------- +# +# A S S E M B L E R B R O K E R S E R V I C E +# +# ------------------------------------------------------------------- +# A list of AssemblerFactory classes that will be registered +# with TurbineAssemblerBrokerService +# ------------------------------------------------------------------- + +services.AssemblerBrokerService.screen=org.apache.turbine.services.assemblerbroker.util.java.JavaScreenFactory +services.AssemblerBrokerService.action=org.apache.turbine.services.assemblerbroker.util.java.JavaActionFactory +services.AssemblerBrokerService.layout=org.apache.turbine.services.assemblerbroker.util.java.JavaLayoutFactory +services.AssemblerBrokerService.page=org.apache.turbine.services.assemblerbroker.util.java.JavaPageFactory +services.AssemblerBrokerService.navigation=org.apache.turbine.services.assemblerbroker.util.java.JavaNavigationFactory +services.AssemblerBrokerService.scheduledjob=org.apache.turbine.services.assemblerbroker.util.java.JavaScheduledJobFactory + +# ------------------------------------------------------------------- +# +# T E M P L A T E S E R V I C E +# +# ------------------------------------------------------------------- + +# Roughly, the number of templates in each category. +# +# Defaults: layout=2, navigation=10, screen=50 + +services.TemplateService.layout.cache.size=2 +services.TemplateService.navigation.cache.size=10 +services.TemplateService.screen.cache.size=50 + +# ------------------------------------------------------------------- +# +# P U L L S E R V I C E +# +# ------------------------------------------------------------------- +# These are the properties for the Pull Service, the service +# that works in conjuction with the Turbine Pull Model API. +# ------------------------------------------------------------------- + +services.PullService.earlyInit= true + +# This determines whether the non-request tools are refreshed +# on each request (request tools aren't ever, because they're +# instantiated for the request only anyway). +services.PullService.tools.per.request.refresh=true +services.PullService.tools.resources.dir = /turbine-resources/ + +# These are tools that are placed in the context by the service +# These tools will be made available to all your +# templates. You list the tools in the following way: +# +# tool.<scope>.<id> = <classname> +# +# <scope> is the tool scope: global, request, session +# or persistent (see below for more details) +# <id> is the name of the tool in the context +# +# You can configure the tools in this way: +# tool.<id>.<parameter> = <value> +# +# So if you find "global", "request", "session" or "persistent" as second +# part, it is a configuration to put a tool into the toolbox, else it is a +# tool specific configuration. +# +# For example: +# +# tool.global.ui = org.apache.turbine.util.pull.UIManager +# tool.global.mm = org.apache.turbine.util.pull.MessageManager +# tool.request.link = org.apache.turbine.util.template.TemplateLink +# tool.request.page = org.apache.turbine.util.template.TemplatePageAttributes +# +# Then: +# +# tool.ui.skin = default +# +# configures the value of "skin" for the "ui" tool. +# +# Tools are accessible in all templates by the <id> given +# to the tool. So for the above listings the UIManager would +# be available as $ui, the MessageManager as $mm, the TemplateLink +# as $link and the TemplatePageAttributes as $page. +# +# You should avoid using tool names called "global", "request", +# "session" or "persistent" because of clashes with the possible Scopes. +# +# Scopes: +# +# global: tool is instantiated once and that instance is available +# to all templates for all requests. Tool must be threadsafe. +# +# request: tool is instantiated once for each request (although the +# PoolService is used to recycle instances). Tool need not +# be threadsafe. +# +# session: tool is instantiated once for each user session, and is +# stored in the user's temporary hashtable. Tool should be +# threadsafe. +# +# persistent: tool is instantitated once for each use session, and +# is stored in the user's permanent hashtable. This means +# for a logged in user the tool will be persisted in the +# user's objectdata. Tool should be threadsafe and +# Serializable. +# +# Defaults: none + +tool.request.link=org.apache.turbine.services.pull.tools.TemplateLink +tool.request.page=org.apache.turbine.util.template.HtmlPageAttributes +tool.request.content=org.apache.turbine.services.pull.tools.ContentTool + +tool.global.ui = org.apache.turbine.services.pull.util.UIManager + +tool.ui.dir.skin = /turbine-skins/ +tool.ui.dir.image = /turbine-images/ +tool.ui.skin = myskin +tool.ui.css = skins.css + +# This pull tool is to allow for easy formatting of Date object into Strings +tool.request.dateFormatter=org.apache.turbine.services.pull.util.DateFormatter + +# Use this tool if you need a place to store data that will persist between +# requests. Any data stored using this tool will be stored in the session. +tool.session.sessionData=org.apache.turbine.services.pull.util.SessionData + +# These are intake tools. +# tool.request.om=org.apache.turbine.om.OMTool +tool.request.intake=org.apache.turbine.services.intake.IntakeTool + +# This is a tool that allows access to the scheduler service. +# tool.request.scheduler=org.apache.turbine.services.SchedulerTool + +# +# The content tool can put its URIs through the Servlet container, +# which might attach things like the jsessionid even to URIs that +# are not servered by the container. +# +# The default behaviour was not to put these through the container. +# +# Set this to true if you need things like jsessionid attached to all +# links generated from the $content pull tool. +# +tool.content.want.encoding = false + +# +# Both the link and the content tool normally return absolute URIs +# You can change this by exchanging the tool classes but this is not +# really recommended. Setting these properties to true allow you +# to change the behaviour if you want only relative URIs (e.g. if you +# run behind a reverse proxy or a load balancer). +# +tool.content.want.relative = true +tool.link.want.relative = true + +# ------------------------------------------------------------------- +# +# V E L O C I T Y S E R V I C E +# +# ------------------------------------------------------------------- + +services.VelocityService.earlyInit= true + +# The location of Velocity configuration file, relative to webapp root +# These properties will override the default properties set by Velocity. +# You should specify the path to the templates directories as well as +# the path to the log file and they should also be relative to webapp root + +services.VelocityService.template.extension=vm +services.VelocityService.default.page = VelocityPage +services.VelocityService.default.screen = VelocityScreen +services.VelocityService.default.layout = VelocityOnlyLayout +services.VelocityService.default.navigation = VelocityNavigation +services.VelocityService.default.error.screen = VelocityErrorScreen +services.VelocityService.default.layout.template = Default.vm + +services.VelocityService.runtime.log=/logs/velocity.log +# services.VelocityService.input.encoding=UTF-8 + +# +# Class Path Loader, Turbine jar +services.VelocityService.velocimacro.library = macros/TurbineMacros.vm + +# Set the following line to true to cause velocity to automatically reload +# library macro files if they change. This is useful for debugging. +services.VelocityService.velocimacro.library.autoreload = true + +services.VelocityService.resource.loader = file +services.VelocityService.file.resource.loader.description = Velocity File Resource Loader +services.VelocityService.file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader +services.VelocityService.file.resource.loader.path = /templates +services.VelocityService.file.resource.loader.cache = false +services.VelocityService.file.resource.loader.modificationCheckInterval = 2 + +services.VelocityService.resource.loader = classpath +services.VelocityService.classpath.resource.loader.description = Velocity Classpath Resource Loader +services.VelocityService.classpath.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader + +# ------------------------------------------------------------------- +# +# U P L O A D S E R V I C E +# +# ------------------------------------------------------------------- + +# Whether the files should be automatically picked up by +# ParameterParser. + +services.UploadService.earlyinit=true + +services.UploadService.automatic=true + +# +# The directory where files will be temporarily stored. +# +services.UploadService.repository=. + +# +# The maximum size of a request that will be processed. +# +services.UploadService.size.max=1048576 + +# +# The maximum size of a request that will have it's elements cached in +# memory by TurbineUploadService class. +# +services.UploadService.size.threshold=10240 + +# ------------------------------------------------------------------- +# +# C R Y P T O S E R V I C E +# +# ------------------------------------------------------------------- + +# +# Standard Unix crypt(3) password encryption. +# +services.CryptoService.algorithm.unix = org.apache.turbine.services.crypto.provider.UnixCrypt +# +# This providers allows access to the Java Message Digest encryption algorithms +# +services.CryptoService.algorithm.java = org.apache.turbine.services.crypto.provider.JavaCrypt +# +# This is a simple, cleartext "encryption" provider. +# +services.CryptoService.algorithm.cleartext = org.apache.turbine.services.crypto.provider.ClearCrypt +# +# Use this provider if you upgrade from Turbine 2.1 to current. It provides bug-to-bug +# compatibility for passwords created with the old Security Service. See the javadocs for +# OldJavaCrypt +# +services.CryptoService.algorithm.oldjava = org.apache.turbine.services.crypto.provider.OldJavaCrypt +# +# This is the default crypto provider. It implements the normal Java MessageDigest ciphers +# You need not to have this, it is the default if no algorithms are given. The default +# provider gives you all the Java MessageDigest Ciphers +# +services.CryptoService.algorithm.default = org.apache.turbine.services.crypto.provider.JavaCrypt + +# ------------------------------------------------------------------- +# +# S E C U R I T Y S E R V I C E +# +# ------------------------------------------------------------------- + +# This is the class that implements the ACL interface. +services.SecurityService.acl.class = org.apache.turbine.util.security.TurbineAccessControlList + +# +# This is used by the SecurityService to make the password checking +# secure. When enabled, passwords are transformed by a one-way +# function into a sequence of bytes that is base64 encoded. +# It is impossible to guess the plain-text form of the password +# from the representation. When user logs in, the entered password +# is transformed the same way and then compared with stored value. +# +# Default: false +# +services.SecurityService.secure.passwords=false + +# +# This property lets you choose what digest algorithm will be used +# for encrypting passwords. Check documentation of your JRE for +# available algorithms. +# +# Default: SHA +# +services.SecurityService.secure.passwords.algorithm=SHA + +services.SecurityService.user.manager = org.apache.turbine.services.security.torque.TorqueUserManager + +services.SecurityService.torque.user.class = org.apache.turbine.services.security.torque.om.TurbineUser +services.SecurityService.torque.group.class = org.apache.turbine.services.security.torque.om.TurbineGroup +services.SecurityService.torque.role.class = org.apache.turbine.services.security.torque.om.TurbineRole +services.SecurityService.torque.permission.class = org.apache.turbine.services.security.torque.om.TurbinePermission + +services.SecurityService.user.class = org.apache.turbine.services.security.torque.TorqueUser +services.SecurityService.group.class = org.apache.turbine.services.security.torque.TorqueGroup +services.SecurityService.permission.class = org.apache.turbine.services.security.torque.TorquePermission +services.SecurityService.role.class = org.apache.turbine.services.security.torque.TorqueRole + +# ------------------------------------------------------------------- +# +# P O O L S E R V I C E +# +# ------------------------------------------------------------------- + +# Default capacity of pools of the Object pooling service. +# +# Default: 128 +services.PoolService.pool.capacity = 128 + +# Class specific capacities used instead of the default if specified. +# +# services.PoolService.pool.capacity.org.apache.turbine.services.rundata.DefaultTurbineRunData=512 + +# ------------------------------------------------------------------- +# +# F A C T O R Y S E R V I C E +# +# ------------------------------------------------------------------- + +# A comma separated list of classloaders (very optional) +# +# Example: org.foo.bar.MyClassLoader, org.ack.joe.YourClassLoader +# +# services.FactoryService.class.loaders= + +# Customized factories to be used instead of the default factory. +# E.g. to instantiate XML parsers, SSL sockets, etc., which require +# specific instantiation not supported by the default factory. +# The property name is prefixed with "factory" followed by the +# name of the production class. The value is the class name of +# the factory implementing the Factory interface. The factory +# will be instantiated by using the service itself. +# +# Examples: +# +# services.FactoryService.factory.javax.xml.parsers.DocumentBuilder=org.foo.xml.DomBuilderFactory +# services.FactoryService.factory.javax.xml.parsers.SAXParser=org.foo.xml.SaxParserFactory +# services.FactoryService.factory.java.net.ServerSocket=org.foo.net.SslServerSocketFactory + +# -------------------------------------------------------------------- +# +# P A R A M E T E R P A R S E R +# +# -------------------------------------------------------------------- +# +# This variable controls the case folding applied to URL variable +# names. +# +# Allowed values: none, lower, upper +# Default: lower +# + +url.case.folding=lower + +# ------------------------------------------------------------------- +# +# A V A L O N C O M P O N E N T S E R V I C E +# +# ------------------------------------------------------------------- +# Components implementing the Avalon lifecycle interfaces can be loaded, +# configured and initialized by Turbine +# ------------------------------------------------------------------- + +# +# Name and location to the configuration file for the components. +# +services.AvalonComponentService.componentConfiguration = conf/test/componentTorqueConfiguration.xml + +# +# Name and location to the configuration file for the component roles. +# +services.AvalonComponentService.componentRoles = conf/test/roleTorqueConfiguration.xml + +# +# Names of the Components to start right at Service init time +services.AvalonComponentService.lookup = org.apache.torque.avalon.Torque + +# ------------------------------------------------------------------- +# +# A D D I T I O N A L P R O P E R T I E S +# +# ------------------------------------------------------------------- +# The full path name to an additional properties file. Properties in +# this file will be included in this property set. Duplicate name +# values will be replaced, so be careful. +# +# Default: none +# ------------------------------------------------------------------- + + + +services.IntakeService.xml.path = conf/test/intake.xml Index: /home/buddy/workspace/TURBINE_2_3_2/conf/test/intake.xml =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/conf/test/intake.xml (revision 0) +++ /home/buddy/workspace/TURBINE_2_3_2/conf/test/intake.xml (revision 0) @@ -0,0 +1,13 @@ +<!DOCTYPE input-data SYSTEM + "http://jakarta.apache.org/turbine/dtd/intake_2_3.dtd"> +<input-data> + <group name="BooleanTest" key="bt"> + <field name="EmptyBooleanTestField" key="ebtf" type="boolean" /> + <field name="BooleanTestField" key="btf" type="boolean"> + <rule value="false" name="required">ValidValue</rule> + </field> + <field name="RequiredBooleanTestField" key="rbtf" type="boolean"> + <rule value="true" name="required">ValidValue</rule> + </field> + </group> +</input-data> \ No newline at end of file Index: /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/services/intake/model/Field.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/services/intake/model/Field.java (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/services/intake/model/Field.java (working copy) @@ -49,6 +49,8 @@ * @author <a href="mailto:[email protected]>Daniel Rall</a> * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> * @author <a href="mailto:[EMAIL PROTECTED]">Quinton McCombs</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Jürgen Hoffmann</a> + * * @version $Id$ */ public abstract class Field @@ -198,7 +200,7 @@ } String validatorClassName = field.getValidator(); - if (validatorClassName == null && field.getRules().size() > 0) + if (validatorClassName == null) { validatorClassName = getDefaultValidator(); } @@ -884,7 +886,24 @@ try { - setter.invoke(obj, valArray); + /** + * In the case we map a Group to an Object using mapToObject, and we want to add an + * additional Field which should not be mapped, and we leave the mapToProperty empty, + * we will get a NPE here. So we have to double check, if we really have a setter set. + */ + if(setter != null) + { + setter.invoke(obj, valArray); + } + else + { + if (isDebugEnabled) + { + log.debug(name + ": has a null setter for the mapToProperty Attribute, although all Fields should be mapped " + + "to " + mapToObject + ". If this is unwanted, You should doublecheck the mapToProperty Attribute, and " + + "consult the logs. The Turbine Intake Serice will have logged a detailed Message with the error."); + } + } } catch (IllegalAccessException e) { Index: /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/BaseURI.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/BaseURI.java (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/BaseURI.java (working copy) @@ -38,6 +38,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> * @author <a href="mailto:[EMAIL PROTECTED]">Quinton McCombs</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Jürgen Hoffmann</a> * @version $Id$ */ Index: /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TemplateURI.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TemplateURI.java (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TemplateURI.java (working copy) @@ -265,7 +265,7 @@ for(Iterator it = pp.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); - + if (!key.equalsIgnoreCase(CGI_ACTION_PARAM) && !key.equalsIgnoreCase(CGI_SCREEN_PARAM) && !key.equalsIgnoreCase(CGI_TEMPLATE_PARAM)) @@ -271,9 +271,16 @@ !key.equalsIgnoreCase(CGI_TEMPLATE_PARAM)) { String[] values = pp.getStrings(key); - for (int i = 0; i < values.length; i++) + if(values != null) { - add(type, key, values[i]); + for (int i = 0; i < values.length; i++) + { + add(type, key, values[i]); + } + } + else + { + add(type, key, ""); } } } Index: /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TurbineURI.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TurbineURI.java (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/java/org/apache/turbine/util/uri/TurbineURI.java (working copy) @@ -43,6 +43,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a> * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Jürgen Hoffmann</a> * @version $Id$ */ @@ -779,9 +780,14 @@ if(StringUtils.isEmpty(val)) { - // Fixme? log.debug("Found a null value for " + key); - output.append("null"); + /** + * We have found a value that is either either empty ("") or null. + * To keep the Framework from magically editing values, and HTTP does not treat key=null as + * an empty value, but as a key with the value "null", we should set its value to "", even if the + * Value was null. + */ + output.append(""); } else { @@ -840,9 +846,16 @@ !key.equalsIgnoreCase(CGI_SCREEN_PARAM)) { String[] values = pp.getStrings(key); - for (int i = 0; i < values.length; i++) + if(values != null) { - add(type, key, values[i]); + for (int i = 0; i < values.length; i++) + { + add(type, key, values[i]); + } + } + else + { + add(type, key, ""); } } } Index: /home/buddy/workspace/TURBINE_2_3_2/src/schema/torque-security-schema.xml =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/schema/torque-security-schema.xml (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/schema/torque-security-schema.xml (working copy) @@ -28,6 +28,7 @@ <!-- users and security. --> <!-- ==================================================================== --> <!-- @author: <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> --> +<!-- @author: <a href="mailto:[EMAIL PROTECTED]">Jürgen Hoffmann</a> --> <!-- @version $Id$ --> <!-- ==================================================================== --> @@ -84,9 +85,9 @@ <column name="LAST_NAME" required="true" size="64" type="VARCHAR"/> <column name="EMAIL" size="64" type="VARCHAR"/> <column name="CONFIRM_VALUE" size="16" type="VARCHAR" javaName="Confirmed"/> - <column name="MODIFIED" type="TIMESTAMP"/> - <column name="CREATED" type="TIMESTAMP" javaName="CreateDate"/> - <column name="LAST_LOGIN" type="TIMESTAMP"/> + <column name="MODIFIED" type="TIMESTAMP" default="00000000000000000" /> + <column name="CREATED" type="TIMESTAMP" javaName="CreateDate" default="00000000000000000" /> + <column name="LAST_LOGIN" type="TIMESTAMP" default="00000000000000000" /> <column name="OBJECTDATA" type="VARBINARY"/> <unique> Index: /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/services/intake/IntakeServiceTest.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/services/intake/IntakeServiceTest.java (revision 0) +++ /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/services/intake/IntakeServiceTest.java (revision 0) @@ -0,0 +1,70 @@ +/* + * This Class and its content are copyrighted by the + * ByteAction GmbH + * + * Created on 12.06.2006 + * + */ +package org.apache.turbine.services.intake; + +import junit.framework.TestSuite; + +import org.apache.commons.configuration.BaseConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.turbine.services.ServiceManager; +import org.apache.turbine.services.TurbineServices; +import org.apache.turbine.services.intake.model.Field; +import org.apache.turbine.services.intake.model.Group; +import org.apache.turbine.services.intake.validator.BooleanValidator; +import org.apache.turbine.test.BaseTurbineTest; +import org.apache.turbine.util.parser.ParserUtils; + + +public class IntakeServiceTest extends BaseTurbineTest +{ + + Group booleanTestGroup = null; + + public IntakeServiceTest(String name) throws Exception + { + super(name, "conf/test/TurbineResourcesWithIntake.properties"); + + ServiceManager serviceManager = TurbineServices.getInstance(); + IntakeService intakeService = (IntakeService) serviceManager.getService(IntakeService.SERVICE_NAME); + booleanTestGroup = intakeService.getGroup("BooleanTest"); + } + + + public void testEmptyBooleanField() throws IntakeException + { + Field booleanField = booleanTestGroup.get("EmptyBooleanTestField"); + assertTrue("The Default Validator of an intake Field type boolean should be BooleanValidator", (booleanField.getValidator() instanceof BooleanValidator)); + assertFalse("An Empty intake Field type boolean should not be required", booleanField.isRequired()); + } + + public void testBooleanField() throws IntakeException + { + Field booleanField = booleanTestGroup.get("BooleanTestField"); + assertTrue("The Default Validator of an intake Field type boolean should be BooleanValidator", (booleanField.getValidator() instanceof BooleanValidator)); + assertFalse("An intake Field type boolean, which is not required, should not be required", booleanField.isRequired()); + } + + public void testRequiredBooleanField() throws IntakeException + { + Field booleanField = booleanTestGroup.get("RequiredBooleanTestField"); + assertTrue("The Default Validator of an intake Field type boolean should be BooleanValidator", (booleanField.getValidator() instanceof BooleanValidator)); + assertTrue("An intake Field type boolean, which is required, should be required", booleanField.isRequired()); + } + + /** + * Factory method for creating a TestSuite for this class. + * + * @return the test suite + */ + public static TestSuite suite() + { + TestSuite suite = new TestSuite(IntakeServiceTest.class); + return suite; + } + +} Index: /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/util/uri/TurbineURITest.java =================================================================== --- /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/util/uri/TurbineURITest.java (revision 412877) +++ /home/buddy/workspace/TURBINE_2_3_2/src/test/org/apache/turbine/util/uri/TurbineURITest.java (working copy) @@ -20,10 +20,9 @@ import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; - import org.apache.turbine.services.ServiceManager; import org.apache.turbine.services.TurbineServices; -import org.apache.turbine.test.BaseTestCase; +import org.apache.turbine.test.BaseTurbineTest; import org.apache.turbine.util.ServerData; import org.apache.turbine.util.parser.ParserUtils; @@ -33,7 +32,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Quinton McCombs</a> * @version $Id$ */ -public class TurbineURITest extends BaseTestCase +public class TurbineURITest extends BaseTurbineTest { private TurbineURI turi; @@ -45,7 +44,7 @@ public TurbineURITest(String testName) throws Exception { - super(testName); + super(testName, "conf/test/TurbineResources.properties"); // Setup configuration ServiceManager serviceManager = TurbineServices.getInstance(); @@ -107,5 +106,19 @@ assertEquals("TurbineURI must not have a queryData", false, turi.hasQueryData()); assertEquals("TurbineURI must not have a pathInfo", false, turi.hasPathInfo()); } + + public void testEmptyStringInPathInfo() + { + turi.addPathInfo("testpathinfo", ""); + assertEquals("If we get an empty parameter, the value should be \"\" instead of null", "/context/servlet/turbine/testpathinfo/", turi.getRelativeLink()); + assertEquals("If we get an empty parameter, the value should be \"\" instead of null", "http://www.testserver.com/context/servlet/turbine/testpathinfo/", turi.getAbsoluteLink()); + } + public void testEmptyStringInQueryData() + { + turi.addQueryData("testquerydata", ""); + assertEquals("If we get an empty parameter, the value should be \"\" instead of null", "/context/servlet/turbine?testquerydata=", turi.getRelativeLink()); + assertEquals("If we get an empty parameter, the value should be \"\" instead of null", "http://www.testserver.com/context/servlet/turbine?testquerydata=", turi.getAbsoluteLink()); + } + }
pgpFYRppqmHas.pgp
Description: PGP signature
