Package com.alvazan.orm.layer0.base

Source Code of com.alvazan.orm.layer0.base.BaseEntityManagerFactoryImpl$OurFilter

package com.alvazan.orm.layer0.base;

import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alvazan.orm.api.base.Bootstrap;
import com.alvazan.orm.api.base.NoSqlEntityManager;
import com.alvazan.orm.api.base.NoSqlEntityManagerFactory;
import com.alvazan.orm.api.base.anno.NoSqlIndexed;
import com.alvazan.orm.api.base.anno.NoSqlQueries;
import com.alvazan.orm.api.base.anno.NoSqlQuery;
import com.alvazan.orm.api.z5api.QueryParser;
import com.alvazan.orm.api.z5api.SpiMetaQuery;
import com.alvazan.orm.api.z8spi.conv.Converter;
import com.alvazan.orm.api.z8spi.conv.StorageTypeEnum;
import com.alvazan.orm.api.z8spi.meta.DboColumnCommonMeta;
import com.alvazan.orm.api.z8spi.meta.DboColumnIdMeta;
import com.alvazan.orm.api.z8spi.meta.DboTableMeta;
import com.alvazan.orm.impl.meta.data.MetaAbstractClass;
import com.alvazan.orm.impl.meta.data.MetaClass;
import com.alvazan.orm.impl.meta.data.MetaClassInheritance;
import com.alvazan.orm.impl.meta.data.MetaClassSingle;
import com.alvazan.orm.impl.meta.data.MetaInfo;
import com.alvazan.orm.impl.meta.scan.ScannerForField;
import com.alvazan.orm.layer3.typed.CachedMeta;
import com.impetus.annovention.ClasspathDiscoverer;
import com.impetus.annovention.Filter;

public class BaseEntityManagerFactoryImpl implements NoSqlEntityManagerFactory {

  private static final Logger log = LoggerFactory.getLogger(BaseEntityManagerFactoryImpl.class);
 
  @Inject
  private Provider<BaseEntityManagerImpl> entityMgrProvider;
  @Inject
  private MyClassAnnotationDiscoveryListener listener;
  @Inject
  private ScannerForField inspectorField;
  @Inject
  private QueryParser noSqlSessionFactory;
  @Inject
  private ClasspathDiscoverer discoverer;
  private boolean isScanned;
  @Inject
  private MetaInfo metaInfo;
  @Inject
  private CachedMeta cache;
 
  private Object injector;

  @Override
  public NoSqlEntityManager createEntityManager() {
    if(!isScanned)
      throw new IllegalStateException("Must call scanForEntities first");
    BaseEntityManagerImpl mgr = entityMgrProvider.get();
    mgr.setup();
    return mgr;
  }

  @SuppressWarnings("rawtypes")
  @Override
  public void rescan(List<Class> classesToScan, ClassLoader cl) {
    List<Class> classes = classesToScan;
    if(classes == null)
      classes = new ArrayList<Class>();
    metaInfo.clearAll();
   
    listener.setClassLoader(cl);
   
    //TODO: Fork annovention, it is a very small library AND then copy from
    //http://code.google.com/p/reflections/source/browse/trunk/reflections/src/main/java/org/reflections/util/ClasspathHelper.java?r=103
    //so that we only scan classes that are in a certain package instead of all classes on the classpath!!!!
    discoverer.setFilter(new OurFilter());
        // Add class annotation listener (optional)
        discoverer.addAnnotationListener(listener);
        // Fire it
        discoverer.discover(cl);
       
        for(Class c : classes) {
          listener.scanClass(c);
        }
       
        if(log.isTraceEnabled()) {
          URL[] resources = discoverer.findResources(cl);
          for(URL res : resources) {
            log.trace("jar="+res);
          }
        }
       
        Collection<MetaAbstractClass> allEntities = metaInfo.getAllEntities();
        for(MetaAbstractClass meta : allEntities) {
          setupQueryStuff(meta);
        }

    log.info("Finished scanning classes, saving meta data");
    isScanned = true;

    BaseEntityManagerImpl tempMgr = (BaseEntityManagerImpl) createEntityManager();
    tempMgr.saveMetaData();

    for (MetaAbstractClass meta : allEntities) {
      setupIndexForKeyOnly(meta);
    }

        cache.init(this);
        log.info("Finished saving meta data, complelety done initializing");
  }
 
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public void setup(Map<String, Object> properties, Map<Class, Converter> converters, ClassLoader cl) {
    if(isScanned)
      throw new IllegalStateException("scanForEntities can only be called once");
    else if(properties == null)
      throw new IllegalArgumentException("'properties' parameter must be supplied");
   
    String val = (String) properties.get(Bootstrap.AUTO_CREATE_KEY);
    if(val == null)
      throw new IllegalArgumentException("Must provide property with key NoSqlEntityManagerFactory.AUTO_CREATE_KEY so we know to update or validate existing schema");
    AutoCreateEnum autoCreate = AutoCreateEnum.translate(val);
    if(autoCreate == null)
      throw new IllegalArgumentException("Property NoSqlEntityManagerFactory.AUTO_CREATE_KEY can only have values validate,update, or create");
   
    inspectorField.setCustomConverters(converters);
   
    log.info("Begin scanning for jars with nosql.Persistence.class");
   
        List<Class> classToScan = (List<Class>) properties.get(Bootstrap.LIST_OF_EXTRA_CLASSES_TO_SCAN_KEY);
       
        if(AutoCreateEnum.CREATE_ONLY != autoCreate)
          throw new UnsupportedOperationException("not implemented yet");
       
    rescan(classToScan, cl);
  }

  @SuppressWarnings({ "rawtypes" })
  public void setupQueryStuff(MetaAbstractClass classMeta) {
    Class<?> clazz = classMeta.getMetaClass();
    NoSqlQuery annotation = clazz.getAnnotation(NoSqlQuery.class);
    NoSqlQueries annotation2 = clazz.getAnnotation(NoSqlQueries.class);
    List<NoSqlQuery> theQueries = new ArrayList<NoSqlQuery>();
    if(annotation2 != null) {
      NoSqlQuery[] queries = annotation2.value();
      List<NoSqlQuery> asList = Arrays.asList(queries);
      theQueries.addAll(asList);
    }
    if(annotation != null)
      theQueries.add(annotation);

    //log.info("Parsing queries for entity="+classMeta.getMetaClass());
    for(NoSqlQuery query : theQueries) {
      log.info("["+classMeta.getMetaClass().getSimpleName()+"]parsing query="+query.name()+" query="+query.query());
      SpiMetaQuery metaQuery = createQueryAndAdd(classMeta, query);
      classMeta.addQuery(query.name(), metaQuery);
    }
   
    if(classMeta instanceof MetaClassInheritance) {
      MetaClassInheritance parentMeta = (MetaClassInheritance) classMeta;
      @SuppressWarnings("unchecked")
      Collection<MetaClassSingle> subMetas = parentMeta.fetchSubclassList();
      for(MetaClassSingle meta : subMetas) {
        setupQueryStuff(meta);
      }
    }
  }

  public void setupIndexForKeyOnly(MetaAbstractClass classMeta) {
    Class<?> clazz = classMeta.getMetaClass();
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      field.setAccessible(true);
      if (field.isAnnotationPresent(NoSqlIndexed.class)) {
        NoSqlIndexed indexAnno = field
            .getAnnotation(NoSqlIndexed.class);
        boolean byKeyOnly = indexAnno.byKeyOnly();
        if (byKeyOnly) {
          DboTableMeta cf = new DboTableMeta();
          String indexTableName = field.getName() + "To"
              + classMeta.getColumnFamily();

          cf.setup(null, indexTableName, false);
          cf.setColNamePrefixType(StorageTypeEnum.STRING);

          DboColumnIdMeta idMeta = new DboColumnIdMeta();
          idMeta.setup(cf, field.getName(), field.getType(), false);

          DboColumnCommonMeta col1 = new DboColumnCommonMeta();
          col1.setup(cf, "value", classMeta.getIdField().getField().getType(), false, false, false);

          BaseEntityManagerImpl tempMgr = (BaseEntityManagerImpl) createEntityManager();
          tempMgr.put(cf);
          tempMgr.put(idMeta);
          tempMgr.put(col1);
          tempMgr.flush();
        }
      }
    }
  }
  @SuppressWarnings("rawtypes")
  private SpiMetaQuery createQueryAndAdd(MetaClass classMeta, NoSqlQuery query) {
    // parse and setup this query once here to be used by ALL of the
    // SpiIndexQuery objects.
    // NOTE: This is meta data to be re-used by all threads and all
    // instances of query objects only!!!!

    // We must walk the tree allowing 2 visitors to see it.
    // The first visitor would be ourselves maybe? to get all parameter info
    // The second visitor is the SPI Index so it can create it's "prototype"
    // query (prototype pattern)
    String errorMsg = "Named Query on class "+classMeta.getMetaClass().getName()+" (name=\""+query.name()+"\",query=\""+query.query()+"\")";
    SpiMetaQuery metaQuery = noSqlSessionFactory.parseQueryForOrm(query.query(), classMeta.getColumnFamily(), errorMsg);

    return metaQuery;
  }
 
  private static class OurFilter implements Filter {
    @Override
    public boolean accepts(String filename) {
      if(filename.endsWith(".class"))
        return true;
      return false;
    }
  }

  public Object getInjector() {
    return injector;
  }

  public void setInjector(Object injector) {
    this.injector = injector;
  }

  @Override
  public void close() {
    this.noSqlSessionFactory.close();
  }

}
TOP

Related Classes of com.alvazan.orm.layer0.base.BaseEntityManagerFactoryImpl$OurFilter

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.