jodd-json/src/main/java/jodd/json/JsonParser.java
protected Object parseObjectContent(Class targetType, Class valueKeyType, Class valueType) {
		// detect special case

		if (targetType == Object.class) {
			targetType = Map.class;
		}

		// continue

		targetType = replaceWithMappedTypeForPath(targetType);

		Object target;
		boolean isTargetTypeMap = true;
		boolean isTargetRealTypeMap = true;
		ClassDescriptor targetTypeClassDescriptor = null;
		TypeData typeData = null;

		if (targetType != null) {
			targetTypeClassDescriptor = ClassIntrospector.get().lookup(targetType);

			// find if the target is really a map
			// because when classMetadataName != null we are forcing
			// map usage locally in this method

			isTargetRealTypeMap = targetTypeClassDescriptor.isMap();

			typeData = jsonAnnotationManager.lookupTypeData(targetType);
		}

		if (isTargetRealTypeMap) {
			// resolve keys only for real maps
			path.push(KEYS);
			valueKeyType = replaceWithMappedTypeForPath(valueKeyType);
			path.pop();
		}

		if (classMetadataName == null) {
			// create instance of target type, no 'class' information
			target = newObjectInstance(targetType);

			isTargetTypeMap = isTargetRealTypeMap;
		} else {
			// all beans will be created first as a map
			target = mapSupplier.get();
		}

		boolean koma = false;

		mainloop:
		while (true) {
			skipWhiteSpaces();

			char c = input[ndx];

			if (c == '}') {
				if (koma) {
					syntaxError("Trailing comma");
				}

				ndx++;
				break;
			}

			koma = false;

			String key = parseString();
			String keyOriginal = key;

			skipWhiteSpaces();

			consume(':');

			skipWhiteSpaces();

			// read the type of the simple property

			PropertyDescriptor pd = null;
			Class propertyType = null;
			Class keyType = null;
			Class componentType = null;

			// resolve simple property

			if (!isTargetRealTypeMap) {
				// replace key with real property value
				key = jsonAnnotationManager.resolveRealName(targetType, key);
			}

			if (!isTargetTypeMap) {
				pd = targetTypeClassDescriptor.getPropertyDescriptor(key, true);

				if (pd != null) {
					propertyType = pd.getType();
					keyType = pd.resolveKeyType(true);
					componentType = pd.resolveComponentType(true);
				}
			}

			Object value;

			if (!isTargetTypeMap) {
				// *** inject into bean
					path.push(key);

					value = parseValue(propertyType, keyType, componentType);

					path.pop();

				if (typeData.rules.match(keyOriginal, !typeData.strict)) {

					if (pd != null) {
						if (lazy) {
							// need to resolve lazy value before injecting objects into it
							value = resolveLazyValue(value);
						}

						// only inject values if target property exist
						injectValueIntoObject(target, pd, value);
					}
				}
			}
			else {
				Object keyValue = key;

				if (valueKeyType != null) {
					keyValue = convertType(key, valueKeyType);
				}

				// *** add to map
				if (isTargetRealTypeMap) {
					path.push(VALUES, key);

					valueType = replaceWithMappedTypeForPath(valueType);
				} else {
					path.push(key);
				}


				value = parseValue(valueType, null, null);

				path.pop();

				((Map) target).put(keyValue, value);
			}

			skipWhiteSpaces();

			c = input[ndx];

			switch (c) {
				case '}': ndx++; break mainloop;
				case ',': ndx++; koma = true; break;
				default: syntaxError("Invalid char: expected } or ,");
			}
		}

		// done

		// convert Map to target type
		if (classMetadataName != null) {
			target = mapToBean.map2bean((Map) target, targetType);
		}

		return target;
	}
protected Object parseObjectContent(Class targetType, Class valueKeyType, Class valueType) {
		// detect special case

		if (targetType == Object.class) {
			targetType = Map.class;
		}

		// continue

		targetType = replaceWithMappedTypeForPath(targetType);

		Object target;
		boolean isTargetTypeMap = true;
		boolean isTargetRealTypeMap = true;
		ClassDescriptor targetTypeClassDescriptor = null;
		TypeData typeData = null;

		if (targetType != null) {
			targetTypeClassDescriptor = ClassIntrospector.get().lookup(targetType);

			// find if the target is really a map
			// because when classMetadataName != null we are forcing
			// map usage locally in this method

			isTargetRealTypeMap = targetTypeClassDescriptor.isMap();

			typeData = jsonAnnotationManager.lookupTypeData(targetType);
		}

		if (isTargetRealTypeMap) {
			// resolve keys only for real maps
			path.push(KEYS);
			valueKeyType = replaceWithMappedTypeForPath(valueKeyType);
			path.pop();
		}

		if (classMetadataName == null) {
			// create instance of target type, no 'class' information
			target = newObjectInstance(targetType);

			isTargetTypeMap = isTargetRealTypeMap;
		} else {
			// all beans will be created first as a map
			target = mapSupplier.get();
		}

		boolean koma = false;

		mainloop:
		while (true) {
			skipWhiteSpaces();

			char c = input[ndx];

			if (c == '}') {
				if (koma) {
					syntaxError("Trailing comma");
				}

				ndx++;
				break;
			}

			koma = false;

			String key = parseString();
			String keyOriginal = key;

			skipWhiteSpaces();

			consume(':');

			skipWhiteSpaces();

			// read the type of the simple property

			PropertyDescriptor pd = null;
			Class propertyType = null;
			Class keyType = null;
			Class componentType = null;

			// resolve simple property

			if (!isTargetRealTypeMap) {
				// replace key with real property value
				key = jsonAnnotationManager.resolveRealName(targetType, key);
			}

			if (!isTargetTypeMap) {
				pd = targetTypeClassDescriptor.getPropertyDescriptor(key, true);

				if (pd != null) {
					propertyType = pd.getType();
					keyType = pd.resolveKeyType(true);
					componentType = pd.resolveComponentType(true);
				}
			}

			Object value;

			if (!isTargetTypeMap) {
				// *** inject into bean
					path.push(key);

					value = parseValue(propertyType, keyType, componentType);

					path.pop();

				if (typeData.rules.match(keyOriginal, !typeData.strict)) {

					if (pd != null) {
						if (lazy) {
							// need to resolve lazy value before injecting objects into it
							value = resolveLazyValue(value);
						}

						// only inject values if target property exist
						injectValueIntoObject(target, pd, value);
					}
				}
			}
			else {
				Object keyValue = key;

				if (valueKeyType != null) {
					keyValue = convertType(key, valueKeyType);
				}

				// *** add to map
				if (isTargetRealTypeMap) {
					path.push(VALUES, key);

					valueType = replaceWithMappedTypeForPath(valueType);
				} else {
					path.push(key);
				}


				value = parseValue(valueType, null, null);

				path.pop();

				((Map) target).put(keyValue, value);
			}

			skipWhiteSpaces();

			c = input[ndx];

			switch (c) {
				case '}': ndx++; break mainloop;
				case ',': ndx++; koma = true; break;
				default: syntaxError("Invalid char: expected } or ,");
			}
		}

		// done

		// convert Map to target type
		if (classMetadataName != null) {
			target = mapToBean.map2bean((Map) target, targetType);
		}

		return target;
	}
