Package com.draagon.meta.manager

Source Code of com.draagon.meta.manager.ObjectManager

/*
* Copyright 2003 Draagon Software LLC. All Rights Reserved.
*
* This software is the proprietary information of Draagon Software LLC.
* Use is subject to license terms.
*/

package com.draagon.meta.manager;

//import com.draagon.meta.manager.db.ObjectMapping;
//import com.draagon.meta.manager.db.MappingHandler;
import com.draagon.meta.*;
import com.draagon.meta.manager.exp.Expression;
import com.draagon.meta.manager.exp.ExpressionGroup;
import com.draagon.meta.manager.exp.ExpressionOperator;
import com.draagon.meta.manager.exp.Range;
import com.draagon.meta.manager.exp.SortOrder;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;
//import javax.servlet.*;


/**
* The Object Manager Base is able to add, update, delete,
* and retrieve objects of those types from a datastore.
*/
public abstract class ObjectManager
{
  private static Log log = LogFactory.getLog( ObjectManager.class );

  public final static String IS_KEY       = "isKey";
  public final static String IS_READONLY  = "isReadOnly";
       
  public final static String AUTO         = "auto";
  public final static String AUTO_CREATE  = "create";
  public final static String AUTO_UPDATE  = "update";

  public final static int CREATE = 1;
  public final static int UPDATE = 2;
  public final static int DELETE = 3;

  public static final int AUTO_NONE    =  0;
  public static final int AUTO_PRIOR   =  1;
  public static final int AUTO_DURING  =  2;
  public static final int AUTO_POST    =  3;

  //private MappingHandler mMappingHandler = null;

  public ObjectManager()
  {
  }

  ///////////////////////////////////////////////////////
  // MANAGEMENT METHODS
  //

  /**
   * Initializes the ObjectManager
   */
  public void init()
  throws Exception
  {
    log.info( "Object Manager " + toString() + " initialized" );
  }

  /**
   * Destroys the Object Manager
   */
  public void destroy()
  {
    log.info( "Object Manager " + toString() + " destroyed" );
  }


  ///////////////////////////////////////////////////////
  // CONNECTION HANDLING METHODS
  //

  /**
   * Retrieves a connection object representing the datastore
   */
  public abstract ObjectConnection getConnection() throws MetaException;

  public abstract void releaseConnection( ObjectConnection oc ) throws MetaException;

  ///////////////////////////////////////////////////////
  // ABSTRACT PERSISTENCE METHODS
  //

  /** Is this a createable class */       
  public abstract boolean isCreateableClass( MetaClass mc );

  /** Is this a readable class */
  public abstract boolean isReadableClass( MetaClass mc );

  /** Gets the update mapping to the DB */
  public abstract boolean isUpdateableClass( MetaClass mc );

  /** Gets the delete mapping to the DB */
  public abstract boolean isDeleteableClass( MetaClass mc );
       
  protected String getPersistenceAttribute( MetaData md, String name )
  {
    try {
      if ( md.hasAttribute( name ))
        return (String) md.getAttribute( name );
    } catch ( MetaAttributeNotFoundException e ) {
      throw new RuntimeException( "[" + md + "] had attribute [" + name + "], but threw exception reading it", e );
    }
    return null;
  }

  protected boolean isReadOnly( MetaData md )
  {
    try {
      if ( "true".equals( md.getAttribute( IS_READONLY ))) return true;
    } catch( MetaAttributeNotFoundException e ) {}
    return false;
  }

  /**
   * Gets an objects reference which can be used to later load the object
   */
  public ObjectRef getObjectRef( Object obj )
  {
    MetaClass mc = MetaClassLoader.findMetaClass( obj );

    Collection<MetaField> keys = getPrimaryKeys( mc );
    if ( keys.size() == 0 )
      throw new IllegalArgumentException( "MetaClass [" + mc + "] has no primary keys, so no object reference is available" );

    String [] ids = new String[ keys.size() ];
    int j = 0;
    for( Iterator<MetaField> i = keys.iterator(); i.hasNext(); j++ )
    {
      MetaField f = i.next();
      ids[ j ] = f.getString( obj );
    }

    return new ObjectRef( mc, ids );
  }

