Massive package refactoring
[lgpl/argeo-commons.git] / org.argeo.api.acr / src / org / argeo / api / acr / CrAttributeType.java
index 446449ec0b42e63b676726770c18de46632324d9..3e12fb1c87067fd188bfa34cac4c44794c9ec5d2 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.api.acr;
 
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.Instant;
@@ -7,34 +9,44 @@ import java.time.format.DateTimeParseException;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.UUID;
 
-import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
 
 /**
  * Minimal standard attribute types that MUST be supported. All related classes
  * belong to java.base and can be implicitly derived form a given
- * <code>String<code>.
+ * <code>String</code>.
  */
-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()), //
+public enum CrAttributeType {
+       BOOLEAN(Boolean.class, W3C_XML_SCHEMA_NS_URI, "boolean", new BooleanFormatter()), //
+       INTEGER(Integer.class, W3C_XML_SCHEMA_NS_URI, "integer", new IntegerFormatter()), //
+       LONG(Long.class, W3C_XML_SCHEMA_NS_URI, "long", new LongFormatter()), //
+       DOUBLE(Double.class, W3C_XML_SCHEMA_NS_URI, "double", 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()), //
+       DATE_TIME(Instant.class, W3C_XML_SCHEMA_NS_URI, "dateTime", new InstantFormatter()), //
+       UUID(UUID.class, ArgeoNamespace.CR_NAMESPACE_URI, "uuid", new UuidFormatter()), //
+       ANY_URI(URI.class, W3C_XML_SCHEMA_NS_URI, "anyUri", new UriFormatter()), //
+       STRING(String.class, W3C_XML_SCHEMA_NS_URI, "string", new StringFormatter()), //
        ;
 
        private final Class<?> clss;
        private final AttributeFormatter<?> formatter;
 
-       private <T> CrAttributeType(Class<T> clss, AttributeFormatter<T> formatter) {
+       private final ContentName qName;
+
+       private <T> CrAttributeType(Class<T> clss, String namespaceUri, String localName, AttributeFormatter<T> formatter) {
                this.clss = clss;
                this.formatter = formatter;
+
+               qName = new ContentName(namespaceUri, localName, RuntimeNamespaceContext.getNamespaceContext());
+       }
+
+       public QName getqName() {
+               return qName;
        }
 
        public Class<?> getClss() {
@@ -45,21 +57,21 @@ public enum CrAttributeType implements ContentNameSupplier {
                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;
-       }
+//     @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;
+//     }
 
        /** Default parsing procedure from a String to an object. */
        public static Object parse(String str) {
@@ -113,10 +125,48 @@ public enum CrAttributeType implements ContentNameSupplier {
                        // silent
                }
 
+               // TODO support QName as a type? It would require a NamespaceContext
+               // see https://www.oreilly.com/library/view/xml-schema/0596002521/re91.html
+
                // default
                return STRING.getFormatter().parse(str);
        }
 
+       /**
+        * Cast well know java types based on {@link Object#toString()} of the provided
+        * object.
+        * 
+        */
+       @SuppressWarnings("unchecked")
+       public static <T> Optional<T> cast(Class<T> clss, Object value) {
+               // TODO Or should we?
+               Objects.requireNonNull(value, "Cannot cast a null value");
+               if (String.class.isAssignableFrom(clss)) {
+                       return Optional.of((T) value.toString());
+               }
+               // Numbers
+               else if (Long.class.isAssignableFrom(clss)) {
+                       if (value instanceof Long)
+                               return Optional.of((T) value);
+                       return Optional.of((T) Long.valueOf(value.toString()));
+               } else if (Integer.class.isAssignableFrom(clss)) {
+                       if (value instanceof Integer)
+                               return Optional.of((T) value);
+                       return Optional.of((T) Integer.valueOf(value.toString()));
+               } else if (Double.class.isAssignableFrom(clss)) {
+                       if (value instanceof Double)
+                               return Optional.of((T) value);
+                       return Optional.of((T) Double.valueOf(value.toString()));
+               }
+               // Numbers
+//             else if (Number.class.isAssignableFrom(clss)) {
+//                     if (value instanceof Number)
+//                             return Optional.of((T) value);
+//                     return Optional.of((T) Number.valueOf(value.toString()));
+//             }
+               return Optional.empty();
+       }
+
        /** Utility to convert a data: URI to bytes. */
        public static byte[] bytesFromDataURI(URI uri) {
                if (!"data".equals(uri.getScheme()))