
com.pekinsoft.validation.conversion.Converter Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
package com.pekinsoft.validation.conversion;
import com.pekinsoft.lookup.Lookup;
import com.pekinsoft.validation.Validator;
import com.pekinsoft.validation.ValidatorUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Converts validators. Can convert a {@link Validator} working on one type (such as {@code String})
* to a `Validator` of a different type, such as `javax.swing.text.Document`.
* In this way, it is possible to write only validators
* for {@code String}s, but use them against `javax.swing.text.Document`s (for validating
* {@code JTextField} and {@code JTextArea} components), etc.
*
* @author Tim Boudreau
*/
public abstract class Converter {
private static Set > registry = new HashSet>();
private final Class from;
private final Class to;
protected Converter (Class from, Class to) {
this.from = from;
this.to = to;
}
public final Class from() {
return from;
}
public final Class to() {
return to;
}
/**
* Create a {@link Validator} for type {@code To} from a validator for type
* {@code From}. For example, a converter that is a factory for Validators
* of {@code javax.swing.text.Document}s from a validator
* that only handles Strings may be created. (Convert would simply return a
* Validator<Document> that wraps the Validator<String>. At validation time
* it will first call Document.getText(), and then pass the result to
* the wrapped Validator<String>).
* @param from The original validator.
* @return A validator of the type requested
*/
public abstract Validator convert (Validator from);
/**
* Will merge the chain of passed validators to one, and then convert it to
* the requested type. See {@link #convert(com.pekinsoft.validation.Validator) }
*
* @param froms A chain of validator to convert.
* @return A validator of the type requested
*/
public final Validator convert (Validator... froms) {
return (convert(ValidatorUtils.merge(froms)));
}
/**
* Register a converter
*
* @param converter
*/
public static void register (Converter,?> converter) {
registry.add (converter);
}
static {
Converter.register (new StringToDocumentConverter());
Converter.register (new StringToComboBoxModelConverter());
Converter.register (new SelectedIndicesToListSelectionModelConverter());
Converter.register (new SelectedIndicesToButtonModelArrayConverter());
}
/**
* Find a converter to create validators for one type from validators for
* another type.
* @param The type of object we get from a component, such as a
* `javax.swing.text.Document`
* @param The type of object we want to process, such as a
* `java.lang.String`
* @param from A class, such as `Document.class`
* @param to A class such as `String.class`
* @return An object which can take validators for type `From`
* and produce validators for type `To`
*/
public static Converter find (Class from, Class to) {
Collection extends Converter> converters
= Lookup.getDefault().lookupAll(Converter.class);
for (Converter,?> c : converters) {
if (c.match(from,to)) {
return c.as(from, to);
}
}
for (Converter,?> c : registry) {
if (c.match(from, to)) {
return c.as(from, to);
}
}
throw new IllegalArgumentException ("No registered converter from " +
from.getName() + " to " + to.getName());
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Converter, ?> other = (Converter, ?>) obj;
if (this.from != other.from && (this.from == null || !this.from.equals(other.from))) {
return false;
}
if (this.to != other.to && (this.to == null || !this.to.equals(other.to))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 23 * hash + (this.from != null ? this.from.hashCode() : 0);
hash = 11 * hash + (this.to != null ? this.to.hashCode() : 0);
return hash;
}
private boolean match (Class> from, Class> to) {
// return from().isAssignableFrom(from) && to().isAssignableFrom(to);
return from().equals(from) && to().equals(to);
}
Converter as (Class t, Class r) {
return new Wrap(t, r, this);
}
static final class Wrap extends Converter {
final Converter other;
private final Exception ex;
Wrap (Class a, Class b, Converter other) {
super (a,b);
this.other = other;
ex = new Exception();
}
@Override
public Validator convert(Validator from) {
Validator tv = ValidatorUtils.cast (other.from, from);
Validator cvt = other.convert(tv);
return ValidatorUtils.cast(to(), cvt);
}
}
// private static final class DepthComparator implements Comparator> {
// int classDepth(Class> type) {
// int depth = 0;
// Set> set = new HashSet>();
// for (;type != null; type = type.getSuperclass()) {
// set.addAll(Arrays.asList(type.getInterfaces()));
// depth++;
// }
// return depth + set.size();
// }
//
// public int compare(Converter, ?> o1, Converter, ?> o2) {
// return classDepth(o1.from()) - classDepth(o2.from());
// }
// }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy