Package com.adaptrex.core.persistence.cayenne

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

/*
* 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.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.lifecycle.id.IdCoder;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.commons.lang3.StringUtils;

import com.adaptrex.core.ext.ExtTypeFormatter;
import com.adaptrex.core.ext.FieldDefinition;
import com.adaptrex.core.persistence.api.AdaptrexCollectionType;
import com.adaptrex.core.persistence.api.AdaptrexEntityType;
import com.adaptrex.core.security.SecureEntity;
import com.adaptrex.core.utilities.StringUtilities;

public class CayenneCollectionType extends AdaptrexCollectionType {

  private Method getter;
  private Method setter;
  private Method adder;
  private Method remover;
 
  /*
   * For non-flat associations
   */
  private Class<?> joinTable;
  private Method joinGetter;
  private Method targetGetter;
  private Method primarySetter;
  private Method targetSetter;
 
 
  public CayenneCollectionType(ObjEntity objEntity, ObjRelationship relationship, Class<?> collectionType, Class<?> itemType, SecureEntity secureEntity) {
    super(relationship.getName(), collectionType, itemType, secureEntity);
   
    DataMap dataMap = objEntity.getDataMap();
    String entityName = objEntity.getName();
    String targetName = relationship.getTargetEntityName();
    Class<?> declaringClass = objEntity.getJavaClass();
   
   
    /*
     * Is this a join table?
     */
    if (targetName.startsWith(entityName + "Has") || targetName.endsWith("Has" + entityName)) {
      ObjEntity joinEntity = dataMap.getObjEntity(targetName);
      joinTable = joinEntity.getJavaClass();
     
     
      /*
       * Get the actual relationship name we want to use
       */
      String relEntityName = targetName
          .replace(entityName + "Has", "")
          .replace("Has" + entityName, "");
         
      String relName = StringUtilities.pluralize(
          StringUtilities.uncapitalize(relEntityName)
        );
      this.name = relName;
      this.itemType = dataMap.getObjEntity(relEntityName).getJavaClass();
      this.idsFieldDefinition =
          new FieldDefinition(
              StringUtilities.uncapitalize(relEntityName) +
                StringUtils.capitalize(AdaptrexEntityType.COLLECTION_IDS_NAME),
              ExtTypeFormatter.AUTO
            );
     
      /*
       * Get the methods to grab the join table and target table
       */
      try {
        joinGetter = declaringClass.getMethod(
            "get" + StringUtilities.pluralize(joinTable.getSimpleName()));
        targetGetter = joinTable.getMethod("get" + this.itemType.getSimpleName());
       
        primarySetter = joinTable.getMethod("set" + declaringClass.getSimpleName(), declaringClass);
        targetSetter = joinTable.getMethod("set" + this.itemType.getSimpleName(), this.itemType);
      } catch (Exception e) {}
     
     
     
     
    }
   
   
    /*
     * Flattened association
     */
    else {
      String relName = StringUtilities.singularize(relationship.getName());
      this.idsFieldDefinition =
          new FieldDefinition(
              relName + StringUtils.capitalize(AdaptrexEntityType.COLLECTION_IDS_NAME),
              ExtTypeFormatter.AUTO
            );
     
      String capName = StringUtilities.capitalize(getName());
     
      try {
        getter = declaringClass.getMethod("get" + capName);
      } catch (Exception e) {}
      if (getter == null) return;
      try {
        setter = declaringClass.getMethod("set" + capName, getter.getReturnType());
      } catch (Exception e) {}
      try {
        adder = declaringClass.getMethod("addTo" + capName, itemType);
      } catch (Exception e) {}
      try {
        remover = declaringClass.getMethod("removeFrom" + capName, itemType);
      } catch (Exception e) {}
    }
  }

  @Override
  public Object getCollectionFrom(Object entity) throws Exception {
    /*
     * Handle non-flattened associations with join tables
     */
    if (joinTable != null) {
      /*
       * Get all recods in join table
       */
      try {
        List<Object> targetCollection = new ArrayList<Object>();
        for (Object joinTableEntity : (Collection<?>) joinGetter.invoke(entity)) {
          targetCollection.add(targetGetter.invoke(joinTableEntity));
        }
        return targetCollection;
      } catch (Exception e) {};
      return null;
    }
   
   
    /*
     * Handle flattened associations
     */
    return getter.invoke(entity);
  }
 
 
  @SuppressWarnings("unchecked")
  public void setByIds(ObjectContext context, Object entity, Object collectionIds) throws Exception {
    List<Object> listItemIds = null;
    if (collectionIds != null) {
      if (collectionIds instanceof String) {
        String stringVal = String.valueOf(collectionIds);
        if (!stringVal.isEmpty())
          listItemIds = (List<Object>) StringUtilities.fromJson(stringVal, List.class);             
      } else if (collectionIds instanceof List) {
        listItemIds = (List<Object>) collectionIds;
      }
    }
   
    /*
     * Non flattened associations with a join table needs special processing
     */
    Collection<Object> oldCollection;
    Collection<Object> joinEntities = null;
    if (joinTable != null) {
      /*
       * Get all recods in join table
       */
      oldCollection = new ArrayList<Object>();
      joinEntities = (Collection<Object>) joinGetter.invoke(entity);
      try {
        for (Object joinTableEntity : joinEntities) {
          oldCollection.add(targetGetter.invoke(joinTableEntity));
        }
      } catch (Exception e) {};
    } else {
      oldCollection = (Collection<Object>) getter.invoke(entity);
    }
   
   
   
    /*
     * Get the matching records for the new collection
     */
    List<Object> newCollection = new ArrayList<Object>();
    IdCoder idCoder = new IdCoder(context.getEntityResolver());
    for (Object listItemId : listItemIds) {
      ObjectId objectId = idCoder.getObjectId(String.valueOf(listItemId));
      ObjectIdQuery query = new ObjectIdQuery(objectId);
      List<?> list = context.performQuery(query);
      Object newForeignObject = list.size() == 0 ? null : list.get(0);
      if (newForeignObject != null) newCollection.add(newForeignObject);
    }
   
    /*
     * Is there a setter for this collection
     */
    if (setter != null) {
      setter.invoke(entity, newCollection);
      return;
    }
   
    /*
     * Loop through oldCollection and remove those that no longer exist
     */
    Iterator<Object> oldIterator = oldCollection.iterator();
    while (oldIterator.hasNext()) {
      Object oldObject = oldIterator.next();
      if (!newCollection.contains(oldObject)) {
        oldIterator.remove();
       
        /*
         * If we have a join table, delete the join record
         */
        if (joinTable != null) {
          for (Object joinEntity : joinEntities) {
            Object testEntity = targetGetter.invoke(joinEntity);
            if (oldObject.equals(testEntity)) {
              context.deleteObjects(joinEntity);
              break;
            }
          }
        }
       
        /*
         * Standard removal
         */
        else {
          remover.invoke(entity, oldObject);
        }
       
      }
    }
   
    /*
     * Add new entities
     */
    newCollection.removeAll(oldCollection);
    for (Object newObject : newCollection) {
      if (joinTable != null) {
        Object joinTableEntity = joinTable.newInstance();
        this.primarySetter.invoke(joinTableEntity, entity);
        this.targetSetter.invoke(joinTableEntity, newObject);
      } else {
        adder.invoke(entity, newObject);
      }
    }
  }
}
TOP

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

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.