  /**
   * Gets an object reference which can be used to later load the object, based on the string reference
   */
  public ObjectRef getObjectRef( String refStr ) {
    return new ObjectRef( refStr );
  }

  /**
   * Gets the object by the id; throws exception if it did not exist
   */
  public abstract Object getObjectByRef( ObjectConnection c, String refStr ) throws MetaException;

  /**
   * Load the specified object from the datastore
   */
  public abstract void loadObject( ObjectConnection c, Object obj ) throws MetaException;

  /**
   * Add the specified object to the datastore
   */
  public abstract void createObject( ObjectConnection c, Object obj ) throws MetaException;

  /**
   * Update the specified object in the datastore
   */
  public abstract void updateObject( ObjectConnection c, Object obj ) throws MetaException;

  /**
   * Delete the specified object from the datastore
   */
  public abstract void deleteObject( ObjectConnection c, Object obj ) throws MetaException;

  ///////////////////////////////////////////////////////
  // DEFAULT IMPEMENTATIONS
  // May be overridden for enhanced performance

  @SuppressWarnings("unchecked")
  protected List<MetaField> getAutoFields( MetaClass mc )
  {
    final String KEY = "getAutoFields()";

    ArrayList<MetaField> auto = (ArrayList<MetaField>) mc.getCacheValue( KEY );
    if ( auto == null )
    {
      auto = new ArrayList<MetaField>();

      for( MetaField f : mc.getMetaFields() )
      {
        if ( f.hasAttribute( AUTO ))
          auto.add( f );
      }

      mc.setCacheValue( KEY, auto );
    }

    return auto;
  }

  protected void handleAutoFields( ObjectConnection c, MetaClass mc, Object obj, int state, int action ) throws MetaException
  {
    for( MetaField f : getAutoFields( mc ))
    {
      Object auto = f.getAttribute( AUTO );
      handleAutoField( c, mc, f, obj, auto, state, action );
    }
  }

  public void handleAutoField( ObjectConnection c, MetaClass mc, MetaField mf, Object obj, Object auto, int state, int action ) throws MetaException
  {
    if ( state == AUTO_PRIOR )
    {
      if ( AUTO_CREATE.equals( auto ) && action == CREATE ) {
        mf.setLong( obj, new Long( System.currentTimeMillis() ));
      }
      else if ( AUTO_UPDATE.equals( auto )) {
        mf.setLong( obj, new Long( System.currentTimeMillis() ));
      }
    }
  }

  public void prePersistence( ObjectConnection c, MetaClass mc, Object obj, int action ) throws MetaException
  {
    handleAutoFields( c, mc, obj, AUTO_PRIOR , action);
  }

  public void postPersistence( ObjectConnection c, MetaClass mc, Object obj, int action ) throws MetaException
  {
    handleAutoFields( c, mc, obj, AUTO_POST , action);

    if ( action == CREATE ) {
      if ( mc instanceof StatefulMetaClass )
      {
        // Update the state of the Object
        ((StatefulMetaClass) mc ).setNew( obj, false );
        ((StatefulMetaClass) mc ).setModified( obj, false );
        ((StatefulMetaClass) mc ).setDeleted( obj, false );
      }
    }
    else if ( action == UPDATE ) {
      // Update the state of the Object
      if ( mc instanceof StatefulMetaClass )
      {
        ((StatefulMetaClass) mc).setNew( obj, false );
        ((StatefulMetaClass) mc).setModified( obj, false );
        ((StatefulMetaClass) mc).setDeleted( obj, false );
      }
    }
    else if ( action == DELETE ) {
      if ( mc instanceof StatefulMetaClass ) {
        ((StatefulMetaClass) mc).setDeleted( obj, true );
      }
    }
  }

