Package com.alvazan.orm.impl.meta.data

Source Code of com.alvazan.orm.impl.meta.data.MetaEmbeddedEntity

package com.alvazan.orm.impl.meta.data;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alvazan.orm.api.base.ToOneProvider;
import com.alvazan.orm.api.base.anno.NoSqlConverter;
import com.alvazan.orm.api.base.anno.NoSqlId;
import com.alvazan.orm.api.base.anno.NoSqlTransient;
import com.alvazan.orm.api.z5api.NoSqlSession;
import com.alvazan.orm.api.z8spi.Row;
import com.alvazan.orm.api.z8spi.meta.DboColumnEmbedMeta;
import com.alvazan.orm.api.z8spi.meta.DboColumnMeta;
import com.alvazan.orm.api.z8spi.meta.DboTableMeta;
import com.alvazan.orm.api.z8spi.meta.IndexData;
import com.alvazan.orm.api.z8spi.meta.RowToPersist;
import com.alvazan.orm.api.z8spi.action.Column;
import com.alvazan.orm.api.z8spi.conv.Converter;
import com.alvazan.orm.api.z8spi.conv.StandardConverters;
import com.alvazan.orm.api.z8spi.meta.InfoForIndex;
import com.alvazan.orm.api.z8spi.meta.ReflectionUtil;
import com.alvazan.orm.impl.meta.data.collections.MapProxyFetchAll;
import com.alvazan.orm.impl.meta.data.collections.OurAbstractCollection;
import com.alvazan.orm.impl.meta.data.collections.SetProxyFetchAll;
import com.alvazan.orm.impl.meta.data.collections.ToOneProviderProxy;

public class MetaEmbeddedEntity<OWNER, PROXY> extends MetaAbstractField<OWNER> {

  private DboColumnEmbedMeta metaDbo = new DboColumnEmbedMeta();
  private MetaAbstractClass<PROXY> classMeta;
  private Field fieldForKey;

  @Override
  public String toString() {
    return "MetaEmbeddedEntity [field='" + field.getDeclaringClass().getName()+"."+field.getName()+"(field type=" +field.getType()+ "), columnName=" + columnName + "]";
  }

  public void setup(DboTableMeta t, Field field, String colName,
      MetaAbstractClass<PROXY> fkMeta) {
    DboTableMeta fkToTable = fkMeta.getMetaDbo();
    metaDbo.setup(t, colName, fkToTable);
    super.setup(field, colName);
    this.classMeta = fkMeta;
  }

  @Override
  public void translateFromColumn(Row row, OWNER entity, NoSqlSession session) {
    Object proxy;
    if (field.getType().equals(Map.class))
      proxy = translateFromColumnMap(row, entity, session);
    else if (field.getType().equals(Collection.class)
        || field.getType().equals(List.class))
      proxy = translateFromColumnList(row, entity, session);
    else if (field.getType().equals(Set.class))
      proxy = translateFromColumnSet(row, entity, session);
    else {
      proxy = translateFromSingleEntity(row, session);
    }

    ReflectionUtil.putFieldValue(entity, field, proxy);
  }

