├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── json-smart-formatting.yml │ └── json-smart-unit-tests.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── accessors-smart ├── .gitignore ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── minidev │ │ └── asm │ │ ├── ASMUtil.java │ │ ├── Accessor.java │ │ ├── BasicFiledFilter.java │ │ ├── BeansAccess.java │ │ ├── BeansAccessBuilder.java │ │ ├── BeansAccessConfig.java │ │ ├── ConvertDate.java │ │ ├── DefaultConverter.java │ │ ├── DynamicClassLoader.java │ │ ├── FieldFilter.java │ │ └── ex │ │ ├── ConvertException.java │ │ └── NoSuchFieldException.java │ └── test │ └── java │ ├── com │ └── mindev │ │ └── pojos │ │ └── AccessorTestPojo.java │ └── net │ └── minidev │ └── asm │ ├── ASMTest.java │ ├── AccessorTest.java │ ├── BTestBeansAccessB.java │ ├── TestDateConvert.java │ ├── TestDateConvertCustom.java │ ├── TestNewInstance.java │ └── bean │ ├── BBoolPriv.java │ ├── BBoolPub.java │ ├── BBooleanPriv.java │ ├── BBooleanPub.java │ ├── BEnumPriv.java │ ├── BEnumPrivAc.java │ ├── BEnumPub.java │ ├── BLongPriv.java │ ├── BLongPrivAc.java │ ├── BLongPub.java │ ├── BLongPubAc.java │ ├── BObjectPriv.java │ ├── BObjectPub.java │ ├── BStrPriv.java │ ├── BStrPrivAc.java │ ├── BStrPub.java │ ├── BStrPubAc.java │ ├── BTest.java │ ├── TEnum.java │ └── TestAsmAtom.java ├── json-smart-action ├── .gitignore ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── minidev │ │ └── json │ │ └── actions │ │ ├── ElementRemover.java │ │ ├── PathLocator.java │ │ ├── PathRemover.java │ │ ├── PathReplicator.java │ │ ├── PathsRetainer.java │ │ ├── navigate │ │ ├── CopyPathsAction.java │ │ ├── JSONNavigateAction.java │ │ ├── JSONNavigator.java │ │ ├── NavigateAction.java │ │ ├── TreeNavigator.java │ │ └── package-info.java │ │ ├── path │ │ ├── DotDelimiter.java │ │ ├── PathDelimiter.java │ │ ├── SlashDelimiter.java │ │ └── TreePath.java │ │ └── traverse │ │ ├── JSONTraverseAction.java │ │ ├── JSONTraverser.java │ │ ├── KeysPrintAction.java │ │ ├── LocatePathsJsonAction.java │ │ ├── RemoveElementsJsonAction.java │ │ ├── RemovePathsJsonAction.java │ │ ├── RetainPathsJsonAction.java │ │ ├── TreeTraverseAction.java │ │ ├── TreeTraverser.java │ │ └── package-info.java │ └── test │ └── java │ └── net │ └── minidev │ └── json │ └── test │ └── actions │ ├── ElementRemoverTest.java │ ├── KeysPrintActionTest.java │ ├── PathLocatorTest.java │ ├── PathRemoverTest.java │ ├── PathReplicatorTest.java │ ├── PathsRetainerTest.java │ └── TreePathTest.java └── json-smart ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── ChangeLog.txt ├── LICENSE.txt ├── mvnw ├── mvnw.cmd ├── pom.xml ├── readme.txt └── src ├── main └── java │ └── net │ └── minidev │ └── json │ ├── JSONArray.java │ ├── JSONAware.java │ ├── JSONAwareEx.java │ ├── JSONNavi.java │ ├── JSONObject.java │ ├── JSONStreamAware.java │ ├── JSONStreamAwareEx.java │ ├── JSONStyle.java │ ├── JSONUtil.java │ ├── JSONValue.java │ ├── JStylerObj.java │ ├── annotate │ ├── JsonIgnore.java │ └── JsonSmartAnnotation.java │ ├── parser │ ├── JSONParser.java │ ├── JSONParserBase.java │ ├── JSONParserByteArray.java │ ├── JSONParserInputStream.java │ ├── JSONParserMemory.java │ ├── JSONParserReader.java │ ├── JSONParserStream.java │ ├── JSONParserString.java │ └── ParseException.java │ ├── reader │ ├── ArrayWriter.java │ ├── BeansWriter.java │ ├── BeansWriterASM.java │ ├── BeansWriterASMRemap.java │ ├── JsonWriter.java │ └── JsonWriterI.java │ └── writer │ ├── ArraysMapper.java │ ├── BeansMapper.java │ ├── CollectionMapper.java │ ├── CompessorMapper.java │ ├── DefaultMapper.java │ ├── DefaultMapperCollection.java │ ├── DefaultMapperOrdered.java │ ├── FakeMapper.java │ ├── JsonReader.java │ ├── JsonReaderI.java │ ├── MapperRemapped.java │ └── UpdaterMapper.java └── test └── java └── net └── minidev └── json ├── test ├── JSONObjectTest.java ├── JSONSimpleTest.java ├── MustThrows.java ├── SerializeReadonlyField.java ├── TestBigDigitUnrestricted.java ├── TestBigValue.java ├── TestCVE202457699.java ├── TestCompressor.java ├── TestCompressorFlags.java ├── TestFloat.java ├── TestFloatStrict.java ├── TestGitHubIssue.java ├── TestInts.java ├── TestInvalidNumber.java ├── TestKeyword.java ├── TestMisc.java ├── TestNavi.java ├── TestNumberPrecision.java ├── TestOverflow.java ├── TestStrict.java ├── TestString.java ├── TestStringStrict.java ├── TestTruncated.java ├── TestUtf8.java ├── strict │ ├── TestExcessiveComma.java │ ├── TestSpecialChar.java │ ├── TestTaillingJunk.java │ └── TestZeroLead.java └── writer │ └── TestWriteFeatures.java └── testMapping ├── TestAdvancedMapper.java ├── TestCustomMappingInstant.java ├── TestDate.java ├── TestFieldRename.java ├── TestMapBeans.java ├── TestMapPrimArrays.java ├── TestMapPublic.java ├── TestMapPublic2.java ├── TestSerPrimArrays.java ├── TestUUID.java └── TestUpdater.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: urielch 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "json-smart" 5 | schedule: 6 | interval: "monthly" 7 | - package-ecosystem: "maven" 8 | directory: "json-smart-action" 9 | schedule: 10 | interval: "monthly" 11 | -------------------------------------------------------------------------------- /.github/workflows/json-smart-formatting.yml: -------------------------------------------------------------------------------- 1 | 2 | name: json smart formatting 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | formatting: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Set up JDK 18 | uses: actions/setup-java@v4 19 | with: 20 | java-version: 21 21 | distribution: 'temurin' 22 | cache: 'maven' 23 | 24 | - name: Check formatting accessors-smart 25 | run: cd accessors-smart; ./mvnw spotless:check 26 | 27 | - name: Check formatting json-smart 28 | run: cd json-smart; ./mvnw spotless:check 29 | 30 | - name: Check formatting json-smart-action 31 | run: cd json-smart-action; ./mvnw spotless:check 32 | -------------------------------------------------------------------------------- /.github/workflows/json-smart-unit-tests.yml: -------------------------------------------------------------------------------- 1 | 2 | name: json smart unit tests 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - update2024 8 | pull_request: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | publish: 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | java-version: [8, 11, 16, 17, 21] 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Set up JDK ${{ matrix.java-version }} 22 | uses: actions/setup-java@v4 23 | with: 24 | java-version: ${{ matrix.java-version }} 25 | distribution: 'temurin' 26 | cache: 'maven' 27 | 28 | - name: Unit tests accessors-smart 29 | run: cd accessors-smart; ./mvnw -B install; ./mvnw -B clean test 30 | 31 | - name: Unit tests json-smart 32 | run: cd json-smart; ./mvnw -B install; ./mvnw -B clean test 33 | 34 | - name: Unit tests json-smart-action 35 | run: cd json-smart-action; ./mvnw -B install; ./mvnw -B clean test 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # file system 2 | .DS_Store 3 | 4 | **/.classpath 5 | **/.idea/ 6 | **/.project 7 | **/.settings/ 8 | **/*.iml 9 | **/bin 10 | **/target 11 | **/.vscode/ 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic" 3 | } -------------------------------------------------------------------------------- /accessors-smart/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /accessors-smart/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/BasicFiledFilter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * A basic implementation of the {@link FieldFilter} interface that permits all operations on 8 | * fields. This implementation returns {@code true} for all checks, indicating that any field can be 9 | * used, read, and written. It serves as a default or fallback strategy when no specific field 10 | * filtering logic is required. 11 | */ 12 | public class BasicFiledFilter implements FieldFilter { 13 | /** default constructor */ 14 | public BasicFiledFilter() { 15 | super(); 16 | } 17 | 18 | /** 19 | * A singleton instance of {@code BasicFieldFilter}. Since the filter does not maintain any state 20 | * and allows all operations, it can be reused across the application. 21 | */ 22 | public static final BasicFiledFilter SINGLETON = new BasicFiledFilter(); 23 | 24 | /** 25 | * Always allows using the specified field. 26 | * 27 | * @param field The field to check. 28 | * @return Always returns {@code true}. 29 | */ 30 | @Override 31 | public boolean canUse(Field field) { 32 | return true; 33 | } 34 | 35 | /** 36 | * Always allows using the specified field in conjunction with a method. 37 | * 38 | * @param field The field to check. 39 | * @param method The method to check. This parameter is not used in the current implementation. 40 | * @return Always returns {@code true}. 41 | */ 42 | @Override 43 | public boolean canUse(Field field, Method method) { 44 | return true; 45 | } 46 | 47 | /** 48 | * Always allows reading the specified field. 49 | * 50 | * @param field The field to check. 51 | * @return Always returns {@code true}. 52 | */ 53 | @Override 54 | public boolean canRead(Field field) { 55 | return true; 56 | } 57 | 58 | /** 59 | * Always allows writing to the specified field. 60 | * 61 | * @param field The field to check. 62 | * @return Always returns {@code true}. 63 | */ 64 | @Override 65 | public boolean canWrite(Field field) { 66 | return true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/BeansAccessConfig.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedHashSet; 5 | 6 | /** Beans Access Config */ 7 | public class BeansAccessConfig { 8 | /** default constructor */ 9 | public BeansAccessConfig() { 10 | super(); 11 | } 12 | 13 | /** 14 | * Field type convertor for all classes 15 | * 16 | *

Convertor classes should contains mapping method Prototyped as: 17 | * 18 | *

public static DestinationType Method(Object data); 19 | * 20 | * @see DefaultConverter 21 | */ 22 | // static protected LinkedHashSet> globalMapper = new LinkedHashSet>(); 23 | 24 | /** 25 | * Field type convertor for custom Class 26 | * 27 | *

Convertor classes should contains mapping method Prototyped as: 28 | * 29 | *

public static DestinationType Method(Object data); 30 | * 31 | * @see DefaultConverter 32 | */ 33 | protected static HashMap, LinkedHashSet>> classMapper = 34 | new HashMap, LinkedHashSet>>(); 35 | 36 | /** FiledName remapper for a specific class or interface */ 37 | protected static HashMap, HashMap> classFiledNameMapper = 38 | new HashMap, HashMap>(); 39 | 40 | static { 41 | addTypeMapper(Object.class, DefaultConverter.class); 42 | addTypeMapper(Object.class, ConvertDate.class); 43 | } 44 | 45 | // /** 46 | // * Field type convertor for all classes 47 | // * 48 | // * Convertor classes should contains mapping method Prototyped as: 49 | // * 50 | // * public static DestinationType Method(Object data); 51 | // * 52 | // * @see DefaultConverter 53 | // */ 54 | // public static void addGlobalTypeMapper(Class mapper) { 55 | // synchronized (globalMapper) { 56 | // globalMapper.add(mapper); 57 | // } 58 | // } 59 | 60 | /** 61 | * Field type convertor for all classes 62 | * 63 | *

Convertor classes should contains mapping method Prototyped as: 64 | * 65 | *

