All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.draagon.meta.manager.db.SimpleMappingHandlerDB Maven / Gradle / Ivy

The newest version!
package com.draagon.meta.manager.db;

import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

import com.draagon.meta.MetaAttributeNotFoundException;
import com.draagon.meta.MetaClass;
import com.draagon.meta.MetaData;
import com.draagon.meta.MetaException;
import com.draagon.meta.MetaField;
import com.draagon.meta.manager.ObjectManager;
import com.draagon.meta.manager.db.defs.BaseTableDef;
import com.draagon.meta.manager.db.defs.ColumnDef;
import com.draagon.meta.manager.db.defs.IndexDef;
import com.draagon.meta.manager.db.defs.InheritenceDef;
import com.draagon.meta.manager.db.defs.NameDef;
import com.draagon.meta.manager.db.defs.SequenceDef;
import com.draagon.meta.manager.db.defs.TableDef;
import com.draagon.meta.manager.db.defs.ViewDef;

public class SimpleMappingHandlerDB implements MappingHandler {

	public final static String TRUE  = "true";
	public final static String FALSE = "false";
	
	public final static String ATTR_TABLE_DEF = "dbTableDef";
	public final static String ATTR_VIEW_DEF  = "dbViewDef";
	public final static String ATTR_COL_DEF   = "dbColDef";

	public final static String AUTO_ID  = "id";

	public final static String IS_INDEX     = "isIndex";
	public final static String IS_UNIQUE 	  = "isUnique";
	public final static String IS_VIEWONLY  = "isViewOnly";

	public final static String FOREIGN_KEY_REF     = "dbForeignKey";
	public final static String VIEW_REF     = "dbView";
	public final static String VIEW_SQL_REF = "dbViewSQL";
	public final static String TABLE_REF    = "dbTable";
	public final static String COL_REF      = "dbColumn";
	public final static String SEQ_REF      = "dbSequence";
	public final static String SEQ_START_REF   = "dbSeqStart";
	public final static String INHERITANCE_REF = "dbInheritance";
	
	@Override
	public ObjectMapping getCreateMapping( MetaClass mc ) {
		
		String name = getTableRef( mc );
		if ( name != null ) {
			return getTableMapping( mc );
		}
		return null;
	}

	@Override
	public ObjectMapping getReadMapping(MetaClass mc) {
		
		// Try to get a view first 
		String name = getViewRef( mc );
		if ( name != null ) {
			return getViewMapping( mc );
		}
		
		// If no view, then get a table
		name = getTableRef( mc );
		if ( name != null ) {
			return getTableMapping( mc );
		}	
		return null;
	}

	@Override
	public ObjectMapping getDeleteMapping(MetaClass mc) {
		return getCreateMapping(mc);
	}

	@Override
	public ObjectMapping getUpdateMapping(MetaClass mc) {
		return getCreateMapping(mc);
	}

	/** Get the table mapping */
	protected ObjectMappingDB getTableMapping( MetaClass mc ) {

		// Create the table definition
		TableDef t = new TableDef( NameDef.parseName( getTableRef( mc )));
		
		// Get all the possible metafields for this metaclass
		Collection fields = mc.getMetaFields();
		
		// Create the mapping
		ObjectMappingDB mapping = new ObjectMappingDB( t );
		
		// See if there is a referenced table
		InheritanceRef iref = getInheritanceDefinition( mc );
		if ( iref != null ) {
			
			// Load the table mapping for the super class
			ObjectMappingDB superMap = getTableMapping( iref.getSuperClass() );
			
			// Sets the parent mapping
			mapping.setSuperMapping( superMap );

			// NOTE:  Kind of shady to grab this here and later grab again, prone to bugs on implementation changes...
			String coln = getColumnRef( iref.getJoinerField() ); 
			
			// Create the inheritence definition
			InheritenceDef inheritence = new InheritenceDef( 
					coln,
					(TableDef) superMap.getDBDef(),
					(ColumnDef) superMap.getArgDef( iref.getSuperJoinerField() ),
					getColumnRef( iref.getDiscriminatorField() ),
					iref.getDiscriminatorValue() );
			
			// Add it to the current table
			t.setInheritence( inheritence );
			
			// Remove the fields found in the superclass
			fields = new ArrayList();
			for( MetaField mf2 : mc.getMetaFields() ) {
				boolean found = false;
				for( MetaField mf : iref.getSuperClass().getMetaFields() ) {
					if ( mf.equals( mf2 )) found = true;
				}
				if ( !found ) fields.add( mf2 );
			}
		}
		
		// Load columns
		loadColumns( fields, t, mapping );
		
		// Return the table mapping
		return mapping;
	}

