/* * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * * 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 com.amazon.carbonado.constraint; import java.lang.annotation.*; import com.amazon.carbonado.MalformedTypeException; /** * Limits the value of a property to lie within a specific length range. The * property value may be a String, CharSequence, or any kind of array. If the * set property length is outside the range, an IllegalArgumentException is * thrown. * *
Example:
* public interface UserInfo extends Storable {
* String getFirstName();
* @LengthConstraint(min=1, max=50)
* void setFirstName(String name);
*
* ...
* }
*
*
* @author Brian S O'Neill
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ConstraintDefinition
public @interface LengthConstraint {
/**
* Specify minimum allowed length for property. Default is zero.
*/
int min() default 0;
/**
* Specify maximum allowed length for property. Default is unlimited.
*/
int max() default Integer.MAX_VALUE;
/**
* Constraint implementation for {@link LengthConstraint}.
*/
public static class Constraint {
private final String mPropertyName;
private final int mMinLength;
private final int mMaxLength;
/**
* @param type type of object that contains the constrained property
* @param propertyName name of property with constraint
* @param ann specific annotation that binds to this constraint class
*/
public Constraint(Class> type, String propertyName, LengthConstraint ann) {
this(type, propertyName, ann.min(), ann.max());
}
/**
* @param type type of object that contains the constrained property
* @param propertyName name of property with constraint
* @param min minimum allowed length
* @param max maximum allowed length
*/
public Constraint(Class> type, String propertyName, int min, int max) {
mPropertyName = propertyName;
mMinLength = min;
mMaxLength = max;
if (mMinLength < 0 || mMaxLength < mMinLength) {
throw new MalformedTypeException
(type, "Illegal length constraint for property \"" + propertyName +
"\": " + rangeString());
}
}
public void constrain(CharSequence str) {
if (str != null) {
constrainLength(str.length());
}
}
public void constrain(boolean[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(byte[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(short[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(char[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(int[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(long[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(float[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(double[] array) {
if (array != null) {
constrainLength(array.length);
}
}
public void constrain(Object[] array) {
if (array != null) {
constrainLength(array.length);
}
}
private void constrainLength(int length) {
if (length < mMinLength || length > mMaxLength) {
throw new IllegalArgumentException
("Value length for \"" + mPropertyName + "\" must be in range " +
rangeString() + ": " + length);
}
}
private String rangeString() {
StringBuilder b = new StringBuilder();
b.append('(');
b.append(mMinLength);
b.append("..");
if (mMaxLength < Integer.MAX_VALUE) {
b.append(mMaxLength);
}
b.append(')');
return b.toString();
}
}
}