diff --git a/.gitignore b/.gitignore index 8f242ff..38a19dd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ # Mobile Tools for Java (J2ME) .mtj.tmp/ +# vim swap files +*.swp + # Package Files # *.jar !gradle-wrapper.jar diff --git a/.gradle/6.3/executionHistory/executionHistory.lock b/.gradle/6.3/executionHistory/executionHistory.lock deleted file mode 100644 index a7604be..0000000 Binary files a/.gradle/6.3/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/6.3/fileChanges/last-build.bin b/.gradle/6.3/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/6.3/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/6.3/fileHashes/fileHashes.lock b/.gradle/6.3/fileHashes/fileHashes.lock deleted file mode 100644 index 2b22044..0000000 Binary files a/.gradle/6.3/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/6.3/gc.properties b/.gradle/6.3/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/6.5/executionHistory/executionHistory.bin b/.gradle/6.5/executionHistory/executionHistory.bin deleted file mode 100644 index ca60313..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.bin and /dev/null differ diff --git a/.gradle/6.5/executionHistory/executionHistory.lock b/.gradle/6.5/executionHistory/executionHistory.lock deleted file mode 100644 index 7ae781a..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/6.5/fileChanges/last-build.bin b/.gradle/6.5/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/6.5/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.bin b/.gradle/6.5/fileHashes/fileHashes.bin deleted file mode 100644 index adb536e..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.lock b/.gradle/6.5/fileHashes/fileHashes.lock deleted file mode 100644 index b89035b..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/6.5/gc.properties b/.gradle/6.5/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index 125640c..0000000 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index b774acd..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Thu Oct 08 23:16:29 MSK 2020 -gradle.version=6.3 diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock deleted file mode 100644 index 2cf264e..0000000 Binary files a/.gradle/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index c8b5c9a..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 87ca0fc..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index fdc392f..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index b0ec460..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index c29a8be..5fdd5a6 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,12 @@ -# Примеры для курса "Разработчик Java" в OTUS +Напишите свой json object writer (object to JSON string) аналогичный gson на основе javax.json. -Группа 2020-09 +Gson это делает так: Gson gson = new Gson(); AnyObject obj = new AnyObject(22, "test", 10); String json = gson.toJson(obj); -### Преподаватели -Сергей Петрелевич
-Стрекалов Павел
-Александр Оруджев
-Вячеслав Лапин
-Виталий Куценко
-Дмитрий Коган +Сделайте так: MyGson myGson = new MyGson(); AnyObject obj = new AnyObject(22, "test", 10); String myJson = myGson.toJson(obj); -Студент: -Kashapov Renat (Кашапов Ренат)
-renat.kashapov@gmail.com \ No newline at end of file +Должно получиться: AnyObject obj2 = gson.fromJson(myJson, AnyObject.class); System.out.println(obj.equals(obj2)); + +Поддержите: + +примитивные типы и Wrapper-ы (Integer, Float и т.д.) строки массивы примитивных типов коллекции (interface Collection) +Не забываться, что obj может быть null :) diff --git a/hw08-MyGSON/build.gradle b/hw08-MyGSON/build.gradle new file mode 100644 index 0000000..b922f72 --- /dev/null +++ b/hw08-MyGSON/build.gradle @@ -0,0 +1,36 @@ +plugins { + id 'java' +} + +group 'ru.otus' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + // https://mvnrepository.com/artifact/com.google.code.gson/gson + compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6' + // https://mvnrepository.com/artifact/javax.json/javax.json-api + compile group: 'javax.json', name: 'javax.json-api', version: '1.1.4' + // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0' + // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.7.0' + // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.7.0' + // https://mvnrepository.com/artifact/org.assertj/assertj-core + testCompile group: 'org.assertj', name: 'assertj-core', version: '3.18.1' + // https://mvnrepository.com/artifact/org.mockito/mockito-core + testCompile group: 'org.mockito', name: 'mockito-core', version: '3.6.28' + // https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter + testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '3.6.28' + // https://mvnrepository.com/artifact/org.glassfish/javax.json + compile group: 'org.glassfish', name: 'javax.json', version: '1.1.4' + +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/hw08-MyGSON/src/main/java/ru/otus/MyGson.java b/hw08-MyGSON/src/main/java/ru/otus/MyGson.java new file mode 100644 index 0000000..031b1ff --- /dev/null +++ b/hw08-MyGSON/src/main/java/ru/otus/MyGson.java @@ -0,0 +1,290 @@ +package ru.otus; + +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class MyGson { + + static final private Set> supportedNonJsonficationClassesSet = new HashSet<>(); + + static { + supportedNonJsonficationClassesSet.add(Boolean.class); + supportedNonJsonficationClassesSet.add(Byte.class); + supportedNonJsonficationClassesSet.add(Character.class); + supportedNonJsonficationClassesSet.add(Double.class); + supportedNonJsonficationClassesSet.add(Float.class); + supportedNonJsonficationClassesSet.add(Integer.class); + supportedNonJsonficationClassesSet.add(Long.class); + supportedNonJsonficationClassesSet.add(Short.class); + supportedNonJsonficationClassesSet.add(String.class); + supportedNonJsonficationClassesSet.add(Number.class); + } + + public String toJson(Object obj) { + switch (defineObjectSort(obj)) { + case "ArrayOrCollection": + return myGsonCreateArrayBuilder(obj).build().toString(); + case "PrimitiveOrWrapperOrString": + return obj.toString(); + case "Custom": + return myGsonCreateObjectBuilder(obj).build().toString(); + default: + return "null"; + } + } + + private void putPrimitiveToJsonArrayBuilder(JsonArrayBuilder jsonArrayBuilder, Object primitive) throws IllegalAccessException { + switch (primitive.getClass().getName()) { + case "boolean": + case "java.lang.Boolean": + jsonArrayBuilder.add((boolean) primitive); + break; + case "byte": + case "java.lang.Byte": + jsonArrayBuilder.add((byte) primitive); + break; + case "char": + case "java.lang.Character": + jsonArrayBuilder.add((char) primitive); + break; + case "double": + case "java.lang.Double": + jsonArrayBuilder.add((double) primitive); + break; + case "float": + case "java.lang.Float": + jsonArrayBuilder.add((float) primitive); + break; + case "int": + case "java.lang.Integer": + jsonArrayBuilder.add((int) primitive); + break; + case "long": + case "java.lang.Long": + jsonArrayBuilder.add((long) primitive); + break; + case "short": + case "java.lang.Short": + jsonArrayBuilder.add((short) primitive); + break; + case "java.lang.String": + jsonArrayBuilder.add((String) primitive); + break; + default: + } + + } + + private void putPrimitiveFieldToJson(JsonObjectBuilder jsonObjectBuilder, Object obj, Field field) throws IllegalAccessException { + switch (field.getType().getName()) { + case "java.lang.Boolean": + jsonObjectBuilder.add(field.getName(),(Boolean) field.get(obj)); + break; + case "boolean": + jsonObjectBuilder.add(field.getName(), field.getBoolean(obj)); + break; + case "java.lang.Byte": + jsonObjectBuilder.add(field.getName(),(Byte)field.get(obj)); + break; + case "byte": + jsonObjectBuilder.add(field.getName(), field.getByte(obj)); + break; + case "java.lang.Character": + jsonObjectBuilder.add(field.getName(),(Character)field.get(obj)); + break; + case "char": + jsonObjectBuilder.add(field.getName(), field.getChar(obj)); + break; + case "java.lang.Double": + jsonObjectBuilder.add(field.getName(),(Double)field.get(obj)); + break; + case "double": + jsonObjectBuilder.add(field.getName(), field.getDouble(obj)); + break; + case "java.lang.Float": + jsonObjectBuilder.add(field.getName(),(Float)field.get(obj)); + break; + case "float": + jsonObjectBuilder.add(field.getName(), field.getFloat(obj)); + break; + case "java.lang.Long": + jsonObjectBuilder.add(field.getName(),(Long)field.get(obj)); + break; + case "long": + jsonObjectBuilder.add(field.getName(), field.getLong(obj)); + break; + case "java.lang.Integer": + jsonObjectBuilder.add(field.getName(), (Integer) field.get(obj)); + break; + case "int": + jsonObjectBuilder.add(field.getName(), field.getInt(obj)); + break; + case "java.lang.Short": + jsonObjectBuilder.add(field.getName(), (Short) field.get(obj)); + break; + case "short": + jsonObjectBuilder.add(field.getName(), field.getShort(obj)); + break; + default: + jsonObjectBuilder.add(field.getName(), field.get(obj).toString()); + } + } + + private String defineObjectSort(Object obj) { + if (obj == null) { + return "Null"; + } + if (obj.getClass().isArray() || obj instanceof Collection) { + return "ArrayOrCollection"; + } else { + if (obj.getClass().isPrimitive() || supportedNonJsonficationClassesSet.contains(obj.getClass())) { + return "PrimitiveOrWrapperOrString"; + } + } + return "Custom"; + } + + private JsonObjectBuilder myGsonCreateObjectBuilder(Object obj) { + JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder(); + Class clazz = obj.getClass(); + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + try { + switch (defineObjectSort(field.get(obj))) { + case "Custom": + jsonObjectBuilder.add(field.getName(), myGsonCreateObjectBuilder(field.get(obj))); + break; + case "ArrayOrCollection": + jsonObjectBuilder.add(field.getName(), myGsonCreateArrayBuilder(field.get(obj))); + break; + case "PrimitiveOrWrapperOrString": + putPrimitiveFieldToJson(jsonObjectBuilder, obj, field); + break; + case "Null": + default: + } + } catch (IllegalAccessException illegalAccessException) { + System.out.println("Accessibility to field " + field.getName() + " doesn't set."); + } + field.setAccessible(false); + } + return jsonObjectBuilder; + } + + private JsonArrayBuilder myGsonCreateArrayBuilder(Object obj) { + JsonArrayBuilder jsonArrayBuilder = Json.createArrayBuilder(); + if (obj instanceof Collection) { + Iterator iterator = ((Collection) obj).iterator(); + while (iterator.hasNext()) { + Object object = iterator.next(); + switch (defineObjectSort(object)) { + case "Null": + break; + case "ArrayOrCollection": + jsonArrayBuilder.add(myGsonCreateArrayBuilder(object)); + break; + case "PrimitiveOrWrapperOrString": + try { + putPrimitiveToJsonArrayBuilder(jsonArrayBuilder, object); + } catch (IllegalAccessException illegalAccessException) { + illegalAccessException.printStackTrace(); + } + break; + case "Custom": + jsonArrayBuilder.add(myGsonCreateObjectBuilder(object)); + break; + default: + } + } + } else { + if (obj.getClass().getComponentType().isPrimitive() + || supportedNonJsonficationClassesSet.contains(obj.getClass().getComponentType())) { + putPrimitiveArrayToJsonArrayBuilder(jsonArrayBuilder, obj); + } else { + Object[] objectArray = (Object[]) obj; + for (Object object : objectArray) { + jsonArrayBuilder.add(myGsonCreateObjectBuilder(object)); + } + } + + } + return jsonArrayBuilder; + } + + private void putPrimitiveArrayToJsonArrayBuilder(JsonArrayBuilder jsonArrayBuilder, Object primitiveArray) { + switch (primitiveArray.getClass().getComponentType().getName()) { + case "boolean": + case "java.lang.Boolean": + boolean[] booleans = (boolean[]) primitiveArray; + for (boolean booleanExemplar : booleans) { + jsonArrayBuilder.add(booleanExemplar); + } + break; + case "byte": + case "java.lang.Byte": + byte[] bytes = (byte[]) primitiveArray; + for (byte byteExemplar : bytes) { + jsonArrayBuilder.add(byteExemplar); + } + break; + case "char": + case "java.lang.Character": + char[] chars = (char[]) primitiveArray; + for (char charExemplar : chars) { + jsonArrayBuilder.add(charExemplar); + } + break; + case "double": + case "java.lang.Double": + double[] doubles = (double[]) primitiveArray; + for (double doubleExemplar : doubles) { + jsonArrayBuilder.add(doubleExemplar); + } + break; + case "float": + case "java.lang.Float": + float[] floats = (float[]) primitiveArray; + for (float floatExemplar : floats) { + jsonArrayBuilder.add(floatExemplar); + } + break; + case "int": + case "java.lang.Integer": + int[] ints = (int[]) primitiveArray; + for (int intExemplar : ints) { + jsonArrayBuilder.add(intExemplar); + } + break; + case "long": + case "java.lang.Long": + long[] longs = (long[]) primitiveArray; + for (long longExemplar : longs) { + jsonArrayBuilder.add(longExemplar); + } + break; + case "short": + case "java.lang.Short": + short[] shorts = (short[]) primitiveArray; + for (short shortExemplar : shorts) { + jsonArrayBuilder.add(shortExemplar); + } + break; + case "java.lang.String": + String[] strings = (String[]) primitiveArray; + for (String stringExemplar : strings) { + jsonArrayBuilder.add(stringExemplar); + } + break; + + default: + } + + } +} \ No newline at end of file diff --git a/hw08-MyGSON/src/main/java/ru/otus/SomeClass.java b/hw08-MyGSON/src/main/java/ru/otus/SomeClass.java new file mode 100644 index 0000000..6dc1315 --- /dev/null +++ b/hw08-MyGSON/src/main/java/ru/otus/SomeClass.java @@ -0,0 +1,152 @@ +package ru.otus; + +import java.util.Arrays; +import java.util.List; + +public class SomeClass { + private int a; + private List b; + private float[] c; + private String d; + private double e; + private Short f; + + public void setA(int a) { + this.a = a; + } + + public void setB(List b) { + this.b = b; + } + + public void setC(float[] c) { + this.c = c; + } + + public void setD(String d) { + this.d = d; + } + + public void setE(double e) { + this.e = e; + } + + public void setF(Short f) { + this.f = f; + } + + private SomeClass(int a, List b, float[] c, String d, double e, Short f) { + this.a = a; + this.b = b.subList(0, b.size()); + this.c = c.clone(); + this.d = d; + this.e = e; + this.f = f; + } + + public static class Builder { + private int a; + private List b; + private float[] c; + private String d; + private double e; + private Short f; + + SomeClass build() { + return new SomeClass(this.a, this.b, this.c, this.d, this.e, this.f); + } + + public Builder setA(int a) { + this.a = a; + return this; + } + + public Builder setB(List b) { + this.b = b; + return this; + } + + public Builder setC(float[] c) { + this.c = c; + return this; + } + + public Builder setD(String d) { + this.d = d; + return this; + } + + public Builder setE(double e) { + this.e = e; + return this; + } + + public Builder setF(Short f) { + this.f = f; + return this; + } + } + + public int getA() { + return a; + } + + public List getB(){ + return b.subList(0,b.size()); + } + + public float[] getC(){ + return c.clone(); + } + + public String getD(){ + return d; + } + + public double getE(){ + return e; + } + + public Short getF(){ + return Short.valueOf(f); + } + + @Override + public boolean equals(Object obj) { + boolean result = true; + if (this == obj){ + return result; + } + if(this.getClass().equals(obj.getClass())){ + SomeClass someObject = (SomeClass) obj; + if (this.a==someObject.getA()){ + if (this.b.equals(someObject.getB())){ + if (Arrays.equals(this.c,someObject.getC())){ + if (this.d.equals(someObject.getD())){ + if(this.e == someObject.getE()){ + if (this.f.equals(someObject.getF())){ + + } else { + result = false; + } + } else { + result = false; + } + } else { + result = false; + } + } else { + result = false; + } + } else { + result = false; + } + } else { + result = false; + } + } else { + result = false; + } + return result; + } +} diff --git a/hw08-MyGSON/src/test/java/ru/otus/MyGsonTest.java b/hw08-MyGSON/src/test/java/ru/otus/MyGsonTest.java new file mode 100644 index 0000000..42dc8eb --- /dev/null +++ b/hw08-MyGSON/src/test/java/ru/otus/MyGsonTest.java @@ -0,0 +1,41 @@ +package ru.otus; + +import com.google.gson.Gson; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class MyGsonTest { + + SomeClass someObject; + SomeClass anotherObject; + + @BeforeEach + void setUp() { + } + + @Test + void toJSONTest(){ + SomeClass.Builder someClassBuilder = new SomeClass.Builder(); + List list = new ArrayList<>(); + list.add(Boolean.TRUE); + for (int i = 1; i < 4; i++) { list.add(Integer.toString(i)); } + someObject = someClassBuilder + .setA(5) + .setB(list) + .setC(new float[] {1F,2F,3F}) + .setD("Hello, Otus!") + .setE(Math.E) + .setF((short) 27) + .build(); + Gson gson = new Gson(); + MyGson myGson = new MyGson(); + anotherObject = gson.fromJson(gson.toJson(someObject), SomeClass.class); + assertEquals(someObject,anotherObject); + } + +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 9a32c0b..331e52e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = 'otus_hw' +include 'hw08-MyGSON' diff --git a/src/main/java/A.java b/src/main/java/A.java deleted file mode 100644 index 6be5562..0000000 --- a/src/main/java/A.java +++ /dev/null @@ -1,5 +0,0 @@ -public class A { - public static void main(String ... args){ - System.out.println("Hello, gradle + git!"); - } -}