static StructrTypeDefinition deserialize(final StructrSchemaDefinition root, final String name, final Map<String, Object> source) {

		final Map<String, StructrPropertyDefinition> deserializedProperties = new TreeMap<>();
		final Map<String, StructrMethodDefinition> deserializedMethods      = new TreeMap<>();
		final StructrTypeDefinition typeDefinition                          = StructrTypeDefinition.determineType(root, name, source);
		final Map<String, Object> properties                                = (Map)source.get(JsonSchema.KEY_PROPERTIES);
		final List<String> requiredPropertyNames                            = (List)source.get(JsonSchema.KEY_REQUIRED);
		final Map<String, Object> views                                     = (Map)source.get(JsonSchema.KEY_VIEWS);
		final Map<String, String> viewOrder                                 = (Map)source.get(JsonSchema.KEY_VIEW_ORDER);
		final Map<String, Object> methods                                   = (Map)source.get(JsonSchema.KEY_METHODS);

		if (properties != null) {

			for (final Entry<String, Object> entry : properties.entrySet()) {

				final String propertyName = entry.getKey();
				final Object value        = entry.getValue();

				if (value instanceof Map) {

					final StructrPropertyDefinition property = StructrPropertyDefinition.deserialize(typeDefinition, propertyName, (Map)value);
					if (property != null) {

						deserializedProperties.put(property.getName(), property);
						typeDefinition.getProperties().add(property);
					}

				} else {

					throw new IllegalStateException("Invalid JSON property definition for property " + propertyName + ", expected object.");
				}
			}
		}

		if (requiredPropertyNames != null) {

			for (final String requiredPropertyName : requiredPropertyNames) {

				// set required properties
				final StructrPropertyDefinition property = deserializedProperties.get(requiredPropertyName);
				if (property != null) {

					property.setRequired(true);

				} else {

					throw new IllegalStateException("Required property " + requiredPropertyName + " not defined for type " + typeDefinition.getName() + ".");
				}
			}
		}

		if (views != null) {

			for (final Entry<String, Object> entry : views.entrySet()) {

				final String viewName = entry.getKey();
				final Object value    = entry.getValue();

				if (value instanceof List) {

					final Set<String> viewProperties = new TreeSet<>((List)value);
					typeDefinition.getViews().put(viewName, viewProperties);

				} else {

					throw new IllegalStateException("View definition " + viewName + " must be of type array.");
				}
			}
		}

		if (viewOrder != null) {

			typeDefinition.getViewOrder().putAll(viewOrder);
		}

		if (methods != null) {

			for (final Entry<String, Object> entry : methods.entrySet()) {

				final String methodName = entry.getKey();
				final Object value      = entry.getValue();

				if (value instanceof Map) {

					final StructrMethodDefinition method = StructrMethodDefinition.deserialize(typeDefinition, methodName, (Map)value);
					if (method != null) {

						deserializedMethods.put(method.getName(), method);
						typeDefinition.getMethods().add(method);
					}

				} else if (value instanceof Collection) {

					// more than on method with the same name exists..
					final Collection<Map<String, Object>> methodList = (Collection)value;

					for (final Map<String, Object> map : methodList) {

						final StructrMethodDefinition method = StructrMethodDefinition.deserialize(typeDefinition, methodName, map);
						if (method != null) {

							deserializedMethods.put(method.getName(), method);
							typeDefinition.getMethods().add(method);
						}
					}

				} else {

					throw new IllegalStateException("Method definition " + methodName + " must be of type string or map.");
				}
			}
		}

		final Object isAbstractValue = source.get(JsonSchema.KEY_IS_ABSTRACT);
		if (isAbstractValue != null && Boolean.TRUE.equals(isAbstractValue)) {

			typeDefinition.setIsAbstract();
		}

		final Object isInterfaceValue = source.get(JsonSchema.KEY_IS_INTERFACE);
		if (isInterfaceValue != null && Boolean.TRUE.equals(isInterfaceValue)) {

			typeDefinition.setIsInterface();
		}

		final Object isBuiltinType = source.get(JsonSchema.KEY_IS_BUILTIN_TYPE);
		if (isBuiltinType != null && Boolean.TRUE.equals(isBuiltinType)) {

			typeDefinition.setIsBuiltinType();
		}

		final Object categoryValue = source.get(JsonSchema.KEY_CATEGORY);
		if (categoryValue != null) {

			typeDefinition.setCategory(categoryValue.toString());
		}

		return typeDefinition;
	}
