public void marshalObject()

in grails-converters/src/main/groovy/org/grails/web/converters/marshaller/json/DomainClassMarshaller.java [118:248]


    public void marshalObject(Object value, JSON json) throws ConverterException {
        JSONWriter writer = json.getWriter();
        value = proxyHandler.unwrapIfProxy(value);
        Class<?> clazz = value.getClass();

        List<String> excludes = json.getExcludes(clazz);
        List<String> includes = json.getIncludes(clazz);
        IncludeExcludeSupport<String> includeExcludeSupport = new IncludeExcludeSupport<String>();


        BeanWrapper beanWrapper = new BeanWrapperImpl(value);

        writer.object();

        if(includeClass && shouldInclude(includeExcludeSupport, includes, excludes, value, "class")) {
            writer.key("class").value(clazz.getName());
        }

        PersistentEntity domainClass = findDomainClass(value);

        if ( domainClass == null ) {
            throw new GrailsConfigurationException("Could not retrieve the respective entity for domain " + value.getClass().getName() + " in the mapping context API");
        }

        PersistentProperty id = domainClass.getIdentity();
        if(id != null) {
            //Composite keys dont return an identity. They also do not render in the JSON. 
            //If using Composite keys, it may be advisable to use a customer Marshaller.
            if(shouldInclude(includeExcludeSupport, includes, excludes, value, id.getName())) {
                Object idValue = extractValue(value, id);
                if(idValue != null) {
                    json.property(id.getName(), idValue);
                }
            }    
        }
        

        if (shouldInclude(includeExcludeSupport, includes, excludes, value, GormProperties.VERSION) && isIncludeVersion()) {
            PersistentProperty versionProperty = domainClass.getVersion();
            Object version = extractValue(value, versionProperty);
            if(version != null) {
                json.property(GormProperties.VERSION, version);
            }
        }

        List<PersistentProperty> properties = domainClass.getPersistentProperties();

        for (PersistentProperty property : properties) {
            if (property.equals(domainClass.getVersion())) {
                continue;
            }

            if(!shouldInclude(includeExcludeSupport, includes, excludes, value, property.getName())) continue;

            writer.key(property.getName());
            if ( !(property instanceof Association) ) {
                // Write non-relation property
                Object val = beanWrapper.getPropertyValue(property.getName());
                json.convertAnother(val);
            }
            else {
                Object referenceObject = beanWrapper.getPropertyValue(property.getName());
                if (isRenderDomainClassRelations()) {
                    if (referenceObject == null) {
                        writer.valueNull();
                    }
                    else {
                        referenceObject = proxyHandler.unwrapIfProxy(referenceObject);
                        if (referenceObject instanceof SortedMap) {
                            referenceObject = new TreeMap((SortedMap) referenceObject);
                        }
                        else if (referenceObject instanceof SortedSet) {
                            referenceObject = new TreeSet((SortedSet) referenceObject);
                        }
                        else if (referenceObject instanceof Set) {
                            referenceObject = new LinkedHashSet((Set) referenceObject);
                        }
                        else if (referenceObject instanceof Map) {
                            referenceObject = new LinkedHashMap((Map) referenceObject);
                        }
                        else if (referenceObject instanceof Collection) {
                            referenceObject = new ArrayList((Collection) referenceObject);
                        }
                        json.convertAnother(referenceObject);
                    }
                }
                else {
                    if (referenceObject == null) {
                        json.value(null);
                    }
                    else {

                        PersistentEntity referencedDomainClass = ((Association) property).getAssociatedEntity();

                        // Embedded are now always fully rendered
                        if (referencedDomainClass == null || ((Association)property).isEmbedded() || property.getType().isEnum()) {
                            json.convertAnother(referenceObject);
                        }
                        else if ( (property instanceof OneToOne) || (property instanceof ManyToOne)|| ((Association)property).isEmbedded()) {
                            asShortObject(referenceObject, json, referencedDomainClass.getIdentity(), referencedDomainClass);
                        }
                        else {
                            PersistentProperty referencedIdProperty = referencedDomainClass.getIdentity();
                            @SuppressWarnings("unused")
                            String refPropertyName = ((Association) property).getReferencedPropertyName();
                            if (referenceObject instanceof Collection) {
                                Collection o = (Collection) referenceObject;
                                writer.array();
                                for (Object el : o) {
                                    asShortObject(el, json, referencedIdProperty, referencedDomainClass);
                                }
                                writer.endArray();
                            }
                            else if (referenceObject instanceof Map) {
                                Map<Object, Object> map = (Map<Object, Object>) referenceObject;
                                for (Map.Entry<Object, Object> entry : map.entrySet()) {
                                    String key = String.valueOf(entry.getKey());
                                    Object o = entry.getValue();
                                    writer.object();
                                    writer.key(key);
                                    asShortObject(o, json, referencedIdProperty, referencedDomainClass);
                                    writer.endObject();
                                }
                            }
                        }
                    }
                }
            }
        }
        writer.endObject();
    }