  /**
   * Determines whether the MetaField is a key
   */
  public boolean isPrimaryKey( MetaField mf )
  {
    try {
      if ( "true".equals( mf.getAttribute( IS_KEY ))) return true;
    } catch( MetaAttributeNotFoundException e ) {}
    return false;
  }

  /**
   * Retrieves a new object of the specified class
   */
  public Object getNewObject( MetaClass mc ) throws PersistenceException
  {
    Object o = mc.newInstance();
    //attachManager( o );
    return o;
  }

  /**
   * Attaches the object to the specified meta manager
   */
  /*public void attachManager( Object obj )
  {
    MetaClass mc = getClassForObject( obj );               
    if ( mc instanceof ManagedMetaClass )
      ((ManagedMetaClass) mc ).attachManager( this, obj );
  }*/

  /**
   * Verifies the object belongs to this ObjectManager
   */
  /*protected void verifyObjectManager( Object obj ) throws PersistenceException
  {
    if ( obj == null ) throw new IllegalArgumentException( "Cannot persist a null object" );
   
    MetaClass mc = getClassForObject( obj );
    if ( !( mc instanceof ManagedMetaClass )) return;

    ManagedMetaClass mmc = (ManagedMetaClass) mc;

    ObjectManager mm = mmc.getManager( obj );

    // WARNING:  Do we care?!
    // Verify that it is the same meta manager
    if ( mm != null && !mm.equals( this ))
      throw new PersistenceException( "This object is attached to a different Object Manager [" + mm + "]" );

    // If not attached, then attach it
    if ( mm == null )
      mmc.attachManager( this, obj );
  }*/

  /**
   * Retrieves the fields of a MetaClass which are keys
   */
  @SuppressWarnings("unchecked")
  public Collection<MetaField> getPrimaryKeys( MetaClass mc )
  //throws MetaException
  {
    final String KEY = "getPrimaryKeys()";

    ArrayList<MetaField> fields = (ArrayList<MetaField>) mc.getCacheValue( KEY );

    if ( fields == null )
    {
      fields = new ArrayList<MetaField>();

      for( Iterator i = mc.getMetaFields().iterator(); i.hasNext(); )
      {
        MetaField f = (MetaField) i.next();
        if ( isPrimaryKey( f )) fields.add( f );
      }

      mc.setCacheValue( KEY, fields );
    }

    //if ( fields.size() == 0 )
      //  throw new RuntimeException( "No keys found for MetaClass [" + mc + "]" );

    return fields;
  }

  /**
   * Get all objects of the specified kind from the datastore
   */
  /*public Collection getObjects( ObjectConnection c, MetaClass mc, Collection fields )
      throws MetaException
    {
      return getObjects( c, mc, fields, new QueryOptions() );
    }*/

  /**
   * Stores the specified object by adding, updating, or deleting
   */
  public void storeObject( ObjectConnection c, Object obj ) throws PersistenceException
  {
    StatefulMetaClass pmc = getStatefulMetaClass( obj );

    if ( pmc.isNew( obj ) ) createObject( c, obj );
    else if ( pmc.isModified( obj ) ) updateObject( c, obj );
    else if ( pmc.isDeleted( obj ) ) deleteObject( c, obj );
  }

  /**
   * Retrieves a persistable metaclass from the given object
   */
  protected StatefulMetaClass getStatefulMetaClass( Object obj )
  {
    MetaClass mc = getClassForObject( obj );
    if ( !( mc instanceof StatefulMetaClass )) return null;

    return (StatefulMetaClass) mc;
  }

  /**
   * Gets the object by the reference; throws exception if it did not exist
   */
  /*public Object getObjectByRef( ObjectConnection c, String refStr )
    throws MetaException
  {
        ObjectRef ref = getObjectRef( refStr );
        Collection fields = getReadableFields( ref.getMetaClass() );
        return getObjectByRef( c, fields, refStr );
  }*/

  /** Gets the total count of objects */
  public long getObjectsCount( ObjectConnection c, MetaClass mc ) throws MetaException
  {
    return getObjectsCount( c, mc, null );
  }
 
  /** Gets the total count of objects with the specified options */
  public long getObjectsCount( ObjectConnection c, MetaClass mc, Expression exp ) throws MetaException
  {
    Collection<MetaField> fields = new ArrayList<MetaField>();
    fields.add( getPrimaryKeys(mc).iterator().next() );
    QueryOptions options = new QueryOptions( exp );
    options.setFields( fields );
    return getObjects( c, mc, new QueryOptions( exp )).size();
  }
 
  /**
   * Get all objects of the specified kind from the datastore
   */
  public Collection<?> getObjects( ObjectConnection c, MetaClass mc ) throws MetaException
  {
    // Collection fields = getReadableFields( mc );
    return getObjects( c, mc, new QueryOptions() );
  }

  /**
   * Get all objects of the specified kind from the datastore
   */
  public abstract Collection<?> getObjects( ObjectConnection c, MetaClass mc, QueryOptions options ) throws MetaException;
  /*  {
        Collection fields = null;

        if ( options.getWriteableOnly() )
          fields = getWriteableFields( mc );
        else
          fields = getReadableFields( mc );

        return getObjects( c, mc, fields, options );
    }*/

  /**
   * Get all objects of the specified kind from the datastore
   */
  /*public Collection getObjects( ObjectConnection c, MetaClass mc, QueryOptions options )
    throws MetaException
    {
        Collection results = getObjects( c, mc, fields );

        Expression exp = options.getExpression();
        SortOrder sort = options.getSortOrder();
        Range range = options.getRange();

        if ( exp != null )
            results = filterObjects( results, exp );

        if ( sort != null )
            results = sortObjects( results, sort );

        if ( range != null )
            results = clipObjects( results, range );

        if( options.isDistinct() )
            results = distinctObjects( results );

        return results;
    }*/

  /**
   * Loads the specified object from the datastore
   */
  /*public void loadObject( ObjectConnection c, Object obj )
    throws MetaException
  {
        Collection fields = getReadableFields( getClassForObject( obj ));
        loadObject( c, fields, obj );
  }*/

  /**
   * Loads the specified fields for the objects from the datastore
   */
  /*public void loadObjects( ObjectConnection c, Collection fields, Collection objs )
    throws MetaException
  {
    for( Iterator i = objs.iterator(); i.hasNext(); )
      loadObject( c, fields, i.next() );
  }*/

  /**
   * Loads the specified objects from the datastore
   */
  public void loadObjects( ObjectConnection c, Collection<?> objs )
  throws MetaException
  {
    for( Iterator<?> i = objs.iterator(); i.hasNext(); )
    {
      Object obj = i.next();
      //Collection fields = getReadableFields( getClassForObject( obj ));
      loadObject( c, obj );
    }
  }

  /**
   * Add the specified objects to the datastore
   */
  public void createObjects( ObjectConnection c, Collection<?> objs )
  throws MetaException
  {
    for( Iterator<?> i = objs.iterator(); i.hasNext(); )
      createObject( c, i.next() );
  }

  /**
   * Update the specified objects in the datastore
   */
  public void updateObjects( ObjectConnection c, Collection<?> objs )
  throws MetaException
  {
    for( Iterator<?> i = objs.iterator(); i.hasNext(); )
      updateObject( c, i.next() );
  }

  /**
   * Delete the specified object from the datastore
   */
  public void deleteObjectByRef( ObjectConnection c, String ref )
  throws MetaException
  {
    deleteObject( c, getObjectByRef( c, ref ));
  }

  /**
   * Delete the specified objects from the datastore
   */
  public int deleteObjects( ObjectConnection c, Collection<?> objs )
  throws MetaException
  {
    int j = 0;
    for( Iterator<?> i = objs.iterator(); i.hasNext(); ) {
      deleteObject( c, i.next() );
      j++;
    }
    return j;
  }

  /**
   * Delete the objects from the datastore where the field has the specified value
   */
  public int deleteObjects( ObjectConnection c, MetaClass mc, Expression exp )
  throws MetaException
  {
    return deleteObjects( c, getObjects( c, mc, new QueryOptions( exp )));
  }

  /**
   * Stores all objecs in the Collection by adding or updating
   */
  public void storeObjects( ObjectConnection c, Collection<?> objs )
  throws MetaException
  {
    for( Iterator<?> i = objs.iterator(); i.hasNext(); )
      storeObject( c, i.next() );
  }


  ///////////////////////////////////////////////////////
  // HELPER METHODS
  // May be overridden for enhanced performance

  /**
   * Sorts the specified objects by the provided sort order
   */
  @SuppressWarnings("unchecked")
  public static Collection<Object> sortObjects( Collection<Object> objs, SortOrder sort )
  throws MetaException
  {
    if ( objs.size() == 0 ||
        sort.getOrder() == SortOrder.NONE ) return objs;

    ArrayList<Object> a = new ArrayList<Object>();
    a.addAll( 0, objs );

    ObjectComparator comp = new ObjectComparator( sort );

    Collections.sort( a, comp );

    return a;
  }


  /**
   * Retrieves the fields of a MetaClass which are persistable
   *  and have been modified.
   */
  protected Collection<MetaField> getModifiedPersistableFields( StatefulMetaClass smc, Collection<MetaField> fields, Object o )
  {
    List<MetaField> dirtyFields = new ArrayList<MetaField>();
    // Iterate each field on the object that is updateable and see if anything has changed
    for( MetaField f : fields ) {
      if ( smc.isFieldModified( f, o )) {
        dirtyFields.add( f );
      }
    }

    return dirtyFields;
  }

  /**
   * Gets the SQL WHERE clause for the fields of a class
   */
  private static boolean getExpressionResult( MetaClass mc, Expression exp, Object obj )
  throws MetaException
  {
    if ( exp instanceof ExpressionGroup )
    {
      return getExpressionResult( mc, ((ExpressionGroup) exp ).getGroup(), obj );
    }
    else if ( exp instanceof ExpressionOperator )
    {
      ExpressionOperator oper = (ExpressionOperator) exp;

      boolean a = getExpressionResult( mc, oper.getExpressionA(), obj );
      boolean b = getExpressionResult( mc, oper.getExpressionB(), obj );

      boolean rc = false;
      if ( oper.getOperator() == ExpressionOperator.AND )
        rc = a & b;
      else
        rc = a | b;

      //ystem.out.println( "[" + oper.getExpressionA() + "](" + a + ") {" + oper.getOperator() + "} [" + oper.getExpressionB() + "](" + b + ") = " + rc );

      return rc;
    }
    else if ( exp.isSpecial() )
    {
      throw new MetaException( "Unsupported Special Expression [" + exp + "]" );
    }
    else
    {
      MetaField f = mc.getMetaField( exp.getField() );

      Object val = f.getObject( obj );
      Object val2 = exp.getValue();
     
      int condition = exp.getCondition();

      if ( condition == Expression.EQUAL
          || condition == Expression.NOT_EQUAL
          || condition == Expression.GREATER
          || condition == Expression.LESSER
          || condition == Expression.EQUAL_GREATER
          || condition == Expression.EQUAL_LESSER
      )
      {
        return compareValue( val, val2, condition );
      }
      else if ( condition == Expression.CONTAIN
          || condition == Expression.NOT_CONTAIN
          || condition == Expression.START_WITH
          || condition == Expression.NOT_START_WITH
          || condition == Expression.END_WITH
          || condition == Expression.NOT_END_WITH
          || condition == Expression.EQUALS_IGNORE_CASE
      )
      {
        String s1 = (val==null)?null:val.toString();
        String s2 = (val2==null)?null:val2.toString();

        if ( s1 == null || s2 == null ) return false;

        boolean rc = compareString( s1.toLowerCase(), s2.toLowerCase(), condition );
        //ystem.out.println( "[" + s1 + "] (" + condition + ") [" + s2 + "] = " + rc );
        return rc;
      }
      else
        throw new MetaException( "Unsupported Expression Condition (" + Expression.condStr(condition) + ") on Expression [" + exp + "]" );
    }
  }

