From b4903d78e4b79f04f56e1e68474bce7c306d138d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sat, 4 Feb 2012 15:26:53 +0100 Subject: [PATCH] Object name validator component * Moved the component from the -user package to the -naming package * Added a separate interface to the component --- .../beans/naming/ObjectNameValidatorBean.java | 136 ++++++++++ .../resources/configuration/meta/naming.xml | 1 + .../beans/user/ObjectNameValidatorBean.java | 77 ------ .../AddAdministratorCommandDelegateBean.java | 8 +- .../player/ValidationCommandDelegateBean.java | 6 +- .../game/GetNewPlanetCommandDelegateBean.java | 6 +- .../CreateAllianceCommandDelegateBean.java | 10 +- .../RenameFleetsCommandDelegateBean.java | 8 +- .../fleets/SplitFleetCommandDelegateBean.java | 8 +- .../RenamePlanetCommandDelegateBean.java | 6 +- .../resources/configuration/meta/sessions.xml | 1 - .../naming/ObjectNameValidator.java | 55 ++++ .../naming/TestObjectNameValidatorBean.java | 249 ++++++++++++++++++ .../com/deepclone/lw/cmd/ObjectNameError.java | 16 ++ 14 files changed, 483 insertions(+), 104 deletions(-) create mode 100644 legacyworlds-server-beans-naming/src/main/java/com/deepclone/lw/beans/naming/ObjectNameValidatorBean.java delete mode 100644 legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/ObjectNameValidatorBean.java create mode 100644 legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/naming/ObjectNameValidator.java create mode 100644 legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/naming/TestObjectNameValidatorBean.java diff --git a/legacyworlds-server-beans-naming/src/main/java/com/deepclone/lw/beans/naming/ObjectNameValidatorBean.java b/legacyworlds-server-beans-naming/src/main/java/com/deepclone/lw/beans/naming/ObjectNameValidatorBean.java new file mode 100644 index 0000000..4f3b83f --- /dev/null +++ b/legacyworlds-server-beans-naming/src/main/java/com/deepclone/lw/beans/naming/ObjectNameValidatorBean.java @@ -0,0 +1,136 @@ +package com.deepclone.lw.beans.naming; + + +import java.util.regex.Pattern; + +import com.deepclone.lw.cmd.ObjectNameError; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; + + + +/** + * Object name validation component + * + *

+ * This component implements the simple name "pre-validation" component, used before an empire or + * map name is sent to the database. + * + *

+ * By default, it will accept names that are between 2 and 20 characters. That may be modified in + * the component's initialisation. + * + * @author E. Benoît + */ +class ObjectNameValidatorBean + implements ObjectNameValidator +{ + /** Default minimal length */ + public static final int MIN_LENGTH = 2; + + /** Default maximal length */ + public static final int MAX_LENGTH = 20; + + /** + * Invalid patterns + * + *

+ * This constant lists patterns which must be rejected systematically. + */ + private static final Pattern fail[] = { + Pattern.compile( "\\s\\s+" ) , Pattern.compile( "[^A-Za-z0-9 _\\'\\!\\:\\,\\-\\.\\*@\\[\\]\\{\\}]" ) + }; + + /** + * Required patterns + * + *

+ * This constant lists patters which must be present for a name to be considered valid. + */ + private static final Pattern needed[] = { + Pattern.compile( "[A-Za-z]" ) + }; + + /** Minimal length of a name */ + private int minLength = MIN_LENGTH; + + /** Maximal length of a name */ + private int maxLength = MAX_LENGTH; + + + /** + * Set the minimal length of a name + * + * @param length + * the new minimal length + */ + public void setMinLength( Integer length ) + { + this.minLength = length; + } + + + /** + * Set the maximal length of a name + * + * @param length + * the new maximal length + */ + public void setMaxLength( Integer length ) + { + this.maxLength = length; + } + + + /* + * (non-Javadoc) + * + * @see com.deepclone.lw.beans.user.ObjectNameValidator#validate(java.lang.String) + */ + @Override + public ObjectNameError validate( String name ) + { + return this.validate( name , this.minLength , this.maxLength ); + } + + + /* + * (non-Javadoc) + * + * @see com.deepclone.lw.beans.user.ObjectNameValidator#customValidate(java.lang.String, int, + * int) + */ + @Override + public ObjectNameError validate( String name , int minLength , int maxLength ) + { + if ( "".equals( name.trim( ) ) ) { + return ObjectNameError.EMPTY; + } + + // No leading or trailing spaces + if ( !name.equals( name.trim( ) ) ) { + return ObjectNameError.INVALID; + } + + // Check length + int length = name.length( ); + if ( length < minLength || length > maxLength ) { + return ObjectNameError.INVALID; + } + + // Check bad patterns + for ( Pattern p : ObjectNameValidatorBean.fail ) { + if ( p.matcher( name ).find( ) ) { + return ObjectNameError.INVALID; + } + } + + // Check good patterns + for ( Pattern p : ObjectNameValidatorBean.needed ) { + if ( !p.matcher( name ).find( ) ) { + return ObjectNameError.INVALID; + } + } + + return null; + } +} diff --git a/legacyworlds-server-beans-naming/src/main/resources/configuration/meta/naming.xml b/legacyworlds-server-beans-naming/src/main/resources/configuration/meta/naming.xml index f63e0df..4750147 100644 --- a/legacyworlds-server-beans-naming/src/main/resources/configuration/meta/naming.xml +++ b/legacyworlds-server-beans-naming/src/main/resources/configuration/meta/naming.xml @@ -4,6 +4,7 @@ xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> + diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/ObjectNameValidatorBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/ObjectNameValidatorBean.java deleted file mode 100644 index cd3bcff..0000000 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/ObjectNameValidatorBean.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.deepclone.lw.beans.user; - - -import java.util.regex.Pattern; - -import com.deepclone.lw.cmd.ObjectNameError; - - - -public class ObjectNameValidatorBean -{ - - private int minLength = 2; - private int maxLength = 20; - - private static Pattern fail[] = { - Pattern.compile( "\\s\\s+" ) , - Pattern.compile( "[^A-Za-z0-9 _\\'\\!\\:\\,\\-\\.\\*@\\[\\]\\{\\}]" ) - }; - - private static Pattern needed[] = { - Pattern.compile( "[A-Za-z]" ) - }; - - - public void setMinLength( Integer v ) - { - this.minLength = v; - } - - - public void setMaxLength( Integer v ) - { - this.maxLength = v; - } - - - public ObjectNameError validate( String name ) - { - return this.customValidate( name , this.minLength , this.maxLength ); - } - - - public ObjectNameError customValidate( String name , int minLength , int maxLength ) - { - if ( "".equals( name.trim( ) ) ) { - return ObjectNameError.EMPTY; - } - - // No leading or trailing spaces - if ( !name.equals( name.trim( ) ) ) { - return ObjectNameError.INVALID; - } - - // Check length - int length = name.length( ); - if ( length < minLength || length > maxLength ) { - return ObjectNameError.INVALID; - } - - // Check bad patterns - for ( Pattern p : ObjectNameValidatorBean.fail ) { - if ( p.matcher( name ).find( ) ) { - return ObjectNameError.INVALID; - } - } - - // Check good patterns - for ( Pattern p : ObjectNameValidatorBean.needed ) { - if ( !p.matcher( name ).find( ) ) { - return ObjectNameError.INVALID; - } - } - - return null; - } -} diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/admin/main/su/AddAdministratorCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/admin/main/su/AddAdministratorCommandDelegateBean.java index 8be8246..ee5aac1 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/admin/main/su/AddAdministratorCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/admin/main/su/AddAdministratorCommandDelegateBean.java @@ -3,7 +3,6 @@ package com.deepclone.lw.beans.user.admin.main.su; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.cmd.ObjectNameError; import com.deepclone.lw.cmd.admin.adata.Administrator; import com.deepclone.lw.cmd.admin.adata.Privileges; @@ -11,6 +10,7 @@ import com.deepclone.lw.cmd.admin.su.AddAdministratorCommand; import com.deepclone.lw.cmd.admin.su.AddAdministratorResponse; import com.deepclone.lw.cmd.admin.su.AddAdministratorResponse.AddressError; import com.deepclone.lw.interfaces.admin.Administration; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; import com.deepclone.lw.utils.EmailAddress; @@ -22,7 +22,7 @@ public class AddAdministratorCommandDelegateBean { private Administration administration; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -33,7 +33,7 @@ public class AddAdministratorCommandDelegateBean @Autowired( required = true ) - public void setValidator( ObjectNameValidatorBean validator ) + public void setValidator( ObjectNameValidator validator ) { this.validator = validator; } @@ -57,7 +57,7 @@ public class AddAdministratorCommandDelegateBean if ( "".equals( name ) ) { nameError = ObjectNameError.EMPTY; } else { - nameError = this.validator.customValidate( name , 2 , 64 ); + nameError = this.validator.validate( name , 2 , 64 ); } // Check address diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/ValidationCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/ValidationCommandDelegateBean.java index 6633bb8..7235287 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/ValidationCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/ValidationCommandDelegateBean.java @@ -3,13 +3,13 @@ package com.deepclone.lw.beans.user.player; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.cmd.ObjectNameError; import com.deepclone.lw.cmd.player.account.AccountValidationCommand; import com.deepclone.lw.cmd.player.account.AccountValidationResponse; import com.deepclone.lw.interfaces.acm.AccountManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -23,7 +23,7 @@ public class ValidationCommandDelegateBean { private AccountManagement manager; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -34,7 +34,7 @@ public class ValidationCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/GetNewPlanetCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/GetNewPlanetCommandDelegateBean.java index e59bb96..9b0add8 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/GetNewPlanetCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/GetNewPlanetCommandDelegateBean.java @@ -3,7 +3,6 @@ package com.deepclone.lw.beans.user.player.game; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.beans.user.player.GameSubTypeBean; @@ -11,6 +10,7 @@ import com.deepclone.lw.cmd.ObjectNameError; import com.deepclone.lw.cmd.player.GetNewPlanetCommand; import com.deepclone.lw.cmd.player.GetNewPlanetResponse; import com.deepclone.lw.interfaces.game.EmpireManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -23,7 +23,7 @@ public class GetNewPlanetCommandDelegateBean { private EmpireManagement empireManagement; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -34,7 +34,7 @@ public class GetNewPlanetCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/alliances/CreateAllianceCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/alliances/CreateAllianceCommandDelegateBean.java index 607054a..fbaa298 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/alliances/CreateAllianceCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/alliances/CreateAllianceCommandDelegateBean.java @@ -3,7 +3,6 @@ package com.deepclone.lw.beans.user.player.game.alliances; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.beans.user.player.GameSubTypeBean; @@ -13,6 +12,7 @@ import com.deepclone.lw.cmd.player.alliances.CreateAllianceCommand; import com.deepclone.lw.cmd.player.alliances.CreateAllianceResponse; import com.deepclone.lw.cmd.player.gdata.alliance.AllianceCreationStatus; import com.deepclone.lw.interfaces.game.AllianceManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -24,7 +24,7 @@ public class CreateAllianceCommandDelegateBean { private AllianceManagement allianceManagement; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -35,7 +35,7 @@ public class CreateAllianceCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } @@ -65,10 +65,10 @@ public class CreateAllianceCommandDelegateBean } String tag = command.getTag( ); - ObjectNameError tagError = this.validator.customValidate( tag , 2 , 5 ); + ObjectNameError tagError = this.validator.validate( tag , 2 , 5 ); String name = command.getName( ); - ObjectNameError nameError = this.validator.customValidate( name , 5 , 64 ); + ObjectNameError nameError = this.validator.validate( name , 5 , 64 ); if ( tagError != null || nameError != null ) { AllianceStatusResponse r = this.allianceManagement.getView( empireId ); diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/RenameFleetsCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/RenameFleetsCommandDelegateBean.java index 240c345..3f57dc8 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/RenameFleetsCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/RenameFleetsCommandDelegateBean.java @@ -3,13 +3,13 @@ package com.deepclone.lw.beans.user.player.game.fleets; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.beans.user.player.GameSubTypeBean; import com.deepclone.lw.cmd.player.fleets.RenameFleetsCommand; import com.deepclone.lw.cmd.player.fleets.RenameFleetsResponse; import com.deepclone.lw.interfaces.game.FleetManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -20,7 +20,7 @@ public class RenameFleetsCommandDelegateBean implements AutowiredCommandDelegate { private FleetManagement fleetManager; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -31,7 +31,7 @@ public class RenameFleetsCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } @@ -64,7 +64,7 @@ public class RenameFleetsCommandDelegateBean boolean error; if ( command.isRename( ) ) { name = command.getName( ).trim( ); - if ( !"".equals( name ) && this.validator.customValidate( name , 1 , 40 ) != null ) { + if ( !"".equals( name ) && this.validator.validate( name , 1 , 40 ) != null ) { error = true; name = null; } else { diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/SplitFleetCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/SplitFleetCommandDelegateBean.java index 3d77684..47e1a17 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/SplitFleetCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/fleets/SplitFleetCommandDelegateBean.java @@ -3,13 +3,13 @@ package com.deepclone.lw.beans.user.player.game.fleets; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.beans.user.player.GameSubTypeBean; import com.deepclone.lw.cmd.player.fleets.SplitFleetCommand; import com.deepclone.lw.cmd.player.fleets.SplitFleetResponse; import com.deepclone.lw.interfaces.game.FleetManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -20,7 +20,7 @@ public class SplitFleetCommandDelegateBean implements AutowiredCommandDelegate { private FleetManagement fleetManager; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -31,7 +31,7 @@ public class SplitFleetCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } @@ -64,7 +64,7 @@ public class SplitFleetCommandDelegateBean boolean error; if ( name != null ) { name = command.getName( ).trim( ); - if ( !"".equals( name ) && this.validator.customValidate( name , 1 , 40 ) != null ) { + if ( !"".equals( name ) && this.validator.validate( name , 1 , 40 ) != null ) { error = true; name = ""; } else { diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/RenamePlanetCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/RenamePlanetCommandDelegateBean.java index f006bee..73b07c3 100644 --- a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/RenamePlanetCommandDelegateBean.java +++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/RenamePlanetCommandDelegateBean.java @@ -3,7 +3,6 @@ package com.deepclone.lw.beans.user.player.game.planets; import org.springframework.beans.factory.annotation.Autowired; -import com.deepclone.lw.beans.user.ObjectNameValidatorBean; import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate; import com.deepclone.lw.beans.user.abst.SessionCommandHandler; import com.deepclone.lw.beans.user.player.GameSubTypeBean; @@ -12,6 +11,7 @@ import com.deepclone.lw.cmd.player.planets.RenamePlanetCommand; import com.deepclone.lw.cmd.player.planets.RenamePlanetResponse; import com.deepclone.lw.cmd.player.planets.ViewPlanetResponse; import com.deepclone.lw.interfaces.game.PlanetsManagement; +import com.deepclone.lw.interfaces.naming.ObjectNameValidator; import com.deepclone.lw.interfaces.session.ServerSession; import com.deepclone.lw.session.Command; import com.deepclone.lw.session.CommandResponse; @@ -24,7 +24,7 @@ public class RenamePlanetCommandDelegateBean { private PlanetsManagement planetsManagement; - private ObjectNameValidatorBean validator; + private ObjectNameValidator validator; @Autowired( required = true ) @@ -35,7 +35,7 @@ public class RenamePlanetCommandDelegateBean @Autowired( required = true ) - public void setObjectNameValidator( ObjectNameValidatorBean validator ) + public void setObjectNameValidator( ObjectNameValidator validator ) { this.validator = validator; } diff --git a/legacyworlds-server-beans-user/src/main/resources/configuration/meta/sessions.xml b/legacyworlds-server-beans-user/src/main/resources/configuration/meta/sessions.xml index 611aa59..b676198 100644 --- a/legacyworlds-server-beans-user/src/main/resources/configuration/meta/sessions.xml +++ b/legacyworlds-server-beans-user/src/main/resources/configuration/meta/sessions.xml @@ -4,7 +4,6 @@ xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> - diff --git a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/naming/ObjectNameValidator.java b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/naming/ObjectNameValidator.java new file mode 100644 index 0000000..12b88de --- /dev/null +++ b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/naming/ObjectNameValidator.java @@ -0,0 +1,55 @@ +package com.deepclone.lw.interfaces.naming; + + +import com.deepclone.lw.cmd.ObjectNameError; + + + +/** + * Object name validator + * + *

+ * This interface corresponds to a component which can be used to "pre-validate" the names of + * objects (empires, map objects, fleets, etc...). It does not check for banned or duplicate names. + * + * @author E. Benoît + */ +public interface ObjectNameValidator +{ + + /** + * Validate a name using the component's defaults + * + *

+ * Check the name's validity. The name must match the usual naming constraints (valid + * characters, no sequences of white space, name starts with an alphabetic character) and its + * length is checked against the component's default constraints. + * + * @param name + * the name to validate + * + * @return the validation error if one occurred, or null if the name is valid + */ + public ObjectNameError validate( String name ); + + + /** + * Validate a name using specific length constraints + * + *

+ * Check the name's validity. The name must match the usual naming constraints (valid + * characters, no sequences of white space, name starts with an alphabetic character) and its + * length is checked against the specific constraints given as arguments. + * + * @param name + * the name to validate + * @param minLength + * the minimal accepted length + * @param maxLength + * the maximal accepted length + * + * @return the validation error if one occurred, or null if the name is valid + */ + public ObjectNameError validate( String name , int minLength , int maxLength ); + +} \ No newline at end of file diff --git a/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/naming/TestObjectNameValidatorBean.java b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/naming/TestObjectNameValidatorBean.java new file mode 100644 index 0000000..1e9d197 --- /dev/null +++ b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/naming/TestObjectNameValidatorBean.java @@ -0,0 +1,249 @@ +package com.deepclone.lw.beans.naming; + + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +import com.deepclone.lw.cmd.ObjectNameError; + + + +/** + * Tests for {@link ObjectNameValidatorBean} + * + * @author E. Benoît + * + */ +public class TestObjectNameValidatorBean +{ + + /** Object name validator being tested */ + private ObjectNameValidatorBean validator; + + + /** + * Create the validator to run tests on + */ + @Before + public void setUp( ) + { + this.validator = new ObjectNameValidatorBean( ); + } + + + /** + * A string shorter than the default minimal length will cause validation to fail with the + * {@link ObjectNameError#INVALID} error on an unmodified validator. + */ + @Test + public void testDefaultMinimalLength( ) + { + String test = ""; + for ( int i = 0 ; i < ObjectNameValidatorBean.MIN_LENGTH - 1 ; i++ ) { + test += "x"; + } + + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string longer than the default maximal length will cause validation to fail with the + * {@link ObjectNameError#INVALID} error on an unmodified validator. + */ + @Test + public void testDefaultMaximalLength( ) + { + String test = ""; + for ( int i = 0 ; i < ObjectNameValidatorBean.MAX_LENGTH + 1 ; i++ ) { + test += "x"; + } + + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string shorter than a modified minimal length will cause validation to fail with the + * {@link ObjectNameError#INVALID} error. + */ + @Test + public void testMinimalLength( ) + { + String test = ""; + for ( int i = 0 ; i < 3 ; i++ ) { + test += "x"; + } + + this.validator.setMinLength( 4 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string longer than a modified maximal length will cause validation to fail with the + * {@link ObjectNameError#INVALID} error on an unmodified validator. + */ + @Test + public void testMaximalLength( ) + { + String test = ""; + for ( int i = 0 ; i < 11 ; i++ ) { + test += "x"; + } + + this.validator.setMinLength( 4 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string that's empty will cause an {@link ObjectNameError#EMPTY} error. + */ + @Test + public void testEmptyString( ) + { + String test = ""; + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.EMPTY , error ); + } + + + /** + * A string that's full of spaces will cause an {@link ObjectNameError#EMPTY} error. + */ + @Test + public void testSpacesOnlyString( ) + { + String test = " "; + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.EMPTY , error ); + } + + + /** + * An otherwise valid string that starts with spaces will cause an + * {@link ObjectNameError#INVALID} error. + */ + @Test + public void testStringStartsWithSpace( ) + { + String test = " abcde"; + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * An otherwise valid string that ends with spaces will cause an {@link ObjectNameError#INVALID} + * error. + */ + @Test + public void testStringEndsWithSpace( ) + { + String test = "abcde "; + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * An otherwise valid string that contains a sequence of two spaces will cause an + * {@link ObjectNameError#INVALID} error. + */ + @Test + public void testStringSpaceSequence( ) + { + String test = "ab cde"; + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string that contains an unsupported character will cause an {@link ObjectNameError#INVALID} + * error. + */ + @Test + public void testStringInvalidCharacter( ) + { + String test = "abcdœ"; + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * A string that does not contain any letter (but is otherwise valid) will cause an + * {@link ObjectNameError#INVALID} error. + */ + @Test + public void testStringNoLetters( ) + { + String test = "@_@12"; + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 10 ); + ObjectNameError error = this.validator.validate( test ); + assertNotNull( error ); + assertEquals( ObjectNameError.INVALID , error ); + } + + + /** + * Test validation on a "good" string + */ + @Test + public void testValidString( ) + { + this.validator.setMinLength( 1 ); + this.validator.setMaxLength( 5 ); + + ObjectNameError error = this.validator.validate( "ab12@" ); + assertNull( error ); + } + + + + /** + * Test validation with call-specific length constraints + */ + @Test + public void testLengthConstraints( ) + { + this.validator.setMinLength( 5 ); + this.validator.setMaxLength( 6 ); + + ObjectNameError error = this.validator.validate( "ab" , 2 , 10 ); + assertNull( error ); + + error = this.validator.validate( "a012345678" , 2 , 10 ); + assertNull( error ); + } + +} diff --git a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/ObjectNameError.java b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/ObjectNameError.java index 650e8fb..493c435 100644 --- a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/ObjectNameError.java +++ b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/ObjectNameError.java @@ -1,11 +1,27 @@ package com.deepclone.lw.cmd; +/** + * The results of a name validation operation + * + * @author E. Benoît + * + */ public enum ObjectNameError { + /** The name is empty */ EMPTY , + + /** The name is used by another object (e.g. duplicate empire name) */ UNAVAILABLE , + + /** The name has been banned from being used again */ BANNED , + + /** + * The name is invalid (too short, too long, sequences of white space, invalid characters, does + * not start with a letter) + */ INVALID }