protected Object parseObjectContent ( Class targetType , Class valueKeyType , Class valueType ) { // detect special case if ( targetType == Object . class ) { targetType = Map . class ; } // continue targetType = replaceWithMappedTypeForPath ( targetType ) ; Object target ; boolean isTargetTypeMap = true ; boolean isTargetRealTypeMap = true ; ClassDescriptor targetTypeClassDescriptor = null ; TypeData typeData = null ; if ( targetType != null ) { targetTypeClassDescriptor = ClassIntrospector . get ( ) . lookup ( targetType ) ; // find if the target is really a map // because when classMetadataName != null we are forcing // map usage locally in this method isTargetRealTypeMap = targetTypeClassDescriptor . isMap ( ) ; typeData = jsonAnnotationManager . lookupTypeData ( targetType ) ; } if ( isTargetRealTypeMap ) { // resolve keys only for real maps path . push ( KEYS ) ; valueKeyType = replaceWithMappedTypeForPath ( valueKeyType ) ; path . pop ( ) ; } if ( classMetadataName == null ) { // create instance of target type, no 'class' information target = newObjectInstance ( targetType ) ; isTargetTypeMap = isTargetRealTypeMap ; } else { // all beans will be created first as a map target = mapSupplier . get ( ) ; } boolean koma = false ; mainloop : while ( true ) { skipWhiteSpaces ( ) ; char c = input [ ndx ] ; if ( c == ' ' ) { if ( koma ) { syntaxError ( "Trailing comma" ) ; } ndx ++ ; break ; } koma = false ; String key = parseString ( ) ; String keyOriginal = key ; skipWhiteSpaces ( ) ; consume ( ' ' ) ; skipWhiteSpaces ( ) ; // read the type of the simple property PropertyDescriptor pd = null ; Class propertyType = null ; Class keyType = null ; Class componentType = null ; // resolve simple property if ( ! isTargetRealTypeMap ) { // replace key with real property value key = jsonAnnotationManager . resolveRealName ( targetType , key ) ; } if ( ! isTargetTypeMap ) { pd = targetTypeClassDescriptor . getPropertyDescriptor ( key , true ) ; if ( pd != null ) { propertyType = pd . getType ( ) ; keyType = pd . resolveKeyType ( true ) ; componentType = pd . resolveComponentType ( true ) ; } } Object value ; if ( ! isTargetTypeMap ) { // *** inject into bean path . push ( key ) ; value = parseValue ( propertyType , keyType , componentType ) ; path . pop ( ) ; if ( typeData . rules . match ( keyOriginal , ! typeData . strict ) ) { if ( pd != null ) { if ( lazy ) { // need to resolve lazy value before injecting objects into it value = resolveLazyValue ( value ) ; } // only inject values if target property exist injectValueIntoObject ( target , pd , value ) ; } } } else { Object keyValue = key ; if ( valueKeyType != null ) { keyValue = convertType ( key , valueKeyType ) ; } // *** add to map if ( isTargetRealTypeMap ) { path . push ( VALUES , key ) ; valueType = replaceWithMappedTypeForPath ( valueType ) ; } else { path . push ( key ) ; } value = parseValue ( valueType , null , null ) ; path . pop ( ) ; ( ( Map ) target ) . put ( keyValue , value ) ; } skipWhiteSpaces ( ) ; c = input [ ndx ] ; switch ( c ) { case ' ' : ndx ++ ; break mainloop ; case ' ' : ndx ++ ; koma = true ; break ; default : syntaxError ( "Invalid char: expected } or ," ) ; } } // done // convert Map to target type if ( classMetadataName != null ) { target = mapToBean . map2bean ( ( Map ) target , targetType ) ; } return target ; }
Parses object, once when open bracket has been consumed.
Parses object once when open bracket has been consumed .