  protected static boolean compareString( String s1, String s2, int condition )
  {
    switch( condition )
    {
    case Expression.CONTAIN:
      if ( s1.indexOf( s2 ) >= 0 ) return true;
      return false;

    case Expression.NOT_CONTAIN:
      if ( s1.indexOf( s2 ) < 0 ) return true;
      return false;

    case Expression.START_WITH:
      return s1.startsWith( s2 );

    case Expression.NOT_START_WITH:
      return !s1.startsWith( s2 );

    case Expression.END_WITH:
      return s1.endsWith( s2 );

    case Expression.NOT_END_WITH:
      return !s1.endsWith( s2 );
     
    case Expression.EQUALS_IGNORE_CASE:
      return s1.equalsIgnoreCase( s2 );

    default:
      throw new IllegalStateException( "compareString with unsupported condition type (" + Expression.condStr(condition) + ")" );
    }
  }

  protected static boolean compareValue( Object val, Object val2, int condition )
  {
    // If it's a collection, then iterate the whole array
    if ( val2 instanceof Collection ) {
     
      // Has to be EQUAL or NOT EQUAL
      if ( condition !=  Expression.EQUAL && condition != Expression.NOT_EQUAL ) {
        throw new IllegalArgumentException( "Can only compare with EQUAL or NOT EQUAL against a collection!" );
      }
     
      // Iterate each value in the collection
      for( Object v : ((Collection<?>)val2)) {
       
        // Get the resulting condition
        boolean ret = compareValue( val, v, condition );
       
        // return true if there are any matches
        if ( condition == Expression.EQUAL && ret ) return true;
       
        // if looking for not equal, return false when finding the first one
        else if ( condition == Expression.NOT_EQUAL && !ret ) return false;
      }
     
      // Return true or false based on the condition
      if ( condition == Expression.EQUAL ) return false;
      else if ( condition == Expression.NOT_EQUAL ) return true;
      else throw new IllegalStateException( "This has to be EQUAL or NOT EQUAL" );
    }
   
    int result = 0;
    if ( val == null || val2 == null )
    {
      if ( val == null && val2 == null ) result = 0;
      else if ( val == null ) result = -1;
      else result = 1;
    }
    else if ( val instanceof Boolean )
    {
      if ( ((Boolean) val ).equals( val2 )) result = 0;
      else result = 1;
    }
    else if ( val instanceof Byte )
    {
      Byte v = (val2 instanceof Byte)?(Byte)val2:new Byte( val2.toString() );
      result = ((Byte) val ).compareTo( v );
    }
    else if ( val instanceof Short )
    {
      Short v = (val2 instanceof Short)?(Short)val2:new Short( val2.toString() );
      result = ((Short) val ).compareTo( v );
    }
    else if ( val instanceof Integer )
    {
      Integer v = (val2 instanceof Integer)?(Integer)val2:new Integer( val2.toString() );
      result = ((Integer) val ).compareTo( v );
    }
    else if ( val instanceof Long )
    {
      Long v = (val2 instanceof Long)?(Long)val2:new Long( val2.toString() );
      result = ((Long) val ).compareTo( v );
    }
    else if ( val instanceof Float )
    {
      Float v = (val2 instanceof Float)?(Float)val2:new Float( val2.toString() );
      result = ((Float) val ).compareTo( v );
    }
    else if ( val instanceof Double )
    {
      Double v = (val2 instanceof Double)?(Double)val2:new Double( val2.toString() );
      result = ((Double) val ).compareTo( v );
    }
    else if ( val instanceof Date )
    {
      Date v = (val2 instanceof Date)?(Date)val2:new Date( Long.parseLong( val2.toString() ));
      result = ((Date) val ).compareTo( v );
    }
    else
    {
      result = val.toString().toLowerCase().compareTo( val2.toString().toLowerCase() );
    }

    switch( condition )
    {
    case Expression.EQUAL:
      if ( result == 0 ) return true;
      else return false;
    case Expression.GREATER:
      if ( result > 0 ) return true;
      else return false;
    case Expression.LESSER:
      if ( result < 0 ) return true;
      else return false;
    case Expression.EQUAL_GREATER:
      if ( result >= 0 ) return true;
      else return false;
    case Expression.EQUAL_LESSER:
      if ( result <= 0 ) return true;
      else return false;
    case Expression.NOT_EQUAL:
      if ( result != 0 ) return true;
      else return false;
    default:
      throw new IllegalArgumentException( "Invalid expression condition [" + Expression.condStr(condition) + "]" );
    }
  }


