
de.tsl2.nano.bean.def.Constraint Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Tom, Thomas Schneider
* created on: 01.12.2013
*
* Copyright: (c) Thomas Schneider 2013, all rights reserved
*/
package de.tsl2.nano.bean.def;
import java.math.BigDecimal;
import java.text.Format;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.core.Commit;
import org.simpleframework.xml.core.Complete;
import org.simpleframework.xml.core.Persist;
import de.tsl2.nano.action.IConstraint;
import de.tsl2.nano.action.IStatus;
import de.tsl2.nano.bean.BeanUtil;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.util.CollectionUtil;
import de.tsl2.nano.core.util.FormatUtil;
import de.tsl2.nano.format.GenericParser;
/**
* Checks constraints of a given value
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
@SuppressWarnings("unchecked")
public class Constraint extends AbstractConstraint implements IConstraint {
/** serialVersionUID */
private static final long serialVersionUID = -4402914326367553367L;
@Attribute(required = false)
Class type;
@Element(required = false)
protected Format format;
@Attribute(required = false)
protected boolean nullable = true;
@Attribute(required = false)
protected int length = UNDEFINED;
@Element(required = false)
Comparable min;
@Element(required = false)
Comparable max;
@Element(required = false)
T defaultValue;
@Attribute(required = false)
private int scale = UNDEFINED;
@Attribute(required = false)
private int precision = UNDEFINED;
@ElementList(inline = true, entry = "value", required = false)
private transient Collection allowedValues;
/**
* constructor
*/
public Constraint() {
}
public Constraint(Class type) {
this(type, null, null);
}
public Constraint(T defaultValue) {
this((Class) defaultValue.getClass(), null, null);
setDefault(defaultValue);
}
/**
* constructor
*
* @param type
* @param min
* @param max
*/
public Constraint(Class type, Comparable min, Comparable max) {
super();
setType(type);
setRange(min, max);
}
public Constraint(Class type, T... allowedValues) {
this(type, allowedValues != null ? Arrays.asList(allowedValues) : null);
}
/**
* tries to set values from given type and allowedValues. will set the length, scale and precision.
* @param type allowed type
* @param allowedValues allowed values. the first value will be used as default value.
*/
public Constraint(Class type, Collection allowedValues) {
super();
setType(type);
if (allowedValues != null && allowedValues.size() > 0) {
setRange(allowedValues);
setDefault(allowedValues.iterator().next());
int length = -1;
for (T v : allowedValues) {
length = Math.max(length, v.toString().length());
}
setLength(length);
if (BigDecimal.class.isAssignableFrom(type)) {
int scale = -1, precision = -1;
for (T v : allowedValues) {
BigDecimal b = (BigDecimal)v;
scale = Math.max(scale, b.scale());
precision = Math.max(precision, b.precision());
}
setScale(scale);
setPrecision(precision);
}
}
}
/**
* setBasicDef
*
* @param length {@link #length()}
* @param nullable {@link #nullable()}
* @param format {@link #getPattern()}
* @param defaultValue {@link #getDefault()}
* @param description {@link #getDescription()}
*/
@Override
public > C setBasicDef(int length,
boolean nullable,
Format format,
T defaultValue) {
this.length = length;
this.nullable = nullable;
this.format = format;
this.defaultValue = defaultValue;
if (defaultValue != null) {
IStatus s = checkStatus(getType() != null ? getType().getSimpleName() : "arg", defaultValue);
if (!s.ok()) {
throw new ManagedException(s.message());
}
}
return (C) this;
}
/**
* setNumberDef
*
* @param scale {@link #scale()}
* @param precision {@link #precision()}
*/
@Override
public > C setNumberDef(int scale, int precision) {
this.scale = scale;
this.precision = precision;
return (C) this;
}
/**
* {@inheritDoc}
*/
@Override
public > C setRange(Comparable min, Comparable max) {
this.min = min;
this.max = max;
return (C) this;
}
@Override
public > C setRange(Collection allowedValues) {
this.allowedValues = allowedValues;
return (C) this;
}
@Override
public Collection getAllowedValues() {
return allowedValues;
}
@Override
public Comparable getMinimum() {
return min;
}
@Override
public Comparable getMaximum() {
return max;
}
/**
* {@inheritDoc}
*/
@Override
public > C setFormat(Format format) {
this.format = format;
return (C) this;
}
/**
* @return Returns the scale.
*/
@Override
public int getScale() {
return scale;
}
/**
* {@inheritDoc}
*/
@Override
public > C setScale(int scale) {
this.scale = scale;
return (C) this;
}
/**
* @return Returns the precision.
*/
@Override
public int getPrecision() {
return precision;
}
/**
* {@inheritDoc}
*/
@Override
public > C setPrecision(int precision) {
this.precision = precision;
return (C) this;
}
/**
* @return Returns the nullable.
*/
@Override
public boolean isNullable() {
return nullable;
}
/**
* {@inheritDoc}
*/
@Override
public > C setNullable(boolean nullable) {
this.nullable = nullable;
return (C) this;
}
/**
* @return Returns the length.
*/
@Override
public int getLength() {
return length;
}
/**
* {@inheritDoc}
*/
@Override
public > C setLength(int length) {
this.length = length;
return (C) this;
}
/**
* @return Returns the defaultValue.
*/
@Override
public T getDefault() {
return defaultValue;
}
/**
* @param defaultValue The defaultValue to set.
*/
@Override
public > C setDefault(T defaultValue) {
this.defaultValue = defaultValue;
return (C) this;
}
@Override
public Format getFormat() {
return format;
}
public static Format createFormat(Class type) {
Format format = null;
if (Collection.class.isAssignableFrom(type)) {
// format = new CollectionExpressionTypeFormat((Class) generic);
} else if (Map.class.isAssignableFrom(type)) {
// format = new MapExpressionFormat((Class) generic);
} else if (type.isEnum()) {
format = FormatUtil.getDefaultFormat(type, true);
} else if (BeanUtil.isStandardType(type)) {
format = FormatUtil.getDefaultFormat(type, true);
//not all types have default formats
if (format == null) {
format = new GenericParser(type);
}
} else {
// setFormat(new ValueExpressionTypeFormat(type));
}
return format;
}
@Override
public Class getType() {
if (type == null) {
type = (Class) Object.class;
}
return type;
}
/** define maximum length */
@SuppressWarnings("rawtypes")
@Override
public > C setType(Class type) {
this.type = type;
if (type.isEnum()) {
setRange(CollectionUtil.getEnumValues((Class) type));
}
return (C) this;
}
@Persist
private void initSerialization() {
//simple-xml has problems on deserializing anonymous classes
if (format != null && format.getClass().isAnonymousClass()) {
format = null;
}
//the enum values should not be persisted
if (Enum.class.isAssignableFrom(getType())) {
allowedValues = null;
}
}
@Complete
private void afterSerialization() {
initDeserialization();
}
@SuppressWarnings("rawtypes")
@Commit
private void initDeserialization() {
if (Enum.class.isAssignableFrom(getType())) {
allowedValues = CollectionUtil.getEnumValues((Class) getType());
}
if (format == null) {
format = createFormat(getType());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy