Skip to content

Commit

Permalink
Merge branch 'HV-395'
Browse files Browse the repository at this point in the history
  • Loading branch information
hferentschik committed Nov 29, 2010
2 parents 66eb9c3 + 96b61f1 commit 7022bd1
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 221 deletions.
Expand Up @@ -36,6 +36,7 @@

import org.hibernate.validator.constraints.CompositionType;
import org.hibernate.validator.metadata.ConstraintDescriptorImpl;
import org.hibernate.validator.util.LRUMap;
import org.hibernate.validator.util.LoggerFactory;
import org.hibernate.validator.util.ValidatorTypeHelper;

Expand All @@ -60,6 +61,7 @@ public class ConstraintTree<A extends Annotation> {
private final ConstraintDescriptorImpl<A> descriptor;
private final Map<Type, Class<? extends ConstraintValidator<?, ?>>> validatorTypes;
private final Map<ValidatorCacheKey, ConstraintValidator<A, ?>> constraintValidatorCache;
private final Map<Type, List<Type>> suitableTypes;

public ConstraintTree(ConstraintDescriptorImpl<A> descriptor) {
this( descriptor, null );
Expand All @@ -83,6 +85,7 @@ private ConstraintTree(ConstraintDescriptorImpl<A> descriptor, ConstraintTree<?>
}

validatorTypes = ValidatorTypeHelper.getValidatorsTypes( descriptor.getConstraintValidatorClasses() );
suitableTypes = new LRUMap<Type, List<Type>>( 10 );
}

private <U extends Annotation> ConstraintTree<U> createConstraintTree(ConstraintDescriptorImpl<U> composingDescriptor) {
Expand Down Expand Up @@ -377,13 +380,17 @@ else if ( assignableClasses.size() > 1 ) {
}

private List<Type> findSuitableValidatorTypes(Type type) {
List<Type> suitableTypes = new ArrayList<Type>();
if(suitableTypes.containsKey( type )) {
return suitableTypes.get( type );
}
List<Type> determinedSuitableTypes = new ArrayList<Type>();
for ( Type validatorType : validatorTypes.keySet() ) {
if ( TypeUtils.isAssignable( validatorType, type ) && !suitableTypes.contains( validatorType ) ) {
suitableTypes.add( validatorType );
if ( TypeUtils.isAssignable( validatorType, type ) && !determinedSuitableTypes.contains( validatorType ) ) {
determinedSuitableTypes.add( validatorType );
}
}
return suitableTypes;
suitableTypes.put( type, determinedSuitableTypes );
return determinedSuitableTypes;
}

/**
Expand Down
Expand Up @@ -28,11 +28,12 @@
public class ConstraintValidatorContextImpl implements ConstraintValidatorContext {

private final List<MessageAndPath> messageAndPaths = new ArrayList<MessageAndPath>( 3 );
private final String propertyPath;
private final PathImpl propertyPath;
private final ConstraintDescriptor<?> constraintDescriptor;
private boolean defaultDisabled;

public ConstraintValidatorContextImpl(String propertyPath, ConstraintDescriptor<?> constraintDescriptor) {

public ConstraintValidatorContextImpl(PathImpl propertyPath, ConstraintDescriptor<?> constraintDescriptor) {
this.propertyPath = propertyPath;
this.constraintDescriptor = constraintDescriptor;
}
Expand Down Expand Up @@ -71,20 +72,16 @@ public final List<MessageAndPath> getMessageAndPathList() {

class ErrorBuilderImpl implements ConstraintViolationBuilder {
private String messageTemplate;
private String propertyPath;
private PathImpl propertyPath;

ErrorBuilderImpl(String template, String path) {
ErrorBuilderImpl(String template, PathImpl path) {
messageTemplate = template;
propertyPath = path;
}

public NodeBuilderDefinedContext addNode(String name) {
String path = propertyPath;
if ( !PathImpl.ROOT_PATH.equals( propertyPath ) ) {
path += PathImpl.PROPERTY_PATH_SEPARATOR;
}
path += name;
return new NodeBuilderImpl( messageTemplate, path );
propertyPath.addNode( name );
return new NodeBuilderImpl( messageTemplate, propertyPath );
}

public ConstraintValidatorContext addConstraintViolation() {
Expand All @@ -95,17 +92,15 @@ public ConstraintValidatorContext addConstraintViolation() {

class NodeBuilderImpl implements ConstraintViolationBuilder.NodeBuilderDefinedContext {
private String messageTemplate;
private String propertyPath;
private PathImpl propertyPath;

NodeBuilderImpl(String template, String path) {
NodeBuilderImpl(String template, PathImpl path) {
messageTemplate = template;
propertyPath = path;
}

public ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
if ( name != null ) {
propertyPath += PathImpl.PROPERTY_PATH_SEPARATOR + name;
}
propertyPath.addNode( name );
return new InIterableNodeBuilderImpl( messageTemplate, propertyPath );
}

Expand All @@ -117,36 +112,20 @@ public ConstraintValidatorContext addConstraintViolation() {

class InIterableNodeBuilderImpl implements ConstraintViolationBuilder.NodeBuilderCustomizableContext {
private String messageTemplate;
private String propertyPath;
private PathImpl propertyPath;

InIterableNodeBuilderImpl(String template, String path) {
InIterableNodeBuilderImpl(String template, PathImpl path) {
this.messageTemplate = template;
this.propertyPath = path;
}

public ConstraintViolationBuilder.NodeContextBuilder inIterable() {
int lastPropertyIndex = propertyPath.lastIndexOf( PathImpl.PROPERTY_PATH_SEPARATOR );
StringBuilder builder = new StringBuilder();

if ( lastPropertyIndex != -1 ) {
builder = new StringBuilder();
builder.append( propertyPath.substring( 0, lastPropertyIndex ) );
builder.append( PathImpl.INDEX_OPEN );
builder.append( PathImpl.INDEX_CLOSE );
builder.append( PathImpl.PROPERTY_PATH_SEPARATOR );
builder.append( propertyPath.substring( lastPropertyIndex + 1 ) );
}
else {
builder.append( propertyPath );
builder.append( PathImpl.INDEX_OPEN );
builder.append( PathImpl.INDEX_CLOSE );
}

return new InIterablePropertiesBuilderImpl( messageTemplate, builder.toString() );
this.propertyPath.getLeafNode().getParent().setIterable( true );
return new InIterablePropertiesBuilderImpl( messageTemplate, propertyPath );
}

public ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
propertyPath += PathImpl.PROPERTY_PATH_SEPARATOR + name;
propertyPath.addNode( name );
return this;
}

Expand All @@ -158,45 +137,31 @@ public ConstraintValidatorContext addConstraintViolation() {

class InIterablePropertiesBuilderImpl implements ConstraintViolationBuilder.NodeContextBuilder {
private String messageTemplate;
private String propertyPath;
private PathImpl propertyPath;

InIterablePropertiesBuilderImpl(String template, String path) {
InIterablePropertiesBuilderImpl(String template, PathImpl path) {
this.messageTemplate = template;
this.propertyPath = path;
}

public ConstraintViolationBuilder.NodeBuilderDefinedContext atKey(Object key) {
StringBuilder builder = addKeyOrIndex( key );
return new NodeBuilderImpl( messageTemplate, builder.toString() );
propertyPath.getLeafNode().getParent().setKey( key );
return new NodeBuilderImpl( messageTemplate, propertyPath );
}

public ConstraintViolationBuilder.NodeBuilderDefinedContext atIndex(Integer index) {
StringBuilder builder = addKeyOrIndex( index );
return new NodeBuilderImpl( messageTemplate, builder.toString() );
propertyPath.getLeafNode().getParent().setIndex( index );
return new NodeBuilderImpl( messageTemplate, propertyPath );
}

public ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
propertyPath += PathImpl.PROPERTY_PATH_SEPARATOR + name;
propertyPath.addNode( name );
return new InIterableNodeBuilderImpl( messageTemplate, propertyPath );
}

public ConstraintValidatorContext addConstraintViolation() {
messageAndPaths.add( new MessageAndPath( messageTemplate, propertyPath ) );
return ConstraintValidatorContextImpl.this;
}

private StringBuilder addKeyOrIndex(Object key) {
int index = propertyPath.lastIndexOf( PathImpl.INDEX_OPEN );
StringBuilder builder = new StringBuilder();
builder.append( propertyPath.substring( 0, index ) );
builder.append( PathImpl.INDEX_OPEN );
builder.append( key );
builder.append( PathImpl.INDEX_CLOSE );
if ( propertyPath.lastIndexOf( PathImpl.PROPERTY_PATH_SEPARATOR ) != -1 ) {
builder.append( PathImpl.PROPERTY_PATH_SEPARATOR );
builder.append( propertyPath.substring( index + 3 ) );
}
return builder;
}
}
}
Expand Up @@ -16,14 +16,18 @@
*/
package org.hibernate.validator.engine;

import javax.validation.Path;

/**
* Container class for a validation error message and its corresponding path.
*
* @author Hardy Ferentschik
*/
public class MessageAndPath {
private final String message;
private final String propertyPath;
private final Path propertyPath;

public MessageAndPath(String message, String property) {
public MessageAndPath(String message, Path property) {
this.message = message;
this.propertyPath = property;
}
Expand All @@ -32,7 +36,7 @@ public final String getMessage() {
return message;
}

public final String getPath() {
public final Path getPath() {
return propertyPath;
}
}
Expand Up @@ -74,7 +74,7 @@ public <U, V> MethodConstraintViolation<T> createConstraintViolation(ValueContex
getRootBean(),
localContext.getCurrentBean(),
localContext.getCurrentValidatedValue(),
PathImpl.createPathFromString(messageAndPath.getPath()),
messageAndPath.getPath(),
descriptor,
localContext.getElementType()
);
Expand Down
Expand Up @@ -25,66 +25,102 @@
public class NodeImpl implements Path.Node, Serializable {
private static final long serialVersionUID = 2075466571633860499L;

public static final String INDEX_OPEN = "[";
public static final String INDEX_CLOSE = "]";

private final String name;
private boolean isInIterable;
private final NodeImpl parent;
private boolean isIterable;
private Integer index;
private Object key;

public NodeImpl(String name) {
public NodeImpl(String name, NodeImpl parent) {
this.name = name;
this.parent = parent;
}

NodeImpl(Path.Node node) {
NodeImpl(NodeImpl node, NodeImpl parent) {
this.name = node.getName();
this.isInIterable = node.isInIterable();
this.index = node.getIndex();
this.key = node.getKey();
this.isIterable = node.isIterable;
this.index = node.index;
this.key = node.key;
this.parent = parent;
}

public final String getName() {
return name;
}

public final boolean isInIterable() {
return isInIterable;
if ( parent == null ) {
return false;
}
else {
return parent.isIterable();
}
}

public final void setInIterable(boolean inIterable) {
isInIterable = inIterable;
public final void setIterable(boolean iterable) {
isIterable = iterable;
}

public final boolean isIterable() {
return isIterable;
}

public final Integer getIndex() {
return index;
if ( parent == null ) {
return null;
}
else {
return parent.index;
}
}

public final void setIndex(Integer index) {
isInIterable = true;
this.index = index;
}

public final Object getKey() {
return key;
if ( parent == null ) {
return null;
}
else {
return parent.key;
}
}

public final void setKey(Object key) {
isInIterable = true;
this.key = key;
}

public NodeImpl getParent() {
return parent;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "NodeImpl" );
sb.append( "{index=" ).append( index );
sb.append( ", name='" ).append( name ).append( '\'' );
sb.append( ", isInIterable=" ).append( isInIterable );
sb.append( ", key=" ).append( key );
sb.append( '}' );
return sb.toString();
return asString();
}

public final String asString() {
StringBuilder builder = new StringBuilder();
builder.append( getName() );
if ( isIterable() ) {
builder.append( INDEX_OPEN );
if ( index != null ) {
builder.append( index);
}
else if ( key != null ) {
builder.append( key );
}
builder.append( INDEX_CLOSE );
}
return builder.toString();
}

@Override
public final boolean equals(Object o) {
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
Expand All @@ -94,7 +130,7 @@ public final boolean equals(Object o) {

NodeImpl node = (NodeImpl) o;

if ( isInIterable != node.isInIterable ) {
if ( isIterable != node.isIterable ) {
return false;
}
if ( index != null ? !index.equals( node.index ) : node.index != null ) {
Expand All @@ -106,14 +142,18 @@ public final boolean equals(Object o) {
if ( name != null ? !name.equals( node.name ) : node.name != null ) {
return false;
}
if ( parent != null ? !parent.equals( node.parent ) : node.parent != null ) {
return false;
}

return true;
}

@Override
public final int hashCode() {
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + ( isInIterable ? 1 : 0 );
result = 31 * result + ( parent != null ? parent.hashCode() : 0 );
result = 31 * result + ( isIterable ? 1 : 0 );
result = 31 * result + ( index != null ? index.hashCode() : 0 );
result = 31 * result + ( key != null ? key.hashCode() : 0 );
return result;
Expand Down

0 comments on commit 7022bd1

Please sign in to comment.