  /**
   * Filters the specified objects by the provided expression
   */
  public static Collection<Object> filterObjects( Collection<Object> objs, Expression exp )
  throws MetaException
  {
    ArrayList<Object> a = new ArrayList<Object>();

    // Check each object for validity
    for( Object o : objs )
    {
      MetaClass mc = MetaClassLoader.findMetaClass( o );

      if ( getExpressionResult( mc, exp, o ))
      {
        //ystem.out.println( "ADDING: " + o );
        a.add( o );
      }
    }

    return a;
  }

  /**
   * Clips the specified objects by the provided range
   */
  public static Collection<Object> clipObjects( Collection<Object> objs, Range range )
  throws MetaException
  {
    ArrayList<Object> a = new ArrayList<Object>();
    int j = 1;
    for( Object o : objs )
    {
      if ( j >= range.getStart() && j <= range.getEnd() )
        a.add( o );
    }

    return a;
  }

  /**
   * Clips the specified objects by the provided range
   */
  public static Collection<Object> distinctObjects( Collection<?> objs )
  throws MetaException
  {
    // TODO:  Check this, as I don't think it works!

    ArrayList<Object> a = new ArrayList<Object>( objs );
    for( Iterator<Object> i = a.iterator(); i.hasNext(); )
    {
      Object o = i.next();

      // Find the first index of the object
      int fi = a.indexOf( o );

      // Remove all objects of the same value
      int li = 0;
      while (( li = a.lastIndexOf( o )) != fi )
        a.remove( li );
    }

    return a;
  }


  /**
   * Attempts to retrieve the MetaClass for a specified object,
   *  and throws an exception if one does not exist
   */
  public MetaClass getClassForObject( Object o )
  throws MetaException
  {
    MetaClass mc = MetaClassLoader.findMetaClass( o );
    if ( mc == null )
      throw new MetaClassNotFoundException( "No MetaClass exists for object [" + o + "]" );

    return mc;
  }

  ///////////////////////////////////////////////////////
  // OBJECT QUERY LANGUAGE METHODS
  //

  public abstract int execute( ObjectConnection c, String query, Collection<?> arguments ) throws MetaException;

  public abstract Collection<?> executeQuery( ObjectConnection c, String query, Collection<?> arguments ) throws MetaException;


  ///////////////////////////////////////////////////////
  // TO STRING METHOD
  public String toString()
  {
    return "Unknown";
  }
}
TOP

Related Classes of com.draagon.meta.manager.ObjectManager

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.