org.eclipse.php.composer.api.entities.JsonEntity.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.php.composer.api.entities.JsonEntity.java

Source

/*******************************************************************************
 * Copyright (c) 2012, 2016, 2017 PDT Extension Group and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     PDT Extension Group - initial API and implementation
 *     Kaloyan Raev - [501269] externalize strings
 *******************************************************************************/
package org.eclipse.php.composer.api.entities;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.php.composer.api.annotation.Name;
import org.eclipse.php.composer.api.json.JsonFormatter;
import org.eclipse.php.composer.api.json.JsonParser;
import org.eclipse.php.composer.api.json.ParseException;

public abstract class JsonEntity extends Entity {

    private transient Set<String> listening = new HashSet<String>();
    @SuppressWarnings("rawtypes")
    private transient Map<Class, Map<String, Field>> fieldNameCache = new HashMap<Class, Map<String, Field>>();

    private transient Log log = LogFactory.getLog(JsonEntity.class);

    protected transient LinkedList<String> sortOrder = new LinkedList<String>();

    public JsonEntity() {
        listen();
        initialize();
    }

    // can be filled by subclasses
    protected void initialize() {
    }

    protected void listen() {
        try {
            for (Field field : getFields(this.getClass())) {
                if (JsonCollection.class.isAssignableFrom(field.getType())) {
                    final String prop = getFieldName(field);
                    final JsonEntity sender = this;

                    if (listening.contains(prop)) {
                        continue;
                    }

                    field.setAccessible(true);
                    JsonEntity obj = (JsonEntity) field.get(this);

                    if (obj != null) {
                        obj.addPropertyChangeListener(new PropertyChangeListener() {
                            public void propertyChange(PropertyChangeEvent e) {
                                firePropertyChange(prop + "." + e.getPropertyName(), e.getOldValue(), //$NON-NLS-1$
                                        e.getNewValue());

                                // append to sort order - use reflection
                                if (sender instanceof AbstractJsonObject) {
                                    try {
                                        Method mtd = JsonEntity.class.getDeclaredMethod("appendSortOrder", //$NON-NLS-1$
                                                String.class);
                                        mtd.setAccessible(true);
                                        mtd.invoke(sender, prop);
                                    } catch (Exception e1) {
                                        e1.printStackTrace();
                                    }
                                }
                            }
                        });

                        listening.add(prop);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
    }

    @SuppressWarnings("rawtypes")
    protected ArrayList<Field> getFields(Class entity) {
        ArrayList<Field> fields = new ArrayList<Field>();
        Class superClass = entity;

        while (superClass != null) {
            for (Field field : superClass.getDeclaredFields()) {
                if (!((field.getModifiers() & Modifier.TRANSIENT) == Modifier.TRANSIENT)) {
                    fields.add(field);
                }
            }
            superClass = superClass.getSuperclass();
        }

        return fields;
    }

    protected String getFieldName(Field field) {
        String name = field.getName();
        for (Annotation anno : field.getAnnotations()) {
            if (anno.annotationType() == Name.class) {
                name = ((Name) anno).value();
            }
        }
        return name;
    }

    @SuppressWarnings("rawtypes")
    protected List<String> getFieldNames(Class entity) {
        ArrayList<String> names = new ArrayList<String>();

        for (Field field : getFields(entity)) {
            names.add(getFieldName(field));
        }

        return names;
    }

    @SuppressWarnings("rawtypes")
    protected Field getFieldByName(Class entity, String fieldName) {

        // create cache
        if (!fieldNameCache.containsKey(entity)) {
            Map<String, Field> mapping = new HashMap<String, Field>();

            for (Field field : getFields(entity)) {
                mapping.put(getFieldName(field), field);
            }
            fieldNameCache.put(entity, mapping);
        }

        Map<String, Field> mapping = fieldNameCache.get(entity);

        if (mapping.containsKey(fieldName)) {
            return mapping.get(fieldName);
        }

        return null;
    }

    protected void appendSortOrder(String name) {
        if (!sortOrder.contains(name)) {
            sortOrder.add(name);
        }
    }

    protected Object getJsonValue(Object value) {
        if (value instanceof JsonValue) {
            return ((JsonValue) value).toJsonValue();
        } else if (value instanceof JsonCollection) {
            JsonCollection coll = (JsonCollection) value;
            if (coll.size() > 0) {
                // call buildJson - use reflection
                try {
                    Method mtd = JsonEntity.class.getDeclaredMethod("buildJson"); //$NON-NLS-1$
                    return mtd.invoke(coll);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            return value;
        }

        return null;
    }

    protected abstract void doParse(Object obj);

    private void parse(String json) throws ParseException {
        JsonParser parser = new JsonParser();
        doParse(parser.parse(json));
    }

    private void parse(Reader reader) throws IOException, ParseException {
        JsonParser parser = new JsonParser();
        doParse(parser.parse(reader));
    }

    public void fromJson(Object json) {
        doParse(json);
    }

    public void fromJson(String json) throws ParseException {
        parse(json);
    }

    public void fromJson(File file) throws IOException, ParseException {
        if (file.length() > 0) {
            fromJson(new FileReader(file));
        }
    }

    public void fromJson(Reader reader) throws IOException, ParseException {
        parse(reader);
    }

    protected abstract Object buildJson();

    public String toJson() {
        return JsonFormatter.format(buildJson());
    }
}