Package com.adaptrex.core.persistence.cayenne

Source Code of com.adaptrex.core.persistence.cayenne.CayennePersistenceManager

/*
* Copyright 2012 Adaptrex, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adaptrex.core.persistence.cayenne;

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

import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.access.DataDomain;
import org.apache.cayenne.configuration.server.ServerRuntime;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.lifecycle.id.IdCoder;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.SelectQuery;
import org.apache.log4j.Logger;

import com.adaptrex.core.ext.ExtConfig;
import com.adaptrex.core.ext.ExtTypeFormatter;
import com.adaptrex.core.ext.ModelInstance;
import com.adaptrex.core.persistence.PersistenceTools;
import com.adaptrex.core.persistence.api.AdaptrexEntityType;
import com.adaptrex.core.persistence.api.AdaptrexPersistenceManager;
import com.adaptrex.core.persistence.api.AdaptrexStoreData;
import com.adaptrex.core.security.SecurityModel;

/**
* CayennePersistenceManager is an Adaptrex wrapper around a single Cayenne DataDomain
* providing access to Adaptrex specific functionality.  When Adaptrex requires a
* specific CayennePersistenceManager it retrieves it from the AdaptrexRegistry.  If
* one doesn't exist, a new one is created and stored in the registry for later
* retrieval.
*/
public class CayennePersistenceManager implements AdaptrexPersistenceManager {
  private static Logger log = Logger.getLogger(CayennePersistenceManager.class);
 
  /**
   * The factory is a Cayenne ServerRuntime used to create ObjectContext instances
   */
  private ServerRuntime factory;
 
  /**
   * Read only ObjectContexts can be shared across threads and users.  We
   * only need to create it once for the lifetime of the application.
   */
  private DataContext readOnlySession;
 
 
  private String name;
 
