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

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

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

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javassist.util.proxy.Proxy;

import javax.inject.Inject;
import javax.inject.Provider;

import com.alvazan.orm.api.base.anno.NoSqlDiscriminatorColumn;
import com.alvazan.orm.api.z5api.NoSqlSession;
import com.alvazan.orm.api.z5api.SpiMetaQuery;
import com.alvazan.orm.api.z8spi.KeyValue;
import com.alvazan.orm.api.z8spi.Row;
import com.alvazan.orm.api.z8spi.action.Column;
import com.alvazan.orm.api.z8spi.conv.StandardConverters;
import com.alvazan.orm.api.z8spi.meta.IndexData;
import com.alvazan.orm.api.z8spi.meta.RowToPersist;
import com.alvazan.orm.impl.meta.data.collections.CacheLoadCallback;

@SuppressWarnings("rawtypes")
public class MetaClassInheritance<T> extends MetaAbstractClass<T> {

  @Inject
  private Provider<MetaClassSingle> classMetaProvider; 
  /**
   * For inheritance for a single table, we have multiple proxies for this class that we may need to
   * create.
   */
  private Map<String, MetaClassSingle<T>> dbTypeToMeta = new HashMap<String, MetaClassSingle<T>>();
  private Map<Class, String> classToType = new HashMap<Class, String>();
  private String discriminatorColumnName;
  private byte[] discColAsBytes;
 
  public String getDiscriminatorColumnName() {
    return discriminatorColumnName;
  }
 
  public Collection<MetaClassSingle<T>> fetchSubclassList() {
    return dbTypeToMeta.values();
  }
 
  public SpiMetaQuery getNamedQuery(Class<? extends T> clazz, String name) {
    if(clazz.equals(getMetaClass()))
      return super.getNamedQuery(clazz, name);
   
    String type = classToType.get(clazz);
    MetaClassSingle<T> metaSingle = dbTypeToMeta.get(type);
    return metaSingle.getNamedQuery(clazz, name);
  }
 
  @SuppressWarnings("unchecked")
  public MetaClassSingle<?> findOrCreate(Class<?> clazz, Class<?> parent) {
    NoSqlDiscriminatorColumn col = clazz.getAnnotation(NoSqlDiscriminatorColumn.class);
    if(col == null)
      throw new IllegalArgumentException("Class "+parent.getName()+" in the NoSqlInheritance annotation, specifies a class" +
          " that is missing the NoSqlDiscriminatorColumn annotation.  Class to add annotation to="+clazz.getName());
    else if(!parent.isAssignableFrom(clazz))
      throw new IllegalArgumentException("Class "+clazz+" is not a subclass of "+parent+" but the" +
          " NoSqlInheritance annotation specifies that class so it needs to be a subclass");
   
    String columnValue = col.value();
    MetaClassSingle<T> metaSingle = dbTypeToMeta.get(columnValue);
    if(metaSingle != null)
      return metaSingle;
   
   
    metaSingle = classMetaProvider.get();
    //All the subclasses need to share the same meta Dbo object!!!! as it is one table for the
    //whole class heirarchy
    metaSingle.setSharedMetaDbo(getMetaDbo());
    dbTypeToMeta.put(columnValue, metaSingle);
    classToType.put(clazz, columnValue);
    return metaSingle;
  }

  @Override
  public boolean hasIndexedField(T entity) {
    Class clazz = entity.getClass();
    if(entity instanceof Proxy) {
      clazz = entity.getClass().getSuperclass();
    }
    String type = classToType.get(clazz);
    MetaClassSingle<T> metaClassSingle = dbTypeToMeta.get(type);
    return metaClassSingle.hasIndexedField(entity);
  }

  @Override
  public KeyValue<T> translateFromRow(Row row, NoSqlSession session) {
    MetaClassSingle<T> metaClassSingle = retrieveMeta(row);
    return metaClassSingle.translateFromRow(row, session);
  }

  private MetaClassSingle<T> retrieveMeta(Row row) {
    Column column = row.getColumn(discColAsBytes);
   
    String type = StandardConverters.convertFromBytes(String.class, column.getValue());
    MetaClassSingle<T> metaClassSingle = this.dbTypeToMeta.get(type);
    return metaClassSingle;
  }


  @Override
  public RowToPersist translateToRow(T entity) {
    Class clazz = entity.getClass();
    if(entity instanceof Proxy) {
      clazz = entity.getClass().getSuperclass();
    }
    String type = classToType.get(clazz);
    MetaClassSingle<T> metaClassSingle = dbTypeToMeta.get(type);
    RowToPersist translateToRow = metaClassSingle.translateToRow(entity);
   
    byte[] value = StandardConverters.convertToBytes(type);
    Column typeCol = new Column();
    typeCol.setName(discColAsBytes);
    typeCol.setValue(value);
    translateToRow.getColumns().add(typeCol);
    return translateToRow;
  }

  @Override
  public List<IndexData> findIndexRemoves(NoSqlProxy proxy, byte[] rowKey) {
    Class clazz = proxy.getClass().getSuperclass();
    String type = classToType.get(clazz);
    MetaClassSingle<T> metaClassSingle = dbTypeToMeta.get(type);
    return metaClassSingle.findIndexRemoves(proxy, rowKey);
  }

  @Override
  public MetaField<T> getMetaFieldByCol(Class c, String columnName) {
    String type = classToType.get(c);
    MetaClassSingle<T> metaSingle = dbTypeToMeta.get(type);
    return metaSingle.getMetaFieldByCol(c, columnName);
  }

  @Override
  public Class<? extends T> getProxyClass() {
    throw new UnsupportedOperationException("not done yet");
  }

  @Override
  public Tuple<T> convertIdToProxy(Row row, NoSqlSession session, byte[] nonVirtKey,
      CacheLoadCallback cacheLoadCallback) {
    if(row == null)
      throw new IllegalArgumentException("bug, inheritance does not support who called this so you can't have inheritance along with it, we need to fix so let us know");
    MetaClassSingle<T> metaClassSingle = retrieveMeta(row);
    return metaClassSingle.convertIdToProxy(row, session, nonVirtKey, cacheLoadCallback);
  }

  @Override
  public List<MetaField<T>> getIndexedColumns() {
    throw new UnsupportedOperationException("not done yet.  ie. don't have index support for inheritance tables yet");
  }

  @Override
  public void fillInInstance(Row row, NoSqlSession session, T inst) {
    MetaClassSingle<T> metaClassSingle = retrieveMeta(row);
    metaClassSingle.fillInInstance(row, session, inst);
  }

  public void setDiscriminatorColumnName(String discColumn) {
    discriminatorColumnName = discColumn;
    discColAsBytes = StandardConverters.convertToBytes(discColumn);
  }

  @Override
  public boolean isPartitioned() {
    throw new UnsupportedOperationException("not done yet.  ie. don't have partition support for inheritance tables yet");
  }
 
}
TOP

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

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.