alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (SelectedValueComparator.java)

This example Spring Framework source code file (SelectedValueComparator.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

bean, bindstatus, classcastexception, collection, enum, iterator, javabean, labeledenum, labeledenum, map, map, object, object, propertyeditor, string, string, util

The Spring Framework SelectedValueComparator.java source code

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * 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 org.springframework.web.servlet.tags.form;

import java.beans.PropertyEditor;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.springframework.core.JdkVersion;
import org.springframework.core.enums.LabeledEnum;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.support.BindStatus;

/**
 * Utility class for testing whether a candidate value matches a {@link BindStatus#getValue data bound value}.
 * Eagerly attempts to prove a comparison through a number of avenues to deal with issues such as instance
 * inequality, logical (String-representation-based) equality and {@link PropertyEditor}-based comparison.
 *
 * <p>Full support is provided for comparing arrays, {@link Collection Collections} and {@link Map Maps}.
 * 
 * <p>

Equality Contract

* For single-valued objects equality is first tested using standard {@link Object#equals Java equality}. As * such, user code should endeavour to implement {@link Object#equals} to speed up the comparison process. If * {@link Object#equals} returns <code>false then an attempt is made at an * {@link #exhaustiveCompare exhaustive comparison} with the aim being to <strong>prove equality rather * than disprove it. * * <p>Special support is given for instances of {@link LabeledEnum} with a String-based * comparison of the candidate value against the code of the {@link LabeledEnum}. This can be useful when a * {@link LabeledEnum} is used to define a list of '<code><option>' elements in HTML. * * <p>Next, an attempt is made to compare the String representations of both the candidate and bound * values. This may result in <code>true in a number of cases due to the fact both values will be represented * as <code>Strings when shown to the user. * * <p>Next, if the candidate value is a String, an attempt is made to compare the bound value to * result of applying the corresponding {@link PropertyEditor} to the candidate. This comparison may be * executed twice, once against the direct <code>String instances, and then against the String * representations if the first comparison results in <code>false. * * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 */ abstract class SelectedValueComparator { /** * Returns <code>true if the supplied candidate value is equal to the value bound to * the supplied {@link BindStatus}. Equality in this case differs from standard Java equality and * is described in more detail <a href="#equality-contract">here. */ public static boolean isSelected(BindStatus bindStatus, Object candidateValue) { if (bindStatus == null) { return (candidateValue == null); } // Check obvious equality matches with the candidate first, // both with the rendered value and with the original value. Object boundValue = bindStatus.getValue(); if (ObjectUtils.nullSafeEquals(boundValue, candidateValue)) { return true; } Object actualValue = bindStatus.getActualValue(); if (actualValue != null && actualValue != boundValue && ObjectUtils.nullSafeEquals(actualValue, candidateValue)) { return true; } if (actualValue != null) { boundValue = actualValue; } else if (boundValue == null) { return false; } // Non-null value but no obvious equality with the candidate value: // go into more exhaustive comparisons. boolean selected = false; if (boundValue.getClass().isArray()) { selected = collectionCompare(CollectionUtils.arrayToList(boundValue), candidateValue, bindStatus); } else if (boundValue instanceof Collection) { selected = collectionCompare((Collection) boundValue, candidateValue, bindStatus); } else if (boundValue instanceof Map) { selected = mapCompare((Map) boundValue, candidateValue, bindStatus); } if (!selected) { selected = exhaustiveCompare(boundValue, candidateValue, bindStatus.getEditor(), null); } return selected; } private static boolean collectionCompare(Collection boundCollection, Object candidateValue, BindStatus bindStatus) { try { if (boundCollection.contains(candidateValue)) { return true; } } catch (ClassCastException ex) { // Probably from a - ignore. } return exhaustiveCollectionCompare(boundCollection, candidateValue, bindStatus); } private static boolean mapCompare(Map boundMap, Object candidateValue, BindStatus bindStatus) { try { if (boundMap.containsKey(candidateValue)) { return true; } } catch (ClassCastException ex) { // Probably from a TreeMap - ignore. } return exhaustiveCollectionCompare(boundMap.keySet(), candidateValue, bindStatus); } private static boolean exhaustiveCollectionCompare( Collection collection, Object candidateValue, BindStatus bindStatus) { Map convertedValueCache = new HashMap(1); PropertyEditor editor = null; boolean candidateIsString = (candidateValue instanceof String); if (!candidateIsString) { editor = bindStatus.findEditor(candidateValue.getClass()); } for (Iterator it = collection.iterator(); it.hasNext();) { Object element = it.next(); if (editor == null && element != null && candidateIsString) { editor = bindStatus.findEditor(element.getClass()); } if (exhaustiveCompare(element, candidateValue, editor, convertedValueCache)) { return true; } } return false; } private static boolean exhaustiveCompare( Object boundValue, Object candidate, PropertyEditor editor, Map convertedValueCache) { String candidateDisplayString = ValueFormatter.getDisplayString(candidate, editor, false); if (boundValue instanceof LabeledEnum) { LabeledEnum labeledEnum = (LabeledEnum) boundValue; String enumCodeAsString = ObjectUtils.getDisplayString(labeledEnum.getCode()); if (enumCodeAsString.equals(candidateDisplayString)) { return true; } String enumLabelAsString = ObjectUtils.getDisplayString(labeledEnum.getLabel()); if (enumLabelAsString.equals(candidateDisplayString)) { return true; } } else if (JdkVersion.isAtLeastJava15() && boundValue.getClass().isEnum()) { Enum boundEnum = (Enum) boundValue; String enumCodeAsString = ObjectUtils.getDisplayString(boundEnum.name()); if (enumCodeAsString.equals(candidateDisplayString)) { return true; } String enumLabelAsString = ObjectUtils.getDisplayString(boundEnum.toString()); if (enumLabelAsString.equals(candidateDisplayString)) { return true; } } else if (ObjectUtils.getDisplayString(boundValue).equals(candidateDisplayString)) { return true; } else if (editor != null && candidate instanceof String) { // Try PE-based comparison (PE should *not* be allowed to escape creating thread) String candidateAsString = (String) candidate; Object candidateAsValue = null; if (convertedValueCache != null && convertedValueCache.containsKey(editor)) { candidateAsValue = convertedValueCache.get(editor); } else { editor.setAsText(candidateAsString); candidateAsValue = editor.getValue(); if (convertedValueCache != null) { convertedValueCache.put(editor, candidateAsValue); } } if (ObjectUtils.nullSafeEquals(boundValue, candidateAsValue)) { return true; } } return false; } }

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework SelectedValueComparator.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.