  private DataDomain dataDomain;
 
 
  /**
   * Creates a persistence manager for a specific DataDomain referenced by the
   * factoryName parameter.  The factoryName should not include the .xml extension
   * <br /><br />
   * To create a persistence manager for the domain configured in
   * cayenne-secondarydomain.xml, you would use a factoryName "cayenne-secondarydomain"
   * @throws Exception
   */
  public CayennePersistenceManager(String factoryName) {
    if (factoryName == null) {
      throw new RuntimeException(
          "Cayenne requires a default factory " +
          "name to be specified in adaptrex.properties");
    }
   
    this.factory = new ServerRuntime(factoryName + ".xml");
    this.readOnlySession = (DataContext) this.factory.getContext();
    this.name = factoryName;
    this.dataDomain = factory.getDataDomain();
   
    try {
      initialize();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
   
    log.info("Creating CayennePersistenceManager for DataDomain " + factoryName);
  }
 
  public CayennePersistenceManager(ServerRuntime factory) {
    this.factory = factory;
    this.readOnlySession = (DataContext) this.factory.getContext();
    this.dataDomain = factory.getDataDomain();
    this.name = dataDomain.getName();
   
    try {
      initialize();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
   
   
    log.info("Creating CayennePersistenceManager for DataDomain " + this.name);
  }
 
 
  private Map<String,CayenneEntityType> adaptrexEntities;
  private void initialize() throws Exception {
    SecurityModel securityModel = PersistenceTools.getSecurityModel();
    adaptrexEntities = new HashMap<String,CayenneEntityType>();
   
    for (ObjEntity objEntity : this.factory.getDataDomain().getEntityResolver().getObjEntities()) {
      CayenneEntityType adaptrexEntity = new CayenneEntityType(objEntity, securityModel);
      adaptrexEntities.put(adaptrexEntity.getName(), adaptrexEntity);
    }
  }
 
  @Override
  public AdaptrexEntityType getAdaptrexEntity(String name) {
    return adaptrexEntities.get(name);
  }
 
  private CayenneEntityType getCayenneEntity(String name) {
    return adaptrexEntities.get(name);
  }
 
 
 
  @Override
  public String getName() {
    return this.name;
  }
 

  /**
   * Returns an ObjectContext for the DataDomain this persistence manager represents.
   * getSession should only be used for read/write ObjectContexts as it generates
   * a new context on each call.  To get a shared read only ObjectContext, call
   * getReadOnlySession instead.
   */
  @Override
  public Object getNativeSession() {
    return this.factory.getContext();
  }
 
  ObjectContext getObjectContext() {
    return this.factory.getContext();
  }

  /**
   * Returns a shared read only ObjectContext for the DataDomain this persistence
   * manager represents.  To get a new ObjectContext for read/write operations, use
   * getSession instead.<br /><br />
   * This read only "session" is specific to Cayenne.  If it's used directly by
   * Adaptrex based applications, they will be Cayenne specific and not portable
   * to other ORMs
   */ 
  ObjectContext getReadOnlyObjectContext() {
    return this.readOnlySession;
  }

  /**
   * Shuts down the ServerRuntime this persistence manager uses to generate its
   * ObjectContexts.  This should be called to clean up Cayenne when the container
   * is shut down.
   */
  @Override
  public void shutdown() {
    log.info("Shutting down ObjectContect for " + this.factory.getDataDomain().getName());
    this.factory.shutdown();
  }
 

  /**
   * Get a persistent entity based on an id for a specific class.  CayennePersistenceManager
   * use a string representation of Cayenne's ObjectId to identify individual objects.
   */
  @Override
  public Object getEntity(Class<?> clazz, Object id) {
    return getEntity(null, clazz, id);
  }

  /**
   * Get a persistent entity based on a key value pair for a specific class.
   */
  @Override
  public Object getEntity(Class<?> clazz, String key, Object value) {
    return getEntity(null, clazz, key, value);
  }

  /**
   * Get a persistent entity based on an id for a specific class.  CayennePersistenceManager
   * use a string representation of Cayenne's ObjectId to identify individual objects.
   */
  private Object getEntity(Object objectContext, Class<?> clazz, Object id) {
    try {
      ObjectContext context = objectContext == null ? this.getReadOnlyObjectContext() : (ObjectContext) objectContext;
      EntityResolver entityResolver = this.factory.getDataDomain().getEntityResolver();
      IdCoder idCoder = new IdCoder(entityResolver);
      ObjectId objectId = idCoder.getObjectId((String) id);
      ObjectIdQuery query = new ObjectIdQuery(objectId);
      List<?> list = context.performQuery(query);
      return list.size() == 0 ? null : list.get(0);
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * Get a persistent entity based on a key value pair for a specific class.
   */
  private Object getEntity(Object objectContext, Class<?> clazz, String key, Object value) {
    try {
      ObjectContext context = objectContext == null ? this.getReadOnlyObjectContext() : (ObjectContext) objectContext;
      Expression exp = ExpressionFactory.matchExp(key, value);
      SelectQuery query = new SelectQuery(clazz, exp);
      List<?> list = context.performQuery(query);
      return list.size() == 0 ? null : list.get(0);
    } catch (Exception e) {
      return null;
    }
  } 

 
 
  /*
   * Get StoreData
   */
  @Override
  public AdaptrexStoreData getStoreData(ExtConfig extConfig) {
    return new CayenneStoreData(extConfig);
 

  @Override
  public ModelInstance getModelInstance(ExtConfig extConfig, Object id) throws Exception {
    Object entity = this.getEntity(extConfig.getEntityClass(), id);
    return new ModelInstance(extConfig, entity);
  }

  @Override
  public ModelInstance getModelInstance(ExtConfig extConfig, String key, Object value) throws Exception {
    Object entity = this.getEntity(extConfig.getEntityClass(), key, value);
    return new ModelInstance(extConfig, entity);
  }
 
  @Override
  public ModelInstance createModelInstance(ExtConfig extConfig, Map<String, Object> data) {
    try {
      ObjectContext objectContext = getObjectContext();
      Class<?> clazz = extConfig.getEntityClass();
      Object entity = objectContext.newObject(clazz);
      this.updateEntity(objectContext, clazz, entity, data);
      return new ModelInstance(extConfig, entity);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  @Override
  public ModelInstance updateModelInstance(ExtConfig extConfig, Object id,  Map<String, Object> data) throws Exception {
    return this.updateModelInstance(extConfig, id, null, null, data);
  }
 
  @Override
  public ModelInstance updateModelInstance(ExtConfig extConfig, String key, Object value, Map<String, Object> data) throws Exception {
    return this.updateModelInstance(extConfig, null, key, value, data);
  }
 
  private ModelInstance updateModelInstance(ExtConfig extConfig, Object id, String key, Object value, Map<String, Object> data) throws Exception {
    ObjectContext objectContext = getObjectContext();
    Class<?> clazz = extConfig.getEntityClass();
    Object entity = id != null
        ? this.getEntity(objectContext, clazz, id)
        : this.getEntity(objectContext, clazz, key, value);
    this.updateEntity(objectContext, clazz, entity, data);
    return new ModelInstance(extConfig, entity);
  }

 
  @Override
  public ModelInstance deleteModelInstance(ExtConfig extConfig, Object id) throws Exception {
    return this.deleteModelInstance(extConfig, id, null, null);
  }
 
  @Override
  public ModelInstance deleteModelInstance(ExtConfig extConfig, String key, Object value) throws Exception {
    return this.deleteModelInstance(extConfig, null, key, value);
 
 
  private ModelInstance deleteModelInstance(ExtConfig extConfig, Object id, String key, Object value) throws Exception {
    ObjectContext objectContext = getObjectContext();
    Class<?> clazz = extConfig.getEntityClass();
    Object entity = id != null
        ? this.getEntity(objectContext, clazz, id)
        : this.getEntity(objectContext, clazz, key, value);
    ModelInstance model = new ModelInstance(extConfig, entity);
    objectContext.deleteObjects(entity);
    objectContext.commitChanges();
    return model;
  }
 
  /*
   * Update
   */
  private void updateEntity(ObjectContext objectContext, Class<?> clazz, Object entity, Map<String,Object> data) throws Exception {
    CayenneEntityType cayenneEntity = getCayenneEntity(clazz.getSimpleName());

    for (String fieldName : data.keySet()) {
      if (fieldName.equals(AdaptrexEntityType.ENTITY_ID_NAME)) continue;
     
      Object newValue = data.get(fieldName);
     
      CayenneFieldType adaptrexField = cayenneEntity.getCayenneField(fieldName);
      if (adaptrexField != null) {
        adaptrexField.setValueFor(entity, ExtTypeFormatter.parse(newValue, adaptrexField.getFieldType()));
        continue;
      }
     
      CayenneAssociationType cayenneAssociation = (CayenneAssociationType) cayenneEntity.getAssociationByIdField(fieldName);
      if (cayenneAssociation != null) {
        cayenneAssociation.setById(objectContext, entity, newValue);
        continue;
      }
     
      CayenneCollectionType cayenneCollection = (CayenneCollectionType) cayenneEntity.getCollectionByIdsField(fieldName);
      if (cayenneCollection != null) {
        cayenneCollection.setByIds(objectContext, entity, newValue);
      }
    }
   
    objectContext.commitChanges();
  };
}
TOP

Related Classes of com.adaptrex.core.persistence.cayenne.CayennePersistenceManager

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.