static StructrTypeDefinition deserialize ( final StructrSchemaDefinition root , final String name , final Map < String , Object > source ) { final Map < String , StructrPropertyDefinition > deserializedProperties = new TreeMap < > ( ) ; final Map < String , StructrMethodDefinition > deserializedMethods = new TreeMap < > ( ) ; final StructrTypeDefinition typeDefinition = StructrTypeDefinition . determineType ( root , name , source ) ; final Map < String , Object > properties = ( Map ) source . get ( JsonSchema . KEY_PROPERTIES ) ; final List < String > requiredPropertyNames = ( List ) source . get ( JsonSchema . KEY_REQUIRED ) ; final Map < String , Object > views = ( Map ) source . get ( JsonSchema . KEY_VIEWS ) ; final Map < String , String > viewOrder = ( Map ) source . get ( JsonSchema . KEY_VIEW_ORDER ) ; final Map < String , Object > methods = ( Map ) source . get ( JsonSchema . KEY_METHODS ) ; if ( properties != null ) { for ( final Entry < String , Object > entry : properties . entrySet ( ) ) { final String propertyName = entry . getKey ( ) ; final Object value = entry . getValue ( ) ; if ( value instanceof Map ) { final StructrPropertyDefinition property = StructrPropertyDefinition . deserialize ( typeDefinition , propertyName , ( Map ) value ) ; if ( property != null ) { deserializedProperties . put ( property . getName ( ) , property ) ; typeDefinition . getProperties ( ) . add ( property ) ; } } else { throw new IllegalStateException ( "Invalid JSON property definition for property " + propertyName + ", expected object." ) ; } } } if ( requiredPropertyNames != null ) { for ( final String requiredPropertyName : requiredPropertyNames ) { final StructrPropertyDefinition property = deserializedProperties . get ( requiredPropertyName ) ; if ( property != null ) { property . setRequired ( true ) ; } else { throw new IllegalStateException ( "Required property " + requiredPropertyName + " not defined for type " + typeDefinition . getName ( ) + "." ) ; } } } if ( views != null ) { for ( final Entry < String , Object > entry : views . entrySet ( ) ) { final String viewName = entry . getKey ( ) ; final Object value = entry . getValue ( ) ; if ( value instanceof List ) { final Set < String > viewProperties = new TreeSet < > ( ( List ) value ) ; typeDefinition . getViews ( ) . put ( viewName , viewProperties ) ; } else { throw new IllegalStateException ( "View definition " + viewName + " must be of type array." ) ; } } } if ( viewOrder != null ) { typeDefinition . getViewOrder ( ) . putAll ( viewOrder ) ; } if ( methods != null ) { for ( final Entry < String , Object > entry : methods . entrySet ( ) ) { final String methodName = entry . getKey ( ) ; final Object value = entry . getValue ( ) ; if ( value instanceof Map ) { final StructrMethodDefinition method = StructrMethodDefinition . deserialize ( typeDefinition , methodName , ( Map ) value ) ; if ( method != null ) { deserializedMethods . put ( method . getName ( ) , method ) ; typeDefinition . getMethods ( ) . add ( method ) ; } } else if ( value instanceof Collection ) { final Collection < Map < String , Object > > methodList = ( Collection ) value ; for ( final Map < String , Object > map : methodList ) { final StructrMethodDefinition method = StructrMethodDefinition . deserialize ( typeDefinition , methodName , map ) ; if ( method != null ) { deserializedMethods . put ( method . getName ( ) , method ) ; typeDefinition . getMethods ( ) . add ( method ) ; } } } else { throw new IllegalStateException ( "Method definition " + methodName + " must be of type string or map." ) ; } } } final Object isAbstractValue = source . get ( JsonSchema . KEY_IS_ABSTRACT ) ; if ( isAbstractValue != null && Boolean . TRUE . equals ( isAbstractValue ) ) { typeDefinition . setIsAbstract ( ) ; } final Object isInterfaceValue = source . get ( JsonSchema . KEY_IS_INTERFACE ) ; if ( isInterfaceValue != null && Boolean . TRUE . equals ( isInterfaceValue ) ) { typeDefinition . setIsInterface ( ) ; } final Object isBuiltinType = source . get ( JsonSchema . KEY_IS_BUILTIN_TYPE ) ; if ( isBuiltinType != null && Boolean . TRUE . equals ( isBuiltinType ) ) { typeDefinition . setIsBuiltinType ( ) ; } final Object categoryValue = source . get ( JsonSchema . KEY_CATEGORY ) ; if ( categoryValue != null ) { typeDefinition . setCategory ( categoryValue . toString ( ) ) ; } return typeDefinition ; }
----- static methods -----