  private Object translateFromSingleEntity(Row row, NoSqlSession session) {
    Object proxy = null;
    String columnName = getColumnName();
    byte[] colBytes = StandardConverters.convertToBytes(columnName);
    Column column = row.getColumn(colBytes);
    if (column == null) {
      column = new Column();
    }
    if (field.getType().equals(ToOneProvider.class)) {
      // THIS IS NOT DONE YET
      proxy = translateFromToComposite(row, session);
    } else {
        proxy = convertIdToProxyComposite(row, session);
    }
    return proxy;
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  private Object translateFromToComposite(Row row, NoSqlSession session) {
    // THIS IS NOT DONE YET
    byte[] bytes = StandardConverters.convertToBytes(columnName);
    Collection<Column> columns = row.columnByPrefix(bytes);
    if (columns != null && !columns.isEmpty()) {
      Column column = columns.iterator().next();
      byte[] fullName = column.getName();
      // strip off the prefix to get the foreign key
      int pkLen = fullName.length - bytes.length;
      byte[] fk = new byte[pkLen];
      for (int i = bytes.length; i < fullName.length; i++) {
        fk[i - bytes.length] = fullName[i];
      }
      ToOneProvider<PROXY> toOne = new ToOneProviderProxy(classMeta, fk,
          session);
      return toOne;
    } else
      return null;
  }

  private Object convertIdToProxyComposite(Row row, NoSqlSession session) {
    byte[] bytes = StandardConverters.convertToBytes(columnName);
    byte[] rowid = StandardConverters.convertToBytes("Id");
        int bytesandrowid = bytes.length + rowid.length;
        byte[] bytesandId = new byte[bytesandrowid];
        System.arraycopy(bytes, 0, bytesandId, 0, bytes.length);
        System.arraycopy(rowid, 0, bytesandId, bytes.length, rowid.length);
        Collection<Column> columns = row.columnByPrefix(bytesandId);
        if (columns != null && !columns.isEmpty()) {
            // Id is present
            Column column = columns.iterator().next();
            byte[] fullName = column.getName();
            // strip off the prefix to get the foreign key
            int pkLen = fullName.length - bytesandrowid;
            byte[] pk = new byte[pkLen];
            for (int i = bytesandrowid; i < fullName.length; i++) {
                pk[i - bytesandrowid] = fullName[i];
            }
            return createProxy(pk, row);
        } else
            return createProxy(null, row);
    }

  private Object translateFromColumnSet(Row row, OWNER entity,
      NoSqlSession session) {
    List<byte[]> keys = parseColNamePostfix(columnName, row);
    Set<PROXY> retVal = new SetProxyFetchAll<PROXY>(entity, session,
        classMeta, keys, field);
    return retVal;
  }

  @SuppressWarnings({ "rawtypes" })
  private Map translateFromColumnMap(Row row, OWNER entity,
      NoSqlSession session) {
    List<byte[]> keys = parseColNamePostfix(columnName, row);
    MapProxyFetchAll proxy = MapProxyFetchAll.create(entity, session,
        classMeta, keys, fieldForKey, field);
    return proxy;
  }

  @SuppressWarnings("unchecked")
  private List<PROXY> translateFromColumnList(Row row, OWNER entity,
      NoSqlSession session) {
    List<byte[]> keys = parseColNamePostfix(columnName, row);
    List<PROXY> retVal = new ArrayList<PROXY>();
    for (byte[] rowkey : keys) {
      Object proxy = createProxy(rowkey, row);
      retVal.add((PROXY)proxy);
    }
    return retVal;
  }

  @Override
  public void translateToColumn(InfoForIndex<OWNER> info) {
    OWNER entity = info.getEntity();
    RowToPersist row = info.getRow();
    if (field.getType().equals(Map.class))
      translateToColumnMap(entity, row);
    else if (field.getType().equals(List.class))
      translateToColumnList(entity, row);
    else translateToColumn(entity, row);
  }

  @SuppressWarnings("unchecked")
  private void translateToColumn(OWNER entity, RowToPersist row) {
    Collection<PROXY> value = new ArrayList<PROXY>();
    value.add((PROXY)ReflectionUtil.fetchFieldValue(entity, field));
    Collection<PROXY> toBeRemoved = new ArrayList<PROXY>();
    translateToColumnImpl(value, row, toBeRemoved);
  }

  @SuppressWarnings("unchecked")
  private void translateToColumnList(OWNER entity, RowToPersist row) {
    Collection<PROXY> values = (Collection<PROXY>) ReflectionUtil
        .fetchFieldValue(entity, field);
    Collection<PROXY> toBeAdded = values;
    // all values in the list get
    // added if not an
    // OurAbstractCollection
    Collection<PROXY> toBeRemoved = new ArrayList<PROXY>();
    if (values instanceof OurAbstractCollection) {
      OurAbstractCollection<PROXY> coll = (OurAbstractCollection<PROXY>) values;
      toBeRemoved = coll.getToBeRemoved();
      toBeAdded = coll.getToBeAdded();
    }
    translateToColumnImpl(toBeAdded, row, toBeRemoved);
  }

  @SuppressWarnings({ "rawtypes", "unchecked" })
  private void translateToColumnMap(OWNER entity, RowToPersist row) {
    Map mapOfProxies = (Map) ReflectionUtil.fetchFieldValue(entity, field);
    Collection<PROXY> toBeAdded = mapOfProxies.values();
    Collection<PROXY> toBeRemoved = new ArrayList<PROXY>();
    if (mapOfProxies instanceof MapProxyFetchAll) {
      MapProxyFetchAll mapProxy = (MapProxyFetchAll) mapOfProxies;
      toBeRemoved = mapProxy.getToBeRemoved();
      toBeAdded = mapProxy.getToBeAdded();
    }
    translateToColumnImpl(toBeAdded, row, toBeRemoved);
  }

  private void translateToColumnImpl(Collection<PROXY> toBeAdded,
      RowToPersist row, Collection<PROXY> toBeRemoved) {
    // removes first
    for (PROXY p : toBeRemoved) {
      byte[] name = formTheName(p);
      row.addEntityToRemove(name);
    }
    if (toBeAdded == null)
      return;
    for (PROXY proxy : toBeAdded) {
      byte[] name = formTheName(proxy);
      if (name != null) {
        // rowkey is not null. i.e., NoSqlId is present
        Column idColumn = new Column();
        idColumn.setName(name);
        idColumn.setValue(null);
        row.getColumns().add(idColumn);
        byte[] idValue = translateOne(proxy);
        Field[] fieldsinClass = proxy.getClass().getDeclaredFields();
        for (Field singleField : fieldsinClass) {
          singleField.setAccessible(true);
          if(Modifier.isTransient(singleField.getModifiers()) ||
              Modifier.isStatic(singleField.getModifiers()) ||
              singleField.isAnnotationPresent(NoSqlTransient.class))
            continue;
          if (!singleField.isAnnotationPresent(NoSqlId.class)) {
            addColumn(proxy, singleField, idValue, row);
          }
        }
      } else {
        if (proxy != null) {
          Field[] fieldsinClass = proxy.getClass().getDeclaredFields();
          for (Field singleField : fieldsinClass) {
            singleField.setAccessible(true);
            if(Modifier.isTransient(singleField.getModifiers()) ||
                Modifier.isStatic(singleField.getModifiers()) ||
                singleField.isAnnotationPresent(NoSqlTransient.class))
              continue;
            addColumnWithoutId(proxy, singleField, row);
          }
        }
      }
    }
  }

  private void addColumn(PROXY proxy, Field singleField, byte[] idValue, RowToPersist row) {
    Object value = ReflectionUtil.fetchFieldValue(proxy, singleField);
    Column c = new Column();
    byte[] columnName = formTheColumnName(proxy, idValue, singleField);
    c.setName(columnName);
        if (value != null) {
            byte[] columnValue = null;
            NoSqlConverter customConv = singleField.getAnnotation(NoSqlConverter.class);
            if (customConv != null) {
                columnValue = getBytesValue(value, customConv);
            } else {
                columnValue = StandardConverters.convertToBytes(value);
            }
            c.setValue(columnValue);
        }
    row.getColumns().add(c);
  }

  private byte[] formTheColumnName(PROXY p, byte[] id, Field singleField) {
    byte[] prefix = StandardConverters.convertToBytes(columnName);
    byte[] singleFieldName = StandardConverters.convertToBytes(singleField.getName());
    byte[] columnName = new byte[ prefix.length + id.length + singleFieldName.length];
    for (int i = 0; i < columnName.length; i++) {
      if (i < prefix.length)
        columnName[i] = prefix[i];
      else if (i < (prefix.length + id.length))
        columnName[i] = id[i - prefix.length];
      else
        columnName[i] = singleFieldName[i - prefix.length - id.length];
    }
    return columnName;
  }

  private byte[] formTheName(PROXY p) {
    byte[] pkData = translateOne(p);
    if (pkData == null)
      return null;
    else
      return formTheNameImpl(columnName, pkData);
  }

  private Object createProxy(byte[] rowKey, Row row) {
    Object newproxy = null;
    try {
      newproxy = classMeta.getMetaClass().newInstance();
    } catch (InstantiationException e) {
      throw new UnsupportedOperationException("There is some problem in creating the proxy");
    } catch (IllegalAccessException e) {
      throw new UnsupportedOperationException("There is some problem in creating the proxy");
    }
    DboColumnMeta colMeta = this.getMetaDbo();
    if (classMeta.getIdField() != null && (rowKey!=null)) {
      // first fill the id
      DboColumnEmbedMeta embedMeta = (DboColumnEmbedMeta) colMeta;
            Object idValue = null;
            MetaField<PROXY> metaFieldId = classMeta.getIdField();
            NoSqlConverter customConvId = metaFieldId.getField().getAnnotation(NoSqlConverter.class);
            byte[] idBytes = null;
            if (customConvId != null) {
                idValue = getValue(rowKey, customConvId);
                idBytes = getBytesValue(idValue, customConvId);
            } else {
                idValue = embedMeta.getFkToColumnFamily().getIdColumnMeta().getStorageType().convertFromNoSql(rowKey);
                idBytes = StandardConverters.convertToBytes(idValue);
            }
            if (metaFieldId != null)
                ReflectionUtil.putFieldValue(newproxy, metaFieldId.getField(),idValue);

      // Now extract other columns
      byte[] prefix = StandardConverters.convertToBytes(getColumnName());
      byte[] embedColumn = new byte[prefix.length + idBytes.length];
        System.arraycopy(prefix,0,embedColumn,0         ,prefix.length);
        System.arraycopy(idBytes,0,embedColumn,prefix.length,idBytes.length);
      Collection<Column> columnsInRow = row.columnByPrefix(embedColumn);
      for (Column colInRow : columnsInRow) {
        byte[] fullNameCol = colInRow.getName();
        int colLen = fullNameCol.length - embedColumn.length;
        byte[] fk = new byte[colLen];
        for (int i = embedColumn.length; i < fullNameCol.length; i++) {
          fk[i - embedColumn.length] = fullNameCol[i];
        }

                Object colVal = colMeta.convertFromStorage2(fk);
                String colName = colMeta.convertTypeToString(colVal);

                Object columnValue = null;
                MetaField<PROXY> metaField = classMeta.getMetaFieldByCol(null, colName);
                if(metaField == null)
                  continue; //skip this field sice we don't know this column
                NoSqlConverter customConv = metaField.getField().getAnnotation(NoSqlConverter.class);
                if (customConv != null) {
                    columnValue = getValue(colInRow.getValue(), customConv);
                } else {
                    columnValue = embedMeta.getFkToColumnFamily().getColumnMeta(colName).getStorageType().convertFromNoSql(colInRow.getValue());
                }
                if (metaField != null)
          ReflectionUtil.putFieldValue(newproxy, metaField.getField(), columnValue);
      }
    } else {
      // No Id is present, only fill the columns
        createProxy2(colMeta, newproxy, row);
    }
    return newproxy;
  }

    private void createProxy2(DboColumnMeta colMeta, Object newproxy, Row row) {
        byte[] colName = StandardConverters.convertToBytes(getColumnName());
        Collection<Column> columnsWORowKey = row.columnByPrefix(colName);
        for (Column col : columnsWORowKey) {
            byte[] fullName = col.getName();
            int embedColumnLen = fullName.length - colName.length;
            byte[] embedColumn = new byte[embedColumnLen];
            for (int i = colName.length; i < fullName.length; i++) {
                embedColumn[i - colName.length] = fullName[i];
            }
            Object colVal = colMeta.convertFromStorage2(embedColumn);
            String columnName = colMeta.convertTypeToString(colVal);

            DboColumnEmbedMeta embedMeta = (DboColumnEmbedMeta) colMeta;
            if (embedMeta.getFkToColumnFamily().getColumnMeta(columnName) == null)
                continue;
            Object columnValue = null;
            MetaField<PROXY> metaField = classMeta.getMetaFieldByCol(null, columnName);
            NoSqlConverter customConv = metaField.getField().getAnnotation(NoSqlConverter.class);
            if (customConv != null) {
                columnValue = getValue(col.getValue(), customConv);
            } else {
                columnValue = embedMeta.getFkToColumnFamily().getColumnMeta(columnName).getStorageType().convertFromNoSql(col.getValue());
            }
            if (classMeta.getMetaFieldByCol(null, columnName) != null)
                ReflectionUtil.putFieldValue(newproxy, classMeta.getMetaFieldByCol(null, columnName).getField(), columnValue);
        }
    }

    private byte[] formTheNameImpl(String colName, byte[] postFix) {
    byte[] prefix = StandardConverters.convertToBytes(colName);
    byte[] rowid = StandardConverters.convertToBytes("Id");
    byte[] name = new byte[prefix.length + rowid.length + postFix.length];
    for (int i = 0; i < name.length; i++) {
      if (i < prefix.length)
        name[i] = prefix[i];
      else if (i < (prefix.length + rowid.length))
        name[i] = rowid[i - prefix.length];
      else
        name[i] = postFix[i - prefix.length - rowid.length];
    }
    return name;
  }

    private byte[] translateOne(PROXY proxy) {
        byte[] byteVal = classMeta.convertEntityToId(proxy);
        return byteVal;
    }

  private List<byte[]> parseColNamePostfix(String columnName, Row row) {
    String columnNameWithPrefix = columnName + "Id";
    byte[] namePrefix = StandardConverters.convertToBytes(columnNameWithPrefix);
    Collection<Column> columns = row.columnByPrefix(namePrefix);
    List<byte[]> entities = new ArrayList<byte[]>();
   
    for(Column col : columns) {
      byte[] rowkeyFullName = col.getName();
      int rkLen = rowkeyFullName.length-namePrefix.length;
      byte[] rk = new byte[rkLen];
      for(int i = namePrefix.length; i < rowkeyFullName.length; i++) {
        rk[i-namePrefix.length] =  rowkeyFullName[i];
      }
      entities.add(rk);
    }
    return entities;
  }

  private void addColumnWithoutId(PROXY proxy, Field singleField, RowToPersist row) {
    Object value = ReflectionUtil.fetchFieldValue(proxy, singleField);
    Column c = new Column();
    //byte[] columnName = formTheColumnName(proxy, idValue, singleField);

    byte[] prefix = StandardConverters.convertToBytes(columnName);
    byte[] singleFieldName = StandardConverters.convertToBytes(singleField.getName());
    byte[] columnName = new byte[ prefix.length + singleFieldName.length];
    for (int i = 0; i < columnName.length; i++) {
      if (i < prefix.length)
        columnName[i] = prefix[i];
      else
        columnName[i] = singleFieldName[i - prefix.length];
    }
    c.setName(columnName);
    if (value != null) {
            byte[] columnValue = null;
            NoSqlConverter customConv = singleField.getAnnotation(NoSqlConverter.class);
            if (customConv != null) {
                columnValue = getBytesValue(value, customConv);
            } else {
                columnValue = StandardConverters.convertToBytes(value);
            }
            c.setValue(columnValue);
    }
    row.getColumns().add(c);
  }

  @Override
  public void removingEntity(InfoForIndex<OWNER> info,
      List<IndexData> indexRemoves, byte[] rowKey) {
    throw new UnsupportedOperationException();
  }

  @Override
  public byte[] translateValue(Object value) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Object fetchField(Object entity) {
    throw new UnsupportedOperationException();
  }

  @Override
  public String translateToString(Object fieldsValue) {
    throw new UnsupportedOperationException();
  }

  @Override
  public DboColumnMeta getMetaDbo() {
    return metaDbo;
  }

  @Override
  protected Object unwrapIfNeeded(Object value) {
    throw new UnsupportedOperationException();
  }

    private byte[] getBytesValue(Object value, NoSqlConverter customConv) {
        Class<? extends Converter> convClazz = customConv.converter();
        Converter converter = ReflectionUtil.create(convClazz);
        return converter.convertToNoSql(value);
    }

    private Object getValue(byte[] value, NoSqlConverter customConv) {
        Class<? extends Converter> convClazz = customConv.converter();
        Converter converter = ReflectionUtil.create(convClazz);
        return converter.convertFromNoSql(value);
    }
}
TOP

Related Classes of com.alvazan.orm.impl.meta.data.MetaEmbeddedEntity

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.