Package com.dubture.getcomposer.core.entities

Source Code of com.dubture.getcomposer.core.entities.JsonEntity

package com.dubture.getcomposer.core.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.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dubture.getcomposer.core.annotation.Name;
import com.dubture.getcomposer.json.JsonFormatter;
import com.dubture.getcomposer.json.JsonParser;
import com.dubture.getcomposer.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(), e.getNewValue());
               
                // append to sort order - use reflection
                if (sender instanceof AbstractJsonObject) {
                  try {
                    Method mtd = JsonEntity.class.getDeclaredMethod("appendSortOrder", 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");
          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());
  }
}
TOP

Related Classes of com.dubture.getcomposer.core.entities.JsonEntity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.