X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2FCrAttributeType.java;fp=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2FCrAttributeType.java;h=ffa28af0aca580a6d358030d9f1e4c038f1aa179;hb=7d2a002f5dcfe8a8c7b29803b70d4b1aff265ed1;hp=0000000000000000000000000000000000000000;hpb=865fc51900459b888938cc0d6943673ee6f20d09;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java b/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java new file mode 100644 index 000000000..ffa28af0a --- /dev/null +++ b/org.argeo.api.acr/src/org/argeo/api/acr/CrAttributeType.java @@ -0,0 +1,201 @@ +package org.argeo.api.acr; + +import java.net.URI; +import java.net.URISyntaxException; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.util.UUID; + +import javax.xml.XMLConstants; + +/** + * Minimal standard attribute types that MUST be supported. All related classes + * belong to java.base and can be implicitly derived form a given + * String. + */ +public enum CrAttributeType implements ContentNameSupplier { + BOOLEAN(Boolean.class, new BooleanFormatter()), // + INTEGER(Integer.class, new IntegerFormatter()), // + LONG(Long.class, new LongFormatter()), // + DOUBLE(Double.class, new DoubleFormatter()), // + // we do not support short and float, like recent additions to Java + // (e.g. optional primitives) + DATE_TIME(Instant.class, new InstantFormatter()), // + UUID(UUID.class, new UuidFormatter()), // + ANY_URI(URI.class, new UriFormatter()), // + STRING(String.class, new StringFormatter()), // + ; + + private final Class clss; + private final AttributeFormatter formatter; + + private CrAttributeType(Class clss, AttributeFormatter formatter) { + this.clss = clss; + this.formatter = formatter; + } + + public Class getClss() { + return clss; + } + + public AttributeFormatter getFormatter() { + return formatter; + } + + @Override + public String getDefaultPrefix() { + if (equals(UUID)) + return CrName.CR_DEFAULT_PREFIX; + else + return "xs"; + } + + @Override + public String getNamespaceURI() { + if (equals(UUID)) + return CrName.CR_NAMESPACE_URI; + else + return XMLConstants.W3C_XML_SCHEMA_NS_URI; + } + + public static Object parse(String str) { + if (str == null) + throw new IllegalArgumentException("String cannot be null"); + // order IS important + try { + if (str.length() == 4 || str.length() == 5) + return BOOLEAN.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + return INTEGER.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + return LONG.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + return DOUBLE.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + return DATE_TIME.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + if (str.length() == 36) + return UUID.getFormatter().parse(str); + } catch (IllegalArgumentException e) { + // silent + } + try { + java.net.URI uri = (java.net.URI) ANY_URI.getFormatter().parse(str); + if (uri.getScheme() != null) + return uri; + String path = uri.getPath(); + if (path.indexOf('/') >= 0) + return uri; + // if it is not clearly a path, we will consider it as a string + // because their is no way to distinguish between 'any_string' + // and 'any_file_name'. + // Note that providing ./any_file_name would result in an equivalent URI + } catch (IllegalArgumentException e) { + // silent + } + + // default + return STRING.getFormatter().parse(str); + } + + static class BooleanFormatter implements AttributeFormatter { + + /** + * @param str must be exactly equals to either 'true' or 'false' (different + * contract than {@link Boolean#parseBoolean(String)}. + */ + @Override + public Boolean parse(String str) throws IllegalArgumentException { + if ("true".equals(str)) + return Boolean.TRUE; + if ("false".equals(str)) + return Boolean.FALSE; + throw new IllegalArgumentException("Argument is neither 'true' or 'false' : " + str); + } + } + + static class IntegerFormatter implements AttributeFormatter { + @Override + public Integer parse(String str) throws NumberFormatException { + return Integer.parseInt(str); + } + } + + static class LongFormatter implements AttributeFormatter { + @Override + public Long parse(String str) throws NumberFormatException { + return Long.parseLong(str); + } + } + + static class DoubleFormatter implements AttributeFormatter { + + @Override + public Double parse(String str) throws NumberFormatException { + return Double.parseDouble(str); + } + } + + static class InstantFormatter implements AttributeFormatter { + + @Override + public Instant parse(String str) throws IllegalArgumentException { + try { + return Instant.parse(str); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException("Cannot parse '" + str + "' as an instant", e); + } + } + } + + static class UuidFormatter implements AttributeFormatter { + + @Override + public UUID parse(String str) throws IllegalArgumentException { + return java.util.UUID.fromString(str); + } + } + + static class UriFormatter implements AttributeFormatter { + + @Override + public URI parse(String str) throws IllegalArgumentException { + try { + return new URI(str); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Cannot parse " + str + " as an URI.", e); + } + } + + } + + static class StringFormatter implements AttributeFormatter { + + @Override + public String parse(String str) { + return str; + } + + @Override + public String format(String obj) { + return obj; + } + + } + +}