	/** Get the table mapping */
	protected ObjectMapping getViewMapping( MetaClass mc ) {

		// Create the view definition
		ViewDef v = new ViewDef( NameDef.parseName( getViewRef( mc )));
		
		// Add the SQL if it exists
		String sql = getViewSQL( mc );
		if ( sql != null ) {
			v.setSQL( sql );
		}
		
		// Create the mapping
		ObjectMappingDB mapping = new ObjectMappingDB( v );
		
		// Load columns
		loadColumns( mc.getMetaFields(), v, mapping );
		
		return mapping;
	}
	
	/** Load the columns for the mapping */
	protected void loadColumns( Collection fields, BaseTableDef table, ObjectMappingDB mapping ) {

		// Iterate through the fields and load the columns
		for( MetaField mf : fields ) {
			
			// Get the column DB name 
			String col = getColumnRef( mf );
			if ( col == null ) continue;
			
			// Make sure it's not for view's only
			if ( table instanceof TableDef ) {
				if ( TRUE.equals( getPersistenceAttribute( mf, IS_VIEWONLY ))) continue;
			}
			
			// Create the column definition
			ColumnDef colDef = new ColumnDef( col, getSQLType( mf ));
			
			// Set the length of the varchar field
			colDef.setLength( mf.getLength() );
			
			// Is it a primary key?
			String key = getPersistenceAttribute( mf , ObjectManager.IS_KEY );
			if ( key != null && key.equalsIgnoreCase( TRUE )) {
				colDef.setPrimaryKey( true );
			}

			// Load extra values if this is a Table Definition
			if ( table instanceof TableDef ) {
				
				// Is it an auto column?
				String auto = getAutoGenerated( mf );
				if ( auto != null ) {
					if ( AUTO_ID.equals( auto )) {
						colDef.setAutoType( ColumnDef.AUTO_ID );
					}
					else if ( ObjectManager.AUTO_CREATE.equals( auto )) {
						colDef.setAutoType( ColumnDef.AUTO_DATE_CREATE );
					}
					else if ( ObjectManager.AUTO_UPDATE.equals( auto )) {
						colDef.setAutoType( ColumnDef.AUTO_DATE_UPDATE );
					}
				}
				
				// Get the sequence if it is defined
				String seq = getSequenceRef( mf );
				if ( seq != null ) {
					int start = getSequenceStart( mf );
					SequenceDef seqDef = new SequenceDef( NameDef.parseName( seq ), start, 1 );
					colDef.setSequence( seqDef );
				}
				
				// Set if it is unique
				colDef.setUnique( isUnique( mf ));
			
				// Check if the column is an index
				if ( isIndex( mf )) {
					
					String name = table.getNameDef().getName() + "_" + col + "_index"; 
						
					IndexDef index = new IndexDef( name, col );
					
					((TableDef) table ).addIndex( index );
				}
			}
			
			// Add the column to the table
			table.addColumn( colDef );
			
			// Add the mapping entry for the column and MetaField
			mapping.addMap( colDef, mf );
		}		
	}
	
	protected int getSQLType( MetaField mf ) {
		switch( mf.getType() )
		{
		case MetaField.BOOLEAN: return Types.BIT;
		case MetaField.BYTE: return Types.TINYINT;
		case MetaField.SHORT: return Types.SMALLINT;
		case MetaField.INT: return Types.INTEGER;
		case MetaField.DATE:  return Types.TIMESTAMP;
		case MetaField.LONG: return Types.BIGINT;
		case MetaField.FLOAT: return Types.FLOAT;
		case MetaField.DOUBLE: return Types.DOUBLE;
		case MetaField.STRING: return Types.VARCHAR;
		case MetaField.OBJECT: return Types.BLOB;
		default: throw new IllegalArgumentException( "Unable to get SQL type for MetaField [" + mf + "] with type (" + mf.getType() + ")" );
		}
	}

	/**
	 * Returns the inheritance definition for a given MetaClass or returns null if none exists 
	 * @param mc The MetaClass to retrieve the inheritance definition for
	 * @return The inheritance definition or null
	 */
	public InheritanceRef getInheritanceDefinition( MetaClass mc ) {

		InheritanceRef def = (InheritanceRef) mc.getCacheValue( INHERITANCE_REF );
		if ( def == null ) {
			if ( !mc.hasAttribute( INHERITANCE_REF )) return null;

			Properties props = (Properties) mc.getAttribute( INHERITANCE_REF );
			if ( props == null ) return null;

			def = new InheritanceRef( mc, props );
		}

		return def;
	}

	/**
	 * Returns whether the metafield is an auto id and is set prior to creation or update
	 */
	protected String getAutoGenerated( MetaField mf ) {
		return getPersistenceAttribute( mf, ObjectManager.AUTO );
	}


	/**
	 * Retrieves the fields of a MetaClass which are persistable
	 */
	/*public Collection getTableFields( MetaClass mc )
    {
        final String KEY = "getTableFields()";

        ArrayList fields = (ArrayList) mc.getCacheValue( KEY );

        if ( fields == null )
        {
	        fields = new ArrayList();

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

	        mc.setCacheValue( KEY, fields );
        }

        return fields;
    }*/


    /**
     * Retrieves the foreign keys defined in the specified MetaClass
     */
  /*public Collection getForeignKeys( MetaClass mc )
  {
    List fKeys = new ArrayList();

    for( MetaField mf : mc.getMetaFields() )
    {
      String fkey = getPersistenceAttribute( mf, FOREIGN_KEY_REF );
      if ( fkey != null )
      {
        int i = fkey.indexOf( "->" );
        if ( i <= 0 )
          throw new IllegalArgumentException( "Invalid Format for " + FOREIGN_KEY_REF + " parameter on MetaField [" + mf + "], no '->' found" );

        String packageName = mc.getPackage();
        String foreignClassStr = fkey.substring( 0, i );
        String foreignFieldStr = fkey.substring( i + 2 );
        MetaClass foreignClass = null;

          if ( foreignClassStr.length() > 0 )
          {
            // Try to find it with the name prepended if not fully qualified
            try {
              if ( foreignClassStr.indexOf( MetaClass.SEPARATOR ) < 0 && packageName.length() > 0 )
                foreignClass = MetaClass.forName( packageName + MetaClass.SEPARATOR + foreignClassStr );
            }
            catch( MetaClassNotFoundException e ) {
              log.debug( "Could not find ForeignKey MetaClass [" + packageName + MetaClass.SEPARATOR + foreignClassStr + "], assuming fully qualified" );
            }

            if ( foreignClass == null ) {
               foreignClass = MetaClass.forName( foreignClassStr );
            }
          }

          // REST HERE
          fKeys.add( new ForeignKeyDef( mf, foreignClass, foreignFieldStr ));
      }
    }

    return fKeys;
  }*/


    /*private boolean isViewOnly( MetaField mf )
    {
	    try {
	      if ( "true".equals( mf.getAttribute( IS_VIEWONLY ))) return true;
	    } catch( MetaAttributeNotFoundException e ) {}
	    return false;
    }*/

	/** Get the persistence attribute */
    private String getPersistenceAttribute( MetaData md, String ref ) {
    	if ( !md.hasAttribute( ref )) return null;
		Object r = md.getAttribute( ref );
		if ( r != null ) return r.toString();
		return null;
	}
    
    /**
     * Retrieves the table name from the MetaClass
     *
     * @return Returns the table name
     * @throws MetaException An exception is thrown if the object is not persistable
     */
    protected String getViewRef( MetaClass mc )
    {
      return getPersistenceAttribute( mc, VIEW_REF );
    }

	/**
     * Retrieves the SQL generation for the view
     *
     * @return Returns the SQL to create the view
     * @throws MetaException An exception is thrown if the object is not persistable
     */
    protected String getViewSQL( MetaClass mc )
    {
      return getPersistenceAttribute( mc, VIEW_SQL_REF );
    }

    /**
     * Retrieves the table name from the MetaClass
     *
     * @return Returns the table name
     * @throws MetaException An exception is thrown if the object is not persistable
     */
    protected String getTableRef( MetaClass mc )
    {
      return getPersistenceAttribute( mc, TABLE_REF );
    }

    /**
     * Retrieves the table column from the MetaField
     *
     * @return Returns the column name
     * @throws MetaException An exception is thrown if the column is not persistable
     */
    protected String getColumnRef( MetaField mf )
    {
      return getPersistenceAttribute( mf, COL_REF );
    }
    
    /**
     * Retrieves the sequence name for the MetaField
     *
     * @return Returns the sequence name
     * @throws MetaException An exception is thrown if the object is not persistable
     */
    public String getSequenceRef( MetaField mf )
    {
      return getPersistenceAttribute( mf, SEQ_REF );
    }

    /**
     * Retrieves the sequence name for the MetaField
     *
     * @return Returns the sequence name
     * @throws MetaException An exception is thrown if the object is not persistable
     */
    public int getSequenceStart( MetaField mf )
    {
      int start = 1;
      try {
        start = Integer.parseInt( getPersistenceAttribute( mf, SEQ_START_REF ));
      } catch( Exception e ) {}
      if ( start < 1 ) start = 1;
      return start;
    }

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

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy