Merge pull request #2 from myrle-krantz/develop

ApplicationName parameter validation.
diff --git a/src/main/java/io/mifos/core/lang/validation/CheckApplicationName.java b/src/main/java/io/mifos/core/lang/validation/CheckApplicationName.java
new file mode 100644
index 0000000..74f9d76
--- /dev/null
+++ b/src/main/java/io/mifos/core/lang/validation/CheckApplicationName.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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.
+ */
+package io.mifos.core.lang.validation;
+
+import io.mifos.core.lang.ApplicationName;
+import io.mifos.core.lang.validation.constraints.ValidApplicationName;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Myrle Krantz
+ */
+public class CheckApplicationName implements ConstraintValidator<ValidApplicationName, String> {
+   public void initialize(final ValidApplicationName constraint) {
+   }
+
+   public boolean isValid(final String obj, final ConstraintValidatorContext context) {
+      if (obj == null)
+         return false;
+
+      try {
+         ApplicationName.fromSpringApplicationName(obj);
+         return true;
+      }
+      catch (final IllegalArgumentException ignored)
+      {
+         return false;
+      }
+   }
+}
diff --git a/src/main/java/io/mifos/core/lang/validation/constraints/ValidApplicationName.java b/src/main/java/io/mifos/core/lang/validation/constraints/ValidApplicationName.java
new file mode 100644
index 0000000..a92e34f
--- /dev/null
+++ b/src/main/java/io/mifos/core/lang/validation/constraints/ValidApplicationName.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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.
+ */
+package io.mifos.core.lang.validation.constraints;
+
+import io.mifos.core.lang.validation.CheckApplicationName;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * The annotated string must not be null, and must contain an application name of the form
+ * appname-v1
+ *
+ * @author Myrle Krantz
+ */
+@SuppressWarnings("unused")
+@Target({ FIELD, METHOD, PARAMETER})
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = CheckApplicationName.class)
+public @interface ValidApplicationName {
+  String message() default "Invalid fineract identifier.";
+  Class<?>[] groups() default { };
+  Class<? extends Payload>[] payload() default { };
+}
diff --git a/src/main/java/io/mifos/core/lang/validation/constraints/ValidIdentifier.java b/src/main/java/io/mifos/core/lang/validation/constraints/ValidIdentifier.java
index ab02397..4896c31 100644
--- a/src/main/java/io/mifos/core/lang/validation/constraints/ValidIdentifier.java
+++ b/src/main/java/io/mifos/core/lang/validation/constraints/ValidIdentifier.java
@@ -32,6 +32,7 @@
  *
  * @author Myrle Krantz
  */
+@SuppressWarnings("unused")
 @Target({ FIELD, METHOD, PARAMETER})
 @Retention(RUNTIME)
 @Documented
diff --git a/src/test/java/io/mifos/core/lang/validation/ValidApplicationNameTest.java b/src/test/java/io/mifos/core/lang/validation/ValidApplicationNameTest.java
new file mode 100644
index 0000000..31613d2
--- /dev/null
+++ b/src/test/java/io/mifos/core/lang/validation/ValidApplicationNameTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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.
+ */
+package io.mifos.core.lang.validation;
+
+import io.mifos.core.lang.validation.constraints.ValidApplicationName;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import java.util.Set;
+
+/**
+ * @author Myrle Krantz
+ */
+public class ValidApplicationNameTest {
+  @Test
+  public void validApplicationName()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("blub-v1");
+    Assert.assertTrue(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void invalidAppplicationName()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("blubv1");
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void nullAppplicationName()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass(null);
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  private boolean isValid(final AnnotatedClass annotatedInstance)
+  {
+
+    final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+    final Validator validator = factory.getValidator();
+    final Set<ConstraintViolation<AnnotatedClass>> errors = validator.validate(annotatedInstance);
+
+    return errors.size() == 0;
+  }
+
+  private static class AnnotatedClass {
+    @ValidApplicationName
+    String applicationName;
+
+    AnnotatedClass(final String applicationName) {
+      this.applicationName = applicationName;
+    }
+  }
+}
diff --git a/src/test/java/io/mifos/core/lang/validation/ValidIdentifierTest.java b/src/test/java/io/mifos/core/lang/validation/ValidIdentifierTest.java
new file mode 100644
index 0000000..e0ebe7f
--- /dev/null
+++ b/src/test/java/io/mifos/core/lang/validation/ValidIdentifierTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2017 The Mifos Initiative
+ *
+ * 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.
+ */
+package io.mifos.core.lang.validation;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import java.util.Set;
+
+/**
+ * @author Myrle Krantz
+ */
+public class ValidIdentifierTest {
+  @Test
+  public void validIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("xxxx");
+    Assert.assertTrue(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void nullIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass(null);
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void emptyStringIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("");
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void tooShortStringIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("x");
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void tooLongStringIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("012345");
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  @Test
+  public void notEncodableStringIdentifier()
+  {
+    final AnnotatedClass annotatedInstance = new AnnotatedClass("x/y/z");
+    Assert.assertFalse(isValid(annotatedInstance));
+  }
+
+  private boolean isValid(final AnnotatedClass annotatedInstance)
+  {
+    final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+    final Validator validator = factory.getValidator();
+    final Set<ConstraintViolation<AnnotatedClass>> errors = validator.validate(annotatedInstance);
+
+    return errors.size() == 0;
+  }
+
+  private static class AnnotatedClass {
+    @ValidIdentifier(maxLength = 5)
+    String applicationName;
+
+    AnnotatedClass(final String applicationName) {
+      this.applicationName = applicationName;
+    }
+  }
+}