diff --git a/.classpath b/.classpath index b95f410..6c4f306 100644 --- a/.classpath +++ b/.classpath @@ -21,7 +21,12 @@ - + + + + + + diff --git a/src/module-info.java b/src/module-info.java index 230c4f4..7ae5ea5 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -9,11 +9,11 @@ open module org.atriasoft.ejson { exports org.atriasoft.ejson.model; exports org.atriasoft.ejson.exception; exports org.atriasoft.ejson.builder; - exports org.atriasoft.ejson.parser; - exports org.atriasoft.ejson.annotation; + exports org.atriasoft.ejson.parser; requires transitive org.atriasoft.etk; requires transitive io.scenarium.logger; requires java.base; + requires org.atriasoft.aknot; } diff --git a/src/org/atriasoft/ejson/Ejson.java b/src/org/atriasoft/ejson/Ejson.java index c0f96fb..ed4b0b7 100644 --- a/src/org/atriasoft/ejson/Ejson.java +++ b/src/org/atriasoft/ejson/Ejson.java @@ -10,11 +10,11 @@ import org.atriasoft.ejson.builder.Builder; import org.atriasoft.ejson.builder.BuilderGeneric; import org.atriasoft.ejson.exception.EjsonBuilderException; import org.atriasoft.ejson.exception.EjsonParserErrorMulti; +import org.atriasoft.ejson.generator.GeneratorGeneric; import org.atriasoft.ejson.internal.Log; import org.atriasoft.ejson.model.JsonNode; import org.atriasoft.ejson.parser.ParseJson; import org.atriasoft.ejson.parser.ParsingProperty; -import org.atriasoft.ejson.serializer.SerializerJson; import org.atriasoft.etk.Uri; public class Ejson { @@ -23,7 +23,7 @@ public class Ejson { */ public static void display(final JsonNode root) { final StringBuilder tmpp = new StringBuilder(); - SerializerJson.serialize(root, tmpp, 0); + GeneratorGeneric.serialize(root, tmpp, 0); Log.info("Generated JSON : \n{}", tmpp.toString()); } @@ -33,7 +33,7 @@ public class Ejson { * @param data Data where the json is stored */ public static void generate(final JsonNode root, final StringBuilder data) { - SerializerJson.serialize(root, data, 1); + GeneratorGeneric.serialize(root, data, 1); } public static JsonNode parse(final String data) throws Exception, EjsonBuilderException, EjsonParserErrorMulti { diff --git a/src/org/atriasoft/ejson/JsonMapper.java__ b/src/org/atriasoft/ejson/JsonMapper.java__ new file mode 100644 index 0000000..4036c01 --- /dev/null +++ b/src/org/atriasoft/ejson/JsonMapper.java__ @@ -0,0 +1,117 @@ +package org.atriasoft.ejson; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.atriasoft.aknot.exception.AknotException; +import org.atriasoft.aknot.model.ModelType; +import org.atriasoft.aknot.pojo.IntrospectionObject; +import org.atriasoft.ejson.builder.BuilderGeneric; +import org.atriasoft.ejson.builder.BuilderIntrospection; +import org.atriasoft.ejson.exception.EjsonBuilderException; +import org.atriasoft.ejson.exception.EjsonException; +import org.atriasoft.ejson.exception.EjsonNodeDoesNotExist; +import org.atriasoft.ejson.parser.ParseJson; +import org.atriasoft.ejson.parser.ParsingProperty; +import org.atriasoft.etk.Uri; + +public class JsonMapper { + + private static String readFile(final Path path, final Charset encoding) throws IOException { + final byte[] encoded = Files.readAllBytes(path); + return new String(encoded, encoding); + } + + public JsonMapper() { + + } + + public void generate(final Object root, final StringBuilder data) throws EjsonException, AknotException { + GeneratorIntrospection generator; + try { + generator = new GeneratorIntrospection(ModelType.NORMAL, root.getClass()); + generator.generate(root, data); + } catch (final EjsonBuilderException ex) { + throw ex; + } catch (final Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Parse a single root node that have the name of the Class Parsed: + *
+	 *   >ClassName a="kk" ... <
+	 *     ...
+	 *   >/ClassName<
+	 * 
+ * @param Object type to parse + * @param data Data String to Parse + * @param classType Object Class to introspect data (POJO) + * @return The Object parsed or null + */ + @SuppressWarnings("unchecked") + public T parse(final String data, final Class classType) throws EjsonException, EjsonNodeDoesNotExist, AknotException { + BuilderGeneric builder; + try { + builder = new BuilderIntrospection(ModelType.NORMAL, classType); + final ParseJson parser = new ParseJson(builder); + final ParsingProperty property = new org.atriasoft.ejson.parser.ParsingProperty(); + property.setDisplayError(true); + + final IntrospectionObject introspectionObject = (IntrospectionObject) parser.parse(data, property); + introspectionObject.generateTheObject(); + final Object listRet = introspectionObject.getData(); + if (listRet != null && !listRet.getClass().isArray() && listRet.getClass().componentType() == classType) { + return (T) listRet; + } else if (listRet != null && listRet.getClass().isArray() && listRet.getClass().componentType() == classType) { + final T[] tmp = (T[]) listRet; + if (tmp.length >= 1) { + return tmp[0]; + } + } + return null; + } catch (final EjsonException ex) { + ex.printStackTrace(); + throw ex; + } + } + + public T read(final Class classType, final Path path) throws EjsonException, AknotException, IOException { + String content = null; + try { + content = readFile(path, StandardCharsets.UTF_8); + } catch (final IOException e) { + e.printStackTrace(); + } + return parse(content, classType); + } + + public T read(final Class classType, final Uri uri) throws EjsonException, AknotException, IOException { + + final byte[] elemData = Uri.getAllData(uri); + if (elemData == null) { + Log.error("Can not read the Stream : " + uri); + return null; + } + final String content = new String(elemData); + return parse(content, classType); + } + + public void store(final Object root, final Path path) throws EjsonException, AknotException, IOException { + final StringBuilder builder = new StringBuilder(); + generate(root, builder); + Files.writeString(path, builder.toString()); + } + + public void store(final Object root, final Uri uri) throws EjsonException, AknotException, IOException { + final StringBuilder builder = new StringBuilder(); + generate(root, builder); + Uri.writeAll(uri, builder.toString()); + } + +} diff --git a/src/org/atriasoft/ejson/annotation/EjsonAnnotation.java b/src/org/atriasoft/ejson/annotation/EjsonAnnotation.java deleted file mode 100644 index 42e2377..0000000 --- a/src/org/atriasoft/ejson/annotation/EjsonAnnotation.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Meta-annotation (annotations used on other annotations) - * used for marking all annotations that are - * part of Ejson package. Can be used for recognizing all - * Ejson annotations generically, and in future also for - * passing other generic annotation configuration. - */ -@Target(ElementType.ANNOTATION_TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface EjsonAnnotation { - // for now, a pure tag annotation, no parameters -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/annotation/JsonDefaultManaged.java b/src/org/atriasoft/ejson/annotation/JsonDefaultManaged.java deleted file mode 100644 index 14587c1..0000000 --- a/src/org/atriasoft/ejson/annotation/JsonDefaultManaged.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that set the element are not managed by default. Need to add @JsonManaged to be enable. - * - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@EjsonAnnotation -public @interface JsonDefaultManaged { - /** - * Set this at false to remove all the field and the function from Json introspection - * @return true if the element are by default managed. - */ - boolean value() default true; -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/annotation/JsonDefaultOptional.java b/src/org/atriasoft/ejson/annotation/JsonDefaultOptional.java deleted file mode 100644 index e7e68d2..0000000 --- a/src/org/atriasoft/ejson/annotation/JsonDefaultOptional.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that set the element not found are ignored. - * - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@EjsonAnnotation -public @interface JsonDefaultOptional { - /** - * Set this at true to set all the element optional. - * @return true if the element are by default optional. - */ - boolean value() default false; -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/annotation/JsonManaged.java b/src/org/atriasoft/ejson/annotation/JsonManaged.java deleted file mode 100644 index 25c9e81..0000000 --- a/src/org/atriasoft/ejson/annotation/JsonManaged.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that force the json Parser to manage this element (used when the class is mark as @JsondefaultNotManaged). - * - */ -@Target({ ElementType.FIELD, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@EjsonAnnotation -public @interface JsonManaged { - /** - * Set this at false to remove this function or this field form the XML parsing system - * @return true if the element is managed. - */ - boolean value() default true; -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/annotation/JsonName.java b/src/org/atriasoft/ejson/annotation/JsonName.java deleted file mode 100644 index 6a85fe5..0000000 --- a/src/org/atriasoft/ejson/annotation/JsonName.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define an other name of the attribute or the Element name. - * - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) -@Retention(RetentionPolicy.RUNTIME) -@EjsonAnnotation -public @interface JsonName { - - /** - * Names of the property of the Element name - * @note The first name if the default generated in serialization. - * @return The list the the possible names - */ - String[] value(); -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/annotation/JsonOptional.java b/src/org/atriasoft/ejson/annotation/JsonOptional.java deleted file mode 100644 index 9ed6e19..0000000 --- a/src/org/atriasoft/ejson/annotation/JsonOptional.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.atriasoft.ejson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that to ignore the element if not present in the XML, the default case the parser throw a missing error. - * - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) -@Retention(RetentionPolicy.RUNTIME) -@EjsonAnnotation -public @interface JsonOptional { - /** - * Set if the element is optional or not. If optional, the parser does not throw error if the element is not declared. - * @return thru if optional - */ - boolean value() default true; -} \ No newline at end of file diff --git a/src/org/atriasoft/ejson/builder/Builder.java b/src/org/atriasoft/ejson/builder/Builder.java index 4532c20..55b61d0 100644 --- a/src/org/atriasoft/ejson/builder/Builder.java +++ b/src/org/atriasoft/ejson/builder/Builder.java @@ -9,6 +9,13 @@ import org.atriasoft.ejson.exception.EjsonBuilderException; public interface Builder { + /** + * End of parsing element + * @param parent Element representing the end of declaration + * @throws EjsonBuilderException Error with this node or element. + */ + void endParsing(Object parent) throws EjsonBuilderException; + /** * New comment added on this Element (For an Array) * @param parent Element representing the node of the Declaration is added diff --git a/src/org/atriasoft/ejson/builder/BuilderGeneric.java b/src/org/atriasoft/ejson/builder/BuilderGeneric.java index a6e3235..c30f61d 100644 --- a/src/org/atriasoft/ejson/builder/BuilderGeneric.java +++ b/src/org/atriasoft/ejson/builder/BuilderGeneric.java @@ -15,9 +15,14 @@ import org.atriasoft.ejson.model.JsonString; public class BuilderGeneric implements Builder { + @Override + public void endParsing(final Object parent) throws EjsonBuilderException { + // nothing to do ... this is for revert build. + } + @Override public Object newArray(final Object parent) throws EjsonBuilderException { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonArray out = new JsonArray(); elem.add(out); return out; @@ -27,7 +32,7 @@ public class BuilderGeneric implements Builder { @Override public Object newArray(final Object parent, final String nodeName) throws EjsonBuilderException { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonArray out = new JsonArray(); elem.put(nodeName, out); return out; @@ -37,7 +42,7 @@ public class BuilderGeneric implements Builder { @Override public void newBoolean(final Object parent, final boolean value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonBoolean out = new JsonBoolean(value); elem.add(out); return; @@ -48,7 +53,7 @@ public class BuilderGeneric implements Builder { @Override public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonBoolean out = new JsonBoolean(value); elem.put(nodeName, out); return; @@ -58,7 +63,7 @@ public class BuilderGeneric implements Builder { @Override public void newNull(final Object parent) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonNull out = new JsonNull(); elem.add(out); return; @@ -69,7 +74,7 @@ public class BuilderGeneric implements Builder { @Override public void newNull(final Object parent, final String nodeName) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonNull out = new JsonNull(); elem.put(nodeName, out); return; @@ -79,7 +84,7 @@ public class BuilderGeneric implements Builder { @Override public void newNumber(final Object parent, final double value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonNumber out = new JsonNumber(value); elem.add(out); return; @@ -90,7 +95,7 @@ public class BuilderGeneric implements Builder { @Override public void newNumber(final Object parent, final long value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonNumber out = new JsonNumber(value); elem.add(out); return; @@ -101,7 +106,7 @@ public class BuilderGeneric implements Builder { @Override public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonNumber out = new JsonNumber(value); elem.put(nodeName, out); return; @@ -111,7 +116,7 @@ public class BuilderGeneric implements Builder { @Override public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonNumber out = new JsonNumber(value); elem.put(nodeName, out); return; @@ -121,7 +126,7 @@ public class BuilderGeneric implements Builder { @Override public Object newObject(final Object parent) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonObject out = new JsonObject(); elem.add(out); return out; @@ -131,7 +136,7 @@ public class BuilderGeneric implements Builder { @Override public Object newObject(final Object parent, final String nodeName) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonObject out = new JsonObject(); elem.put(nodeName, out); return out; @@ -146,7 +151,7 @@ public class BuilderGeneric implements Builder { @Override public void newString(final Object parent, final String value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonArray elem) { + if (parent instanceof final JsonArray elem) { final JsonString out = new JsonString(value); elem.add(out); return; @@ -157,7 +162,7 @@ public class BuilderGeneric implements Builder { @Override public void newString(final Object parent, final String nodeName, final String value) throws EjsonBuilderException, Exception { - if (parent instanceof JsonObject elem) { + if (parent instanceof final JsonObject elem) { final JsonString out = new JsonString(value); elem.put(nodeName, out); return; diff --git a/src/org/atriasoft/ejson/builder/BuilderIntrospection.java b/src/org/atriasoft/ejson/builder/BuilderIntrospection.java new file mode 100644 index 0000000..19b9415 --- /dev/null +++ b/src/org/atriasoft/ejson/builder/BuilderIntrospection.java @@ -0,0 +1,189 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2021, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +package org.atriasoft.ejson.builder; + +import org.atriasoft.aknot.exception.AknotException; +import org.atriasoft.aknot.model.IntrospectionModel; +import org.atriasoft.aknot.model.ModelType; +import org.atriasoft.aknot.pojo.CacheIntrospectionModel; +import org.atriasoft.ejson.exception.EjsonBuilderException; +import org.atriasoft.ejson.exception.EjsonException; +import org.atriasoft.ejson.model.JsonArray; +import org.atriasoft.ejson.model.JsonBoolean; +import org.atriasoft.ejson.model.JsonNull; +import org.atriasoft.ejson.model.JsonNumber; +import org.atriasoft.ejson.model.JsonObject; +import org.atriasoft.ejson.model.JsonString; + +public class BuilderIntrospection implements Builder { + // Keep in cach all the object alredy parsed ==> optimize CPU + CacheIntrospectionModel cacheModel = new CacheIntrospectionModel(); + // The root class (need to keep it if we use 2 time the builder, the root class is no more accessible). + final Class rootClassType; + final String rootNodeName; + + public BuilderIntrospection(final ModelType model, final Class classType) throws EjsonException, AknotException { + this.rootClassType = classType; + final IntrospectionModel typeModel = this.cacheModel.findOrCreate(model, null, classType); + this.rootNodeName = typeModel.getNames()[0]; + } + + @Override + public void endParsing(final Object parent) throws EjsonBuilderException { + // nothing to do ... this is for revert build. + } + + @Override + public Object newArray(final Object parent) throws EjsonBuilderException { + if (parent instanceof final JsonArray elem) { + final JsonArray out = new JsonArray(); + elem.add(out); + return out; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + } + + @Override + public Object newArray(final Object parent, final String nodeName) throws EjsonBuilderException { + if (parent instanceof final JsonObject elem) { + final JsonArray out = new JsonArray(); + elem.put(nodeName, out); + return out; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public void newBoolean(final Object parent, final boolean value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonBoolean out = new JsonBoolean(value); + elem.add(out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + + } + + @Override + public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonBoolean out = new JsonBoolean(value); + elem.put(nodeName, out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public void newNull(final Object parent) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonNull out = new JsonNull(); + elem.add(out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + + } + + @Override + public void newNull(final Object parent, final String nodeName) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonNull out = new JsonNull(); + elem.put(nodeName, out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public void newNumber(final Object parent, final double value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonNumber out = new JsonNumber(value); + elem.add(out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + + } + + @Override + public void newNumber(final Object parent, final long value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonNumber out = new JsonNumber(value); + elem.add(out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + + } + + @Override + public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonNumber out = new JsonNumber(value); + elem.put(nodeName, out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonNumber out = new JsonNumber(value); + elem.put(nodeName, out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public Object newObject(final Object parent) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonObject out = new JsonObject(); + elem.add(out); + return out; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + } + + @Override + public Object newObject(final Object parent, final String nodeName) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonObject out = new JsonObject(); + elem.put(nodeName, out); + return out; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + + @Override + public Object newRoot() throws EjsonBuilderException { + return new JsonObject(); + } + + @Override + public void newString(final Object parent, final String value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonArray elem) { + final JsonString out = new JsonString(value); + elem.add(out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than array"); + + } + + @Override + public void newString(final Object parent, final String nodeName, final String value) throws EjsonBuilderException, Exception { + if (parent instanceof final JsonObject elem) { + final JsonString out = new JsonString(value); + elem.put(nodeName, out); + return; + } + throw new EjsonBuilderException("can not add Comment on something else than Object"); + } + +} diff --git a/src/org/atriasoft/ejson/builder/IntrospectionObject.java b/src/org/atriasoft/ejson/builder/IntrospectionObject.java new file mode 100644 index 0000000..6da15f2 --- /dev/null +++ b/src/org/atriasoft/ejson/builder/IntrospectionObject.java @@ -0,0 +1,168 @@ +package org.atriasoft.ejson.builder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.atriasoft.aknot.exception.AknotException; +import org.atriasoft.aknot.model.IntrospectionModel; +import org.atriasoft.ejson.exception.EjsonException; +import org.atriasoft.ejson.exception.EjsonNodeDoesNotExist; +import org.atriasoft.ejson.internal.Log; + +public class IntrospectionObject { + public static final String PUBLIC_TEXT_NAME = "##<< ** TEXT-ZONE ** >>##"; + private final IntrospectionModel modelInterface; + private Object data = null; + private final Map properties = new HashMap<>(); + private final Map> nodes = new HashMap<>(); + + public IntrospectionObject(final IntrospectionModel dataInterface) { + this.modelInterface = dataInterface; + } + + @SuppressWarnings("unchecked") + public void addObject(final String nodeName, final Object value) throws EjsonException { + if (value == null) { + // specific case when a List is empty but define for a specific list ==> need no action + return; + } + final String beanName = this.modelInterface.getBeanName(nodeName); + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + List node = this.nodes.get(beanName); + if (node == null) { + if (List.class.isAssignableFrom(value.getClass())) { + node = (List) value; + } else if (value.getClass().isArray()) { + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + } else { + node = new ArrayList<>(); + node.add(value); + } + this.nodes.put(beanName, node); + } else if (value.getClass().isArray()) { + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + Log.error("this is a big problem ..."); + } else if (List.class.isAssignableFrom(value.getClass())) { + final List nodeIn = (List) value; + node.addAll(nodeIn); + } else { + node.add(value); + } + } + + public void generateTheObject() throws AknotException { + if (this.data != null) { + // nothing to do ... ==> element already created + return; + } + Log.warning("Create the element for the Specific node ... type = " + this.modelInterface.getClassType().getCanonicalName() + (this.modelInterface.isArray() ? "[array]" : "") + + (this.modelInterface.isList() ? "[List]" : "")); + Log.warning(" Properties : " + this.properties.keySet()); + Log.warning(" Nodes : " + this.nodes.keySet()); + this.data = this.modelInterface.createObject(this.properties, this.nodes); + } + + public Object getData() { + return this.data; + } + + public IntrospectionModel getModelIntrospection() { + return this.modelInterface; + } + + public String getTreeNameOfSubNode(final String nodeName) throws AknotException, EjsonNodeDoesNotExist { + final String beanName = this.modelInterface.getBeanName(nodeName); + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + return this.modelInterface.getTreeNameOfSubNode(beanName); + } + + public Class getTypeOfProperty(final String nodeName) throws AknotException, EjsonNodeDoesNotExist { + final String beanName = this.modelInterface.getBeanName(nodeName); + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + return this.modelInterface.getTypeOfProperty(beanName); + } + + /** + * Detect a subNode, and ask the type of the node at the parent Class + * @param nodeName Name of the node + * @return Class of the node to create + */ + public Class getTypeOfSubNode(final String nodeName) throws AknotException, EjsonNodeDoesNotExist { + final String beanName = this.modelInterface.getBeanNameModel(nodeName); + + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + return this.modelInterface.getTypeOfSubNode(beanName); + } + + public Class getTypeOfSubNodeSubType(final String nodeName) throws AknotException, EjsonNodeDoesNotExist { + final String beanName = this.modelInterface.getBeanNameModel(nodeName); + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + return this.modelInterface.getTypeOfSubNodeList(beanName); + } + + public Class getTypeOfSubProperty(final String nodeName) throws AknotException, EjsonNodeDoesNotExist { + final String beanName = this.modelInterface.getBeanName(nodeName); + if (beanName == null) { + throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist..."); + } + return this.modelInterface.getTypeOfSubProperty(beanName); + } + + public boolean isSubNodeOrPropertyExist(final String nodeName) { + final String beanName = this.modelInterface.getBeanName(nodeName); + if (beanName == null) { + return false; + } + return true; + } + + public void putProperty(final String propertyName, final Object propertyValue) throws AknotException, EjsonException { + String beanName = null; + if (propertyName == PUBLIC_TEXT_NAME) { + beanName = this.modelInterface.getTextBeanName(); + } else { + beanName = this.modelInterface.getBeanName(propertyName); + } + if (this.properties.containsKey(beanName)) { + throw new EjsonException("Property have multiple values ==> impossible case; A Node must contain only 1 attibutes"); + } + this.properties.put(beanName, propertyValue); + } + + public void setText(final String text) throws AknotException, EjsonException { + if (this.data != null) { + throw new EjsonException("Can not set multiple text value in a single NODE ..."); + } + this.data = this.modelInterface.getValueFromText(text); + } + +} diff --git a/src/org/atriasoft/ejson/exception/EjsonParserError.java b/src/org/atriasoft/ejson/exception/EjsonParserError.java index a95e3b5..d023a90 100644 --- a/src/org/atriasoft/ejson/exception/EjsonParserError.java +++ b/src/org/atriasoft/ejson/exception/EjsonParserError.java @@ -1,9 +1,9 @@ package org.atriasoft.ejson.exception; -import org.atriasoft.ejson.parser.FilePos; - import java.io.Serial; +import org.atriasoft.etk.util.FilePos; + public class EjsonParserError extends EjsonBuilderException { @Serial private static final long serialVersionUID = 1L; diff --git a/src/org/atriasoft/ejson/serializer/SerializerJson.java b/src/org/atriasoft/ejson/generator/GeneratorGeneric.java similarity index 86% rename from src/org/atriasoft/ejson/serializer/SerializerJson.java rename to src/org/atriasoft/ejson/generator/GeneratorGeneric.java index 7d5bd04..ed157e9 100644 --- a/src/org/atriasoft/ejson/serializer/SerializerJson.java +++ b/src/org/atriasoft/ejson/generator/GeneratorGeneric.java @@ -1,4 +1,4 @@ -package org.atriasoft.ejson.serializer; +package org.atriasoft.ejson.generator; import java.util.Iterator; import java.util.List; @@ -11,22 +11,22 @@ import org.atriasoft.ejson.model.JsonNull; import org.atriasoft.ejson.model.JsonNumber; import org.atriasoft.ejson.model.JsonObject; import org.atriasoft.ejson.model.JsonString; -import org.atriasoft.ejson.parser.Tools; +import org.atriasoft.etk.Tools; -public class SerializerJson { +public class GeneratorGeneric { public static void serialize(final JsonNode node, final StringBuilder data, final int indent) { if (node instanceof JsonObject) { - SerializerJson.serializeObject((JsonObject) node, data, indent); + GeneratorGeneric.serializeObject((JsonObject) node, data, indent); } else if (node instanceof JsonArray) { - SerializerJson.serializeArray((JsonArray) node, data, indent); + GeneratorGeneric.serializeArray((JsonArray) node, data, indent); } else if (node instanceof JsonNumber) { - SerializerJson.serializeNumber((JsonNumber) node, data, indent); + GeneratorGeneric.serializeNumber((JsonNumber) node, data, indent); } else if (node instanceof JsonNull) { - SerializerJson.serializeNull((JsonNull) node, data, indent); + GeneratorGeneric.serializeNull((JsonNull) node, data, indent); } else if (node instanceof JsonString) { - SerializerJson.serializeString((JsonString) node, data, indent); + GeneratorGeneric.serializeString((JsonString) node, data, indent); } else if (node instanceof JsonBoolean) { - SerializerJson.serializeBoolean((JsonBoolean) node, data, indent); + GeneratorGeneric.serializeBoolean((JsonBoolean) node, data, indent); } else { // TODO throw an error ... } @@ -44,7 +44,7 @@ public class SerializerJson { if (needComa) { data.append(","); } - SerializerJson.serialize(jsonNode, data, -1); + GeneratorGeneric.serialize(jsonNode, data, -1); needComa = true; } data.append("]"); @@ -83,7 +83,7 @@ public class SerializerJson { Tools.addIndent(data, indent); } if (tmp.get(iii) != null) { - SerializerJson.serialize(tmp.get(iii), data, indent + 1); + GeneratorGeneric.serialize(tmp.get(iii), data, indent + 1); if (iii < tmp.size() - 1) { data.append(","); } @@ -135,7 +135,7 @@ public class SerializerJson { data.append("\""); data.append(entry.getKey()); data.append("\":"); - SerializerJson.serialize(entry.getValue(), data, -1); + GeneratorGeneric.serialize(entry.getValue(), data, -1); } data.append("}"); } else { @@ -180,7 +180,7 @@ public class SerializerJson { data.append("\""); data.append(entry.getKey()); data.append("\": "); - SerializerJson.serialize(entry.getValue(), data, indent + 1); + GeneratorGeneric.serialize(entry.getValue(), data, indent + 1); if (iterator.hasNext()) { data.append(","); } @@ -208,6 +208,6 @@ public class SerializerJson { data.append("\""); } - private SerializerJson() {} + private GeneratorGeneric() {} } diff --git a/src/org/atriasoft/ejson/parser/FilePos.java b/src/org/atriasoft/ejson/parser/FilePos.java deleted file mode 100644 index 0dc60d2..0000000 --- a/src/org/atriasoft/ejson/parser/FilePos.java +++ /dev/null @@ -1,185 +0,0 @@ -/** @file - * @author Edouard DUPIN - * @copyright 2021, Edouard DUPIN, all right reserved - * @license MPL v2.0 (see license file) - */ -package org.atriasoft.ejson.parser; - -/** @file - * @author Edouard DUPIN - * @copyright 2011, Edouard DUPIN, all right reserved - * @license MPL v2.0 (see license file) - */ - -/** - * Position in the file of the original data. - */ -public class FilePos { - private int col; //!< source text colomn - private int line; //!< source Line colomn - - /** - * default contructor (set line and col at 0) - */ - public FilePos() { - this.col = 0; - this.line = 0; - } - - /** - * initialize constructor - * @param line Line in the file - * @param col Colomn in the file - */ - public FilePos(final int line, final int col) { - this.col = col; - this.line = line; - } - - /** - * Addition operator - * @param obj Addition object.. - * @return Reference on this - */ - public FilePos add(final FilePos obj) { - if (obj.line == 0) { - this.col += obj.col; - } else { - this.col = obj.col; - this.line += obj.line; - } - return this; - } - - /** - * Colomn addition operator - * @param col Number of colomn to add - * @return Reference on this - */ - public FilePos add(final int col) { - this.col += col; - return this; - } - - /** - * Check if the value is a new line and update internal property - * @param val Char value to check - * @return true We find a new line - * @return false We NOT find a new line - */ - public boolean check(final Character val) { - this.col++; - if (val == '\n') { - newLine(); - return true; - } - return false; - } - - /** - * Reset position at 0,0 - */ - public void clear() { - this.col = 0; - this.line = 0; - } - - @Override - public FilePos clone() { - final FilePos out = new FilePos(); - out.col = this.col; - out.line = this.line; - return out; - } - - /** - * Decrement the colomn position - * @return Reference on this - */ - public FilePos decrement() { - this.col--; - return this; - } - - @Override - public boolean equals(final Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof FilePos)) { - return false; - } - final FilePos other = (FilePos) obj; - return this.col == other.col && this.line == other.line; - } - - /** - * Get the colomn position - * @return Colomn in number of utf8-char - */ - public int getCol() { - return this.col; - } - - /** - * Get the line number position - * @return line ID (start at 0) - */ - public int getLine() { - return this.line; - } - - @Override - public int hashCode() { - return super.hashCode() + this.line + this.col; - } - - /** - * Increment the colomn position - * @return Reference on this - */ - public FilePos increment() { - this.col++; - return this; - } - - /** - * Find a new line & reset colomn at 0 - */ - public void newLine() { - this.col = 0; - this.line++; - } - - /** - * Asignment operator - * @param obj Object to copy - * @return Reference on this - */ - public FilePos set(final FilePos obj) { - this.col = obj.col; - this.line = obj.line; - return this; - } - - /** - * Setter of specific data - * @param line Line in the file - * @param col Colomn in the file - */ - public void set(final int line, final int col) { - this.col = col; - this.line = line; - } - - @Override - public String toString() { - String out = "(l="; - out += this.line; - out += ",c="; - out += this.col; - out += ")"; - return out; - } - -} diff --git a/src/org/atriasoft/ejson/parser/ParseJson.java b/src/org/atriasoft/ejson/parser/ParseJson.java index 2c97764..8aa1ad5 100644 --- a/src/org/atriasoft/ejson/parser/ParseJson.java +++ b/src/org/atriasoft/ejson/parser/ParseJson.java @@ -5,6 +5,8 @@ import org.atriasoft.ejson.exception.EjsonBuilderException; import org.atriasoft.ejson.exception.EjsonParserError; import org.atriasoft.ejson.exception.EjsonParserErrorMulti; import org.atriasoft.ejson.internal.Log; +import org.atriasoft.etk.Tools; +import org.atriasoft.etk.util.FilePos; public class ParseJson { // global builder that is generate the final Tree @@ -30,6 +32,10 @@ public class ParseJson { } else if (data.charAt(iii) == ']') { // find end of value: pos.value = iii; // == > return the end element type ==> usefull to check end and check if adding element is needed + if (parent != null) { + // continue parsing without registering object ... + this.builder.endParsing(parent); + } return true; } else if (data.charAt(iii) == '{') { pos.value = iii + 1; @@ -133,13 +139,13 @@ public class ParseJson { } else if (data.charAt(iii) == '}') { // find an error .... parsingProperty.createError(new EjsonParserError(Tools.extractLine(data, iii), filePos, "Find '}' with no element in the element... Check if is not a ']' element (to stop array)")); - // move the curent index + // move the current index pos.value = iii + 1; return false; } else { // find an error .... parsingProperty.createError(new EjsonParserError(Tools.extractLine(data, iii + 1), filePos, "Find '" + data.charAt(iii) + "' with no element in the array...")); - // move the curent index + // move the current index pos.value = iii + 1; return false; } @@ -213,7 +219,6 @@ public class ParseJson { for (int iii = startPos; iii < data.length(); iii++) { //Log.verbose("parse Object: '{}'", data.charAt(iii)); filePos.check(data.charAt(iii)); - final FilePos tmpPos; if (data.charAt(iii) == ' ' || data.charAt(iii) == '\t' || data.charAt(iii) == '\n' || data.charAt(iii) == '\r') { // white space == > nothing to do ... } else if (data.charAt(iii) == '#') { @@ -226,6 +231,9 @@ public class ParseJson { } else if (data.charAt(iii) == '}') { // find end of value: pos.value = iii; // == > return the end element type ==> usefull to check end and check if adding element is needed + if (parent != null) { + this.builder.endParsing(parent); + } return true; } else if (mode == StatusParsing.parseName) { if (data.charAt(iii) == '"' || data.charAt(iii) == '\'') { @@ -428,6 +436,7 @@ public class ParseJson { } return null; } + this.builder.endParsing(rootNode); return rootNode; } diff --git a/src/org/atriasoft/ejson/parser/ParsingProperty.java b/src/org/atriasoft/ejson/parser/ParsingProperty.java index c7f8ad8..628845e 100644 --- a/src/org/atriasoft/ejson/parser/ParsingProperty.java +++ b/src/org/atriasoft/ejson/parser/ParsingProperty.java @@ -6,6 +6,7 @@ import java.util.List; import org.atriasoft.ejson.exception.EjsonParserError; import org.atriasoft.ejson.internal.Log; +import org.atriasoft.etk.Tools; public class ParsingProperty { /// check the case sensitive of the nodes (end marker) and attribute (duplicates) @@ -14,8 +15,6 @@ public class ParsingProperty { private final List errors = new ArrayList<>(); /// Permissive XML parsing (allows some errors must not be critical). private boolean permisiveXML = false; - // Mode to store the Element name or the Attibute name - private StoreMode storeMode = StoreMode.NORMAL; /// throw when an error when it is detected (if permissive XML it throw only at the end of parsing). private boolean throwOnError = true; /// write error when not throw on error. @@ -100,14 +99,6 @@ public class ParsingProperty { return Collections.unmodifiableList(this.errors); } - /** - * Get the current storing mode - * @return store element and attribute values - */ - public StoreMode getStoreMode() { - return this.storeMode; - } - /** * Check is error has been detected * @return true if some error are stored. @@ -156,14 +147,6 @@ public class ParsingProperty { this.permisiveXML = permisiveXML; } - /** - * Set the new storing mode for Element and Attributes - * @param storeMode new Storing mode - */ - public void setStoreMode(final StoreMode storeMode) { - this.storeMode = storeMode; - } - /** * Set throwing on error (if permissive, it throw at the end of parsing) * @param throwOnError true if it throw on error. diff --git a/src/org/atriasoft/ejson/parser/StoreMode.java b/src/org/atriasoft/ejson/parser/StoreMode.java deleted file mode 100644 index b53964a..0000000 --- a/src/org/atriasoft/ejson/parser/StoreMode.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.atriasoft.ejson.parser; - -public enum StoreMode { - NORMAL, - UPPERCASE, - LOWERCASE, -} diff --git a/src/org/atriasoft/ejson/parser/Tools.java b/src/org/atriasoft/ejson/parser/Tools.java deleted file mode 100644 index 35137a4..0000000 --- a/src/org/atriasoft/ejson/parser/Tools.java +++ /dev/null @@ -1,288 +0,0 @@ -package org.atriasoft.ejson.parser; - -public class Tools { - /** - * add indentation of the string input. - * @param data String where the indentation is done. - * @param indent Number of tab to add at the string. - */ - public static void addIndent(final StringBuilder data, final int indent) { - data.append("\t".repeat(Math.max(0, indent))); - } - - /** - * check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \\n\\t\\r and for first char : not -.0123456789). - * @param val Value to check the conformity. - * @param firstChar True if the element check is the first char. - * @return true The value can be a part of attribute name / false The value can NOT be a part of attribute name - */ - public static boolean checkAvaillable(final Character val, final boolean firstChar) { - if (val == '!' || val == '"' || val == '#' || val == '$' || val == '%' || val == '&' || val == '\'' // ' - || val == '(' || val == ')' || val == '*' || val == '+' || val == ',' || val == '/' || val == ';' || val == '<' || val == '=' || val == '>' || val == '?' || val == '@' || val == '[' - || val == '\\' || val == ']' || val == '^' || val == '`' || val == '{' || val == '|' || val == '}' || val == '~' || val == ' ' || val == '\n' || val == '\t' || val == '\r') { - return false; - } - if (firstChar) { - if (val == '-' || val == '.' || (val >= '0' && val <= '9')) { - return false; - } - } - return true; - } - - public static boolean checkNumber(final Character val) { - if (val == '-' || val == '+' || val == 'e' || val == '.' || (val >= '0' && val <= '9')) { - return true; - } - return false; - } - - public static boolean checkString(final Character val) { - if (val == '!' || val == '"' || val == '#' || val == '$' || val == '%' || val == '&' || val == '\'' // ' - || val == '(' || val == ')' || val == '*' || val == '+' || val == ',' || val == '/' || val == ':' || val == ';' || val == '<' || val == '=' || val == '>' || val == '?' || val == '@' - || val == '[' || val == '\\' || val == ']' || val == '^' || val == '`' || val == '{' || val == '|' || val == '}' || val == '~' || val == ' ' || val == '\n' || val == '\t' - || val == '\r') { - return false; - } - return true; - } - - public static String cleanNumberList(final String data) { - return data.replaceAll("[ \t\n\r]", "").replaceAll(",", ";"); - } - - /** - * count the number of white char in the string from the specify position (stop at the first element that is not a white char) - * @param data Data to parse. - * @param pos Start position in the string. - * @param filePos new poistion of te file to add. - * @return number of white element. - */ - public static int countWhiteChar(final String data, final int pos, final FilePos filePos) { - filePos.clear(); - int white = 0; - for (int iii = pos; iii < data.length(); iii++) { - filePos.check(data.charAt(iii)); - if (!Tools.isWhiteChar(data.charAt(iii))) { - break; - } - white++; - } - filePos.decrement(); - return white; - } - - public static String createPosPointer(final String line, final int pos) { - final StringBuilder out = new StringBuilder(); - int iii; - for (iii = 0; iii < pos && iii < line.length(); iii++) { - if (line.charAt(iii) == '\t') { - out.append("\t"); - } else { - out.append(" "); - } - } - for (; iii < pos; iii++) { - out.append(" "); - } - out.append("^"); - return out.toString(); - } - - // based on this: https://stackoverflow.com/questions/4052840/most-efficient-way-to-make-the-first-character-of-a-string-lower-case - public static String decapitalizeFirst(final String string) { - if (string == null || string.length() == 0) { - return string; - } - final char[] c = string.toCharArray(); - c[0] = Character.toLowerCase(c[0]); - return new String(c); - } - - /** - * Display the current element that is currently parse. - * @param val Char that is parsed. - * @param filePos Position of the char in the file. - */ - public static void drawElementParsed(final Character val, final FilePos filePos) { - // if (val == '\n') { - // Log.debug("{} parse '\\n'", filePos); - // } else if (val == '\t') { - // Log.debug("{} parse '\\t'", filePos); - // } else { - // Log.debug("{} parse '{}'", filePos, val); - // } - } - - public static String extractLine(final String data, final int pos) { - // search back : '\n' - int startPos = data.lastIndexOf('\n', pos); - if (startPos == pos) { - startPos = 0; - } else { - startPos++; - } - // search forward : '\n' - int stopPos = pos; - if (data.length() != pos && data.charAt(pos) != '\n') { - stopPos = data.indexOf('\n', pos); - if (stopPos == pos) { - stopPos = data.length(); - } - } - if (startPos >= data.length()) { - return ""; - } - if (stopPos == -1) { - return ""; - } - if (stopPos >= data.length()) { - stopPos = data.length(); - } - return data.substring(startPos, stopPos); - } - - public static boolean isWhiteChar(final Character val) { - return val == ' ' || val == '\t' || val == '\n' || val == '\r'; - } - - public static Boolean[] parseBooleanClassStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final Boolean[] out = new Boolean[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Boolean.valueOf(str); - } - return out; - } - - public static boolean[] parseBooleanStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final boolean[] out = new boolean[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Boolean.parseBoolean(str); - } - return out; - } - - public static Byte[] parseByteClassStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final Byte[] out = new Byte[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Byte.parseByte(str); - } - return out; - } - - public static byte[] parseByteStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final byte[] out = new byte[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Byte.parseByte(str); - } - return out; - } - - public static Integer[] parseIntegerClassStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final Integer[] out = new Integer[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Integer.parseInt(str); - } - return out; - } - - public static int[] parseIntegerStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final int[] out = new int[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Integer.parseInt(str); - } - return out; - } - - public static Long[] parseLongClassStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final Long[] out = new Long[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Long.parseLong(str); - } - return out; - } - - public static long[] parseLongStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final long[] out = new long[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Long.parseLong(str); - } - return out; - } - - public static Short[] parseShortClassStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final Short[] out = new Short[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Short.parseShort(str); - } - return out; - } - - public static short[] parseShortStringList(String data) { // throws NumberFormatException - data = Tools.cleanNumberList(data); - final String[] dataArray = data.split(";"); - final short[] out = new short[dataArray.length]; - int count = 0; - for (final String str : dataArray) { - out[count++] = Short.parseShort(str); - } - return out; - } - - // transform the Text with : - // "<" == "<" - // ">" == ">" - // "&" == "&" - // "'" == "'" - // """ == """ - public static String replaceSpecialChar(final String inval) { - String out = inval; - out = out.replace("<", "<"); - out = out.replace(">", ">"); - out = out.replace("'", "'"); - out = out.replace(""", "\""); - out = out.replace("&", "&"); - //EXMLERROR("INNN '"<< inval << "' => '" << out << "'"); - return out; - } - - public static String replaceSpecialCharOut(final String inval) { - String out = inval; - out = out.replace("<", "<"); - out = out.replace(">", ">"); - out = out.replace("'", "'"); - out = out.replace("\"", """); - out = out.replace("&", "&"); - //EXMLERROR("OUTTT '"<< inval << "' => '" << out << "'"); - return out; - } - - private Tools() {} -} diff --git a/test/src/test/atriasoft/ejson/EjsonLocal.java b/test/src/test/atriasoft/ejson/generic/EjsonLocal.java similarity index 93% rename from test/src/test/atriasoft/ejson/EjsonLocal.java rename to test/src/test/atriasoft/ejson/generic/EjsonLocal.java index db1f160..c422d84 100644 --- a/test/src/test/atriasoft/ejson/EjsonLocal.java +++ b/test/src/test/atriasoft/ejson/generic/EjsonLocal.java @@ -3,12 +3,14 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.generic; import org.atriasoft.ejson.Ejson; import org.atriasoft.ejson.model.JsonNode; import org.junit.jupiter.api.Assertions; +import test.atriasoft.ejson.internal.Log; + class EjsonLocal { // errorPos : -1 : no error , 1 : parsing error, 2 generation error, 3 comparaison error ???? public static void test(final String ref, final String input, final int errorPos) { diff --git a/test/src/test/atriasoft/ejson/EjsonTestAll.java b/test/src/test/atriasoft/ejson/generic/EjsonTestAll.java similarity index 99% rename from test/src/test/atriasoft/ejson/EjsonTestAll.java rename to test/src/test/atriasoft/ejson/generic/EjsonTestAll.java index 270a8cc..f0331e4 100644 --- a/test/src/test/atriasoft/ejson/EjsonTestAll.java +++ b/test/src/test/atriasoft/ejson/generic/EjsonTestAll.java @@ -3,11 +3,13 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.generic; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import test.atriasoft.ejson.internal.Log; + public class EjsonTestAll { //@formatter:off private static String refOutputAll = "{\n" diff --git a/test/src/test/atriasoft/ejson/EjsonTestBoolean.java b/test/src/test/atriasoft/ejson/generic/EjsonTestBoolean.java similarity index 96% rename from test/src/test/atriasoft/ejson/EjsonTestBoolean.java rename to test/src/test/atriasoft/ejson/generic/EjsonTestBoolean.java index 81127dc..c0da106 100644 --- a/test/src/test/atriasoft/ejson/EjsonTestBoolean.java +++ b/test/src/test/atriasoft/ejson/generic/EjsonTestBoolean.java @@ -3,12 +3,14 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.generic; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import test.atriasoft.ejson.internal.Log; + public class EjsonTestBoolean { private static String refOutputBoolean1 = "{\n\t\"tmpElement\": true\n}"; diff --git a/test/src/test/atriasoft/ejson/EjsonTestNull.java b/test/src/test/atriasoft/ejson/generic/EjsonTestNull.java similarity index 93% rename from test/src/test/atriasoft/ejson/EjsonTestNull.java rename to test/src/test/atriasoft/ejson/generic/EjsonTestNull.java index f2638b3..7f32d74 100644 --- a/test/src/test/atriasoft/ejson/EjsonTestNull.java +++ b/test/src/test/atriasoft/ejson/generic/EjsonTestNull.java @@ -3,12 +3,14 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.generic; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import test.atriasoft.ejson.internal.Log; + public class EjsonTestNull { private static final String REF_OUTPUT_NULL = "{\n\t\"tmpElement\": null\n}"; diff --git a/test/src/test/atriasoft/ejson/EjsonTestNumber.java b/test/src/test/atriasoft/ejson/generic/EjsonTestNumber.java similarity index 93% rename from test/src/test/atriasoft/ejson/EjsonTestNumber.java rename to test/src/test/atriasoft/ejson/generic/EjsonTestNumber.java index f2511cf..dcfbf40 100644 --- a/test/src/test/atriasoft/ejson/EjsonTestNumber.java +++ b/test/src/test/atriasoft/ejson/generic/EjsonTestNumber.java @@ -3,12 +3,14 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.generic; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import test.atriasoft.ejson.internal.Log; + public class EjsonTestNumber { private static final String REF_OUTPUT_NUMBER = "{\n\t\"tmpElement\": 956256\n}"; diff --git a/test/src/test/atriasoft/ejson/Log.java b/test/src/test/atriasoft/ejson/internal/Log.java similarity index 98% rename from test/src/test/atriasoft/ejson/Log.java rename to test/src/test/atriasoft/ejson/internal/Log.java index ce0fcdc..ac4648d 100644 --- a/test/src/test/atriasoft/ejson/Log.java +++ b/test/src/test/atriasoft/ejson/internal/Log.java @@ -3,7 +3,7 @@ * @copyright 2021, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -package test.atriasoft.ejson; +package test.atriasoft.ejson.internal; import io.scenarium.logger.LogLevel; import io.scenarium.logger.Logger; diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassInversion.java b/test/src/test/atriasoft/ejson/introspection/model/ClassInversion.java new file mode 100644 index 0000000..fb667a9 --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassInversion.java @@ -0,0 +1,8 @@ +package test.atriasoft.ejson.introspection.model; + +import org.atriasoft.aknot.annotation.AknotDefaultManaged; + +@AknotDefaultManaged(value = false) +public class ClassInversion { + +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java b/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java new file mode 100644 index 0000000..74df72d --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java @@ -0,0 +1,17 @@ +package test.atriasoft.ejson.introspection.model; + +import org.atriasoft.aknot.annotation.AknotName; + +@AknotName("elem") +public class ClassMethodEnum { + private SimpleEnum data; + + public SimpleEnum getData() { + return this.data; + } + + public void setData(final SimpleEnum data) { + this.data = data; + } + +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMemberOnly.java b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMemberOnly.java new file mode 100644 index 0000000..95219a7 --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMemberOnly.java @@ -0,0 +1,31 @@ +package test.atriasoft.ejson.introspection.model; + +import org.atriasoft.aknot.annotation.AknotDefaultAttribute; +import org.atriasoft.aknot.annotation.AknotName; + +@AknotDefaultAttribute +@AknotName("elem") +public class ClassPublicMemberOnly { + public boolean[] memberArrayBoolean; + public Boolean[] memberArrayBooleanClass; + public byte[] memberArrayByte; + public Byte[] memberArrayByteClass; + public int[] memberArrayInteger; + public Integer[] memberArrayIntegerClass; + public long[] memberArrayLong; + public Long[] memberArrayLongClass; + public short[] memberArrayShort; + public Short[] memberArrayShortClass; + public boolean memberBoolean; + public Boolean memberBooleanClass; + //this work !!! @AKName(value = "jhkjhhkj") + public byte memberByte; + public Byte memberByteClass; + public int memberInteger; + public Integer memberIntegerClass; + public long memberLong; + public Long memberLongClass; + public short memberShort; + public Short memberShortClass; + public String memberStringClass; +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodOnly.java b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodOnly.java new file mode 100644 index 0000000..067178b --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodOnly.java @@ -0,0 +1,198 @@ +package test.atriasoft.ejson.introspection.model; + +import org.atriasoft.aknot.annotation.AknotDefaultAttribute; +import org.atriasoft.aknot.annotation.AknotName; + +@AknotDefaultAttribute +@AknotName("elem") +public class ClassPublicMethodOnly { + private boolean[] memberArrayBoolean; + private Boolean[] memberArrayBooleanClass; + private byte[] memberArrayByte; + private Byte[] memberArrayByteClass; + private int[] memberArrayInteger; + private Integer[] memberArrayIntegerClass; + private long[] memberArrayLong; + private Long[] memberArrayLongClass; + private short[] memberArrayShort; + private Short[] memberArrayShortClass; + private boolean memberBoolean; + private Boolean memberBooleanClass; + private byte memberByte; + private Byte memberByteClass; + private int memberInteger; + private Integer memberIntegerClass; + private long memberLong; + private Long memberLongClass; + private short memberShort; + private Short memberShortClass; + private String memberStringClass; + + public boolean[] getMemberArrayBoolean() { + return this.memberArrayBoolean; + } + + public Boolean[] getMemberArrayBooleanClass() { + return this.memberArrayBooleanClass; + } + + public byte[] getMemberArrayByte() { + return this.memberArrayByte; + } + + public Byte[] getMemberArrayByteClass() { + return this.memberArrayByteClass; + } + + public int[] getMemberArrayInteger() { + return this.memberArrayInteger; + } + + public Integer[] getMemberArrayIntegerClass() { + return this.memberArrayIntegerClass; + } + + public long[] getMemberArrayLong() { + return this.memberArrayLong; + } + + public Long[] getMemberArrayLongClass() { + return this.memberArrayLongClass; + } + + public short[] getMemberArrayShort() { + return this.memberArrayShort; + } + + public Short[] getMemberArrayShortClass() { + return this.memberArrayShortClass; + } + + public byte getMemberByte() { + return this.memberByte; + } + + public Byte getMemberByteClass() { + return this.memberByteClass; + } + + public int getMemberInteger() { + return this.memberInteger; + } + + public Integer getMemberIntegerClass() { + return this.memberIntegerClass; + } + + public long getMemberLong() { + return this.memberLong; + } + + public Long getMemberLongClass() { + return this.memberLongClass; + } + + public short getMemberShort() { + return this.memberShort; + } + + public Short getMemberShortClass() { + return this.memberShortClass; + } + + public String getMemberStringClass() { + return this.memberStringClass; + } + + public boolean isMemberBoolean() { + return this.memberBoolean; + } + + public Boolean isMemberBooleanClass() { + return this.memberBooleanClass; + } + + public void setMemberArrayBoolean(final boolean[] memberArrayBoolean) { + this.memberArrayBoolean = memberArrayBoolean; + } + + public void setMemberArrayBooleanClass(final Boolean[] memberArrayBooleanClass) { + this.memberArrayBooleanClass = memberArrayBooleanClass; + } + + public void setMemberArrayByte(final byte[] memberArrayByte) { + this.memberArrayByte = memberArrayByte; + } + + public void setMemberArrayByteClass(final Byte[] memberArrayByteClass) { + this.memberArrayByteClass = memberArrayByteClass; + } + + public void setMemberArrayInteger(final int[] memberArrayInteger) { + this.memberArrayInteger = memberArrayInteger; + } + + public void setMemberArrayIntegerClass(final Integer[] memberArrayIntegerClass) { + this.memberArrayIntegerClass = memberArrayIntegerClass; + } + + public void setMemberArrayLong(final long[] memberArrayLong) { + this.memberArrayLong = memberArrayLong; + } + + public void setMemberArrayLongClass(final Long[] memberArrayLongClass) { + this.memberArrayLongClass = memberArrayLongClass; + } + + public void setMemberArrayShort(final short[] memberArrayShort) { + this.memberArrayShort = memberArrayShort; + } + + public void setMemberArrayShortClass(final Short[] memberArrayShortClass) { + this.memberArrayShortClass = memberArrayShortClass; + } + + public void setMemberBoolean(final boolean memberBoolean) { + this.memberBoolean = memberBoolean; + } + + public void setMemberBooleanClass(final Boolean memberBooleanClass) { + this.memberBooleanClass = memberBooleanClass; + } + + public void setMemberByte(final byte memberByte) { + this.memberByte = memberByte; + } + + public void setMemberByteClass(final Byte memberByteClass) { + this.memberByteClass = memberByteClass; + } + + public void setMemberInteger(final int memberInteger) { + this.memberInteger = memberInteger; + } + + public void setMemberIntegerClass(final Integer memberIntegerClass) { + this.memberIntegerClass = memberIntegerClass; + } + + public void setMemberLong(final long memberLong) { + this.memberLong = memberLong; + } + + public void setMemberLongClass(final Long memberLongClass) { + this.memberLongClass = memberLongClass; + } + + public void setMemberShort(final short memberShort) { + this.memberShort = memberShort; + } + + public void setMemberShortClass(final Short memberShortClass) { + this.memberShortClass = memberShortClass; + } + + public void setMemberStringClass(final String memberStringClass) { + this.memberStringClass = memberStringClass; + } +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeNode.java b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeNode.java new file mode 100644 index 0000000..4bb5c61 --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeNode.java @@ -0,0 +1,248 @@ +package test.atriasoft.ejson.introspection.model; + +import java.util.List; + +import org.atriasoft.aknot.annotation.AknotName; + +@AknotName("elem") +public class ClassPublicMethodeNode { + + private boolean[] memberArrayBoolean; + private Boolean[] memberArrayBooleanClass; + private byte[] memberArrayByte; + private Byte[] memberArrayByteClass; + private int[] memberArrayInteger; + private Integer[] memberArrayIntegerClass; + private long[] memberArrayLong; + private Long[] memberArrayLongClass; + private short[] memberArrayShort; + private Short[] memberArrayShortClass; + private List memberListBooleanClass; + private List memberListByteClass; + private List memberListIntegerClass; + private List memberListLongClass; + private List memberListShortClass; + private boolean memberBoolean; + private Boolean memberBooleanClass; + private byte memberByte; + private Byte memberByteClass; + private int memberInteger; + private Integer memberIntegerClass; + private long memberLong; + private Long memberLongClass; + private short memberShort; + private Short memberShortClass; + private String memberStringClass; + + public boolean[] getMemberArrayBoolean() { + return this.memberArrayBoolean; + } + + public Boolean[] getMemberArrayBooleanClass() { + return this.memberArrayBooleanClass; + } + + public byte[] getMemberArrayByte() { + return this.memberArrayByte; + } + + public Byte[] getMemberArrayByteClass() { + return this.memberArrayByteClass; + } + + public int[] getMemberArrayInteger() { + return this.memberArrayInteger; + } + + public Integer[] getMemberArrayIntegerClass() { + return this.memberArrayIntegerClass; + } + + public long[] getMemberArrayLong() { + return this.memberArrayLong; + } + + public Long[] getMemberArrayLongClass() { + return this.memberArrayLongClass; + } + + public short[] getMemberArrayShort() { + return this.memberArrayShort; + } + + public Short[] getMemberArrayShortClass() { + return this.memberArrayShortClass; + } + + public Boolean getMemberBooleanClass() { + return this.memberBooleanClass; + } + + public byte getMemberByte() { + return this.memberByte; + } + + public Byte getMemberByteClass() { + return this.memberByteClass; + } + + public int getMemberInteger() { + return this.memberInteger; + } + + public Integer getMemberIntegerClass() { + return this.memberIntegerClass; + } + + public List getMemberListBooleanClass() { + return this.memberListBooleanClass; + } + + public List getMemberListByteClass() { + return this.memberListByteClass; + } + + public List getMemberListIntegerClass() { + return this.memberListIntegerClass; + } + + public List getMemberListLongClass() { + return this.memberListLongClass; + } + + public List getMemberListShortClass() { + return this.memberListShortClass; + } + + public long getMemberLong() { + return this.memberLong; + } + + public Long getMemberLongClass() { + return this.memberLongClass; + } + + public short getMemberShort() { + return this.memberShort; + } + + public Short getMemberShortClass() { + return this.memberShortClass; + } + + public String getMemberStringClass() { + return this.memberStringClass; + } + + public boolean isMemberBoolean() { + return this.memberBoolean; + } + + public Boolean isMemberBooleanClass() { + return this.memberBooleanClass; + } + + public void setMemberArrayBoolean(final boolean[] memberArrayBoolean) { + this.memberArrayBoolean = memberArrayBoolean; + } + + public void setMemberArrayBooleanClass(final Boolean[] memberArrayBooleanClass) { + this.memberArrayBooleanClass = memberArrayBooleanClass; + } + + public void setMemberArrayByte(final byte[] memberArrayByte) { + this.memberArrayByte = memberArrayByte; + } + + public void setMemberArrayByteClass(final Byte[] memberArrayByteClass) { + this.memberArrayByteClass = memberArrayByteClass; + } + + public void setMemberArrayInteger(final int[] memberArrayInteger) { + this.memberArrayInteger = memberArrayInteger; + } + + public void setMemberArrayIntegerClass(final Integer[] memberArrayIntegerClass) { + this.memberArrayIntegerClass = memberArrayIntegerClass; + } + + public void setMemberArrayLong(final long[] memberArrayLong) { + this.memberArrayLong = memberArrayLong; + } + + public void setMemberArrayLongClass(final Long[] memberArrayLongClass) { + this.memberArrayLongClass = memberArrayLongClass; + } + + public void setMemberArrayShort(final short[] memberArrayShort) { + this.memberArrayShort = memberArrayShort; + } + + public void setMemberArrayShortClass(final Short[] memberArrayShortClass) { + this.memberArrayShortClass = memberArrayShortClass; + } + + public void setMemberBoolean(final boolean memberBoolean) { + this.memberBoolean = memberBoolean; + } + + public void setMemberBooleanClass(final Boolean memberBooleanClass) { + this.memberBooleanClass = memberBooleanClass; + } + + public void setMemberByte(final byte memberByte) { + this.memberByte = memberByte; + } + + public void setMemberByteClass(final Byte memberByteClass) { + this.memberByteClass = memberByteClass; + } + + public void setMemberInteger(final int memberInteger) { + this.memberInteger = memberInteger; + } + + public void setMemberIntegerClass(final Integer memberIntegerClass) { + this.memberIntegerClass = memberIntegerClass; + } + + public void setMemberListBooleanClass(final List memberListBooleanClass) { + this.memberListBooleanClass = memberListBooleanClass; + } + + public void setMemberListByteClass(final List memberListByteClass) { + this.memberListByteClass = memberListByteClass; + } + + public void setMemberListIntegerClass(final List memberListIntegerClass) { + this.memberListIntegerClass = memberListIntegerClass; + } + + public void setMemberListLongClass(final List memberListLongClass) { + this.memberListLongClass = memberListLongClass; + } + + public void setMemberListShortClass(final List memberListShortClass) { + this.memberListShortClass = memberListShortClass; + } + + public void setMemberLong(final long memberLong) { + this.memberLong = memberLong; + } + + public void setMemberLongClass(final Long memberLongClass) { + this.memberLongClass = memberLongClass; + } + + public void setMemberShort(final short memberShort) { + this.memberShort = memberShort; + } + + public void setMemberShortClass(final Short memberShortClass) { + this.memberShortClass = memberShortClass; + } + + public void setMemberStringClass(final String memberStringClass) { + this.memberStringClass = memberStringClass; + } +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeStructured.java b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeStructured.java new file mode 100644 index 0000000..702b766 --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicMethodeStructured.java @@ -0,0 +1,32 @@ +package test.atriasoft.ejson.introspection.model; + +import java.util.List; + +import org.atriasoft.aknot.annotation.AknotList; +import org.atriasoft.aknot.annotation.AknotName; + +@AknotName("elem") +public class ClassPublicMethodeStructured { + // note: when private the decorator must be set on getter or setter, liker this you can use the internal name you want... + private byte[] memberArrayByte; + private List memberListByte; + + @AknotList(value = "value") + public byte[] getMemberArrayByte() { + return this.memberArrayByte; + } + + @AknotList(value = "elem") + public List getMemberListByte() { + return this.memberListByte; + } + + public void setMemberArrayByte(final byte[] memberArrayByte) { + this.memberArrayByte = memberArrayByte; + } + + public void setMemberListByte(final List memberListByte) { + this.memberListByte = memberListByte; + } + +} diff --git a/test/src/test/atriasoft/ejson/introspection/model/SimpleEnum.java b/test/src/test/atriasoft/ejson/introspection/model/SimpleEnum.java new file mode 100644 index 0000000..1558aa5 --- /dev/null +++ b/test/src/test/atriasoft/ejson/introspection/model/SimpleEnum.java @@ -0,0 +1,7 @@ +package test.atriasoft.ejson.introspection.model; + +public enum SimpleEnum { + PLIF, + PLAF, + PROUT; +}