public static DestinationType Method(Object data); 66 | * 67 | * @see DefaultConverter 68 | * @param clz class 69 | * @param mapper mapper 70 | */ 71 | public static void addTypeMapper(Class clz, Class mapper) { 72 | synchronized (classMapper) { 73 | LinkedHashSet> h = classMapper.get(clz); 74 | if (h == null) { 75 | h = new LinkedHashSet>(); 76 | classMapper.put(clz, h); 77 | } 78 | 79 | h.add(mapper); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/DynamicClassLoader.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * Simple extension from ClassLoader overriding the loadClass(String name, boolean resolve) method 22 | * and allowing to register new classes 23 | * 24 | * @author uriel 25 | */ 26 | class DynamicClassLoader extends ClassLoader { 27 | DynamicClassLoader(ClassLoader parent) { 28 | super(parent); 29 | } 30 | 31 | private static final String BEAN_AC = BeansAccess.class.getName(); 32 | 33 | /** Predefined define defineClass method signature (name, bytes, offset, length) */ 34 | private static final Class[] DEF_CLASS_SIG = 35 | new Class[] {String.class, byte[].class, int.class, int.class}; 36 | 37 | /** 38 | * @param parent used to choose the ClassLoader 39 | * @param clsName C 40 | * @param clsData 41 | * @return 42 | */ 43 | public static Class directLoad(Class parent, String clsName, byte[] clsData) { 44 | DynamicClassLoader loader = new DynamicClassLoader(parent.getClassLoader()); 45 | @SuppressWarnings("unchecked") 46 | Class clzz = (Class) loader.defineClass(clsName, clsData); 47 | return clzz; 48 | } 49 | 50 | public static T directInstance(Class parent, String clsName, byte[] clsData) 51 | throws InstantiationException, IllegalAccessException { 52 | Class clzz = directLoad(parent, clsName, clsData); 53 | return clzz.newInstance(); 54 | } 55 | 56 | @Override 57 | protected synchronized java.lang.Class loadClass(String name, boolean resolve) 58 | throws ClassNotFoundException { 59 | /* 60 | * check class by fullname as String. 61 | */ 62 | if (name.equals(BEAN_AC)) return BeansAccess.class; 63 | /* 64 | * Use default class loader 65 | */ 66 | return super.loadClass(name, resolve); 67 | } 68 | 69 | /** 70 | * Call defineClass into the parent classLoader using the method.setAccessible(boolean) hack 71 | * 72 | * @see ClassLoader#defineClass(String, byte[], int, int) 73 | */ 74 | Class defineClass(String name, byte[] bytes) throws ClassFormatError { 75 | try { 76 | // Attempt to load the access class in the same loader, which makes 77 | // protected and default access members accessible. 78 | Method method = ClassLoader.class.getDeclaredMethod("defineClass", DEF_CLASS_SIG); 79 | method.setAccessible(true); 80 | return (Class) 81 | method.invoke( 82 | getParent(), 83 | new Object[] {name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length)}); 84 | } catch (Exception ignored) { 85 | } 86 | return defineClass(name, bytes, 0, bytes.length); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/FieldFilter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | /** allow to control read/write access to field */ 7 | public interface FieldFilter { 8 | /** 9 | * NOT Implemented YET 10 | * 11 | * @param field the field 12 | * @return boolean 13 | */ 14 | public boolean canUse(Field field); 15 | 16 | /** 17 | * Can the field be used 18 | * 19 | * @param field the field 20 | * @param method the method 21 | * @return boolean 22 | */ 23 | public boolean canUse(Field field, Method method); 24 | 25 | /** 26 | * NOT Implemented YET 27 | * 28 | * @param field the field 29 | * @return boolean 30 | */ 31 | public boolean canRead(Field field); 32 | 33 | /** 34 | * NOT Implemented YET 35 | * 36 | * @param field the field 37 | * @return boolean 38 | */ 39 | public boolean canWrite(Field field); 40 | } 41 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/ex/ConvertException.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.ex; 2 | 3 | /** 4 | * An exception that is thrown to indicate a problem occurred during a conversion process. This 5 | * class extends {@link RuntimeException} and is used to signify errors encountered while converting 6 | * between types, typically within a dynamic type conversion framework or library. 7 | */ 8 | public class ConvertException extends RuntimeException { 9 | private static final long serialVersionUID = 1L; 10 | 11 | /** 12 | * Constructs a new {@code ConvertException} with {@code null} as its detail message. The cause is 13 | * not initialized, and may subsequently be initialized by a call to {@link #initCause}. 14 | */ 15 | public ConvertException() { 16 | super(); 17 | } 18 | 19 | /** 20 | * Constructs a new {@code ConvertException} with the specified detail message. The cause is not 21 | * initialized, and may subsequently be initialized by a call to {@link #initCause}. 22 | * 23 | * @param message the detail message. The detail message is saved for later retrieval by the 24 | * {@link #getMessage()} method. 25 | */ 26 | public ConvertException(String message) { 27 | super(message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /accessors-smart/src/main/java/net/minidev/asm/ex/NoSuchFieldException.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.ex; 2 | 3 | /** 4 | * Same exception as java.lang.NoSuchFieldException but extends RuntimException 5 | * 6 | * @author uriel 7 | */ 8 | public class NoSuchFieldException extends RuntimeException { 9 | private static final long serialVersionUID = 1L; 10 | 11 | /** default constructor */ 12 | public NoSuchFieldException() { 13 | super(); 14 | } 15 | 16 | /** 17 | * constuctor from message. 18 | * 19 | * @param message the detail message. The detail message is saved for later retrieval by the 20 | * Throwable.getMessage() method. 21 | */ 22 | public NoSuchFieldException(String message) { 23 | super(message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/com/mindev/pojos/AccessorTestPojo.java: -------------------------------------------------------------------------------- 1 | package com.mindev.pojos; 2 | 3 | public class AccessorTestPojo { 4 | 5 | // Field with only setter method 6 | @SuppressWarnings("unused") 7 | private int writeOnlyField; 8 | 9 | // Field with only getter method 10 | private int readOnlyField; 11 | 12 | // Field with both getter and setter methods 13 | private int readAndWriteableField; 14 | 15 | public void setWriteOnlyField(int writeOnlyField) { 16 | this.writeOnlyField = writeOnlyField; 17 | } 18 | 19 | public int getReadOnlyField() { 20 | return readOnlyField; 21 | } 22 | 23 | public int getReadAndWriteableField() { 24 | return readAndWriteableField; 25 | } 26 | 27 | public void setReadAndWriteableField(int readAndWriteableField) { 28 | this.readAndWriteableField = readAndWriteableField; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/ASMTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.HashMap; 6 | import net.minidev.asm.bean.BTest; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class ASMTest { 10 | 11 | @Test 12 | public void testGet() throws Exception { 13 | // long T1; 14 | 15 | BeansAccess acBT = BeansAccess.get(BTest.class); 16 | // BeansAccess acHand = new BTestBeansAccessB(); 17 | 18 | HashMap m = new HashMap(); 19 | m.put("A", "ab"); 20 | m.put("B", "Bc"); 21 | m.put("C", "cD"); 22 | m.put("D", "de"); 23 | m.put("E", "ef"); 24 | 25 | // String clsPath = FastMap1Builder.getName(m.size()); 26 | // String clsName = clsPath.replace("/", "."); 27 | 28 | // byte[] data; 29 | 30 | // data = FastMap1Builder.dump(m.size()); 31 | // data = FastMap2Builder.dump(m); 32 | // data = FastMapTestDump.dump(clsPath); 33 | 34 | // DynamicClassLoader loader = new 35 | // DynamicClassLoader(BTest.class.getClassLoader()); 36 | // byte[] data = BTestBeansAccessDump.dump(); 37 | // Class cls = (Class) loader.defineClass(clsName, 38 | // data); 39 | // Constructor c = (Constructor) 40 | // cls.getConstructors()[0]; 41 | // FastMap f = c.newInstance(m); 42 | // f = new FastMapTest_2(m); 43 | // f = new FastMapTest_3(); 44 | // f = new FastMapTest_2(m); 45 | // f = new FastMapTest_3(); 46 | // 4 entré 47 | // map => 1.279 48 | // fastMap => 3.323 49 | // FastMapTest_1 3.323 50 | // FastMapTest_2 3.323 51 | // FastMapTest_3 0.015 52 | 53 | // 3 entry 54 | // map => 0.983 55 | // fastmap => 1.014 56 | // 2 entry 57 | // map => 0,920 58 | // fastMap => 0,608 59 | 60 | // 7 entry 61 | // f 2.667 62 | // m 0,640 63 | 64 | // 6 entree 65 | // f 2.215 66 | // m 0,608 67 | 68 | // 4 entree 69 | // f 0.032 70 | // m 0,593 71 | 72 | // 5 entree 73 | // f 74 | // m 0.609 75 | // V2 2.402 76 | // V3 2.247 77 | // for (int i = 0; i < 20000; i++) { 78 | // f.get("A"); 79 | // f.get("B"); 80 | // f.get("C"); 81 | // f.get("D"); 82 | // f.get("E"); 83 | // f.get("F"); 84 | // f.get("G"); 85 | // f.get("H"); 86 | // f.get("I"); 87 | // } 88 | // System.gc(); 89 | // long T = System.nanoTime(); 90 | // for (int i = 0; i < 20000000; i++) { 91 | // m.get("A"); 92 | // m.get("B"); 93 | // m.get("C"); 94 | // m.get("D"); 95 | // m.get("E"); 96 | // m.get("F"); 97 | // m.get("G"); 98 | // m.get("H"); 99 | // m.get("I"); 100 | // } 101 | // T = System.nanoTime() - T; 102 | // 10 774 968 103 | // 596 295 451 104 | // 2 321 087 341 105 | 106 | BeansAccess ac; 107 | ac = acBT; 108 | // ac = acHand; 109 | // ac = acASMHand; 110 | subtext(ac); 111 | // T1 = System.currentTimeMillis(); 112 | // for (int i = 0; i < 2000000; i++) 113 | // subtext(ac); 114 | // T1 = System.currentTimeMillis() - T1; 115 | } 116 | 117 | @Test 118 | private void subtext(BeansAccess acc) { 119 | BTest t = new BTest(); 120 | acc.set(t, "pubBoolValue", true); 121 | acc.set(t, "pubIntValue", 13); 122 | acc.set(t, "pubStrValue", "Test"); 123 | acc.set(t, "privIntValue", 16); 124 | acc.set(t, "privStrValue", "test Priv"); 125 | assertEquals(Integer.valueOf(13), acc.get(t, "pubIntValue")); 126 | acc.set(t, "pubIntValue", 14); 127 | assertEquals(Integer.valueOf(14), acc.get(t, "pubIntValue")); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/AccessorTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import com.mindev.pojos.AccessorTestPojo; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class AccessorTest { 12 | 13 | private static class AcceptAllFilter implements FieldFilter { 14 | 15 | @Override 16 | public boolean canUse(Field field) { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean canUse(Field field, Method method) { 22 | return true; 23 | } 24 | 25 | @Override 26 | public boolean canRead(Field field) { 27 | return true; 28 | } 29 | 30 | @Override 31 | public boolean canWrite(Field field) { 32 | return true; 33 | } 34 | } 35 | 36 | private static class AcceptNoneFilter implements FieldFilter { 37 | 38 | @Override 39 | public boolean canUse(Field field) { 40 | return false; 41 | } 42 | 43 | @Override 44 | public boolean canUse(Field field, Method method) { 45 | return false; 46 | } 47 | 48 | @Override 49 | public boolean canRead(Field field) { 50 | return false; 51 | } 52 | 53 | @Override 54 | public boolean canWrite(Field field) { 55 | return false; 56 | } 57 | } 58 | 59 | @Test 60 | public void testWriteOnlyField() throws NoSuchFieldException, SecurityException { 61 | 62 | Field writeOnlyField = AccessorTestPojo.class.getDeclaredField("writeOnlyField"); 63 | Accessor accessor = new Accessor(AccessorTestPojo.class, writeOnlyField, new AcceptAllFilter()); 64 | 65 | assertTrue(accessor.isWritable()); 66 | assertFalse(accessor.isReadable()); 67 | 68 | accessor = new Accessor(AccessorTestPojo.class, writeOnlyField, new AcceptNoneFilter()); 69 | assertFalse(accessor.isWritable()); 70 | assertFalse(accessor.isReadable()); 71 | } 72 | 73 | @Test 74 | public void testReadOnlyField() throws NoSuchFieldException, SecurityException { 75 | 76 | Field readOnlyField = AccessorTestPojo.class.getDeclaredField("readOnlyField"); 77 | Accessor accessor = new Accessor(AccessorTestPojo.class, readOnlyField, new AcceptAllFilter()); 78 | 79 | assertFalse(accessor.isWritable()); 80 | assertTrue(accessor.isReadable()); 81 | 82 | accessor = new Accessor(AccessorTestPojo.class, readOnlyField, new AcceptNoneFilter()); 83 | assertFalse(accessor.isWritable()); 84 | assertFalse(accessor.isReadable()); 85 | } 86 | 87 | @Test 88 | public void testReadAndWriteableField() throws NoSuchFieldException, SecurityException { 89 | 90 | Field readAndWriteableField = AccessorTestPojo.class.getDeclaredField("readAndWriteableField"); 91 | Accessor accessor = 92 | new Accessor(AccessorTestPojo.class, readAndWriteableField, new AcceptAllFilter()); 93 | 94 | assertTrue(accessor.isWritable()); 95 | assertTrue(accessor.isReadable()); 96 | 97 | accessor = new Accessor(AccessorTestPojo.class, readAndWriteableField, new AcceptNoneFilter()); 98 | assertFalse(accessor.isWritable()); 99 | assertFalse(accessor.isReadable()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/TestDateConvertCustom.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class TestDateConvertCustom { 8 | /** 9 | * some JAVA version use aternative space. 10 | * 11 | * @throws Exception 12 | */ 13 | @Test 14 | public void testCANADACustom() throws Exception { 15 | String testDate = "Jan 23, 2012, 1:42:59 PM"; 16 | ConvertDate.convertToDate(testDate); 17 | assertTrue(true, "parse " + testDate + " do not crash"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/TestNewInstance.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm; 2 | 3 | import java.util.TreeMap; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class TestNewInstance { 7 | @Test 8 | public void testLangUtilPkg() { 9 | @SuppressWarnings("rawtypes") 10 | BeansAccess acTm = BeansAccess.get(TreeMap.class); 11 | acTm.newInstance(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BBoolPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BBoolPriv { 4 | private boolean value; 5 | 6 | public boolean isValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(boolean value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BBoolPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BBoolPub { 4 | public boolean value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BBooleanPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BBooleanPriv { 4 | private Boolean value; 5 | 6 | public Boolean getValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(Boolean value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BBooleanPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BBooleanPub { 4 | public Boolean value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BEnumPriv { 4 | private TEnum value; 5 | 6 | public TEnum getValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(TEnum value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPrivAc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import net.minidev.asm.BeansAccess; 4 | 5 | @SuppressWarnings("rawtypes") 6 | public class BEnumPrivAc extends BeansAccess { 7 | 8 | @Override 9 | public void set(Object object, int methodIndex, Object value) { 10 | if (methodIndex == 0) { 11 | if (value != null) 12 | // value = TEnum.valueOf((String) value); 13 | value = TEnum.valueOf(value.toString()); 14 | ((BEnumPriv) object).setValue((TEnum) value); 15 | return; 16 | } 17 | throw new net.minidev.asm.ex.NoSuchFieldException( 18 | "mapping BEnumPriv failed to map field:".concat(Integer.toString(methodIndex))); 19 | } 20 | 21 | @Override 22 | public Object get(Object object, int methodIndex) { 23 | if (methodIndex == 0) { 24 | return ((BEnumPriv) object).getValue(); 25 | } 26 | throw new net.minidev.asm.ex.NoSuchFieldException( 27 | "mapping BEnumPriv failed to map field:".concat(Integer.toString(methodIndex))); 28 | } 29 | 30 | @Override 31 | public void set(Object object, String methodIndex, Object value) { 32 | if (methodIndex.equals("value")) { 33 | if (value != null) 34 | // value = TEnum.valueOf((String) value); 35 | value = TEnum.valueOf(value.toString()); 36 | ((BEnumPriv) object).setValue((TEnum) value); 37 | return; 38 | } 39 | throw new net.minidev.asm.ex.NoSuchFieldException( 40 | "mapping BEnumPriv failed to map field:".concat(methodIndex)); 41 | } 42 | 43 | @Override 44 | public Object get(Object object, String methodIndex) { 45 | if (methodIndex.equals("value")) { 46 | return ((BEnumPriv) object).getValue(); 47 | } 48 | throw new net.minidev.asm.ex.NoSuchFieldException( 49 | "mapping BEnumPriv failed to map field:".concat(methodIndex)); 50 | } 51 | 52 | @Override 53 | public Object newInstance() { 54 | return new BEnumPriv(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BEnumPub { 4 | public TEnum value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BLongPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BLongPriv { 4 | private Long value; 5 | 6 | public Long getValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(Long value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BLongPrivAc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import net.minidev.asm.BeansAccess; 4 | import net.minidev.asm.DefaultConverter; 5 | 6 | @SuppressWarnings("rawtypes") 7 | public class BLongPrivAc extends BeansAccess { 8 | 9 | @Override 10 | public void set(Object object, int methodIndex, Object value) { 11 | if (methodIndex == 0) { 12 | ((BLongPriv) object).setValue(DefaultConverter.convertToLong(value)); 13 | return; 14 | } 15 | } 16 | 17 | @Override 18 | public Object get(Object object, int methodIndex) { 19 | if (methodIndex == 0) { 20 | return ((BLongPriv) object).getValue(); 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | public void set(Object object, String methodIndex, Object value) { 27 | if (methodIndex.equals("value")) { 28 | ((BLongPriv) object).setValue(DefaultConverter.convertToLong(value)); 29 | return; 30 | } 31 | } 32 | 33 | @Override 34 | public Object get(Object object, String methodIndex) { 35 | if (methodIndex.equals("value")) { 36 | return ((BLongPriv) object).getValue(); 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | public Object newInstance() { 43 | return new BLongPriv(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BLongPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BLongPub { 4 | public Long value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BLongPubAc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import net.minidev.asm.BeansAccess; 4 | import net.minidev.asm.DefaultConverter; 5 | 6 | @SuppressWarnings("rawtypes") 7 | public class BLongPubAc extends BeansAccess { 8 | 9 | @Override 10 | public void set(Object object, int methodIndex, Object value) { 11 | if (methodIndex == 0) { 12 | ((BLongPub) object).value = DefaultConverter.convertToLong(value); 13 | return; 14 | } 15 | } 16 | 17 | @Override 18 | public Object get(Object object, int methodIndex) { 19 | if (methodIndex == 0) { 20 | return ((BLongPub) object).value; 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | public void set(Object object, String methodIndex, Object value) { 27 | if (methodIndex.equals("value")) { 28 | ((BLongPub) object).value = DefaultConverter.convertToLong(value); 29 | return; 30 | } 31 | } 32 | 33 | @Override 34 | public Object get(Object object, String methodIndex) { 35 | if (methodIndex.equals("value")) { 36 | return ((BLongPub) object).value; 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | public Object newInstance() { 43 | return new BLongPub(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BObjectPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BObjectPriv { 4 | private Object value; 5 | 6 | public Object getValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(Object value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BObjectPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BObjectPub { 4 | public Object value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BStrPriv.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BStrPriv { 4 | private String value; 5 | 6 | public String getValue() { 7 | return value; 8 | } 9 | 10 | public void setValue(String value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BStrPrivAc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import net.minidev.asm.BeansAccess; 4 | 5 | @SuppressWarnings("rawtypes") 6 | public class BStrPrivAc extends BeansAccess { 7 | 8 | @Override 9 | public void set(Object object, int methodIndex, Object value) { 10 | if (methodIndex == 0) { 11 | if (value != null) value = value.toString(); 12 | ((BStrPriv) object).setValue((String) value); 13 | return; 14 | } 15 | } 16 | 17 | @Override 18 | public Object get(Object object, int methodIndex) { 19 | if (methodIndex == 0) { 20 | return ((BStrPriv) object).getValue(); 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | public void set(Object object, String methodIndex, Object value) { 27 | if (methodIndex.equals("value")) { 28 | if (value != null) value = value.toString(); 29 | ((BStrPriv) object).setValue((String) value); 30 | return; 31 | } 32 | } 33 | 34 | @Override 35 | public Object get(Object object, String methodIndex) { 36 | if (methodIndex.equals("value")) { 37 | return ((BStrPriv) object).getValue(); 38 | } 39 | return null; 40 | } 41 | 42 | @Override 43 | public Object newInstance() { 44 | return new BStrPriv(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BStrPub.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BStrPub { 4 | public String value; 5 | } 6 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BStrPubAc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import net.minidev.asm.BeansAccess; 4 | 5 | @SuppressWarnings("rawtypes") 6 | public class BStrPubAc extends BeansAccess { 7 | 8 | @Override 9 | public void set(Object object, int methodIndex, Object value) { 10 | if (methodIndex == 0) { 11 | if (value != null) value = value.toString(); 12 | ((BStrPub) object).value = (String) value; 13 | return; 14 | } 15 | } 16 | 17 | @Override 18 | public Object get(Object object, int methodIndex) { 19 | if (methodIndex == 0) { 20 | return ((BStrPub) object).value; 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | public void set(Object object, String methodIndex, Object value) { 27 | if (methodIndex.equals("value")) { 28 | if (value != null) value = value.toString(); 29 | ((BStrPub) object).value = (String) value; 30 | return; 31 | } 32 | } 33 | 34 | @Override 35 | public Object get(Object object, String methodIndex) { 36 | if (methodIndex.equals("value")) { 37 | return ((BStrPub) object).value; 38 | } 39 | return null; 40 | } 41 | 42 | @Override 43 | public BStrPub newInstance() { 44 | return new BStrPub(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/BTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public class BTest { 4 | public int pubIntValue; 5 | public String pubStrValue; 6 | private int privIntValue; 7 | private String privStrValue; 8 | public boolean pubBoolValue; 9 | public Integer pubIntegerValue; 10 | public TEnum pubTEnum; 11 | 12 | public void setPrivIntValue(int privIntValue) { 13 | this.privIntValue = privIntValue; 14 | } 15 | 16 | public int getPrivIntValue() { 17 | return privIntValue; 18 | } 19 | 20 | public void setPrivStrValue(String privStrValue) { 21 | this.privStrValue = privStrValue; 22 | } 23 | 24 | public String getPrivStrValue() { 25 | return privStrValue; 26 | } 27 | 28 | public String toString() { 29 | return "Public(i:" 30 | + pubIntValue 31 | + " s:" 32 | + pubStrValue 33 | + "B: " 34 | + pubBoolValue 35 | + ") Private(i:" 36 | + privIntValue 37 | + " s:" 38 | + privStrValue 39 | + ")"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/TEnum.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | public enum TEnum { 4 | V1, 5 | V2, 6 | V3 7 | } 8 | -------------------------------------------------------------------------------- /accessors-smart/src/test/java/net/minidev/asm/bean/TestAsmAtom.java: -------------------------------------------------------------------------------- 1 | package net.minidev.asm.bean; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.asm.BeansAccess; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class TestAsmAtom { 9 | 10 | @Test 11 | public void testpub() throws Exception { 12 | // int fieldID = 0; 13 | String fieldID = "value"; 14 | { 15 | BeansAccess ac = BeansAccess.get(BStrPub.class); 16 | BStrPub p = ac.newInstance(); 17 | String val = "toto"; 18 | ac.set(p, fieldID, val); 19 | assertEquals(val, ac.get(p, fieldID)); 20 | } 21 | { 22 | BeansAccess ac = BeansAccess.get(BLongPub.class); 23 | BLongPub p = ac.newInstance(); 24 | Long val = 123L; 25 | ac.set(p, fieldID, val); 26 | assertEquals(val, ac.get(p, fieldID)); 27 | } 28 | { 29 | BeansAccess ac = BeansAccess.get(BBooleanPub.class); 30 | BBooleanPub p = ac.newInstance(); 31 | Boolean val = Boolean.TRUE; 32 | ac.set(p, fieldID, val); 33 | assertEquals(val, ac.get(p, fieldID)); 34 | } 35 | { 36 | BeansAccess ac = BeansAccess.get(BBoolPub.class); 37 | BBoolPub p = ac.newInstance(); 38 | Boolean val = Boolean.TRUE; 39 | ac.set(p, fieldID, val); 40 | assertEquals(val, ac.get(p, fieldID)); 41 | } 42 | { 43 | BeansAccess ac = BeansAccess.get(BEnumPriv.class); 44 | BEnumPriv p = ac.newInstance(); 45 | TEnum val = TEnum.V2; 46 | ac.set(p, fieldID, val); 47 | assertEquals(val, ac.get(p, fieldID)); 48 | } 49 | { 50 | BeansAccess ac = BeansAccess.get(BObjectPriv.class); 51 | BObjectPriv p = ac.newInstance(); 52 | TEnum val = TEnum.V2; 53 | ac.set(p, fieldID, val); 54 | assertEquals(val, ac.get(p, fieldID)); 55 | } 56 | } 57 | 58 | public void testPriv() throws Exception { 59 | // int fieldID = 0; 60 | String fieldID = "value"; 61 | { 62 | BeansAccess ac = BeansAccess.get(BStrPriv.class); 63 | BStrPriv p = ac.newInstance(); 64 | String val = "toto"; 65 | ac.set(p, fieldID, val); 66 | assertEquals(val, ac.get(p, fieldID)); 67 | } 68 | { 69 | BeansAccess ac = BeansAccess.get(BLongPriv.class); 70 | BLongPriv p = ac.newInstance(); 71 | Long val = 123L; 72 | ac.set(p, fieldID, val); 73 | assertEquals(val, ac.get(p, fieldID)); 74 | } 75 | { 76 | BeansAccess ac = BeansAccess.get(BBooleanPriv.class); 77 | BBooleanPriv p = ac.newInstance(); 78 | Boolean val = Boolean.TRUE; 79 | ac.set(p, fieldID, val); 80 | assertEquals(val, ac.get(p, fieldID)); 81 | } 82 | { 83 | BeansAccess ac = BeansAccess.get(BBoolPriv.class); 84 | BBoolPriv p = ac.newInstance(); 85 | Boolean val = Boolean.TRUE; 86 | ac.set(p, fieldID, val); 87 | assertEquals(val, ac.get(p, fieldID)); 88 | } 89 | { 90 | BeansAccess ac = BeansAccess.get(BEnumPub.class); 91 | BEnumPub p = ac.newInstance(); 92 | TEnum val = TEnum.V2; 93 | ac.set(p, fieldID, val); 94 | assertEquals(val, ac.get(p, fieldID)); 95 | } 96 | { 97 | BeansAccess ac = BeansAccess.get(BObjectPub.class); 98 | BObjectPub p = ac.newInstance(); 99 | TEnum val = TEnum.V2; 100 | ac.set(p, fieldID, val); 101 | assertEquals(val, ac.get(p, fieldID)); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /json-smart-action/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /json-smart-action/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/ElementRemover.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions; 2 | 3 | import java.util.*; 4 | import net.minidev.json.JSONObject; 5 | import net.minidev.json.actions.traverse.JSONTraverseAction; 6 | import net.minidev.json.actions.traverse.JSONTraverser; 7 | import net.minidev.json.actions.traverse.RemoveElementsJsonAction; 8 | 9 | /** 10 | * Removes key:value elements from every node of a {@link JSONObject} matching the list of 11 | * user-specified elements. 12 | * 13 | *

An element to remove must be specified as a key:value pair 14 | * 15 | *

Usage Example: 16 | * 17 | *

To remove the element k2:v2 from the {@link JSONObject} {k0:{k2:v2, k3:v3}, k1:{k2:v2, k4:v4}} 18 | * use the remover like so: 19 | * 20 | *

21 |  * PathRemover pr = new PathRemover("k2.v2");
22 |  * JSONObject cleanObject = pr.remove(new JSONObject(...));
23 |  * 
24 | * 25 | * The resulting object 'cleanObject' would be {k0:{k3:v3}, k1:{k4:v4}} 26 | * 27 | *

See unit tests for more examples 28 | * 29 | * @author adoneitan@gmail.com 30 | */ 31 | public class ElementRemover { 32 | private Map elementsToRemove; 33 | 34 | public ElementRemover(Map elementsToRemove) { 35 | this.elementsToRemove = 36 | elementsToRemove == null ? Collections.emptyMap() : elementsToRemove; 37 | } 38 | 39 | public ElementRemover(JSONObject elementsToRemove) { 40 | this.elementsToRemove = 41 | elementsToRemove == null ? Collections.emptyMap() : elementsToRemove; 42 | } 43 | 44 | public JSONObject remove(JSONObject objectToClean) { 45 | JSONTraverseAction strategy = new RemoveElementsJsonAction(this.elementsToRemove); 46 | JSONTraverser traversal = new JSONTraverser(strategy); 47 | traversal.traverse(objectToClean); 48 | return (JSONObject) strategy.result(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/PathLocator.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import net.minidev.json.JSONArray; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.actions.path.DotDelimiter; 10 | import net.minidev.json.actions.path.PathDelimiter; 11 | import net.minidev.json.actions.traverse.JSONTraverseAction; 12 | import net.minidev.json.actions.traverse.JSONTraverser; 13 | import net.minidev.json.actions.traverse.LocatePathsJsonAction; 14 | 15 | /** 16 | * Searches for paths in a {@link JSONObject} and returns those found. 17 | * 18 | *

Traverses the specified {@link JSONObject} searching for nodes whose paths (from the root 19 | * down) match any of the user-specified paths. The paths that match are returned. 20 | * 21 | *

A path to locate must be specified in the n-gram format - a list of keys from the root down 22 | * separated by dots: K0[[[[.K1].K2].K3]...]
23 | * A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in 24 | * their name are not supported. 25 | * 26 | *

27 | * 28 | * @author adoneitan@gmail.com 29 | */ 30 | public class PathLocator { 31 | protected List pathsToFind; 32 | protected PathDelimiter pathDelimiter = new DotDelimiter().withAcceptDelimiterInNodeName(false); 33 | 34 | public PathLocator(JSONArray pathsToFind) { 35 | if (pathsToFind == null || pathsToFind.isEmpty()) { 36 | this.pathsToFind = Collections.emptyList(); 37 | } else { 38 | this.pathsToFind = new ArrayList(); 39 | for (Object s : pathsToFind) { 40 | this.pathsToFind.add((String) s); 41 | } 42 | } 43 | } 44 | 45 | public PathLocator(List pathsToFind) { 46 | this.pathsToFind = 47 | pathsToFind == null || pathsToFind.size() == 0 48 | ? Collections.emptyList() 49 | : pathsToFind; 50 | } 51 | 52 | public PathLocator(String... pathsToFind) { 53 | this.pathsToFind = 54 | pathsToFind == null || pathsToFind.length == 0 55 | ? Collections.emptyList() 56 | : Arrays.asList(pathsToFind); 57 | } 58 | 59 | public PathLocator with(PathDelimiter pathDelimiter) { 60 | this.pathDelimiter = pathDelimiter; 61 | return this; 62 | } 63 | 64 | @SuppressWarnings("unchecked") 65 | public List locate(JSONObject object) { 66 | JSONTraverseAction action = new LocatePathsJsonAction(this.pathsToFind, pathDelimiter); 67 | JSONTraverser traversal = new JSONTraverser(action).with(pathDelimiter); 68 | traversal.traverse(object); 69 | return (List) action.result(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/PathRemover.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import net.minidev.json.JSONArray; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.actions.traverse.JSONTraverseAction; 10 | import net.minidev.json.actions.traverse.JSONTraverser; 11 | import net.minidev.json.actions.traverse.RemovePathsJsonAction; 12 | 13 | /** 14 | * Removes branches of nodes from a {@link JSONObject} matching the list of user-specified 15 | * paths. 16 | * 17 | *

A path to remove must be specified in the n-gram format - a list of keys from the root down 18 | * separated by dots: K0[[[[.K1].K2].K3]...]
19 | * A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in 20 | * their name are not supported. 21 | * 22 | *

Usage Example: 23 | * 24 | *

To remove the field k1.k2 from the {@link JSONObject} {k1:{k2:v2}, k3:{k4:v4}} use the remover 25 | * like so: 26 | * 27 | *

28 |  * PathRemover pr = new PathRemover("k1.k2");
29 |  * JSONObject cleanObject = pr.remove(new JSONObject(...));
30 |  * 
31 | * 32 | * The resulting object 'cleanObject' would be {k1:{k3:{k4:v4}}} 33 | * 34 | *

See unit tests for more examples 35 | * 36 | * @author adoneitan@gmail.com 37 | */ 38 | public class PathRemover { 39 | protected List pathsToRemove; 40 | 41 | public PathRemover(JSONArray pathsToRemove) { 42 | if (pathsToRemove == null || pathsToRemove.isEmpty()) { 43 | this.pathsToRemove = Collections.emptyList(); 44 | } else { 45 | this.pathsToRemove = new ArrayList(); 46 | for (Object s : pathsToRemove) { 47 | this.pathsToRemove.add((String) s); 48 | } 49 | } 50 | } 51 | 52 | public PathRemover(List pathsToRemove) { 53 | this.pathsToRemove = 54 | pathsToRemove == null || pathsToRemove.size() == 0 55 | ? Collections.emptyList() 56 | : pathsToRemove; 57 | } 58 | 59 | public PathRemover(String... pathsToRemove) { 60 | this.pathsToRemove = 61 | pathsToRemove == null || pathsToRemove.length == 0 62 | ? Collections.emptyList() 63 | : Arrays.asList(pathsToRemove); 64 | } 65 | 66 | public JSONObject remove(JSONObject objectToClean) { 67 | JSONTraverseAction strategy = new RemovePathsJsonAction(this.pathsToRemove); 68 | JSONTraverser traversal = new JSONTraverser(strategy); 69 | traversal.traverse(objectToClean); 70 | return (JSONObject) strategy.result(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/PathReplicator.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import net.minidev.json.JSONArray; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.actions.navigate.CopyPathsAction; 10 | import net.minidev.json.actions.navigate.JSONNavigator; 11 | 12 | /** 13 | * Creates a copy of a {@link JSONObject} consisting only of the nodes on the user-specified 14 | * paths. 15 | * 16 | *

Paths that do not exist in the specified object are ignored silently. Specifying an empty list 17 | * of paths to copy or only non-existent paths will result in an empty object being returned. 18 | * 19 | *

A path to copy must be specified in the n-gram format - a list of keys from the root down 20 | * separated by dots: K0[[[[.K1].K2].K3]...]
21 | * A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in 22 | * their name are not supported. 23 | * 24 | *

Sample usage: 25 | * 26 | *

To replicate the branch k1.k2 from {k1:{k2:v2}, k3:{k4:v4}} use the {@link PathReplicator} 27 | * like so: 28 | * 29 | *

30 |  * PathReplicator pr = new {@link PathReplicator}("k1.k2")
31 |  * JSONObject copiedObject = pr.copy(new JSONObject(...))
32 |  * 
33 | * 34 | * The resulting object 'copiedObject' would be {k1:{k2:v2}} 35 | * 36 | *

see unit tests for more examples 37 | * 38 | * @author adoneitan@gmail.com 39 | * @since 15 March 2016. 40 | */ 41 | public class PathReplicator { 42 | protected List pathsToCopy; 43 | 44 | public PathReplicator(JSONArray pathsToCopy) { 45 | if (pathsToCopy == null || pathsToCopy.isEmpty()) { 46 | this.pathsToCopy = Collections.emptyList(); 47 | } else { 48 | this.pathsToCopy = new LinkedList(); 49 | for (Object s : pathsToCopy) { 50 | this.pathsToCopy.add((String) s); 51 | } 52 | } 53 | } 54 | 55 | public PathReplicator(List pathsToCopy) { 56 | this.pathsToCopy = 57 | pathsToCopy == null || pathsToCopy.size() == 0 58 | ? Collections.emptyList() 59 | : pathsToCopy; 60 | } 61 | 62 | public PathReplicator(String... pathsToCopy) { 63 | this.pathsToCopy = 64 | pathsToCopy == null || pathsToCopy.length == 0 65 | ? Collections.emptyList() 66 | : new LinkedList(Arrays.asList(pathsToCopy)); 67 | } 68 | 69 | public JSONObject replicate(JSONObject sourceObj) throws Exception { 70 | CopyPathsAction s = new CopyPathsAction(); 71 | JSONNavigator n = new JSONNavigator(s, pathsToCopy); 72 | n.nav(sourceObj); 73 | return (JSONObject) s.result(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/PathsRetainer.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import net.minidev.json.JSONArray; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.actions.path.DotDelimiter; 10 | import net.minidev.json.actions.path.PathDelimiter; 11 | import net.minidev.json.actions.traverse.JSONTraverseAction; 12 | import net.minidev.json.actions.traverse.JSONTraverser; 13 | import net.minidev.json.actions.traverse.LocatePathsJsonAction; 14 | import net.minidev.json.actions.traverse.RetainPathsJsonAction; 15 | 16 | /** 17 | * Retains branches of nodes of a {@link JSONObject} matching the list of user-specified 18 | * paths. 19 | * 20 | *

A path to copy must be specified in the n-gram format - a list of keys from the root down 21 | * separated by dots: K0[[[[.K1].K2].K3]...]
22 | * A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in 23 | * their name are not supported. 24 | * 25 | *

Example: 26 | * 27 | *

to retain the field k1.k2 in the {@link JSONObject} {k1:{k2:v1}, k3:{k4:v2}} instantiate the 28 | * retainer like so: new JSONObjectCleaner("k1.k2") The resulting object would be {k1:{k2:v1}} 29 | * 30 | *

See unit tests in JSONObjectRetainerTest for more examples 31 | * 32 | * @author adoneitan@gmail.com 33 | */ 34 | public class PathsRetainer { 35 | protected List pathsToRetain; 36 | protected PathDelimiter pathDelimiter = new DotDelimiter().withAcceptDelimiterInNodeName(false); 37 | 38 | public PathsRetainer(JSONArray pathsToRetain) { 39 | if (pathsToRetain == null || pathsToRetain.isEmpty()) { 40 | this.pathsToRetain = Collections.emptyList(); 41 | } else { 42 | this.pathsToRetain = new LinkedList(); 43 | for (Object s : pathsToRetain) { 44 | this.pathsToRetain.add((String) s); 45 | } 46 | } 47 | } 48 | 49 | public PathsRetainer(List pathsToRetain) { 50 | this.pathsToRetain = 51 | pathsToRetain == null || pathsToRetain.size() == 0 52 | ? Collections.emptyList() 53 | : pathsToRetain; 54 | } 55 | 56 | public PathsRetainer(String... pathsToRetain) { 57 | this.pathsToRetain = 58 | pathsToRetain == null || pathsToRetain.length == 0 59 | ? Collections.emptyList() 60 | : new LinkedList(Arrays.asList(pathsToRetain)); 61 | } 62 | 63 | public PathsRetainer with(PathDelimiter pathDelimiter) { 64 | this.pathDelimiter = pathDelimiter; 65 | return this; 66 | } 67 | 68 | @SuppressWarnings("unchecked") 69 | public JSONObject retain(JSONObject object) { 70 | /** 71 | * a path to retain which contains a path in the object, but is not itself a path in the object, 72 | * will cause the sub-path to be retained although it shouldn't: object = {k0:v0} retain = 73 | * {k0.k1} so the false path to retain has to be removed from the pathsToRetain list. 74 | * 75 | *

The {@link LocatePathsJsonAction} returns only paths which exist in the object. 76 | */ 77 | JSONTraverseAction locateAction = new LocatePathsJsonAction(pathsToRetain, pathDelimiter); 78 | JSONTraverser t1 = new JSONTraverser(locateAction); 79 | t1.traverse(object); 80 | List realPathsToRetain = (List) locateAction.result(); 81 | 82 | // now reduce the object using only existing paths 83 | JSONTraverseAction retainer = new RetainPathsJsonAction(realPathsToRetain, pathDelimiter); 84 | JSONTraverser t2 = new JSONTraverser(retainer).with(pathDelimiter); 85 | t2.traverse(object); 86 | return (JSONObject) retainer.result(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/navigate/CopyPathsAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.navigate; 2 | 3 | import java.util.Collection; 4 | import java.util.Stack; 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.actions.path.TreePath; 8 | 9 | /** 10 | * Creates a copy of a {@link JSONObject} containing just the nodes on the paths specified. 11 | * 12 | *

Specified paths that do not exist in the source object are ignored silently. Specifying an 13 | * empty list of paths to navigate or only non-existent paths will result in an empty object being 14 | * returned. 15 | * 16 | *

See package-info for more details 17 | * 18 | *

Example: 19 | * 20 | *

To copy the branch k1.k2 from {k1:{k2:v1}, k3:{k4:v2}} instantiate the copier like so: new 21 | * JSONObjectCopier("k1.k2") The resulting copy would be {k1:{k2:v1}} 22 | * 23 | *

See unit tests for more examples 24 | * 25 | * @author adoneitan@gmail.com 26 | * @since 15 March 2016. 27 | */ 28 | public class CopyPathsAction implements JSONNavigateAction { 29 | protected JSONObject destTree; 30 | protected JSONObject destBranch; 31 | protected Stack destNodeStack; 32 | 33 | @Override 34 | public boolean start(JSONObject source, Collection pathsToCopy) { 35 | if (source == null) { 36 | destTree = null; 37 | return false; 38 | } 39 | destTree = new JSONObject(); 40 | if (pathsToCopy == null || pathsToCopy.size() == 0) { 41 | return false; 42 | } 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean recurInto(TreePath jp, JSONObject o) { 48 | // reached JSONObject node - instantiate it and recur 49 | handleNewNode(jp, new JSONObject()); 50 | return true; 51 | } 52 | 53 | private void handleNewNode(TreePath jp, Object node) { 54 | if (!jp.hasPrev()) { 55 | return; 56 | } 57 | if (destNodeStack.peek() instanceof JSONObject) { 58 | ((JSONObject) destNodeStack.peek()).put(jp.curr(), node); 59 | } else if (destNodeStack.peek() instanceof JSONArray) { 60 | ((JSONArray) destNodeStack.peek()).add(node); 61 | } 62 | destNodeStack.push(node); 63 | } 64 | 65 | @Override 66 | public boolean recurInto(TreePath jp, JSONArray o) { 67 | // reached JSONArray node - instantiate it and recur 68 | handleNewNode(jp, new JSONArray()); 69 | return true; 70 | } 71 | 72 | @Override 73 | public void foundLeafBeforePathEnd(TreePath jp, Object obj) { 74 | throw new IllegalArgumentException( 75 | "branch is shorter than path - path not found in source: '" + jp.origin() + "'"); 76 | } 77 | 78 | @Override 79 | public void pathTailNotFound(TreePath jp, Object source) { 80 | throw new IllegalArgumentException( 81 | "cannot find next element of path - path not found in source: '" + jp.origin() + "'"); 82 | } 83 | 84 | @Override 85 | public void handleLeaf(TreePath jp, Object o) { 86 | ((JSONObject) destNodeStack.peek()).put(jp.curr(), o); 87 | } 88 | 89 | @Override 90 | public void handleLeaf(TreePath jp, int arrIndex, Object o) { 91 | ((JSONArray) destNodeStack.peek()).add(o); 92 | } 93 | 94 | @Override 95 | public void recurEnd(TreePath jp, JSONObject jo) { 96 | destNodeStack.pop(); 97 | } 98 | 99 | @Override 100 | public void recurEnd(TreePath jp, JSONArray ja) { 101 | destNodeStack.pop(); 102 | } 103 | 104 | @Override 105 | public boolean pathStart(String path) { 106 | destBranch = new JSONObject(); 107 | destNodeStack = new Stack(); 108 | destNodeStack.push(destBranch); 109 | return true; 110 | } 111 | 112 | @Override 113 | public void pathEnd(String path) { 114 | destTree.merge(destBranch); 115 | } 116 | 117 | @Override 118 | public boolean failSilently(String path, Exception e) { 119 | return false; 120 | } 121 | 122 | @Override 123 | public boolean failFast(String path, Exception e) { 124 | return false; 125 | } 126 | 127 | @Override 128 | public void end() {} 129 | 130 | @Override 131 | public Object result() { 132 | return destTree; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/navigate/JSONNavigateAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.navigate; 2 | 3 | import net.minidev.json.JSONArray; 4 | import net.minidev.json.JSONObject; 5 | 6 | /** 7 | * An interface for a processing action on the nodes of a {@link JSONObject} while navigating its 8 | * branches. 9 | * 10 | *

See package-info for more details 11 | * 12 | * @author adoneitan@gmail.com 13 | * @since 15 June 2016. 14 | */ 15 | public interface JSONNavigateAction extends NavigateAction {} 16 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/navigate/JSONNavigator.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.navigate; 2 | 3 | import java.util.List; 4 | import net.minidev.json.JSONArray; 5 | import net.minidev.json.JSONObject; 6 | 7 | /** 8 | * @author adoneitan@gmail.com 9 | * @since 15 June 2016. 10 | */ 11 | public class JSONNavigator extends TreeNavigator { 12 | 13 | public JSONNavigator(JSONNavigateAction action, List pathsToNavigate) { 14 | super(action, pathsToNavigate); 15 | } 16 | 17 | public JSONNavigator(JSONNavigateAction action, String... pathsToNavigate) { 18 | super(action, pathsToNavigate); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/navigate/NavigateAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.navigate; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | import java.util.Map; 6 | import net.minidev.json.actions.path.TreePath; 7 | 8 | /** 9 | * An interface for a processing action on the nodes of a {@link M} while navigating its branches. 10 | * 11 | *

See package-info for more details 12 | * 13 | * @author adoneitan@gmail.com 14 | * @since 15 June 2016 15 | */ 16 | public interface NavigateAction, L extends List> { 17 | /** 18 | * called before navigation of a new path starts 19 | * 20 | * @param path TODO 21 | * @return true if the specified path should be navigated 22 | */ 23 | boolean pathStart(String path); 24 | 25 | /** 26 | * called before any navigation of the {@link M} starts 27 | * 28 | * @param objectToNavigate TODO 29 | * @param pathsToNavigate TODO 30 | * @return true if navigation should start at all 31 | */ 32 | boolean start(M objectToNavigate, Collection pathsToNavigate); 33 | 34 | /** 35 | * reached end of branch in source before end of specified path - the specified path does not 36 | * exist in the source 37 | * 38 | * @param tp TODO 39 | * @param source TODO 40 | */ 41 | void pathTailNotFound(TreePath tp, Object source); 42 | 43 | /** 44 | * called after the navigation of a path ends 45 | * 46 | * @param path TODO 47 | */ 48 | void pathEnd(String path); 49 | 50 | /** 51 | * called if navigation of a path throws an exception 52 | * 53 | * @param path TODO 54 | * @param e TODO 55 | * @return true if the failure on this path should not abort the rest of the navigation 56 | */ 57 | boolean failSilently(String path, Exception e); 58 | 59 | /** 60 | * called if navigation of a path throws an exception 61 | * 62 | * @param path TODO 63 | * @param e TODO 64 | * @return true if the failure on this path should abort the rest of the navigation 65 | */ 66 | boolean failFast(String path, Exception e); 67 | 68 | /** 69 | * called when an object node is encountered on the path 70 | * 71 | * @param tp TODO 72 | * @param sourceNode TODO 73 | * @return true if the navigator should navigate into the object 74 | */ 75 | boolean recurInto(TreePath tp, M sourceNode); 76 | 77 | /** 78 | * called when an array node is encountered on the path 79 | * 80 | * @param tp TODO 81 | * @param sourceNode TODO 82 | * @return true if the navigator should navigate into the array 83 | */ 84 | boolean recurInto(TreePath tp, L sourceNode); 85 | 86 | /** 87 | * reached leaf node (not a container) in source but specified path expects children - the 88 | * specified path does not exist in the source 89 | * 90 | * @param jp TODO 91 | * @param obj TODO 92 | */ 93 | void foundLeafBeforePathEnd(TreePath jp, Object obj); 94 | 95 | /** 96 | * called when a leaf node is reached in a M. a leaf in a M is a key-value pair where the value is 97 | * not a container itself (it is not a M nor a L) 98 | * 99 | * @param tp - the JsonPath pointing to the leaf 100 | * @param value TODO 101 | */ 102 | void handleLeaf(TreePath tp, Object value); 103 | 104 | /** 105 | * called when a leaf in a L is reached. a leaf in a L is a non-container item (it is not a M nor 106 | * a L) 107 | * 108 | * @param tp - 109 | * @param arrIndex - 110 | * @param arrItem - the item 111 | */ 112 | void handleLeaf(TreePath tp, int arrIndex, Object arrItem); 113 | 114 | /** 115 | * called when navigation of an {@link M} type object ends 116 | * 117 | * @param tp the path pointing to the object 118 | * @param m TODO 119 | */ 120 | void recurEnd(TreePath tp, M m); 121 | 122 | /** 123 | * called when navigation of an {@link L} type object ends 124 | * 125 | * @param tp the path pointing to the object 126 | * @param l TODO 127 | */ 128 | void recurEnd(TreePath tp, L l); 129 | 130 | /** called after all navigation ends, and just before the navigation method exits */ 131 | void end(); 132 | 133 | /** 134 | * holds the result of the navigation, as assigned by the action implementing this interface 135 | * 136 | * @return - result 137 | */ 138 | Object result(); 139 | } 140 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/navigate/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Navigate user-specified paths in a tree made up of {@link java.util.Map}s and {@link 3 | * java.util.List} and process them 4 | * 5 | *

{@link net.minidev.json.actions.navigate.TreeNavigator} only navigates through branches 6 | * corresponding to user-specified paths. For each path, the navigation starts at the root and moves 7 | * down the branch. 8 | * 9 | *

The {@link net.minidev.json.actions.navigate.TreeNavigator} accepts a {@link 10 | * net.minidev.json.actions.navigate.NavigateAction} and provides callback hooks at each significant 11 | * step which the {@link net.minidev.json.actions.navigate.NavigateAction} may use to process the 12 | * nodes. 13 | * 14 | *

A path to navigate must be specified in the n-gram format - a list of keys from the root down 15 | * separated by dots: K0[[[[.K1].K2].K3]...]
16 | * A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in 17 | * their name are not supported. 18 | * 19 | *

Sample usage: 20 | * 21 | *

22 |  * NavigateAction navAction = new NavigateAction(){...};
23 |  * JSONNavigator jsonNav = new JSONNavigator(navAction, "foo.bar.path");
24 |  * jsonNav.nav(new JSONObject(...));
25 |  * Object result = navAction.result();
26 |  * 
27 | * 28 | * @author adoneitan@gmail.com 29 | */ 30 | package net.minidev.json.actions.navigate; 31 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/path/DotDelimiter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.path; 2 | 3 | /** 4 | * Encapsulates the delimiter '.' of the path parts when the path is specified in n-gram format. For 5 | * example: root.node1.node11.leaf 6 | * 7 | * @author adoneitan@gmail.com 8 | * @since 31 May2016 9 | */ 10 | public class DotDelimiter extends PathDelimiter { 11 | protected static final char DELIM_CHAR = '.'; 12 | 13 | public DotDelimiter() { 14 | super(DELIM_CHAR); 15 | } 16 | 17 | public String regex() { 18 | return "\\."; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/path/PathDelimiter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.path; 2 | 3 | /** 4 | * Encapsulates the delimiter of the path parts when given in n-gram format. 5 | * 6 | * @author adoneitan@gmail.com 7 | * @since 31 May 2016 8 | */ 9 | public abstract class PathDelimiter { 10 | protected char delimChar; 11 | protected String delimStr; 12 | protected boolean acceptDelimInKey; 13 | 14 | public PathDelimiter(char delim) { 15 | this.delimChar = delim; 16 | this.delimStr = String.valueOf(delim); 17 | } 18 | 19 | public PathDelimiter withAcceptDelimiterInNodeName(boolean acceptDelimInKey) { 20 | this.acceptDelimInKey = acceptDelimInKey; 21 | return this; 22 | } 23 | 24 | public boolean accept(String key) { 25 | if (!acceptDelimInKey && key.contains(delimStr)) return false; 26 | return true; 27 | } 28 | 29 | public String str() { 30 | return delimStr; 31 | } 32 | 33 | public char chr() { 34 | return delimChar; 35 | } 36 | 37 | public abstract String regex(); 38 | } 39 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/path/SlashDelimiter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.path; 2 | 3 | /** 4 | * Encapsulates the delimiter '.' of the path parts when the path is specified in n-gram format. For 5 | * example: root.node1.node11.leaf 6 | * 7 | * @author adoneitan@gmail.com 8 | * @since 31 May 2016 9 | */ 10 | public class SlashDelimiter extends PathDelimiter { 11 | protected static final char DELIM_CHAR = '/'; 12 | 13 | public SlashDelimiter() { 14 | super(DELIM_CHAR); 15 | super.withAcceptDelimiterInNodeName(false); 16 | } 17 | 18 | public String regex() { 19 | return "\\/"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/JSONTraverseAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import net.minidev.json.JSONArray; 4 | import net.minidev.json.JSONObject; 5 | 6 | /** 7 | * An interface for a processing action on the nodes of a {@link JSONObject} while traversing it. 8 | * 9 | *

See package-info for more details 10 | * 11 | * @author adoneitan@gmail.com 12 | */ 13 | public interface JSONTraverseAction extends TreeTraverseAction {} 14 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/JSONTraverser.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import net.minidev.json.JSONArray; 4 | import net.minidev.json.JSONObject; 5 | import net.minidev.json.actions.path.DotDelimiter; 6 | import net.minidev.json.actions.path.PathDelimiter; 7 | 8 | /** 9 | * Traverses every node of a {@link JSONObject} 10 | * 11 | *

{@link JSONTraverser} accepts an action and provides callback hooks for it to act on the 12 | * traversed nodes at each significant step. See {@link JSONTraverseAction}. 13 | * 14 | *

A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot 15 | * in their name are not supported. 16 | * 17 | *

See package-info for more details 18 | * 19 | * @author adoneitan@gmail.com 20 | */ 21 | public class JSONTraverser extends TreeTraverser { 22 | public JSONTraverser(JSONTraverseAction action) { 23 | super(action, new DotDelimiter()); 24 | } 25 | 26 | public JSONTraverser with(PathDelimiter delim) { 27 | super.delim = delim; 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/KeysPrintAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.Map.Entry; 4 | import net.minidev.json.JSONArray; 5 | import net.minidev.json.JSONObject; 6 | 7 | /** 8 | * @author adoneitan@gmail.com 9 | * @since 5/24/16. 10 | */ 11 | public class KeysPrintAction implements JSONTraverseAction { 12 | @Override 13 | public boolean start(JSONObject object) { 14 | return true; 15 | } 16 | 17 | @Override 18 | public boolean traverseEntry(String fullPathToEntry, Entry entry) { 19 | // System.out.println(entry.getKey()); 20 | return true; 21 | } 22 | 23 | @Override 24 | public boolean recurInto(String pathToEntry, JSONObject entryValue) { 25 | return true; 26 | } 27 | 28 | @Override 29 | public boolean recurInto(String pathToEntry, JSONArray entryValue) { 30 | return true; 31 | } 32 | 33 | @Override 34 | public void handleLeaf(String pathToEntry, Entry entry) {} 35 | 36 | @Override 37 | public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) {} 38 | 39 | @Override 40 | public boolean removeEntry(String fullPathToEntry, Entry entry) { 41 | return false; 42 | } 43 | 44 | @Override 45 | public void end() {} 46 | 47 | @Override 48 | public Object result() { 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/LocatePathsJsonAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.Map.Entry; 6 | import net.minidev.json.JSONArray; 7 | import net.minidev.json.JSONObject; 8 | import net.minidev.json.actions.path.PathDelimiter; 9 | 10 | /** 11 | * Searches for paths in a {@link JSONObject} and returns those found 12 | * 13 | *

A path is not removed from the user-specified list once its processing is over, because 14 | * identical objects in the same array are supported by this action. 15 | * 16 | *

See package-info for more details 17 | * 18 | *

See unit tests for examples 19 | * 20 | * @author adoneitan@gmail.com 21 | */ 22 | public class LocatePathsJsonAction implements JSONTraverseAction { 23 | protected List pathsFound; 24 | protected List pathsToFind; 25 | protected PathDelimiter delim; 26 | 27 | /** 28 | * @param pathsToFind A path to a field in the {@link JSONObject} should be specified in n-gram 29 | * format where keys are chained: k0[[[.k1].k2]...] 30 | * @param delim - 31 | */ 32 | public LocatePathsJsonAction(List pathsToFind, PathDelimiter delim) { 33 | this.pathsToFind = pathsToFind; 34 | this.delim = delim; 35 | pathsFound = new LinkedList(); 36 | } 37 | 38 | @Override 39 | public boolean start(JSONObject object) { 40 | return object != null && pathsToFind != null && pathsToFind.size() > 0; 41 | } 42 | 43 | @Override 44 | public boolean traverseEntry(String fullPathToEntry, Entry entry) { 45 | if (!delim.accept(entry.getKey())) { 46 | return false; 47 | } 48 | locatePath(fullPathToEntry); 49 | return true; 50 | } 51 | 52 | @Override 53 | public boolean recurInto(String pathToEntry, JSONObject entryValue) { 54 | return true; 55 | } 56 | 57 | @Override 58 | public boolean recurInto(String pathToEntry, JSONArray entryValue) { 59 | return true; 60 | } 61 | 62 | @Override 63 | public void handleLeaf(String pathToEntry, Entry entry) {} 64 | 65 | @Override 66 | public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) {} 67 | 68 | @Override 69 | public boolean removeEntry(String fullPathToEntry, Entry entry) { 70 | return false; 71 | } 72 | 73 | @Override 74 | public void end() { 75 | // nothing to do 76 | } 77 | 78 | @Override 79 | public Object result() { 80 | return pathsFound; 81 | } 82 | 83 | private void locatePath(String pathToEntry) { 84 | if (pathsToFind.contains(pathToEntry)) { 85 | // reached end of path that is being searched 86 | pathsFound.add(pathToEntry); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/RemoveElementsJsonAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.Map; 4 | import java.util.Map.Entry; 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.JSONObject; 7 | 8 | /** 9 | * Removes key:value elements from a {@link JSONObject}. 10 | * 11 | *

An element is not removed from the user-specified list once its processing is over, because it 12 | * may appear in more than one node. 13 | * 14 | *

See package-info for more details 15 | * 16 | *

See unit tests for examples 17 | * 18 | * @author adoneitan@gmail.com 19 | */ 20 | public class RemoveElementsJsonAction implements JSONTraverseAction { 21 | protected JSONObject result; 22 | protected final Map elementsToRemove; 23 | protected final boolean allowDotChar; 24 | 25 | public RemoveElementsJsonAction(Map elementsToRemove, boolean allowDotChar) { 26 | this.elementsToRemove = elementsToRemove; 27 | this.allowDotChar = allowDotChar; 28 | } 29 | 30 | public RemoveElementsJsonAction(Map elementsToRemove) { 31 | this(elementsToRemove, false); 32 | } 33 | 34 | @Override 35 | public boolean start(JSONObject object) { 36 | result = object; 37 | return object != null && elementsToRemove != null && elementsToRemove.size() > 0; 38 | } 39 | 40 | @Override 41 | public boolean removeEntry(String fullPathToEntry, Entry entry) { 42 | return elementsToRemove.entrySet().contains(entry); 43 | } 44 | 45 | @Override 46 | public boolean traverseEntry(String fullPathToEntry, Entry entry) { 47 | // must traverse the whole object 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean recurInto(String pathToEntry, JSONObject entryValue) { 53 | return true; 54 | } 55 | 56 | @Override 57 | public boolean recurInto(String pathToEntry, JSONArray entryValue) { 58 | return true; 59 | } 60 | 61 | @Override 62 | public void handleLeaf(String pathToEntry, Entry entry) {} 63 | 64 | @Override 65 | public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) {} 66 | 67 | @Override 68 | public void end() { 69 | // nothing to do 70 | } 71 | 72 | @Override 73 | public Object result() { 74 | return result; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/RemovePathsJsonAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.List; 4 | import java.util.Map.Entry; 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.JSONObject; 7 | 8 | /** 9 | * Removes branches from a {@link JSONObject}. 10 | * 11 | *

A path is not removed from the user-specified list once its processing is over, because 12 | * identical objects in the same array are supported by this action. 13 | * 14 | *

See package-info for more details 15 | * 16 | *

See unit tests for examples 17 | * 18 | * @author adoneitan@gmail.com 19 | */ 20 | public class RemovePathsJsonAction implements JSONTraverseAction { 21 | protected JSONObject result; 22 | protected List pathsToRemove; 23 | 24 | public RemovePathsJsonAction(List pathsToRemove) { 25 | this.pathsToRemove = pathsToRemove; 26 | } 27 | 28 | @Override 29 | public boolean start(JSONObject object) { 30 | result = object; 31 | return object != null && pathsToRemove != null && pathsToRemove.size() > 0; 32 | } 33 | 34 | @Override 35 | public boolean removeEntry(String fullPathToEntry, Entry entry) { 36 | return pathsToRemove.contains(fullPathToEntry); 37 | } 38 | 39 | @Override 40 | public boolean traverseEntry(String fullPathToEntry, Entry entry) { 41 | // must traverse the whole object 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean recurInto(String pathToEntry, JSONObject entryValue) { 47 | return true; 48 | } 49 | 50 | @Override 51 | public boolean recurInto(String pathToEntry, JSONArray entryValue) { 52 | return true; 53 | } 54 | 55 | @Override 56 | public void handleLeaf(String pathToEntry, Entry entry) {} 57 | 58 | @Override 59 | public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) {} 60 | 61 | @Override 62 | public void end() { 63 | // nothing to do 64 | } 65 | 66 | @Override 67 | public Object result() { 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/RetainPathsJsonAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map.Entry; 6 | import net.minidev.json.JSONArray; 7 | import net.minidev.json.JSONObject; 8 | import net.minidev.json.actions.path.PathDelimiter; 9 | 10 | /** 11 | * Retain branches or parts of branches matching a specified list of paths. 12 | * 13 | *

Paths are matched from the root down. If a user-specified path ends at a non-leaf node, the 14 | * rest of the branch from that node to the leaf is not retained. 15 | * 16 | *

A path is not removed from the user-specified list once its processing is over, because 17 | * identical objects in the same array are supported by this action. 18 | * 19 | *

See package-info for more details 20 | * 21 | *

See unit tests for examples 22 | * 23 | * @author adoneitan@gmail.com 24 | */ 25 | public class RetainPathsJsonAction implements JSONTraverseAction { 26 | protected final PathDelimiter delim; 27 | protected JSONObject result; 28 | protected List pathsToRetain; 29 | 30 | /** 31 | * @param pathsToRetain TODO 32 | * @param delim TODO 33 | */ 34 | public RetainPathsJsonAction(List pathsToRetain, PathDelimiter delim) { 35 | this.pathsToRetain = new ArrayList(pathsToRetain); 36 | this.delim = delim; 37 | } 38 | 39 | @Override 40 | public boolean start(JSONObject object) { 41 | if (object == null) { 42 | result = null; 43 | return false; 44 | } 45 | if (pathsToRetain == null || pathsToRetain.size() == 0) { 46 | result = new JSONObject(); 47 | return false; 48 | } 49 | result = object; 50 | return true; 51 | } 52 | 53 | @Override 54 | public boolean traverseEntry(String fullPathToEntry, Entry entry) { 55 | return true; 56 | } 57 | 58 | @Override 59 | public boolean recurInto(String fullPathToSubtree, JSONObject entryValue) { 60 | return true; 61 | } 62 | 63 | @Override 64 | public boolean recurInto(String fullPathToArrayItem, JSONArray entryValue) { 65 | return true; 66 | } 67 | 68 | @Override 69 | public void handleLeaf(String pathToEntry, Entry entry) {} 70 | 71 | @Override 72 | public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) {} 73 | 74 | @Override 75 | public boolean removeEntry(String fullPathToEntry, Entry entry) { 76 | return discardPath(fullPathToEntry, entry); 77 | } 78 | 79 | @Override 80 | public void end() { 81 | // nothing to do 82 | } 83 | 84 | @Override 85 | public Object result() { 86 | return result; 87 | } 88 | 89 | /** 90 | * if the full path to the entry is not contained in any of the paths to retain - remove it from 91 | * the object this step does not remove entries whose full path is contained in a path to retain 92 | * but are not equal to an entry to retain 93 | * 94 | * @param pathToEntry TODO 95 | * @param entry TODO 96 | * @return TODO 97 | */ 98 | protected boolean discardPath(String pathToEntry, Entry entry) { 99 | if (!foundAsPrefix(pathToEntry) || !delim.accept(entry.getKey())) { 100 | // skip traversal of subtree and remove from the traversal iterator 101 | return true; 102 | } 103 | return false; 104 | } 105 | 106 | /** 107 | * @param path TODO 108 | * @return TODO 109 | */ 110 | protected boolean foundAsPrefix(String path) { 111 | for (String p : pathsToRetain) { 112 | if (p == path || (p != null && path != null && p.startsWith(path))) { 113 | return true; 114 | } 115 | } 116 | return false; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/TreeTraverseAction.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | /** 8 | * An interface for a processing action on the nodes of a {@link M} tree while traversing it. The 9 | * order in which the callbacks are listed below is the order in which they are called by the {@link 10 | * TreeTraverser} 11 | * 12 | *

See package-info for more details 13 | * 14 | * @author adoneitan@gmail.com 15 | */ 16 | public interface TreeTraverseAction, L extends List> { 17 | /** 18 | * called before any traversal of the {@link M} tree starts 19 | * 20 | * @param object TODO 21 | * @return true if traversal should start at all 22 | */ 23 | boolean start(M object); 24 | 25 | /** 26 | * called when a new entry is encountered and before any processing is performed on it 27 | * 28 | * @param fullPathToEntry TODO 29 | * @param entry TODO 30 | * @return true if the entry should be processed 31 | */ 32 | boolean traverseEntry(String fullPathToEntry, Entry entry); 33 | 34 | /** 35 | * the last callback for each entry in an {@link M} map. if this method returns true the {@link 36 | * TreeTraverser} removes the entry from the map. there is no further handling of the entry. 37 | * 38 | * @param fullPathToEntry TODO 39 | * @param entry TODO 40 | * @return true if the entry and its subtree should be removed from the M tree 41 | */ 42 | boolean removeEntry(String fullPathToEntry, Entry entry); 43 | 44 | /** 45 | * called when a non-leaf entry is encountered inside an M object 46 | * 47 | * @param fullPathToSubtree TODO 48 | * @param entryValue TODO 49 | * @return true if the non-leaf entry should be recursively traversed 50 | */ 51 | boolean recurInto(String fullPathToSubtree, M entryValue); 52 | 53 | /** 54 | * called when a non-leaf item is encountered inside an L object 55 | * 56 | * @param fullPathToContainingList TODO 57 | * @param entryValue TODO 58 | * @return true if the non-leaf item should be recursively traversed 59 | */ 60 | boolean recurInto(String fullPathToContainingList, L entryValue); 61 | 62 | /** 63 | * called for each leaf of an M map is encountered 64 | * 65 | * @param fullPathToEntry TODO 66 | * @param entry TODO 67 | */ 68 | void handleLeaf(String fullPathToEntry, Entry entry); 69 | 70 | /** 71 | * called for each leaf of an L list is encountered 72 | * 73 | * @param fullPathToContainingList - the item 74 | * @param listIndex - the ordered location of the item in the list 75 | * @param listItem - 76 | */ 77 | void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem); 78 | 79 | /** called after the traversal ends, and just before the {@link #start} method exits */ 80 | void end(); 81 | 82 | /** 83 | * holds the result of the traversal, as assigned by the action implementing this interface 84 | * 85 | * @return result 86 | */ 87 | Object result(); 88 | } 89 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/TreeTraverser.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.actions.traverse; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import net.minidev.json.actions.path.PathDelimiter; 8 | 9 | /** 10 | * Traverses every node of a tree made up of a combination of {@link Map}s and {@link List}s 11 | * 12 | *

{@link TreeTraverser} accepts an action and provides callback hooks for it to act on the 13 | * traversed nodes at each significant step. See {@link TreeTraverseAction}. 14 | * 15 | *

See package-info for more details 16 | * 17 | * @author adoneitan@gmail.com 18 | */ 19 | public class TreeTraverser, L extends List> { 20 | protected TreeTraverseAction action; 21 | protected PathDelimiter delim; 22 | protected String pathPrefix = ""; 23 | 24 | public TreeTraverser(TreeTraverseAction action, PathDelimiter delim) { 25 | this.action = action; 26 | this.delim = delim; 27 | } 28 | 29 | public TreeTraverser with(String pathPrefix) { 30 | this.pathPrefix = pathPrefix; 31 | return this; 32 | } 33 | 34 | public void traverse(M map) { 35 | if (action.start(map)) { 36 | depthFirst(pathPrefix, map); 37 | } 38 | action.end(); 39 | } 40 | 41 | @SuppressWarnings("unchecked") 42 | private void depthFirst(String fullPath, M map) { 43 | if (map == null || map.entrySet() == null || !action.recurInto(fullPath, map)) { 44 | return; 45 | } 46 | Iterator> it = map.entrySet().iterator(); 47 | while (it.hasNext()) { 48 | Entry entry = it.next(); 49 | String fullPathToEntry = buildPath(fullPath, entry.getKey()); 50 | 51 | if (!action.traverseEntry(fullPathToEntry, entry)) { 52 | continue; 53 | } else if (action.removeEntry(fullPathToEntry, entry)) { 54 | it.remove(); 55 | continue; 56 | } 57 | 58 | if (entry.getValue() instanceof Map) { 59 | depthFirst(fullPathToEntry, (M) entry.getValue()); 60 | } else if (entry.getValue() instanceof List) { 61 | depthFirst(fullPathToEntry, (L) entry.getValue()); 62 | } else { 63 | action.handleLeaf(fullPathToEntry, entry); 64 | } 65 | } 66 | } 67 | 68 | @SuppressWarnings("unchecked") 69 | private void depthFirst(String fullPath, L list) { 70 | if (!action.recurInto(fullPath, (L) list)) { 71 | return; 72 | } 73 | int listIndex = 0; 74 | for (Object listItem : list.toArray()) { 75 | if (listItem instanceof Map) { 76 | depthFirst(fullPath, (M) listItem); 77 | } else if (listItem instanceof List) { 78 | depthFirst(fullPath, (L) listItem); 79 | } else { 80 | action.handleLeaf(fullPath, listIndex, listItem); 81 | } 82 | listIndex++; 83 | } 84 | } 85 | 86 | private String buildPath(String fullPath, String entryKey) { 87 | return pathPrefix.equals(fullPath) ? pathPrefix + entryKey : fullPath + delim.str() + entryKey; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /json-smart-action/src/main/java/net/minidev/json/actions/traverse/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Traverse all the nodes in a {@link net.minidev.json.JSONObject} and process them 3 | * 4 | *

The traversal starts at the root and moves breadth-first down the branches. The {@link 5 | * net.minidev.json.actions.traverse.TreeTraverser} accepts a {@link 6 | * net.minidev.json.actions.traverse.JSONTraverseAction} and provides callback hooks at each 7 | * significant step which the {@link net.minidev.json.actions.traverse.JSONTraverseAction} may use 8 | * to process the nodes. 9 | * 10 | *

The {@link net.minidev.json.actions.traverse.TreeTraverser} assumes that paths in the tree 11 | * which the {@link net.minidev.json.JSONObject} represents are specified in the n-gram format - a 12 | * list of keys from the root down separated by dots: 13 | * 14 | *

K0[[[[.K1].K2].K3]...] 15 | * 16 | *

A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot 17 | * in their name are not supported. 18 | * 19 | *

Sample usage: 20 | * 21 | *

22 |  * TraverseAction tAction = new TraverseAction(){...};
23 |  * JSONTraverser jsonTrv = new JSONTraverser(tAction);
24 |  * jsonTrv.traverse(new JSONObject(...));
25 |  * Object result = tAction.result();
26 |  * 
27 | * 28 | * @author adoneitan@gmail.com 29 | */ 30 | package net.minidev.json.actions.traverse; 31 | -------------------------------------------------------------------------------- /json-smart-action/src/test/java/net/minidev/json/test/actions/ElementRemoverTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.actions; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.stream.Stream; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONValue; 8 | import net.minidev.json.actions.ElementRemover; 9 | import net.minidev.json.parser.ParseException; 10 | import org.junit.jupiter.params.ParameterizedTest; 11 | import org.junit.jupiter.params.provider.Arguments; 12 | import org.junit.jupiter.params.provider.MethodSource; 13 | 14 | /** 15 | * Tests {@link ElementRemover} 16 | * 17 | * @author adoneitan@gmail.com 18 | */ 19 | // @RunWith(Parameterized.class) 20 | public class ElementRemoverTest { 21 | 22 | public ElementRemoverTest() {} 23 | 24 | private static String filter(String test) { 25 | if (test == null) return null; 26 | return test.replace("'", "\""); 27 | } 28 | 29 | public static Stream params() { 30 | return Stream.of( 31 | Arguments.of( 32 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 33 | null, 34 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), 35 | Arguments.of( 36 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 37 | "{}", 38 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), 39 | Arguments.of( 40 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 41 | "{'k0':'v2'}", 42 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), 43 | Arguments.of( 44 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 45 | "{'k2':'v2'}", 46 | "{'k0':{},'k1':{'k3':'v3'}}"), 47 | Arguments.of( 48 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 49 | "{'k0':{'k2':'v2'}}", 50 | "{'k1':{'k2':'v2','k3':'v3'}}"), 51 | Arguments.of( 52 | "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", 53 | "{'k2':'v2','k3':'v3'}", 54 | "{'k0':{},'k1':{}}"), 55 | Arguments.of("{'k0':{}}", "{}", "{'k0':{}}")); 56 | } 57 | ; 58 | 59 | @ParameterizedTest 60 | @MethodSource("params") 61 | public void test(String jsonToClean, String elementsToRemove, String expectedJson) 62 | throws ParseException { 63 | jsonToClean = filter(jsonToClean); 64 | elementsToRemove = filter(elementsToRemove); 65 | expectedJson = filter(expectedJson); 66 | 67 | JSONObject objectToClean = 68 | jsonToClean != null ? (JSONObject) JSONValue.parseWithException(jsonToClean) : null; 69 | JSONObject expectedObject = 70 | expectedJson != null ? (JSONObject) JSONValue.parseWithException(expectedJson) : null; 71 | JSONObject toRemove = 72 | elementsToRemove != null 73 | ? (JSONObject) JSONValue.parseWithException(elementsToRemove) 74 | : null; 75 | ElementRemover er = new ElementRemover(toRemove); 76 | er.remove(objectToClean); 77 | assertEquals(expectedObject, objectToClean); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /json-smart-action/src/test/java/net/minidev/json/test/actions/KeysPrintActionTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.actions; 2 | 3 | import net.minidev.json.JSONObject; 4 | import net.minidev.json.JSONValue; 5 | import net.minidev.json.actions.traverse.JSONTraverser; 6 | import net.minidev.json.actions.traverse.KeysPrintAction; 7 | import net.minidev.json.parser.ParseException; 8 | import org.junit.jupiter.api.Test; 9 | 10 | /** 11 | * @author adoneitan@gmail.com 12 | * @since 30 May 2016 13 | */ 14 | public class KeysPrintActionTest { 15 | @Test 16 | public void test() throws ParseException { 17 | KeysPrintAction p = new KeysPrintAction(); 18 | JSONTraverser t = new JSONTraverser(p); 19 | 20 | String data = 21 | "{" 22 | + "'k0':{" 23 | + "'k01':{" 24 | + "'k011':'v2'" 25 | + "}" 26 | + "}," 27 | + "'k1':{" 28 | + "'k11':{" 29 | + "'k111':'v5'" 30 | + "}," 31 | + "'k12':{" 32 | + "'k121':'v5'" 33 | + "}" 34 | + "}," 35 | + "'k3':{" 36 | + "'k31':{" 37 | + "'k311':'v5'" 38 | + "}" 39 | + "}" 40 | + "}"; 41 | JSONObject jo = (JSONObject) JSONValue.parseWithException(data.replace("'", "\"")); 42 | t.traverse(jo); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /json-smart-action/src/test/java/net/minidev/json/test/actions/TreePathTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.actions; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import net.minidev.json.actions.path.DotDelimiter; 7 | import net.minidev.json.actions.path.PathDelimiter; 8 | import net.minidev.json.actions.path.TreePath; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * @author adoneitan@gmail.com 13 | */ 14 | public class TreePathTest { 15 | private static final PathDelimiter delim = new DotDelimiter().withAcceptDelimiterInNodeName(true); 16 | 17 | @Test 18 | public void testIterator() { 19 | TreePath jp = new TreePath("a.b.c", delim); 20 | assertTrue(jp.nextIndex() == 0); 21 | assertTrue(jp.prevIndex() == -1); 22 | assertTrue("".equals(jp.curr())); 23 | assertTrue("".equals(jp.origin())); 24 | assertTrue("a.b.c".equals(jp.remainder())); 25 | assertTrue(jp.hasNext()); 26 | assertFalse(jp.hasPrev()); 27 | 28 | jp.next(); 29 | assertTrue("a".equals(jp.curr())); 30 | assertTrue("a".equals(jp.origin())); 31 | assertTrue("b.c".equals(jp.remainder())); 32 | assertTrue(jp.hasNext()); 33 | assertTrue(jp.hasPrev()); 34 | 35 | jp.next(); 36 | assertTrue("b".equals(jp.curr())); 37 | assertTrue("a.b".equals(jp.origin())); 38 | assertTrue("c".equals(jp.remainder())); 39 | assertTrue(jp.hasNext()); 40 | assertTrue(jp.hasPrev()); 41 | 42 | jp.next(); 43 | assertTrue("c".equals(jp.curr())); 44 | assertTrue("a.b.c".equals(jp.origin())); 45 | assertTrue("".equals(jp.remainder())); 46 | assertFalse(jp.hasNext()); 47 | assertTrue(jp.hasPrev()); 48 | 49 | /** 50 | * the first prev() after a next only changes direction. see {@link ListIterator} for details 51 | */ 52 | jp.prev(); 53 | assertTrue("c".equals(jp.curr())); 54 | assertTrue("a.b.c".equals(jp.origin())); 55 | assertTrue("".equals(jp.remainder())); 56 | assertTrue(jp.hasNext()); 57 | assertTrue(jp.hasPrev()); 58 | 59 | jp.prev(); 60 | assertTrue("b".equals(jp.curr())); 61 | assertTrue("a.b".equals(jp.origin())); 62 | assertTrue("c".equals(jp.remainder())); 63 | assertTrue(jp.hasNext()); 64 | assertTrue(jp.hasPrev()); 65 | 66 | jp.prev(); 67 | assertTrue("a".equals(jp.curr())); 68 | assertTrue("a".equals(jp.origin())); 69 | assertTrue("b.c".equals(jp.remainder())); 70 | assertTrue(jp.hasNext()); 71 | assertFalse(jp.hasPrev()); 72 | } 73 | 74 | @Test 75 | public void testSubPath() { 76 | TreePath jp = new TreePath("a.b.c", delim); 77 | assertTrue(jp.subPath(1, 2).equals("b.c")); 78 | } 79 | 80 | @Test 81 | public void testClone() throws CloneNotSupportedException { 82 | TreePath jp1 = new TreePath("a.b.c", delim); 83 | TreePath jp2 = jp1.clone(); 84 | assertTrue(jp1.equals(jp2)); 85 | 86 | jp1.next(); 87 | TreePath jp3 = jp1.clone(); 88 | assertTrue(jp1.equals(jp3)); 89 | 90 | jp1.prev(); 91 | TreePath jp4 = jp1.clone(); 92 | assertTrue(jp1.equals(jp4)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /json-smart/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /json-smart/ChangeLog.txt: -------------------------------------------------------------------------------- 1 | Version 1.0.4 (2011/05/02) 2 | * First Public version 3 | Version 1.0.4-1 (2011/05/03) 4 | * Performance Improvement 5 | Version 1.0.4-2 (2011/05/06) 6 | * add support for non protected string starting with digits. 7 | * add Junit tests 8 | 9 | -------------------------------------------------------------------------------- /json-smart/readme.txt: -------------------------------------------------------------------------------- 1 | @see: 2 | http://code.google.com/p/json-smart/ -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/JSONAware.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | /** 19 | * Beans that support customized output of JSON text shall implement this interface. 20 | * 21 | * @author FangYidong <fangyidong@yahoo.com.cn> 22 | */ 23 | public interface JSONAware { 24 | /** 25 | * @return JSON text 26 | */ 27 | String toJSONString(); 28 | } 29 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/JSONAwareEx.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | /** 19 | * Beans that support advanced output of JSON text shall implement this interface. 20 | * 21 | *

Adding compressions and formating features 22 | * 23 | * @author Uriel Chemouni <uchemouni@gmail.com> 24 | */ 25 | public interface JSONAwareEx extends JSONAware { 26 | /** 27 | * @return JSON text 28 | */ 29 | String toJSONString(JSONStyle compression); 30 | } 31 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/JSONStreamAware.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.IOException; 19 | 20 | /** 21 | * Beans that support customized output of JSON text to a writer shall implement this interface. 22 | * 23 | * @author FangYidong <fangyidong@yahoo.com.cn> 24 | */ 25 | public interface JSONStreamAware { 26 | /** write JSON string to out. */ 27 | void writeJSONString(Appendable out) throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/JSONStreamAwareEx.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.IOException; 19 | 20 | /** 21 | * Beans that support customized output of JSON text to a writer shall implement this interface. 22 | * 23 | * @author FangYidong <fangyidong@yahoo.com.cn> 24 | */ 25 | public interface JSONStreamAwareEx extends JSONStreamAware { 26 | /** write JSON string to out. */ 27 | void writeJSONString(Appendable out, JSONStyle compression) throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/annotate/JsonIgnore.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.annotate; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * block access to a field or to a getter or to a setter. 10 | * 11 | *

If field and getter are annotate with @JsonIgnore the field will be Writable only 12 | * 13 | *

If field and setter are annotate with @JsonIgnore the field will be Readable only 14 | * 15 | *

If getter and setter are annotate with @JsonIgnore the field will be Read/Write using field if 16 | * the field is public (default ) 17 | * 18 | * @author uriel 19 | */ 20 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD}) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @JsonSmartAnnotation 23 | public @interface JsonIgnore { 24 | boolean value() default true; 25 | } 26 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/annotate/JsonSmartAnnotation.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.annotate; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Jackson Annotation like 10 | * 11 | * @author uriel 12 | */ 13 | @Target({ElementType.ANNOTATION_TYPE}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface JsonSmartAnnotation {} 16 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/parser/JSONParserByteArray.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.parser; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; 19 | 20 | import java.nio.charset.StandardCharsets; 21 | import net.minidev.json.JSONValue; 22 | import net.minidev.json.writer.JsonReaderI; 23 | 24 | /** 25 | * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 26 | * 27 | * @author Uriel Chemouni <uchemouni@gmail.com> 28 | */ 29 | class JSONParserByteArray extends JSONParserMemory { 30 | private byte[] in; 31 | 32 | public JSONParserByteArray(int permissiveMode) { 33 | super(permissiveMode); 34 | } 35 | 36 | /** 37 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 38 | * ContainerFactory 39 | */ 40 | public Object parse(byte[] in) throws ParseException { 41 | return parse(in, JSONValue.defaultReader.DEFAULT); 42 | } 43 | 44 | // 45 | // 46 | // 47 | // 48 | // 49 | // 50 | // 51 | 52 | /** 53 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 54 | * ContainerFactory 55 | */ 56 | public T parse(byte[] in, JsonReaderI mapper) throws ParseException { 57 | this.base = mapper.base; 58 | this.in = in; 59 | this.len = in.length; 60 | return parse(mapper); 61 | } 62 | 63 | protected void extractString(int beginIndex, int endIndex) { 64 | xs = new String(in, beginIndex, endIndex - beginIndex, StandardCharsets.UTF_8); 65 | } 66 | 67 | protected void extractStringTrim(int start, int stop) { 68 | byte[] val = this.in; /* avoid getfield opcode */ 69 | 70 | while ((start < stop) && (val[start] <= ' ')) { 71 | start++; 72 | } 73 | while ((start < stop) && (val[stop - 1] <= ' ')) { 74 | stop--; 75 | } 76 | xs = new String(in, start, stop - start, StandardCharsets.UTF_8); 77 | } 78 | 79 | protected int indexOf(char c, int pos) { 80 | for (int i = pos; i < len; i++) if (in[i] == (byte) c) return i; 81 | return -1; 82 | } 83 | 84 | protected void read() { 85 | if (++pos >= len) this.c = EOI; 86 | else this.c = (char) in[pos]; 87 | } 88 | 89 | /** Same as read() in memory parsing */ 90 | protected void readS() { 91 | if (++pos >= len) this.c = EOI; 92 | else this.c = (char) in[pos]; 93 | } 94 | 95 | /** read data can not be EOI */ 96 | protected void readNoEnd() throws ParseException { 97 | if (++pos >= len) { 98 | this.c = EOI; 99 | throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); 100 | } else this.c = (char) in[pos]; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/parser/JSONParserInputStream.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.parser; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.InputStream; 19 | import java.io.InputStreamReader; 20 | import java.io.UnsupportedEncodingException; 21 | import java.nio.charset.StandardCharsets; 22 | import net.minidev.json.writer.JsonReaderI; 23 | 24 | /** 25 | * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 26 | * 27 | * @author Uriel Chemouni <uchemouni@gmail.com> 28 | */ 29 | class JSONParserInputStream extends JSONParserReader { 30 | 31 | // len 32 | public JSONParserInputStream(int permissiveMode) { 33 | super(permissiveMode); 34 | } 35 | 36 | /** 37 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 38 | * ContainerFactory 39 | * 40 | * @throws UnsupportedEncodingException 41 | */ 42 | public Object parse(InputStream in) throws ParseException, UnsupportedEncodingException { 43 | InputStreamReader i2 = new InputStreamReader(in, StandardCharsets.UTF_8); 44 | return super.parse(i2); 45 | } 46 | 47 | /** 48 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 49 | * ContainerFactory 50 | */ 51 | public T parse(InputStream in, JsonReaderI mapper) 52 | throws ParseException, UnsupportedEncodingException { 53 | InputStreamReader i2 = new InputStreamReader(in, StandardCharsets.UTF_8); 54 | // 55 | return super.parse(i2, mapper); 56 | } 57 | 58 | // 59 | // 60 | // 61 | // 62 | // 63 | // 64 | // 65 | // 66 | } 67 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/parser/JSONParserReader.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.parser; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; 19 | 20 | import java.io.IOException; 21 | import java.io.Reader; 22 | import net.minidev.json.JSONValue; 23 | import net.minidev.json.writer.JsonReaderI; 24 | 25 | /** 26 | * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 27 | * 28 | * @author Uriel Chemouni <uchemouni@gmail.com> 29 | */ 30 | class JSONParserReader extends JSONParserStream { 31 | private Reader in; 32 | 33 | // len 34 | public JSONParserReader(int permissiveMode) { 35 | super(permissiveMode); 36 | } 37 | 38 | /** 39 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 40 | * ContainerFactory 41 | */ 42 | public Object parse(Reader in) throws ParseException { 43 | return parse(in, JSONValue.defaultReader.DEFAULT); 44 | } 45 | 46 | /** 47 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 48 | * ContainerFactory 49 | */ 50 | public T parse(Reader in, JsonReaderI mapper) throws ParseException { 51 | this.base = mapper.base; 52 | // 53 | this.in = in; 54 | return super.parse(mapper); 55 | } 56 | 57 | // 58 | // 59 | // 60 | // 61 | // 62 | // 63 | // 64 | 65 | protected void read() throws IOException { 66 | int i = in.read(); 67 | c = (i == -1) ? (char) EOI : (char) i; 68 | pos++; 69 | // 70 | } 71 | 72 | protected void readS() throws IOException { 73 | sb.append(c); 74 | int i = in.read(); 75 | if (i == -1) { 76 | c = EOI; 77 | } else { 78 | c = (char) i; 79 | pos++; 80 | } 81 | } 82 | 83 | protected void readNoEnd() throws ParseException, IOException { 84 | int i = in.read(); 85 | if (i == -1) throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); 86 | c = (char) i; 87 | // 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.parser; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_CHAR; 19 | import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_TOKEN; 20 | 21 | import java.io.IOException; 22 | 23 | /** 24 | * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 25 | * 26 | * @author Uriel Chemouni <uchemouni@gmail.com> 27 | * @see JSONParserInputStream 28 | * @see JSONParserReader 29 | */ 30 | abstract class JSONParserStream extends JSONParserBase { 31 | // len 32 | // 33 | public JSONParserStream(int permissiveMode) { 34 | super(permissiveMode); 35 | } 36 | 37 | protected void readNQString(boolean[] stop) throws IOException { 38 | sb.clear(); 39 | skipNQString(stop); 40 | xs = sb.toString().trim(); 41 | } 42 | 43 | protected Object readNumber(boolean[] stop) throws ParseException, IOException { 44 | sb.clear(); 45 | sb.append(c); // accept first char digit or - 46 | read(); 47 | skipDigits(); 48 | 49 | // Integer digit 50 | if (c != '.' && c != 'E' && c != 'e') { 51 | skipSpace(); 52 | if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { 53 | // convert string 54 | skipNQString(stop); 55 | xs = sb.toString().trim(); 56 | if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); 57 | return xs; 58 | } 59 | xs = sb.toString().trim(); 60 | return parseNumber(xs); 61 | } 62 | // floating point 63 | if (c == '.') { 64 | sb.append(c); 65 | read(); 66 | skipDigits(); 67 | } 68 | if (c != 'E' && c != 'e') { 69 | skipSpace(); 70 | if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { 71 | // convert string 72 | skipNQString(stop); 73 | xs = sb.toString().trim(); 74 | if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); 75 | return xs; 76 | } 77 | xs = sb.toString().trim(); 78 | return extractFloat(); 79 | } 80 | sb.append('E'); 81 | read(); 82 | if (c == '+' || c == '-' || c >= '0' && c <= '9') { 83 | sb.append(c); 84 | read(); // skip first char 85 | skipDigits(); 86 | skipSpace(); 87 | if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { 88 | // convert string 89 | skipNQString(stop); 90 | xs = sb.toString().trim(); 91 | if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); 92 | return xs; 93 | } 94 | xs = sb.toString().trim(); 95 | return extractFloat(); 96 | } else { 97 | skipNQString(stop); 98 | xs = sb.toString().trim(); 99 | if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); 100 | if (!acceptLeadinZero) checkLeadinZero(); 101 | return xs; 102 | } 103 | // throw new ParseException(pos - 1, ERROR_UNEXPECTED_CHAR, null); 104 | } 105 | 106 | protected void readString() throws ParseException, IOException { 107 | if (!acceptSimpleQuote && c == '\'') { 108 | if (acceptNonQuote) { 109 | readNQString(stopAll); 110 | return; 111 | } 112 | throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); 113 | } 114 | sb.clear(); 115 | // 116 | // 117 | // 118 | // 119 | // 120 | // 121 | // 122 | // 123 | // 124 | // 125 | /* assert (c == '\"' || c == '\'') */ 126 | readString2(); 127 | } 128 | 129 | // 130 | // 131 | // 132 | // 133 | // 134 | // 135 | // 136 | // 137 | } 138 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.parser; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; 19 | 20 | import net.minidev.json.JSONValue; 21 | import net.minidev.json.writer.JsonReaderI; 22 | 23 | /** 24 | * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 25 | * 26 | * @author Uriel Chemouni <uchemouni@gmail.com> 27 | */ 28 | class JSONParserString extends JSONParserMemory { 29 | private String in; 30 | 31 | public JSONParserString(int permissiveMode) { 32 | super(permissiveMode); 33 | } 34 | 35 | /** 36 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 37 | * ContainerFactory 38 | */ 39 | public Object parse(String in) throws ParseException { 40 | return parse(in, JSONValue.defaultReader.DEFAULT); 41 | } 42 | 43 | // 44 | // 45 | // 46 | // 47 | // 48 | // 49 | // 50 | 51 | /** 52 | * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a 53 | * ContainerFactory 54 | */ 55 | public T parse(String in, JsonReaderI mapper) throws ParseException { 56 | this.base = mapper.base; 57 | this.in = in; 58 | this.len = in.length(); 59 | return parse(mapper); 60 | } 61 | 62 | protected void extractString(int beginIndex, int endIndex) { 63 | xs = in.substring(beginIndex, endIndex); 64 | } 65 | 66 | protected void extractStringTrim(int start, int stop) { 67 | while (start < stop - 1 && Character.isWhitespace(in.charAt(start))) { 68 | start++; 69 | } 70 | while (stop - 1 > start && Character.isWhitespace(in.charAt(stop - 1))) { 71 | stop--; 72 | } 73 | extractString(start, stop); 74 | } 75 | 76 | protected int indexOf(char c, int pos) { 77 | return in.indexOf(c, pos); 78 | } 79 | 80 | /** Read next char or END OF INPUT */ 81 | protected void read() { 82 | if (++pos >= len) this.c = EOI; 83 | else this.c = in.charAt(pos); 84 | } 85 | 86 | /** Same as read() in memory parsing */ 87 | protected void readS() { 88 | if (++pos >= len) this.c = EOI; 89 | else this.c = in.charAt(pos); 90 | } 91 | 92 | /** read data can not be EOI */ 93 | protected void readNoEnd() throws ParseException { 94 | if (++pos >= len) { 95 | this.c = EOI; 96 | throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); 97 | } else this.c = in.charAt(pos); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/reader/ArrayWriter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.reader; 2 | 3 | import java.io.IOException; 4 | import net.minidev.json.JSONStyle; 5 | import net.minidev.json.JSONValue; 6 | 7 | public class ArrayWriter implements JsonWriterI { 8 | public void writeJSONString(E value, Appendable out, JSONStyle compression) 9 | throws IOException { 10 | compression.arrayStart(out); 11 | boolean needSep = false; 12 | for (Object o : ((Object[]) value)) { 13 | if (needSep) compression.objectNext(out); 14 | else needSep = true; 15 | JSONValue.writeJSONString(o, out, compression); 16 | } 17 | compression.arrayStop(out); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/reader/BeansWriter.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.reader; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.Modifier; 7 | import net.minidev.json.JSONStyle; 8 | import net.minidev.json.JSONUtil; 9 | 10 | public class BeansWriter implements JsonWriterI { 11 | public void writeJSONString(E value, Appendable out, JSONStyle compression) 12 | throws IOException { 13 | try { 14 | Class nextClass = value.getClass(); 15 | boolean needSep = false; 16 | compression.objectStart(out); 17 | while (nextClass != Object.class) { 18 | Field[] fields = nextClass.getDeclaredFields(); 19 | for (Field field : fields) { 20 | int m = field.getModifiers(); 21 | if ((m & (Modifier.STATIC | Modifier.TRANSIENT | Modifier.FINAL)) > 0) continue; 22 | Object v = null; 23 | if ((m & Modifier.PUBLIC) > 0) { 24 | v = field.get(value); 25 | } else { 26 | String g = JSONUtil.getGetterName(field.getName()); 27 | Method mtd = null; 28 | 29 | try { 30 | mtd = nextClass.getDeclaredMethod(g); 31 | } catch (Exception e) { 32 | } 33 | if (mtd == null) { 34 | Class c2 = field.getType(); 35 | if (c2 == Boolean.TYPE || c2 == Boolean.class) { 36 | g = JSONUtil.getIsName(field.getName()); 37 | mtd = nextClass.getDeclaredMethod(g); 38 | } 39 | } 40 | if (mtd == null) continue; 41 | v = mtd.invoke(value); 42 | } 43 | if (v == null && compression.ignoreNull()) continue; 44 | if (needSep) compression.objectNext(out); 45 | else needSep = true; 46 | String key = field.getName(); 47 | 48 | JsonWriter.writeJSONKV(key, v, out, compression); 49 | // compression.objectElmStop(out); 50 | } 51 | nextClass = nextClass.getSuperclass(); 52 | } 53 | compression.objectStop(out); 54 | } catch (Exception e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/reader/BeansWriterASM.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.reader; 2 | 3 | import java.io.IOException; 4 | import net.minidev.asm.Accessor; 5 | import net.minidev.asm.BeansAccess; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONStyle; 8 | import net.minidev.json.JSONUtil; 9 | 10 | public class BeansWriterASM implements JsonWriterI { 11 | public void writeJSONString(E value, Appendable out, JSONStyle compression) 12 | throws IOException { 13 | try { 14 | Class cls = value.getClass(); 15 | boolean needSep = false; 16 | @SuppressWarnings("rawtypes") 17 | BeansAccess fields = BeansAccess.get(cls, JSONUtil.JSON_SMART_FIELD_FILTER); 18 | out.append('{'); 19 | for (Accessor field : fields.getAccessors()) { 20 | @SuppressWarnings("unchecked") 21 | Object v = fields.get(value, field.getIndex()); 22 | if (v == null && compression.ignoreNull()) continue; 23 | if (needSep) out.append(','); 24 | else needSep = true; 25 | String key = field.getName(); 26 | JSONObject.writeJSONKV(key, v, out, compression); 27 | } 28 | out.append('}'); 29 | } catch (IOException e) { 30 | throw e; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/reader/BeansWriterASMRemap.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.reader; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import net.minidev.asm.Accessor; 7 | import net.minidev.asm.BeansAccess; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.JSONStyle; 10 | import net.minidev.json.JSONUtil; 11 | 12 | public class BeansWriterASMRemap implements JsonWriterI { 13 | private Map rename = new HashMap(); 14 | 15 | public void renameField(String source, String dest) { 16 | rename.put(source, dest); 17 | } 18 | 19 | private String rename(String key) { 20 | String k2 = rename.get(key); 21 | if (k2 != null) return k2; 22 | return key; 23 | } 24 | 25 | public void writeJSONString(E value, Appendable out, JSONStyle compression) 26 | throws IOException { 27 | try { 28 | Class cls = value.getClass(); 29 | boolean needSep = false; 30 | @SuppressWarnings("rawtypes") 31 | BeansAccess fields = BeansAccess.get(cls, JSONUtil.JSON_SMART_FIELD_FILTER); 32 | out.append('{'); 33 | for (Accessor field : fields.getAccessors()) { 34 | @SuppressWarnings("unchecked") 35 | Object v = fields.get(value, field.getIndex()); 36 | if (v == null && compression.ignoreNull()) continue; 37 | if (needSep) out.append(','); 38 | else needSep = true; 39 | String key = field.getName(); 40 | key = rename(key); 41 | JSONObject.writeJSONKV(key, v, out, compression); 42 | } 43 | out.append('}'); 44 | } catch (IOException e) { 45 | throw e; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/reader/JsonWriterI.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.reader; 2 | 3 | import java.io.IOException; 4 | import net.minidev.json.JSONStyle; 5 | 6 | public interface JsonWriterI { 7 | public void writeJSONString(E value, Appendable out, JSONStyle compression) 8 | throws IOException; 9 | } 10 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/DefaultMapper.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | /* 4 | * Copyright 2011-2014 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import net.minidev.json.JSONArray; 19 | import net.minidev.json.JSONAwareEx; 20 | import net.minidev.json.JSONObject; 21 | 22 | /** 23 | * Simple Reader Class for generic Map 24 | * 25 | * @author uriel 26 | * @param 27 | */ 28 | public class DefaultMapper extends JsonReaderI { 29 | protected DefaultMapper(JsonReader base) { 30 | super(base); 31 | } 32 | 33 | @Override 34 | public JsonReaderI startObject(String key) { 35 | return base.DEFAULT; 36 | } 37 | 38 | @Override 39 | public JsonReaderI startArray(String key) { 40 | return base.DEFAULT; 41 | } 42 | 43 | @Override 44 | public Object createObject() { 45 | return new JSONObject(); 46 | } 47 | 48 | @Override 49 | public Object createArray() { 50 | return new JSONArray(); 51 | } 52 | 53 | @Override 54 | public void setValue(Object current, String key, Object value) { 55 | ((JSONObject) current).put(key, value); 56 | } 57 | 58 | @Override 59 | public void addValue(Object current, Object value) { 60 | ((JSONArray) current).add(value); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/DefaultMapperCollection.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.lang.reflect.Constructor; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class DefaultMapperCollection extends JsonReaderI { 23 | Class clz; 24 | 25 | // ? extends Collection 26 | public DefaultMapperCollection(JsonReader base, Class clz) { 27 | super(base); 28 | this.clz = clz; 29 | } 30 | 31 | // public static AMapper DEFAULT = new 32 | // DefaultMapperCollection(); 33 | @Override 34 | public JsonReaderI startObject(String key) { 35 | return this; 36 | } 37 | 38 | @Override 39 | public JsonReaderI startArray(String key) { 40 | return this; 41 | } 42 | 43 | @Override 44 | public Object createObject() { 45 | try { 46 | Constructor c = clz.getConstructor(); 47 | return c.newInstance(); 48 | } catch (Exception e) { 49 | return null; 50 | } 51 | } 52 | 53 | @Override 54 | public Object createArray() { 55 | try { 56 | Constructor c = clz.getConstructor(); 57 | return c.newInstance(); 58 | } catch (Exception e) { 59 | return null; 60 | } 61 | } 62 | 63 | @SuppressWarnings({"unchecked"}) 64 | @Override 65 | public void setValue(Object current, String key, Object value) { 66 | ((Map) current).put(key, value); 67 | } 68 | 69 | @SuppressWarnings("unchecked") 70 | @Override 71 | public void addValue(Object current, Object value) { 72 | ((List) current).add(value); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/DefaultMapperOrdered.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.util.LinkedHashMap; 19 | import java.util.Map; 20 | import net.minidev.json.JSONArray; 21 | import net.minidev.json.JSONAwareEx; 22 | 23 | public class DefaultMapperOrdered extends JsonReaderI { 24 | protected DefaultMapperOrdered(JsonReader base) { 25 | super(base); 26 | } 27 | ; 28 | 29 | @Override 30 | public JsonReaderI startObject(String key) { 31 | return base.DEFAULT_ORDERED; 32 | } 33 | 34 | @Override 35 | public JsonReaderI startArray(String key) { 36 | return base.DEFAULT_ORDERED; 37 | } 38 | 39 | @SuppressWarnings("unchecked") 40 | public void setValue(Object current, String key, Object value) { 41 | ((Map) current).put(key, value); 42 | } 43 | 44 | @Override 45 | public Object createObject() { 46 | return new LinkedHashMap(); 47 | } 48 | 49 | @Override 50 | public void addValue(Object current, Object value) { 51 | ((JSONArray) current).add(value); 52 | } 53 | 54 | @Override 55 | public Object createArray() { 56 | return new JSONArray(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/FakeMapper.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | public class FakeMapper extends JsonReaderI { 20 | private FakeMapper() { 21 | super(null); 22 | } 23 | 24 | public static JsonReaderI DEFAULT = new FakeMapper(); 25 | 26 | @Override 27 | public JsonReaderI startObject(String key) { 28 | return this; 29 | } 30 | 31 | @Override 32 | public JsonReaderI startArray(String key) { 33 | return this; 34 | } 35 | 36 | @Override 37 | public void setValue(Object current, String key, Object value) {} 38 | 39 | @Override 40 | public void addValue(Object current, Object value) {} 41 | 42 | @Override 43 | public Object createObject() { 44 | return null; 45 | } 46 | 47 | @Override 48 | public Object createArray() { 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/JsonReaderI.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | /* 4 | * Copyright 2011-2024 JSON-SMART authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | import java.io.IOException; 19 | import java.lang.reflect.Type; 20 | import net.minidev.json.parser.ParseException; 21 | 22 | /** 23 | * Default datatype mapper use by Json-smart ton store data. 24 | * 25 | * @author uriel Chemouni 26 | * @param result type 27 | */ 28 | public abstract class JsonReaderI { 29 | public final JsonReader base; 30 | 31 | /** 32 | * Reader can be link to the JsonReader Base 33 | * 34 | * @param base parent reader 35 | */ 36 | public JsonReaderI(JsonReader base) { 37 | this.base = base; 38 | } 39 | 40 | private static String ERR_MSG = "Invalid or non Implemented status"; 41 | 42 | /** 43 | * called when json-smart parser meet an object key 44 | * 45 | * @param key key name 46 | */ 47 | public JsonReaderI startObject(String key) throws ParseException, IOException { 48 | throw new RuntimeException( 49 | ERR_MSG + " startObject(String key) in " + this.getClass() + " key=" + key); 50 | } 51 | 52 | /** 53 | * called when json-smart parser start an array. 54 | * 55 | * @param key the destination key name, or null. 56 | */ 57 | public JsonReaderI startArray(String key) throws ParseException, IOException { 58 | throw new RuntimeException(ERR_MSG + " startArray in " + this.getClass() + " key=" + key); 59 | } 60 | 61 | /** called when json-smart done parsing a value */ 62 | public void setValue(Object current, String key, Object value) 63 | throws ParseException, IOException { 64 | throw new RuntimeException(ERR_MSG + " setValue in " + this.getClass() + " key=" + key); 65 | } 66 | 67 | /** ------------- */ 68 | public Object getValue(Object current, String key) { 69 | throw new RuntimeException( 70 | ERR_MSG + " getValue(Object current, String key) in " + this.getClass() + " key=" + key); 71 | } 72 | 73 | // Object current, 74 | public Type getType(String key) { 75 | throw new RuntimeException( 76 | ERR_MSG + " getType(String key) in " + this.getClass() + " key=" + key); 77 | } 78 | 79 | /** add a value in an array json object. */ 80 | public void addValue(Object current, Object value) throws ParseException, IOException { 81 | throw new RuntimeException( 82 | ERR_MSG + " addValue(Object current, Object value) in " + this.getClass()); 83 | } 84 | 85 | /** use to instantiate a new object that will be used as an object */ 86 | public Object createObject() { 87 | throw new RuntimeException(ERR_MSG + " createObject() in " + this.getClass()); 88 | } 89 | 90 | /** use to instantiate a new object that will be used as an array */ 91 | public Object createArray() { 92 | throw new RuntimeException(ERR_MSG + " createArray() in " + this.getClass()); 93 | } 94 | 95 | /** 96 | * Allow a mapper to convert a temporary structure to the final data format. 97 | * 98 | *

example: convert an List<Integer> to an int[] 99 | */ 100 | @SuppressWarnings("unchecked") 101 | public T convert(Object current) { 102 | return (T) current; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/MapperRemapped.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Type; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import net.minidev.json.parser.ParseException; 8 | 9 | /** 10 | * Simple solution to support on read field renaming 11 | * 12 | * @author uriel 13 | * @param 14 | */ 15 | public class MapperRemapped extends JsonReaderI { 16 | private Map rename; 17 | private JsonReaderI parent; 18 | 19 | public MapperRemapped(JsonReaderI parent) { 20 | super(parent.base); 21 | this.parent = parent; 22 | this.rename = new HashMap(); 23 | } 24 | 25 | public void renameField(String source, String dest) { 26 | rename.put(source, dest); 27 | } 28 | 29 | private String rename(String key) { 30 | String k2 = rename.get(key); 31 | if (k2 != null) return k2; 32 | return key; 33 | } 34 | 35 | @Override 36 | public void setValue(Object current, String key, Object value) 37 | throws ParseException, IOException { 38 | key = rename(key); 39 | parent.setValue(current, key, value); 40 | } 41 | 42 | public Object getValue(Object current, String key) { 43 | key = rename(key); 44 | return parent.getValue(current, key); 45 | } 46 | 47 | @Override 48 | public Type getType(String key) { 49 | key = rename(key); 50 | return parent.getType(key); 51 | } 52 | 53 | @Override 54 | public JsonReaderI startArray(String key) throws ParseException, IOException { 55 | key = rename(key); 56 | return parent.startArray(key); 57 | } 58 | 59 | @Override 60 | public JsonReaderI startObject(String key) throws ParseException, IOException { 61 | key = rename(key); 62 | return parent.startObject(key); 63 | } 64 | 65 | @Override 66 | public Object createObject() { 67 | return parent.createObject(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /json-smart/src/main/java/net/minidev/json/writer/UpdaterMapper.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.writer; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Type; 5 | import net.minidev.json.parser.ParseException; 6 | 7 | public class UpdaterMapper extends JsonReaderI { 8 | final T obj; 9 | final JsonReaderI mapper; 10 | 11 | public UpdaterMapper(JsonReader base, T obj) { 12 | super(base); 13 | if (obj == null) throw new NullPointerException("can not update null Object"); 14 | this.obj = obj; 15 | this.mapper = (JsonReaderI) base.getMapper(obj.getClass()); 16 | } 17 | 18 | public UpdaterMapper(JsonReader base, T obj, Type type) { 19 | super(base); 20 | if (obj == null) throw new NullPointerException("can not update null Object"); 21 | this.obj = obj; 22 | this.mapper = (JsonReaderI) base.getMapper(type); 23 | } 24 | 25 | /** called when json-smart parser meet an object key */ 26 | public JsonReaderI startObject(String key) throws ParseException, IOException { 27 | Object bean = mapper.getValue(obj, key); 28 | if (bean == null) return mapper.startObject(key); 29 | return new UpdaterMapper(base, bean, mapper.getType(key)); 30 | } 31 | 32 | /** 33 | * called when json-smart parser start an array. 34 | * 35 | * @param key the destination key name, or null. 36 | */ 37 | public JsonReaderI startArray(String key) throws ParseException, IOException { 38 | // if (obj != null) 39 | return mapper.startArray(key); 40 | } 41 | 42 | /** called when json-smart done parsing a value */ 43 | public void setValue(Object current, String key, Object value) 44 | throws ParseException, IOException { 45 | // if (obj != null) 46 | mapper.setValue(current, key, value); 47 | } 48 | 49 | /** add a value in an array json object. */ 50 | public void addValue(Object current, Object value) throws ParseException, IOException { 51 | // if (obj != null) 52 | mapper.addValue(current, value); 53 | } 54 | 55 | /** use to instantiate a new object that will be used as an object */ 56 | public Object createObject() { 57 | if (obj != null) return obj; 58 | return mapper.createObject(); 59 | } 60 | 61 | /** use to instantiate a new object that will be used as an array */ 62 | public Object createArray() { 63 | if (obj != null) return obj; 64 | return mapper.createArray(); 65 | } 66 | 67 | /** 68 | * Allow a mapper to convert a temporary structure to the final data format. 69 | * 70 | *

example: convert an List<Integer> to an int[] 71 | */ 72 | @SuppressWarnings("unchecked") 73 | public T convert(Object current) { 74 | if (obj != null) return obj; 75 | return (T) mapper.convert(current); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/JSONSimpleTest.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.parser.JSONParser; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class JSONSimpleTest { 10 | @Test 11 | public void testLong() throws Exception { 12 | String s = "[1]"; 13 | JSONParser p = new JSONParser(JSONParser.MODE_JSON_SIMPLE); 14 | JSONArray array = (JSONArray) p.parse(s); 15 | assertEquals(Long.valueOf(1), (Long) array.get(0)); 16 | } 17 | 18 | @Test 19 | public void testDefault() throws Exception { 20 | String s = "[1]"; 21 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 22 | JSONArray array = (JSONArray) p.parse(s); 23 | assertEquals(Integer.valueOf(1), (Integer) array.get(0)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/MustThrows.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | 6 | import net.minidev.json.parser.JSONParser; 7 | import net.minidev.json.parser.ParseException; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class MustThrows { 11 | 12 | @Test 13 | public static void testStrictInvalidJson(String json, int execptionType) throws Exception { 14 | testStrictInvalidJson(json, execptionType, null); 15 | } 16 | 17 | @Test 18 | public static void testStrictInvalidJson(String json, int execptionType, Class cls) 19 | throws Exception { 20 | testInvalidJson(json, JSONParser.MODE_RFC4627, execptionType, cls); 21 | } 22 | 23 | @Test 24 | public static void testInvalidJson(String json, int permissifMode, int execptionType) 25 | throws Exception { 26 | testInvalidJson(json, permissifMode, execptionType, null); 27 | } 28 | 29 | public static void testInvalidJson( 30 | String json, int permissifMode, int execptionType, Class cls) throws Exception { 31 | JSONParser p = new JSONParser(permissifMode); 32 | try { 33 | if (cls == null) p.parse(json); 34 | else p.parse(json, cls); 35 | assertFalse(true, "Exception Should Occure parsing:" + json); 36 | } catch (ParseException e) { 37 | if (execptionType == -1) execptionType = e.getErrorType(); 38 | assertEquals(execptionType, e.getErrorType()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/SerializeReadonlyField.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.Map; 10 | import net.minidev.json.JSONObject; 11 | import net.minidev.json.JSONValue; 12 | import org.junit.jupiter.api.Test; 13 | 14 | public class SerializeReadonlyField { 15 | /** https://github.com/netplex/json-smart-v2/issues/49 */ 16 | @Test 17 | public static void main(String[] args) { 18 | MyData data = new MyData("a"); 19 | Map m = new HashMap<>(); 20 | m.put("data", data); 21 | String a = new JSONObject(m).toString(); 22 | assertEquals("{\"data\":{\"someField\":\"a\"}}", a.toString()); 23 | } 24 | 25 | public static class MyData { 26 | private String someField; 27 | 28 | public MyData(String someField) { 29 | this.someField = someField; 30 | } 31 | 32 | public String getSomeField() { 33 | return someField; 34 | } 35 | 36 | // Remove comment to make serialization to work 37 | /* 38 | * public void setSomeField(String someField) { this.someField = someField; } 39 | */ 40 | } 41 | 42 | /** https://github.com/netplex/json-smart-v2/issues/59 */ 43 | @Test 44 | public void test() { 45 | // should not crash 46 | Map cachedTable1 = new LinkedHashMap<>(); 47 | Iterable path = Paths.get("/"); 48 | cachedTable1.put("1", path); 49 | JSONValue.toJSONString(cachedTable1); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestBigDigitUnrestricted.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.math.BigDecimal; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.parser.JSONParser; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestBigDigitUnrestricted { 11 | public static String[] VALID_DOUBLE_JSON = 12 | new String[] { 13 | "{\"v\":0.12345678912345678}", 14 | "\"v\":\"1.7976931348623157E308\"", 15 | "\"v\":\"1.7976931348623157E+308\"", 16 | "\"v\":\"1.7976931348623157e+308\"" 17 | }; 18 | 19 | @Test 20 | public void testRestrictedBigDigit() throws Exception { 21 | JSONParser p = new JSONParser(JSONParser.MODE_RFC4627); 22 | String json = VALID_DOUBLE_JSON[0]; 23 | JSONObject obj = (JSONObject) p.parse(json); 24 | Object value = obj.get("v"); 25 | assertEquals(Double.class, value.getClass(), "Should not Store this big number as a double"); 26 | } 27 | 28 | @Test 29 | public void testUnrestrictedBigDigit() throws Exception { 30 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 31 | String json = VALID_DOUBLE_JSON[0]; 32 | JSONObject obj = (JSONObject) p.parse(json); 33 | Object value = obj.get("v"); 34 | assertEquals( 35 | BigDecimal.class, value.getClass(), "Should not Store this big number as a double"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestBigValue.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.math.BigDecimal; 6 | import java.math.BigInteger; 7 | import java.util.HashMap; 8 | import net.minidev.json.JSONObject; 9 | import net.minidev.json.JSONValue; 10 | import org.junit.jupiter.api.Test; 11 | 12 | public class TestBigValue { 13 | String bigStr = "12345678901234567890123456789"; 14 | 15 | /** test BigDecimal serialization */ 16 | @Test 17 | public void testBigDecimal() { 18 | HashMap map = new HashMap(); 19 | BigDecimal bigDec = new BigDecimal(bigStr + "." + bigStr); 20 | map.put("big", bigDec); 21 | String test = JSONValue.toJSONString(map); 22 | String result = "{\"big\":" + bigStr + "." + bigStr + "}"; 23 | assertEquals(result, test); 24 | JSONObject obj = (JSONObject) JSONValue.parse(test); 25 | assertEquals(bigDec, obj.get("big")); 26 | assertEquals(bigDec.getClass(), obj.get("big").getClass()); 27 | } 28 | 29 | /** test BigInteger serialization */ 30 | @Test 31 | public void testBigInteger() { 32 | HashMap map = new HashMap(); 33 | BigInteger bigInt = new BigInteger(bigStr); 34 | map.put("big", bigInt); 35 | String test = JSONValue.toJSONString(map); 36 | String result = "{\"big\":" + bigStr + "}"; 37 | assertEquals(result, test); 38 | JSONObject obj = (JSONObject) JSONValue.parse(test); 39 | assertEquals(bigInt, obj.get("big")); 40 | assertEquals(bigInt.getClass(), obj.get("big").getClass()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestCVE202457699.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertThrows; 4 | 5 | import net.minidev.json.parser.JSONParser; 6 | import net.minidev.json.parser.ParseException; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestCVE202457699 { 10 | 11 | private static final String MALICIOUS_STRING = createMaliciousString(); 12 | 13 | @Test 14 | public void jsonSimpleParserShouldRestrictDepth() { 15 | JSONParser p = new JSONParser(JSONParser.MODE_JSON_SIMPLE); 16 | assertThrows( 17 | ParseException.class, 18 | () -> p.parse(MALICIOUS_STRING), 19 | "Malicious payload, having non natural depths"); 20 | } 21 | 22 | @Test 23 | public void strictestParserShouldRestrictDepth() { 24 | JSONParser p = new JSONParser(JSONParser.MODE_STRICTEST); 25 | assertThrows( 26 | ParseException.class, 27 | () -> p.parse(MALICIOUS_STRING), 28 | "Malicious payload, having non natural depths"); 29 | } 30 | 31 | @Test 32 | public void rfc4627ParserShouldRestrictDepth() { 33 | JSONParser p = new JSONParser(JSONParser.MODE_RFC4627); 34 | assertThrows( 35 | ParseException.class, 36 | () -> p.parse(MALICIOUS_STRING), 37 | "Malicious payload, having non natural depths"); 38 | } 39 | 40 | @Test 41 | public void permissiveParserShouldRestrictDepth() { 42 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 43 | assertThrows( 44 | ParseException.class, 45 | () -> p.parse(MALICIOUS_STRING), 46 | "Malicious payload, having non natural depths"); 47 | } 48 | 49 | private static String createMaliciousString() { 50 | StringBuilder sb = new StringBuilder(); 51 | for (int i = 0; i < 10000; i++) { 52 | sb.append("{\"a\":"); 53 | } 54 | sb.append("1"); 55 | for (int i = 0; i < 10000; i++) { 56 | sb.append("}"); 57 | } 58 | return sb.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestCompressor.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONValue; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class TestCompressor { 9 | @Test 10 | public void testCompressor() { 11 | String j = "{'a':{'b':'c','d':'e'},f:[1,2,'XYZ']}".replace('\'', '"'); 12 | String sol = j.replace(" ", "").replace("\"", ""); 13 | String comp = JSONValue.compress(j); 14 | assertEquals(sol, comp); 15 | } 16 | 17 | @Test 18 | public void testCompressor2() { 19 | String j = "[{} ]"; 20 | String sol = j.replace(" ", ""); 21 | String comp = JSONValue.compress(j); 22 | assertEquals(sol, comp); 23 | } 24 | 25 | @Test 26 | public void testCompressor3() { 27 | String j = "[[],[],[] ]"; 28 | String sol = j.replace(" ", ""); 29 | String comp = JSONValue.compress(j); 30 | assertEquals(sol, comp); 31 | } 32 | 33 | @Test 34 | public void testCompressor4() { 35 | String j = "[[1],[2,3],[4] ]"; 36 | String sol = j.replace(" ", ""); 37 | String comp = JSONValue.compress(j); 38 | assertEquals(sol, comp); 39 | } 40 | 41 | @Test 42 | public void testCompressor5() { 43 | String j = "[{},{},{} ]"; 44 | String sol = j.replace(" ", ""); 45 | String comp = JSONValue.compress(j); 46 | assertEquals(sol, comp); 47 | } 48 | 49 | @Test 50 | public void testCompressor6() { 51 | String j = "[{a:b},{c:d},{e:f}]"; 52 | String sol = j; 53 | String comp = JSONValue.compress(j); 54 | assertEquals(sol, comp); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestCompressorFlags.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONObject; 6 | import net.minidev.json.JSONStyle; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | /** 11 | * Test all Compression Styles 12 | * 13 | * @author Uriel Chemouni <uchemouni@gmail.com> 14 | */ 15 | public class TestCompressorFlags { 16 | 17 | @Test 18 | public void testProtect() throws Exception { 19 | String compressed = "{k:value}"; 20 | String nCompress = "{\"k\":\"value\"}"; 21 | 22 | JSONObject obj = (JSONObject) JSONValue.parse(nCompress); 23 | 24 | // test MAX_COMPRESS 25 | String r = obj.toJSONString(JSONStyle.MAX_COMPRESS); 26 | assertEquals(compressed, r); 27 | 28 | // test LT_COMPRESS 29 | r = obj.toJSONString(JSONStyle.LT_COMPRESS); 30 | assertEquals(nCompress, r); 31 | 32 | // test NO_COMPRESS 33 | r = obj.toJSONString(JSONStyle.NO_COMPRESS); 34 | assertEquals(nCompress, r); 35 | 36 | // only keys values 37 | JSONStyle style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_KEYS); 38 | r = obj.toJSONString(style); 39 | assertEquals("{k:\"value\"}", r); 40 | 41 | // only protect values 42 | style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_VALUES); 43 | r = obj.toJSONString(style); 44 | assertEquals("{\"k\":value}", r); 45 | } 46 | 47 | @Test 48 | public void testAggresive() throws Exception { 49 | String r; 50 | JSONStyle style; 51 | 52 | String NProtectValue = "{\"a b\":\"c d\"}"; 53 | JSONObject obj = (JSONObject) JSONValue.parse(NProtectValue); 54 | 55 | /** Test Without Agressive */ 56 | style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_KEYS); 57 | r = obj.toJSONString(style); 58 | assertEquals(NProtectValue, r); 59 | 60 | style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_VALUES); 61 | r = obj.toJSONString(style); 62 | assertEquals(NProtectValue, r); 63 | 64 | /** Test With Agressive */ 65 | style = new JSONStyle(-1 & (JSONStyle.FLAG_PROTECT_VALUES | JSONStyle.FLAG_AGRESSIVE)); 66 | r = obj.toJSONString(style); 67 | assertEquals("{\"a b\":c d}", r); 68 | 69 | style = new JSONStyle(-1 & (JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_AGRESSIVE)); 70 | r = obj.toJSONString(style); 71 | assertEquals("{a b:\"c d\"}", r); 72 | 73 | style = JSONStyle.MAX_COMPRESS; 74 | r = obj.toJSONString(style); 75 | assertEquals("{a b:c d}", r); 76 | } 77 | 78 | @Test 79 | public void test4Web() throws Exception { 80 | String NProtectValue = "{\"k\":\"http:\\/\\/url\"}"; 81 | 82 | JSONObject obj = (JSONObject) JSONValue.parse(NProtectValue); 83 | 84 | String r = obj.toJSONString(JSONStyle.MAX_COMPRESS); 85 | assertEquals("{k:\"http://url\"}", r); 86 | 87 | r = obj.toJSONString(JSONStyle.LT_COMPRESS); 88 | assertEquals("{\"k\":\"http://url\"}", r); 89 | 90 | r = obj.toJSONString(JSONStyle.NO_COMPRESS); 91 | assertEquals("{\"k\":\"http:\\/\\/url\"}", r); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestFloat.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONStyle; 8 | import net.minidev.json.parser.JSONParser; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class TestFloat { 12 | public static String[] TRUE_NUMBERS = 13 | new String[] { 14 | "1.0", 15 | "123.456", 16 | "1.0E1", 17 | "123.456E12", 18 | "1.0E+1", 19 | "123.456E+12", 20 | "1.0E-1", 21 | "123.456E-12", 22 | "1.0e1", 23 | "123.456e12", 24 | "1.0e+1", 25 | "123.456e+12", 26 | "1.0e-1", 27 | "123.456e-12" 28 | }; 29 | 30 | public static String[] FALSE_NUMBERS = 31 | new String[] {"1.0%", "123.45.6", "1.0E", "++123.456E12", "+-01", "1.0E+1.2"}; 32 | 33 | @Test 34 | public void testPrecisionFloat() throws Exception { 35 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 36 | for (int len = 15; len < 25; len++) { 37 | StringBuilder sb = new StringBuilder("0."); 38 | for (int i = 0; i < len; i++) { 39 | sb.append("123456789".charAt(i % 9)); 40 | } 41 | String s = sb.toString(); 42 | String json = "{v:" + s + "}"; 43 | JSONObject obj = (JSONObject) p.parse(json); 44 | Object value = obj.get("v").toString(); 45 | assertEquals(s, value, "Should not loose precision on a " + len + " digits long"); 46 | } 47 | } 48 | 49 | @Test 50 | public void testFloat() throws Exception { 51 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 52 | for (String s : TRUE_NUMBERS) { 53 | String json = "{v:" + s + "}"; 54 | Double val = Double.valueOf(s.trim()); 55 | JSONObject obj = (JSONObject) p.parse(json); 56 | Object value = obj.get("v"); 57 | assertEquals(val, value, "Should be parse as double"); 58 | } 59 | } 60 | 61 | @Test 62 | public void testNonFloat() throws Exception { 63 | JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); 64 | for (String s : FALSE_NUMBERS) { 65 | String json = "{v:" + s + "}"; 66 | JSONObject obj = (JSONObject) p.parse(json); 67 | assertEquals(s, obj.get("v"), "Should be parse as string"); 68 | 69 | String correct = "{\"v\":\"" + s + "\"}"; 70 | assertEquals(correct, obj.toJSONString(), "Should be re serialized as"); 71 | } 72 | } 73 | 74 | /** Error reported in issue 44 */ 75 | @Test 76 | public void testUUID() { 77 | String UUID = "58860611416142319131902418361e88"; 78 | JSONObject obj = new JSONObject(); 79 | obj.put("uuid", UUID); 80 | String compressed = obj.toJSONString(JSONStyle.MAX_COMPRESS); 81 | assertTrue(compressed.contains("uuid:\"")); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestFloatStrict.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONObject; 6 | import net.minidev.json.parser.JSONParser; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestFloatStrict { 10 | 11 | @Test 12 | public void testFloat() throws Exception { 13 | for (String s : TestFloat.TRUE_NUMBERS) { 14 | String json = "{\"v\":" + s + "}"; 15 | Double val = Double.valueOf(s.trim()); 16 | JSONObject obj = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(json); 17 | Object value = obj.get("v"); 18 | assertEquals(val, value, "Should be parse as double"); 19 | } 20 | } 21 | 22 | @Test 23 | public void testNonFloat() throws Exception { 24 | for (String s : TestFloat.FALSE_NUMBERS) { 25 | String json = "{\"v\":" + s + "}"; 26 | MustThrows.testStrictInvalidJson(json, -1); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestGitHubIssue.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static net.minidev.json.parser.JSONParser.MODE_PERMISSIVE; 4 | 5 | import net.minidev.json.parser.JSONParser; 6 | import net.minidev.json.parser.ParseException; 7 | import org.junit.jupiter.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestGitHubIssue { 11 | @Test 12 | public void issue68() { 13 | Assertions.assertThrows( 14 | ParseException.class, 15 | () -> { 16 | JSONParser parser = new JSONParser(MODE_PERMISSIVE); 17 | String input = "'1"; 18 | parser.parse(input); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestInts.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.math.BigDecimal; 6 | import java.math.BigInteger; 7 | import net.minidev.json.JSONObject; 8 | import net.minidev.json.parser.JSONParser; 9 | import net.minidev.json.parser.ParseException; 10 | import org.junit.jupiter.api.Test; 11 | 12 | public class TestInts { 13 | 14 | @Test 15 | public void testIntMax() throws Exception { 16 | String s = "{t:" + Integer.MAX_VALUE + "}"; 17 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 18 | assertEquals(o.get("t"), Integer.MAX_VALUE); 19 | } 20 | 21 | @Test 22 | public void testIntMin() throws Exception { 23 | String s = "{t:" + Integer.MIN_VALUE + "}"; 24 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 25 | assertEquals(o.get("t"), Integer.MIN_VALUE); 26 | } 27 | 28 | @Test 29 | public void testIntResult() throws Exception { 30 | String s = "{\"t\":1}"; 31 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 32 | assertEquals(o.get("t"), Integer.valueOf(1)); 33 | 34 | o = (JSONObject) new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse(s); 35 | assertEquals(o.get("t"), Long.valueOf(1)); 36 | 37 | o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 38 | assertEquals(o.get("t"), Integer.valueOf(1)); 39 | } 40 | 41 | @Test 42 | public void testInt() throws Exception { 43 | String s = "{t:90}"; 44 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 45 | assertEquals(o.get("t"), Integer.valueOf(90)); 46 | } 47 | 48 | @Test 49 | public void testIntNeg() throws Exception { 50 | String s = "{t:-90}"; 51 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 52 | assertEquals(o.get("t"), -90); 53 | } 54 | 55 | @Test 56 | public void testBigInt() throws Exception { 57 | StringBuilder sb = new StringBuilder(); 58 | for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); 59 | String bigText = sb.toString(); 60 | BigInteger big = new BigInteger(bigText, 10); 61 | String s = "{t:" + bigText + "}"; 62 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 63 | assertEquals(o.get("t"), big); 64 | } 65 | 66 | @Test 67 | public void testBigDoubleInt() throws Exception { 68 | StringBuilder sb = new StringBuilder(); 69 | for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); 70 | sb.append('.'); 71 | for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); 72 | 73 | String bigText = sb.toString(); 74 | BigDecimal big = new BigDecimal(bigText); 75 | String s = "{\"t\":" + bigText + "}"; 76 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 77 | assertEquals(o.get("t"), big); 78 | o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 79 | assertEquals(o.get("t"), big); 80 | } 81 | 82 | @Test 83 | public void testjunkTaillingData() throws Exception { 84 | String s = "{\"t\":124}$ifsisg045"; 85 | 86 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse(s); 87 | assertEquals(o.get("t"), 124L); 88 | 89 | MustThrows.testInvalidJson(s, JSONParser.MODE_RFC4627, ParseException.ERROR_UNEXPECTED_TOKEN); 90 | // o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 91 | // assertEquals(o.get("t"), 124); 92 | 93 | o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 94 | assertEquals(o.get("t"), 124); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestInvalidNumber.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONStyle; 8 | import net.minidev.json.JSONValue; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * test invalid number that will be handle ad string 13 | * 14 | * @author uriel 15 | */ 16 | public class TestInvalidNumber { 17 | 18 | private void validFloatAsFloat(String test) { 19 | JSONObject o = new JSONObject(); 20 | o.put("a", test); 21 | String comp = JSONValue.toJSONString(o, JSONStyle.MAX_COMPRESS); 22 | assertEquals("{a:\"" + test + "\"}", comp); 23 | o = JSONValue.parse(comp, JSONObject.class); 24 | Object convertedValue = o.get("a"); 25 | assertEquals(convertedValue, test, "Should handle valid number '" + test + "' as number"); 26 | } 27 | 28 | private void invalidFloatAsText(String test) { 29 | JSONObject o = new JSONObject(); 30 | o.put("a", test); 31 | String comp = JSONValue.toJSONString(o, JSONStyle.MAX_COMPRESS); 32 | assertEquals("{a:" + test + "}", comp); 33 | o = JSONValue.parse(comp, JSONObject.class); 34 | Object convertedValue = o.get("a"); 35 | assertEquals(convertedValue, test, "should handle invalid number '" + test + "' as string"); 36 | } 37 | 38 | @Test 39 | public void testF1() { 40 | validFloatAsFloat("51e88"); 41 | } 42 | 43 | @Test 44 | public void testF2() { 45 | validFloatAsFloat("51e+88"); 46 | } 47 | 48 | @Test 49 | public void testF3() { 50 | validFloatAsFloat("51e-88"); 51 | } 52 | 53 | @Test 54 | public void testF4() { 55 | invalidFloatAsText("51ee88"); 56 | } 57 | 58 | @Test 59 | public void testCVE_2021_27568() { 60 | try { 61 | JSONValue.parseWithException("{a:-.}"); 62 | assertFalse(true, "should Throws Exception before"); 63 | } catch (Exception e) { 64 | assertEquals(e.getMessage(), "Unexpected token -. at position 5.", "should throw EOF"); 65 | } 66 | 67 | try { 68 | JSONValue.parseWithException("{a:2e+}"); 69 | assertFalse(true, "should Throws Exception before"); 70 | } catch (Exception e) { 71 | assertEquals(e.getMessage(), "Unexpected token 2e+ at position 6.", "should throw EOF"); 72 | } 73 | 74 | try { 75 | JSONValue.parseWithException("{a:[45e-}"); 76 | assertFalse(true, "should Throws Exception before"); 77 | } catch (Exception e) { 78 | assertEquals(e.getMessage(), "Unexpected End Of File position 8: EOF", "should throw EOF"); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestKeyword.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNull; 5 | 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.parser.JSONParser; 8 | import net.minidev.json.parser.ParseException; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class TestKeyword { 12 | 13 | @Test 14 | public void testBool() throws Exception { 15 | String s = "{t:true}"; 16 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 17 | assertEquals(o.get("t"), true); 18 | 19 | s = "{t:false}"; 20 | o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 21 | assertEquals(o.get("t"), false); 22 | } 23 | 24 | @Test 25 | public void testNull() throws Exception { 26 | String s = "{t:null}"; 27 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 28 | assertNull(o.get("t")); 29 | } 30 | 31 | @Test 32 | public void testNaN() throws Exception { 33 | String s = "{t:NaN}"; 34 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 35 | assertEquals(o.get("t"), Float.NaN); 36 | } 37 | 38 | @Test 39 | public void testNaNStrict() throws Exception { 40 | String s = "{\"t\":NaN}"; 41 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_TOKEN); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestMisc.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestMisc { 11 | 12 | @Test 13 | public void testIssue23() throws Exception { 14 | String s = JSONValue.toJSONString(new int[] {1, 2, 50, 1234, 10000}); 15 | assertEquals("[1,2,50,1234,10000]", s); 16 | } 17 | 18 | @Test 19 | public void testEmptyStrict() throws Exception { 20 | String s = "{\"key1\":\"v1\", \"key2\":{}, \"key3\":[]}"; 21 | JSONObject o = (JSONObject) JSONValue.parseStrict(s); 22 | 23 | assertEquals(o.get("key1"), "v1"); 24 | assertEquals(((JSONObject) o.get("key2")).size(), 0); 25 | assertEquals(((JSONArray) o.get("key3")).size(), 0); 26 | } 27 | 28 | @Test 29 | public void testBool() throws Exception { 30 | String s = "{\"key1\":\"v1\", \"key2\":{}, \"key3\":[]}"; 31 | JSONObject o = (JSONObject) JSONValue.parseWithException(s); 32 | 33 | assertEquals(o.get("key1"), "v1"); 34 | assertEquals(((JSONObject) o.get("key2")).size(), 0); 35 | assertEquals(((JSONArray) o.get("key3")).size(), 0); 36 | } 37 | 38 | @Test 39 | public void testInt() throws Exception { 40 | String s = "123"; 41 | Object o = JSONValue.parseWithException(s); 42 | assertEquals(o, 123); 43 | } 44 | 45 | @Test 46 | public void testFloat() throws Exception { 47 | String s = "123.5"; 48 | Object o = JSONValue.parseWithException(s); 49 | assertEquals(o, Double.valueOf(123.5)); 50 | } 51 | 52 | @Test 53 | public void testFloat2() throws Exception { 54 | String s = "123.5E1"; 55 | Object o = JSONValue.parseWithException(s); 56 | assertEquals(o, Double.valueOf(1235)); 57 | } 58 | 59 | @Test 60 | public void testFloat3() throws Exception { 61 | String s = "123..5"; 62 | Object o = JSONValue.parseWithException(s); 63 | assertEquals(o, "123..5"); 64 | } 65 | 66 | @Test 67 | public void testFloat4() throws Exception { 68 | String s = "123é.5"; 69 | Object o = JSONValue.parseWithException(s); 70 | assertEquals(o, 123); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestNavi.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import net.minidev.json.JSONAwareEx; 7 | import net.minidev.json.JSONNavi; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestNavi { 11 | @Test 12 | public void testNaviWrite() { 13 | JSONNavi nav = JSONNavi.newInstance(); 14 | nav.set("name", "jhone") 15 | .set("age", 42) 16 | .at("childName") 17 | .add("fifi", "riri", "loulou") 18 | .up() 19 | .at("cat") 20 | .set("color", "red"); 21 | String s1 = 22 | "{\"name\":\"jhone\",\"age\":42,\"childName\":[\"fifi\",\"riri\",\"loulou\"],\"cat\":{\"color\":\"red\"}}"; 23 | String s2 = nav.toString(); 24 | assertEquals(s1, s2); 25 | } 26 | 27 | @Test 28 | public void testNaviWrite2() { 29 | JSONNavi nav = JSONNavi.newInstance(); 30 | nav.at("name") 31 | .set("toto") 32 | .up() 33 | .set("tutu", "V2") 34 | .at("size") 35 | .set("width", 10) 36 | .set("higth", 35) 37 | .up(3) 38 | .set("FinUp", 1) 39 | .at("array") 40 | .add(0, 1, 2, 3, 4, 5); 41 | nav.at(-1); 42 | assertEquals("/array[5]", nav.getJPath()); 43 | String s1 = 44 | "{'name':'toto','tutu':'V2','size':{'width':10,'higth':35},'FinUp':1,'array':[0,1,2,3,4,5]}" 45 | .replace('\'', '"'); 46 | String s2 = nav.toString(); 47 | assertEquals(s1, s2); 48 | } 49 | 50 | @Test 51 | public void testNaviRead() { 52 | String json = "{name:foo,str:null,ar:[1,2,3,4]}"; 53 | JSONNavi nav = new JSONNavi(json, JSONAwareEx.class); 54 | nav.at(5); 55 | assertTrue(nav.hasFailure(), "Navigator should be in error stat"); 56 | nav.root(); 57 | assertEquals(3, nav.at("ar").at(2).asInt()); 58 | nav.up(2); 59 | assertEquals(4, nav.at("ar").at(-1).asInt()); 60 | nav.up(2); 61 | assertEquals("foo", nav.at("name").asString()); 62 | } 63 | 64 | @Test 65 | public void testNaviWriteArray() { 66 | String expected = 67 | "{'type':'bundle','data':[{'type':'object','name':'obj1'},{'type':'object','name':'obj2'}]}" 68 | .replace('\'', '"'); 69 | JSONNavi nav = JSONNavi.newInstance(); 70 | nav.set("type", "bundle") 71 | .at("data") 72 | .array() 73 | .at(0) 74 | .set("type", "object") 75 | .set("name", "obj1") 76 | .up() 77 | .at(1) 78 | .set("type", "object") 79 | .set("name", "obj2") 80 | .root(); 81 | String s2 = nav.toString(); 82 | assertEquals(expected, s2); 83 | 84 | nav = JSONNavi.newInstance(); 85 | nav.set("type", "bundle") 86 | .at("data") 87 | .array() 88 | .atNext() 89 | .set("type", "object") 90 | .set("name", "obj1") 91 | .up() 92 | .atNext() 93 | .set("type", "object") 94 | .set("name", "obj2") 95 | .root(); 96 | s2 = nav.toString(); 97 | assertEquals(expected, s2); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestNumberPrecision.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.math.BigInteger; 6 | import net.minidev.json.JSONArray; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestNumberPrecision { 11 | @Test 12 | public void testMaxLong() { 13 | Long v = Long.MAX_VALUE; 14 | String s = "[" + v + "]"; 15 | JSONArray array = (JSONArray) JSONValue.parse(s); 16 | Object r = array.get(0); 17 | assertEquals(v, r); 18 | } 19 | 20 | @Test 21 | public void testMinLong() { 22 | Long v = Long.MIN_VALUE; 23 | String s = "[" + v + "]"; 24 | JSONArray array = (JSONArray) JSONValue.parse(s); 25 | Object r = array.get(0); 26 | assertEquals(v, r); 27 | } 28 | 29 | @Test 30 | public void testMinBig() { 31 | BigInteger v = BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE); 32 | String s = "[" + v + "]"; 33 | JSONArray array = (JSONArray) JSONValue.parse(s); 34 | Object r = array.get(0); 35 | assertEquals(v, r); 36 | } 37 | 38 | @Test 39 | public void testMaxBig() { 40 | BigInteger v = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE); 41 | String s = "[" + v + "]"; 42 | JSONArray array = (JSONArray) JSONValue.parse(s); 43 | Object r = array.get(0); 44 | assertEquals(v, r); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestOverflow.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.junit.jupiter.api.Assertions.fail; 6 | 7 | import net.minidev.json.JSONArray; 8 | import net.minidev.json.JSONValue; 9 | import net.minidev.json.parser.JSONParser; 10 | import net.minidev.json.parser.ParseException; 11 | import org.junit.jupiter.api.Test; 12 | 13 | public class TestOverflow { 14 | @Test 15 | public void stressTest() throws Exception { 16 | int size = 10000; 17 | StringBuilder sb = new StringBuilder(10 + size * 4); 18 | for (int i = 0; i < size; i++) { 19 | sb.append("{a:"); 20 | } 21 | sb.append("true"); 22 | for (int i = 0; i < size; i++) { 23 | sb.append("}"); 24 | } 25 | String s = sb.toString(); 26 | try { 27 | JSONValue.parseWithException(s); 28 | } catch (ParseException e) { 29 | assertEquals(e.getErrorType(), ParseException.ERROR_UNEXPECTED_JSON_DEPTH); 30 | return; 31 | } 32 | fail(); 33 | } 34 | 35 | @Test 36 | public void shouldNotFailWhenInfiniteJsonDepth() throws Exception { 37 | int size = 500; 38 | StringBuilder sb = new StringBuilder(10 + size * 4); 39 | for (int i = 0; i < size; i++) { 40 | sb.append("{a:"); 41 | } 42 | sb.append("true"); 43 | for (int i = 0; i < size; i++) { 44 | sb.append("}"); 45 | } 46 | String s = sb.toString(); 47 | try { 48 | JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE & ~JSONParser.LIMIT_JSON_DEPTH); 49 | parser.parse(s, JSONValue.defaultReader.DEFAULT); 50 | } catch (ParseException e) { 51 | fail(); 52 | } 53 | } 54 | 55 | @Test 56 | public void shouldNotFailParsingArraysWith400Elements() throws Exception { 57 | int size = 400; 58 | StringBuilder sb = new StringBuilder(); 59 | sb.append("["); 60 | for (int i = 0; i < size; i++) { 61 | sb.append("{a:true}"); 62 | if (i + 1 < size) { 63 | sb.append(","); 64 | } 65 | } 66 | sb.append("]"); 67 | String s = sb.toString(); 68 | JSONArray array = (JSONArray) JSONValue.parseWithException(s); 69 | assertEquals(array.size(), size); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestStrict.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONObject; 6 | import net.minidev.json.parser.JSONParser; 7 | import net.minidev.json.parser.ParseException; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestStrict { 11 | 12 | @Test 13 | public void testS1() throws Exception { 14 | String text = "My Test"; 15 | String s = "{t:\"" + text + "\"}"; 16 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 17 | assertEquals(o.get("t"), text); 18 | } 19 | 20 | @Test 21 | public void testS2() throws Exception { 22 | String text = "My Test"; 23 | String s = "{t:'" + text + "'}"; 24 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 25 | assertEquals(o.get("t"), text); 26 | } 27 | 28 | @Test 29 | public void testSEscape() throws Exception { 30 | String text = "My\r\nTest"; 31 | String text2 = "My\\r\\nTest"; 32 | String s = "{t:'" + text2 + "'}"; 33 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 34 | assertEquals(o.get("t"), text); 35 | } 36 | 37 | @Test 38 | public void testBadString() throws Exception { 39 | String s = "{\"t\":\"Before\u000CAfter\"}"; 40 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 41 | assertEquals("Before\u000CAfter", o.get("t")); 42 | try { 43 | o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 44 | assertEquals("nothink", o.get("t")); 45 | } catch (ParseException e) { 46 | assertEquals("Exception", "Exception"); 47 | } 48 | } 49 | 50 | /** issue report gitHub 8 by jochenberger */ 51 | @Test 52 | public void testDataAfterValue() throws Exception { 53 | String s = "{\"foo\":\"bar\"x}"; 54 | MustThrows.testInvalidJson( 55 | s, 56 | JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE, 57 | ParseException.ERROR_UNEXPECTED_TOKEN); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestString.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONObject; 6 | import net.minidev.json.parser.JSONParser; 7 | import net.minidev.json.parser.ParseException; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestString { 11 | 12 | @Test 13 | public void testS0() throws Exception { 14 | MustThrows.testStrictInvalidJson( 15 | "{\"1\":\"one\"\n\"2\":\"two\"}", ParseException.ERROR_UNEXPECTED_TOKEN); 16 | } 17 | 18 | @Test 19 | public void testS1() throws Exception { 20 | String text = "My Test"; 21 | String s = "{t:\"" + text + "\"}"; 22 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 23 | assertEquals(o.get("t"), text); 24 | } 25 | 26 | @Test 27 | public void testS2() throws Exception { 28 | String text = "My Test"; 29 | String s = "{t:'" + text + "'}"; 30 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 31 | assertEquals(o.get("t"), text); 32 | } 33 | 34 | @Test 35 | public void testSEscape() throws Exception { 36 | String text = "My\r\nTest"; 37 | String text2 = "My\\r\\nTest"; 38 | String s = "{t:'" + text2 + "'}"; 39 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 40 | assertEquals(o.get("t"), text); 41 | } 42 | 43 | @Test 44 | public void testBadString() throws Exception { 45 | String s = "{\"t\":\"Before\u000CAfter\"}"; 46 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 47 | assertEquals("Before\u000CAfter", o.get("t")); 48 | try { 49 | o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 50 | assertEquals("nothink", o.get("t")); 51 | } catch (ParseException e) { 52 | assertEquals("Exception", "Exception"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestStringStrict.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import net.minidev.json.parser.ParseException; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class TestStringStrict { 7 | 8 | @Test 9 | public void testS1() throws Exception { 10 | String text = "My Test"; 11 | String s = "{t:\"" + text + "\"}"; 12 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_TOKEN); 13 | } 14 | 15 | @Test 16 | public void testSEscape() throws Exception { 17 | String text2 = "My\\r\\nTest"; 18 | String s = "{\"t\":'" + text2 + "'}"; 19 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestTruncated.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import net.minidev.json.parser.ParseException; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class TestTruncated { 7 | 8 | @Test 9 | public void testS1() throws Exception { 10 | String s = "{\"key\":{}"; 11 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); 12 | } 13 | 14 | @Test 15 | public void testS2() throws Exception { 16 | String s = "{\"key\":"; 17 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); 18 | } 19 | 20 | @Test 21 | public void testS3() throws Exception { 22 | String s = "{\"key\":123"; 23 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/TestUtf8.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.io.ByteArrayInputStream; 6 | import java.io.StringReader; 7 | import java.nio.charset.StandardCharsets; 8 | import java.util.stream.Stream; 9 | import net.minidev.json.JSONObject; 10 | import net.minidev.json.JSONValue; 11 | import org.junit.jupiter.params.ParameterizedTest; 12 | import org.junit.jupiter.params.provider.Arguments; 13 | import org.junit.jupiter.params.provider.MethodSource; 14 | 15 | public class TestUtf8 { 16 | public static Stream languages() { 17 | return Stream.of( 18 | Arguments.of("Sinhala", "සිංහල ජාතිය"), 19 | Arguments.of("Japanese", "日本語"), 20 | Arguments.of("Russian", "Русский"), 21 | Arguments.of("Farsi", "فارسی"), 22 | Arguments.of("Korean", "한국어"), 23 | Arguments.of("Armenian", "Հայերեն"), 24 | Arguments.of("Hindi", "हिन्दी"), 25 | Arguments.of("Hebrew", "עברית"), 26 | Arguments.of("Chinese", "中文"), 27 | Arguments.of("Amharic", "አማርኛ"), 28 | Arguments.of("Malayalam", "മലയാളം"), 29 | Arguments.of("Assyrian Neo-Aramaic", "ܐܬܘܪܝܐ"), 30 | Arguments.of("Georgian", "მარგალური"), 31 | Arguments.of( 32 | "Emojis", 33 | "🐶🐱🐭🐹🐰🦊🐻🐼🐻‍❄🐨🐯🦁🐮🐷🐽🐸🐵🙈🙉🙊🐒🐔🐧🐦🐤🐣🐥🦆🦅🦉🦇🐺🐗🐴🦄🐝🐛")); 34 | } 35 | ; 36 | 37 | @ParameterizedTest 38 | @MethodSource("languages") 39 | public void supportI18nString(String language, String nonLatinText) throws Exception { 40 | String json = "{\"key\":\"" + nonLatinText + "\"}"; 41 | JSONObject obj = (JSONObject) JSONValue.parse(json); 42 | String actual = (String) obj.get("key"); 43 | assertEquals(nonLatinText, actual, "Parsing String " + language + " text"); 44 | } 45 | 46 | @ParameterizedTest 47 | @MethodSource("languages") 48 | public void supportI18nStringReader(String language, String nonLatinText) throws Exception { 49 | String json = "{\"key\":\"" + nonLatinText + "\"}"; 50 | StringReader reader = new StringReader(json); 51 | JSONObject obj = (JSONObject) JSONValue.parse(reader); 52 | 53 | String actual = (String) obj.get("key"); 54 | assertEquals(nonLatinText, actual, "Parsing StringReader " + language + " text"); 55 | } 56 | 57 | @ParameterizedTest 58 | @MethodSource("languages") 59 | public void supportI18nByteArrayInputStream(String language, String nonLatinText) 60 | throws Exception { 61 | String json = "{\"key\":\"" + nonLatinText + "\"}"; 62 | ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); 63 | JSONObject obj = (JSONObject) JSONValue.parse(bis); 64 | String actual = (String) obj.get("key"); 65 | assertEquals(nonLatinText, actual, "Parsing ByteArrayInputStream " + language + " text"); 66 | } 67 | 68 | @ParameterizedTest 69 | @MethodSource("languages") 70 | public void supportI18nBytes(String language, String nonLatinText) throws Exception { 71 | String json = "{\"key\":\"" + nonLatinText + "\"}"; 72 | byte[] bs = json.getBytes(StandardCharsets.UTF_8); 73 | JSONObject obj = JSONValue.parse(bs, JSONObject.class); 74 | String actual = (String) obj.get("key"); 75 | assertEquals(nonLatinText, actual, "Parsing bytes[] " + language + " text"); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/strict/TestExcessiveComma.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.strict; 2 | 3 | import net.minidev.json.JSONValue; 4 | import net.minidev.json.parser.ParseException; 5 | import net.minidev.json.test.MustThrows; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class TestExcessiveComma { 9 | @Test 10 | public void testExcessiveComma1A() throws Exception { 11 | String s = "[1,2,,3]"; 12 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 13 | JSONValue.parseWithException(s); 14 | } 15 | 16 | @Test 17 | public void testExcessiveComma2A() throws Exception { 18 | String s = "[1,2,]"; 19 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 20 | JSONValue.parseWithException(s); 21 | } 22 | 23 | @Test 24 | public void testExcessiveComma3A() throws Exception { 25 | String s = "[,]"; 26 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 27 | JSONValue.parseWithException(s); 28 | } 29 | 30 | @Test 31 | public void testExcessiveComma4A() throws Exception { 32 | String s = "[,5]"; 33 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 34 | JSONValue.parseWithException(s); 35 | } 36 | 37 | @Test 38 | public void testExcessiveComma1O() throws Exception { 39 | String s = "{\"a\":1,,\"b\":1}"; 40 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 41 | JSONValue.parseWithException(s); 42 | } 43 | 44 | @Test 45 | public void testExcessiveComma2O() throws Exception { 46 | String s = "{\"a\":1,}"; 47 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 48 | JSONValue.parseWithException(s); 49 | } 50 | 51 | @Test 52 | public void testExcessiveComma3O() throws Exception { 53 | String s = "{,}"; 54 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); 55 | JSONValue.parseWithException(s); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/strict/TestSpecialChar.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.strict; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.parser.JSONParser; 7 | import net.minidev.json.parser.ParseException; 8 | import net.minidev.json.test.MustThrows; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * Test control charaters 13 | * 14 | * @author uriel 15 | */ 16 | public class TestSpecialChar { 17 | 18 | @Test 19 | public void testSpecial127() throws Exception { 20 | String s127 = String.format("%c", 127); 21 | String s = String.format("[\"%c\"]", 127); 22 | MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_CHAR); 23 | 24 | JSONArray o = (JSONArray) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 25 | assertEquals(o.get(0), s127); 26 | } 27 | 28 | @Test 29 | public void testSpecial31() throws Exception { 30 | String s = String.format("[\"%c\"]", 31); 31 | MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_CHAR); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/strict/TestTaillingJunk.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.strict; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONObject; 6 | import net.minidev.json.parser.JSONParser; 7 | import net.minidev.json.parser.ParseException; 8 | import net.minidev.json.test.MustThrows; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * @since 1.0.7 13 | */ 14 | public class TestTaillingJunk { 15 | 16 | @Test 17 | public void testTaillingSpace() throws Exception { 18 | String s = "{\"t\":0} "; 19 | MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_TOKEN); 20 | 21 | s = "{\"t\":0} "; 22 | JSONObject o = 23 | (JSONObject) 24 | new JSONParser(JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE).parse(s); 25 | assertEquals(o.get("t"), 0); 26 | } 27 | 28 | @Test 29 | public void testTaillingSpace2() throws Exception { 30 | String s = "{\"t\":0} \r\n "; 31 | JSONObject o = 32 | (JSONObject) 33 | new JSONParser(JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE).parse(s); 34 | assertEquals(o.get("t"), 0); 35 | } 36 | 37 | @Test 38 | public void testTaillingData() throws Exception { 39 | String s = "{\"t\":0} 0"; 40 | MustThrows.testInvalidJson( 41 | s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_TOKEN, null); 42 | } 43 | 44 | @Test 45 | public void testTaillingDataPermisive() throws Exception { 46 | String s = "{\"t\":0} 0"; 47 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 48 | assertEquals(o.get("t"), 0); 49 | } 50 | 51 | @Test 52 | public void testTaillingDataWithSpaceAllowed() throws Exception { 53 | String s = "{\"t\":0}{"; 54 | MustThrows.testInvalidJson( 55 | s, 56 | JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE, 57 | ParseException.ERROR_UNEXPECTED_TOKEN); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/strict/TestZeroLead.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.strict; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONArray; 6 | import net.minidev.json.JSONObject; 7 | import net.minidev.json.JSONValue; 8 | import net.minidev.json.parser.JSONParser; 9 | import net.minidev.json.parser.ParseException; 10 | import net.minidev.json.test.MustThrows; 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * @since 1.0.7 15 | */ 16 | public class TestZeroLead { 17 | 18 | @Test 19 | public void test0O() throws Exception { 20 | String s = "{\"t\":0}"; 21 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 22 | assertEquals(o.get("t"), 0); 23 | JSONValue.parseWithException(s); 24 | } 25 | 26 | @Test 27 | public void test0A() throws Exception { 28 | String s = "[0]"; 29 | JSONArray o = (JSONArray) new JSONParser(JSONParser.MODE_RFC4627).parse(s); 30 | assertEquals(o.get(0), 0); 31 | JSONValue.parseWithException(s); 32 | } 33 | 34 | @Test 35 | public void test0Float() throws Exception { 36 | String s = "[00.0]"; 37 | // strict 38 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); 39 | // PERMISIVE 40 | JSONValue.parseWithException(s); 41 | } 42 | 43 | @Test 44 | public void test01Float() throws Exception { 45 | String s = "[01.0]"; 46 | // strict 47 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); 48 | // PERMISIVE 49 | JSONValue.parseWithException(s); 50 | } 51 | 52 | @Test 53 | public void test00001() throws Exception { 54 | String s = "{\"t\":00001}"; 55 | JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); 56 | assertEquals(o.get("t"), 1); 57 | JSONValue.parseWithException(s); 58 | } 59 | 60 | @Test 61 | public void test00001Strict() throws Exception { 62 | String s = "{\"t\":00001}"; 63 | MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); 64 | JSONValue.parseWithException(s); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/test/writer/TestWriteFeatures.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.test.writer; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONStyle; 6 | import net.minidev.json.JSONValue; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestWriteFeatures { 10 | 11 | @Test 12 | public void testS1() throws Exception { 13 | Beans beans = new Beans(); 14 | String s = JSONValue.toJSONString(beans, JSONStyle.MAX_COMPRESS); 15 | assertEquals("{}", s); 16 | s = JSONValue.toJSONString(beans, JSONStyle.NO_COMPRESS); 17 | if (s.startsWith("{\"b")) { 18 | assertEquals("{\"b\":null,\"a\":null}", s); 19 | } else { 20 | assertEquals("{\"a\":null,\"b\":null}", s); 21 | } 22 | beans.a = "a"; 23 | s = JSONValue.toJSONString(beans, JSONStyle.MAX_COMPRESS); 24 | assertEquals("{a:a}", s); 25 | } 26 | 27 | public static class Beans { 28 | public String a; 29 | public String b; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestAdvancedMapper.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import net.minidev.asm.BeansAccessConfig; 8 | import net.minidev.json.JSONValue; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class TestAdvancedMapper { 12 | public static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); 13 | 14 | @Test 15 | public void testCustomBean() throws Exception { 16 | BeansAccessConfig.addTypeMapper(Object.class, MyLocalConverterot.class); 17 | String s = "{'val':2,'date':'19/04/2010'}"; 18 | TestBean r = JSONValue.parseWithException(s, TestBean.class); 19 | assertEquals("19/04/2010", sdf.format(r.date)); 20 | } 21 | 22 | public static class TestBean { 23 | public int val; 24 | public Date date; 25 | } 26 | 27 | public static class MyLocalConverterot { 28 | 29 | public static Date fromString(Object text) throws Exception { 30 | if (text == null) return null; 31 | synchronized (sdf) { 32 | return sdf.parse(text.toString()); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestCustomMappingInstant.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.io.IOException; 6 | import java.time.Instant; 7 | import net.minidev.json.JSONStyle; 8 | import net.minidev.json.JSONValue; 9 | import net.minidev.json.parser.ParseException; 10 | import net.minidev.json.writer.JsonReaderI; 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * Test JDK 8+ java.time.Instant 15 | * 16 | *

Serialize a custom class Sample 1 17 | * 18 | * @author uriel 19 | */ 20 | public class TestCustomMappingInstant { 21 | 22 | @Test 23 | public void test_dummy() throws IOException { 24 | @SuppressWarnings("unused") 25 | ParseException e = null; 26 | JSONValue.toJSONString(true, JSONStyle.MAX_COMPRESS); 27 | } 28 | 29 | public void test_instant() { 30 | JSONValue.registerWriter( 31 | java.time.Instant.class, 32 | new net.minidev.json.reader.JsonWriterI() { 33 | @Override 34 | public void writeJSONString( 35 | java.time.Instant value, Appendable out, JSONStyle compression) throws IOException { 36 | if (value == null) out.append("null"); 37 | else out.append(Long.toString(value.toEpochMilli())); 38 | } 39 | }); 40 | 41 | JSONValue.registerReader( 42 | RegularClass.class, 43 | new JsonReaderI(JSONValue.defaultReader) { 44 | @Override 45 | public void setValue(Object current, String key, Object value) 46 | throws ParseException, IOException { 47 | if (key.equals("instant")) { 48 | Instant inst = Instant.ofEpochMilli((((Number) value).longValue())); 49 | ((RegularClass) current).setInstant(inst); 50 | } 51 | } 52 | 53 | @Override 54 | public Object createObject() { 55 | return new RegularClass(); 56 | } 57 | }); 58 | Instant instant = Instant.now(); 59 | RegularClass regularClass = new RegularClass(); 60 | regularClass.setInstant(instant); 61 | String data = JSONValue.toJSONString(regularClass); 62 | RegularClass result = JSONValue.parse(data, RegularClass.class); 63 | assertEquals(result.getInstant(), instant); 64 | } 65 | 66 | public static class RegularClass { 67 | private java.time.Instant instant; 68 | 69 | public java.time.Instant getInstant() { 70 | return instant; 71 | } 72 | 73 | public void setInstant(java.time.Instant instant) { 74 | this.instant = instant; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestDate.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONValue; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class TestDate { 9 | @Test 10 | public void testBooleans() throws Exception { 11 | String s = "[true,true,false]"; 12 | boolean[] bs = new boolean[] {true, true, false}; 13 | String s2 = JSONValue.toJSONString(bs); 14 | assertEquals(s, s2); 15 | } 16 | 17 | @Test 18 | public void testInts() throws Exception { 19 | String s = "[1,2,3]"; 20 | int[] bs = new int[] {1, 2, 3}; 21 | String s2 = JSONValue.toJSONString(bs); 22 | assertEquals(s, s2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestFieldRename.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import net.minidev.json.JSONValue; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestFieldRename { 10 | 11 | public static class TRen { 12 | public String new_; 13 | public String default_; 14 | } 15 | 16 | @Test 17 | public void testRemap() throws Exception { 18 | String text = "{'new':'foo','default':'bar'}"; 19 | JSONValue.remapField(TRen.class, "default", "default_"); 20 | JSONValue.remapField(TRen.class, "new", "new_"); 21 | 22 | TRen t = JSONValue.parse(text, TRen.class); 23 | assertEquals(t.new_, "foo"); 24 | assertEquals(t.default_, "bar"); 25 | String dest = JSONValue.toJSONString(t); 26 | assertTrue(dest.contains("\"default\"")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestMapBeans.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.Map; 6 | import net.minidev.json.JSONValue; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestMapBeans { 10 | 11 | @Test 12 | public void testObjInts() throws Exception { 13 | String s = "{\"vint\":[1,2,3]}"; 14 | T1 r = JSONValue.parse(s, T1.class); 15 | assertEquals(3, r.vint[2]); 16 | } 17 | 18 | @Test 19 | public void testObjIntKey() throws Exception { 20 | String s = "{\"data\":{\"1\":\"toto\"}}"; 21 | T2 r = JSONValue.parse(s, T2.class); 22 | assertEquals("toto", r.data.get(1)); 23 | } 24 | 25 | @Test 26 | public void testObjEnumKey() throws Exception { 27 | String s = "{\"data\":{\"red\":10}}"; 28 | T3 r = JSONValue.parse(s, T3.class); 29 | assertEquals((Integer) 10, r.data.get(ColorEnum.red)); 30 | } 31 | 32 | @Test 33 | public void testObjBool1() throws Exception { 34 | String s = "{\"data\":true}"; 35 | T4 r = JSONValue.parse(s, T4.class); 36 | assertEquals(true, r.data); 37 | } 38 | 39 | @Test 40 | public void testObjBool2() throws Exception { 41 | String s = "{\"data\":true}"; 42 | T5 r = JSONValue.parse(s, T5.class); 43 | assertEquals(true, r.data); 44 | } 45 | 46 | /** class containing primitive array; */ 47 | public static class T1 { 48 | private int[] vint; 49 | 50 | public int[] getVint() { 51 | return vint; 52 | } 53 | 54 | public void setVint(int[] vint) { 55 | this.vint = vint; 56 | } 57 | } 58 | 59 | /** class containing Map interface; */ 60 | public static class T2 { 61 | private Map data; 62 | 63 | public Map getData() { 64 | return data; 65 | } 66 | 67 | public void setData(Map data) { 68 | this.data = data; 69 | } 70 | } 71 | 72 | public static enum ColorEnum { 73 | bleu, 74 | green, 75 | red, 76 | yellow 77 | } 78 | 79 | public static class T3 { 80 | private Map data; 81 | 82 | public Map getData() { 83 | return data; 84 | } 85 | 86 | public void setData(Map data) { 87 | this.data = data; 88 | } 89 | } 90 | 91 | public static class T4 { 92 | private boolean data; 93 | 94 | public boolean getData() { 95 | return data; 96 | } 97 | 98 | public void setData(boolean data) { 99 | this.data = data; 100 | } 101 | } 102 | 103 | public static class T5 { 104 | private boolean data; 105 | 106 | public boolean isData() { 107 | return data; 108 | } 109 | 110 | public void setData(boolean data) { 111 | this.data = data; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestMapPrimArrays.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONValue; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class TestMapPrimArrays { 9 | @Test 10 | public void testInts() throws Exception { 11 | String s = "[1,2,3]"; 12 | int[] r = JSONValue.parse(s, int[].class); 13 | assertEquals(3, r[2]); 14 | } 15 | 16 | @Test 17 | public void testIntss() throws Exception { 18 | String s = "[[1],[2],[3,4]]"; 19 | int[][] r = JSONValue.parse(s, int[][].class); 20 | assertEquals(3, r[2][0]); 21 | assertEquals(4, r[2][1]); 22 | } 23 | 24 | @Test 25 | public void testLongs() throws Exception { 26 | String s = "[1,2,3]"; 27 | long[] r = JSONValue.parse(s, long[].class); 28 | assertEquals(3, r[2]); 29 | } 30 | 31 | @Test 32 | public void testFloat() throws Exception { 33 | String s = "[1.2,22.4,3.14]"; 34 | float[] r = JSONValue.parse(s, float[].class); 35 | assertEquals(3.14F, r[2]); 36 | } 37 | 38 | @Test 39 | public void testDouble() throws Exception { 40 | String s = "[1.2,22.4,3.14]"; 41 | double[] r = JSONValue.parse(s, double[].class); 42 | assertEquals(3.14, r[2]); 43 | } 44 | 45 | @Test 46 | public void testBooleans() throws Exception { 47 | String s = "[true,true,false]"; 48 | boolean[] r = JSONValue.parse(s, boolean[].class); 49 | assertEquals(true, r[1]); 50 | assertEquals(false, r[2]); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestMapPublic.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.Map; 6 | import java.util.TreeMap; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestMapPublic { 11 | @Test 12 | public void testObjInts() throws Exception { 13 | String s = "{\"vint\":[1,2,3]}"; 14 | T1 r = JSONValue.parse(s, T1.class); 15 | assertEquals(3, r.vint[2]); 16 | } 17 | 18 | String MultiTyepJson = 19 | "{\"name\":\"B\",\"age\":120,\"cost\":12000,\"flag\":3,\"valid\":true,\"f\":1.2,\"d\":1.5,\"l\":12345678912345}"; 20 | 21 | @Test 22 | public void testObjMixte() throws Exception { 23 | T2 r = JSONValue.parse(MultiTyepJson, T2.class); 24 | assertEquals("B", r.name); 25 | assertEquals(120, r.age); 26 | assertEquals(12000, r.cost); 27 | assertEquals(3, r.flag); 28 | assertEquals(true, r.valid); 29 | assertEquals(1.2F, r.f); 30 | assertEquals(1.5, r.d); 31 | assertEquals(12345678912345L, r.l); 32 | } 33 | 34 | @Test 35 | public void testObjMixtePrim() throws Exception { 36 | T3 r = JSONValue.parse(MultiTyepJson, T3.class); 37 | assertEquals("B", r.name); 38 | assertEquals(Short.valueOf((short) 120), r.age); 39 | assertEquals(Integer.valueOf(12000), r.cost); 40 | assertEquals(Byte.valueOf((byte) 3), r.flag); 41 | assertEquals(Boolean.TRUE, r.valid); 42 | assertEquals(1.2F, r.f); 43 | assertEquals(1.5, r.d); 44 | assertEquals(Long.valueOf(12345678912345L), r.l); 45 | } 46 | 47 | public static class T1 { 48 | public int[] vint; 49 | } 50 | 51 | public static class T2 { 52 | public String name; 53 | public short age; 54 | public int cost; 55 | public byte flag; 56 | public boolean valid; 57 | public float f; 58 | public double d; 59 | public long l; 60 | } 61 | 62 | public static class T3 { 63 | public String name; 64 | public Short age; 65 | public Integer cost; 66 | public Byte flag; 67 | public Boolean valid; 68 | public Float f; 69 | public Double d; 70 | public Long l; 71 | } 72 | 73 | public static class T123 { 74 | public T1 t1; 75 | public T2 t2; 76 | public T3 t3; 77 | } 78 | 79 | public static class T5 { 80 | public Map data; 81 | } 82 | 83 | public static class T6 { 84 | public TreeMap data; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestMapPublic2.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.Map; 6 | import java.util.TreeMap; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestMapPublic2 { 11 | String s = "{\"data\":{\"a\":\"b\"}}"; 12 | 13 | @Test 14 | public void testMapPublicInterface() throws Exception { 15 | T5 r = JSONValue.parse(s, T5.class); 16 | assertEquals(1, r.data.size()); 17 | } 18 | 19 | @Test 20 | public void testMapPublicMapClass() throws Exception { 21 | T6 r = JSONValue.parse(s, T6.class); 22 | assertEquals(1, r.data.size()); 23 | } 24 | 25 | String MultiTyepJson = 26 | "{\"name\":\"B\",\"age\":120,\"cost\":12000,\"flag\":3,\"valid\":true,\"f\":1.2,\"d\":1.5,\"l\":12345678912345}"; 27 | 28 | public static class T5 { 29 | public Map data; 30 | } 31 | 32 | public static class T6 { 33 | public TreeMap data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestSerPrimArrays.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import net.minidev.json.JSONValue; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestSerPrimArrays { 11 | SimpleDateFormat sdf; 12 | 13 | String testDateString; 14 | Date testDate; 15 | 16 | public TestSerPrimArrays() { 17 | try { 18 | sdf = new SimpleDateFormat("dd/MM/yyyy"); 19 | testDateString = "12/01/2010"; 20 | testDate = sdf.parse(testDateString); 21 | } catch (Exception e) { 22 | } 23 | } 24 | 25 | @Test 26 | public void testDate() throws Exception { 27 | String s = "'" + testDateString + "'"; 28 | Date dt = JSONValue.parse(s, Date.class); 29 | assertEquals(dt, this.testDate); 30 | } 31 | 32 | @Test 33 | public void testDtObj() throws Exception { 34 | String s = "{date:'" + testDateString + "'}"; 35 | ADate dt = JSONValue.parse(s, ADate.class); 36 | assertEquals(dt.date, this.testDate); 37 | } 38 | 39 | public static class ADate { 40 | public Date date; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestUUID.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.io.IOException; 6 | import java.util.UUID; 7 | import net.minidev.json.JSONObject; 8 | import net.minidev.json.JSONStyle; 9 | import net.minidev.json.JSONValue; 10 | import net.minidev.json.parser.ParseException; 11 | import net.minidev.json.reader.JsonWriterI; 12 | import net.minidev.json.writer.JsonReaderI; 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class TestUUID { 16 | @Test 17 | void testUUID() throws ParseException { 18 | JSONObject obj = new JSONObject(); 19 | UUID uuid = new UUID(123, 456); 20 | JSONValue.registerWriter( 21 | UUID.class, 22 | new JsonWriterI() { 23 | @Override 24 | public void writeJSONString(UUID value, Appendable out, JSONStyle compression) 25 | throws IOException { 26 | out.append(value.toString()); 27 | } 28 | }); 29 | 30 | JSONValue.registerReader( 31 | UUIDHolder.class, 32 | new JsonReaderI(JSONValue.defaultReader) { 33 | @Override 34 | public void setValue(Object current, String key, Object value) 35 | throws ParseException, IOException { 36 | if ("v".equals(key)) { 37 | ((UUIDHolder) current).setV(UUID.fromString((String) value)); 38 | return; 39 | } 40 | super.setValue(current, key, value); 41 | } 42 | 43 | @Override 44 | public Object createObject() { 45 | return new UUIDHolder(); 46 | } 47 | }); 48 | 49 | obj.put("v", uuid); 50 | String asText = obj.toJSONString(); 51 | assertEquals("{\"v\":00000000-0000-007b-0000-0000000001c8}", asText); 52 | UUIDHolder rebuild = JSONValue.parseWithException(asText, UUIDHolder.class); 53 | assertEquals(uuid, rebuild.getV()); 54 | } 55 | 56 | public static class UUIDHolder { 57 | private UUID v; 58 | 59 | public UUID getV() { 60 | return v; 61 | } 62 | 63 | public void setV(UUID uuid) { 64 | this.v = uuid; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /json-smart/src/test/java/net/minidev/json/testMapping/TestUpdater.java: -------------------------------------------------------------------------------- 1 | package net.minidev.json.testMapping; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minidev.json.JSONValue; 6 | import net.minidev.json.testMapping.TestMapPublic.T1; 7 | import net.minidev.json.testMapping.TestMapPublic.T123; 8 | import net.minidev.json.testMapping.TestMapPublic.T2; 9 | import net.minidev.json.testMapping.TestMapPublic.T3; 10 | import org.junit.jupiter.api.Test; 11 | 12 | public class TestUpdater { 13 | 14 | @Test 15 | public void testUpdate1() throws Exception { 16 | T3 t3 = new T3(); 17 | t3.age = 20; 18 | t3.f = 1.4f; 19 | t3.l = 120000L; 20 | 21 | String s = "{\"name\":\"text\"}"; 22 | T3 t3_1 = JSONValue.parse(s, t3); 23 | assertEquals(t3, t3_1); 24 | assertEquals("text", t3.name); 25 | assertEquals((Long) 120000L, t3.l); 26 | } 27 | 28 | @Test 29 | public void testUpdateExistingBeans() throws Exception { 30 | T123 t123 = new T123(); 31 | T1 t1 = new T1(); 32 | T2 t2 = new T2(); 33 | T3 t3 = new T3(); 34 | t123.t1 = t1; 35 | t123.t2 = t2; 36 | t123.t3 = t3; 37 | 38 | String s = "{\"t2\":{\"name\":\"valueT2\"},\"t3\":{\"name\":\"valueT3\"},}"; 39 | T123 res = JSONValue.parse(s, t123); 40 | assertEquals(res, t123); 41 | assertEquals(res.t2, t2); 42 | assertEquals(res.t2.name, "valueT2"); 43 | assertEquals(res.t3.name, "valueT3"); 44 | } 45 | 46 | @Test 47 | public void testUpdateNullBean() throws Exception { 48 | T123 t123 = new T123(); 49 | T1 t1 = new T1(); 50 | T2 t2 = null; 51 | T3 t3 = null; 52 | t123.t1 = t1; 53 | t123.t2 = t2; 54 | t123.t3 = t3; 55 | 56 | String s = "{\"t2\":{\"name\":\"valueT2\"},\"t3\":{\"name\":\"valueT3\"},}"; 57 | T123 res = JSONValue.parse(s, t123); 58 | assertEquals(res, t123); 59 | assertEquals(res.t2.name, "valueT2"); 60 | assertEquals(res.t3.name, "valueT3"); 61 | } 62 | } 63 | --------------------------------------------------------------------------------