AbstractPersistentObject.java :  » ERP-CRM-Financial » Personal-Finance-Manager » br » com » gfpshare » db » Java Open Source

Java Open Source » ERP CRM Financial » Personal Finance Manager 
Personal Finance Manager » br » com » gfpshare » db » AbstractPersistentObject.java
/*
 * Created on 22/05/2004
 * 
 * Swing Components - visit http://sf.net/projects/gfd
 * 
 * Copyright (C) 2004  Igor Regis da Silva Simes
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

package br.com.gfpshare.db;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Igor Regis da Silva Simoes
 */
public abstract class AbstractPersistentObject implements PersistentObject
{
    /**
     *
     */
    private SQLParser sqlParser = null;
    
    /**
     *
     */
    protected boolean autoPk = true;
    
    /**
     *
     */
    private static HashMap<String, ArrayList<String>> allColumns = new HashMap<String, ArrayList<String>>(7);
    
    /**
     * 
     */
    private static HashMap<String, ArrayList<String>> colunas = new HashMap<String, ArrayList<String>>(7);
  
    /**
     * 
     */
    private static HashMap<String, ArrayList<String>> pks = new HashMap<String, ArrayList<String>>(2);
  
  /**
     *
     */
    protected boolean[] crescente = null;
    
    /**
     *
     */
    private ArrayList<SQLCondition> condicoesExtras = new ArrayList<SQLCondition>();

    /**
     * 
     */
    private String resultadoDesejado = null;
    
    /**
     *
     */
    private String dataBase = null;
    
    /**
     * Dados a respeito da atual clausula de sql que ser executada por este persistent object
     */
    private ParsedPreparedStatement currentStatement = new ParsedPreparedStatement();
    
    /**
     *
     */
    public AbstractPersistentObject()
    {
      ArrayList<String> allColumns = new ArrayList<String>();
      allColumns.addAll(getColumnsName());
      allColumns.addAll(getPkNames());
        
        crescente = new boolean[allColumns.size()];

        for(int i=0; i<crescente.length; i++)
        {
            crescente[i] = true;
        }
        if (AbstractPersistentObject.allColumns.get(this.getClass().getName()) == null)
          AbstractPersistentObject.allColumns.put(this.getClass().getName(), allColumns);
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#getInsertSQL()
     */
    public final String getInsertSQL()
    {
        if (autoPk)
            currentStatement = getSqlParser().getInsertSQL(getTableName(), getAsMap(), getColumnsName());
        else
            currentStatement = getSqlParser().getInsertSQL(getTableName(), getAsMap(), AbstractPersistentObject.allColumns.get(this.getClass().getName()));
        return currentStatement.sql;
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#getUpdateSQL()
     */
    public final String getUpdateSQL()
    {
        if (autoPk)
            currentStatement = getSqlParser().getUpdateSQL(getTableName(), getAsMap(), getColumnsName(), getPkNames());
        else
            currentStatement = getSqlParser().getUpdateSQL(getTableName(), getAsMap(), AbstractPersistentObject.allColumns.get(this.getClass().getName()), getPkNames());
        return currentStatement.sql;
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#getSelectSQL()
     */
    public final String getSelectSQL()
    {
        condicoesExtras.trimToSize();
        currentStatement = getSqlParser().getSelectSQL(resultadoDesejado, getTableName(), getAsMap(), AbstractPersistentObject.allColumns.get(this.getClass().getName()), getOrderBy(), crescente, condicoesExtras);
        return currentStatement.sql;
    }

    /**
     * @see br.com.gfpshare.db.PersistentObject#getDeleteSQL()
     */
    public final String getDeleteSQL()
    {
        currentStatement = getSqlParser().getDeleteSQL(getTableName(), getAsMap(), AbstractPersistentObject.allColumns.get(this.getClass().getName()), condicoesExtras, getPkNames());
        return currentStatement.sql;
    }

    public ArrayList<Object> getParametrosSQL()
    {
        ArrayList<Object> retorno = new ArrayList<Object>();
        for (SQLCondition<Object> condicao : condicoesExtras)
        {
            if (condicao.getCondicao() != SQLCondition.Condicao.IS_NULL)
                retorno.add(condicao.getValor());
            if (condicao.getCondicao() == SQLCondition.Condicao.BETWEEN)
                retorno.add(condicao.getValor_2());
        }
        retorno.addAll(currentStatement.params);
        currentStatement = new ParsedPreparedStatement();
        return retorno;
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#setOrderBy(java.lang.String[])
     */
    public final void setOrderBy(String[] columns)
    {
        boolean swap;
        ArrayList<String> allColumns = AbstractPersistentObject.allColumns.get(getClass().getName());

        for(int n=columns.length-1; n>=0; n--)
        {
            for(int i=0; i<allColumns.size(); i++)
            {
                if (allColumns.get(i).toString().equals(columns[n]))
                {
                    swap = this.crescente[i];
                    
                    for(int j=i; j>0; j--)
                    {
                      String swap2 = allColumns.get(j-1);
                        allColumns.set(j-1, null);
                        allColumns.set(j, swap2);
                        this.crescente[j] = this.crescente[j-1];
                    }
                    
                    allColumns.set(0, columns[n]);
                    this.crescente[0] = !swap;
                }
            }
            
        }
        AbstractPersistentObject.allColumns.put(this.getClass().getName(), allColumns);
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#getOrderBy()
     */
    public final String[] getOrderBy()
    {
      ArrayList<String> allColumns = AbstractPersistentObject.allColumns.get(this.getClass().getName());
        return allColumns.toArray(new String[allColumns.size()]);
    }
    
    /*
     * @see br.com.igor.db.PersistentObject#addCondicaoExtra(java.lang.String)
     */
    public final void addCondicaoExtra(SQLCondition condicao)
    {
        condicoesExtras.add(condicao);
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#removeCondicaoExtra(java.lang.String)
     */
    public final void removeCondicaoExtra(SQLCondition condicao)
    {
        condicoesExtras.remove(condicao);
    }

    /**
     * Retorna o parser a ser usado na formulao do sql.
     * @return SQLParser.
     */
    private SQLParser getSqlParser()
    {
        if (sqlParser == null)
            sqlParser = SQLParserFactory.getSQLParserFactory().getParser(dataBase);
        return sqlParser;
    }
    
  /**
   * @see br.com.gfpshare.db.PersistentObject#setDataBase(java.lang.String)
   */
  public void setDataBase(String dataBase)
    {
        this.dataBase = dataBase;
    }
    
    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
        Map objetoMap = getAsMap();
        Object[] chaves = objetoMap.keySet().toArray();
        
        String representacao = getTableName();
        
        for (Object chave : chaves)
            if(objetoMap.get(chave) != null)
                representacao += ", " + chave + " = " + objetoMap.get(chave);

        return representacao;
    }
    
  /**
   * @see br.com.gfpshare.db.PersistentObject#getResultadoDesejado()
   */
  public String getResultadoDesejado()
  {
    return resultadoDesejado;
  }
  
  /*
   * @see br.com.igor.db.PersistentObject#setResultadoDesejado(java.lang.String)
   */
  public void setResultadoDesejado(String resultadoDesejado)
  {
    this.resultadoDesejado = resultadoDesejado;
  }

    /**
     * @see br.com.gfpshare.db.PersistentObject#getColumnsName()
     */
    public final ArrayList<String> getColumnsName()
    {
      ArrayList<String> colunas = AbstractPersistentObject.colunas.get(this.getClass().getName());
      if (colunas != null)
        return colunas;
      colunas = new ArrayList<String>();
      
        ArrayList<Field> fields = getAllDeclaredFields(Column.class);
        for (Field field : fields)
            if (!field.getAnnotation(Column.class).isPk())
                colunas.add(field.getAnnotation(Column.class).nome());
        
      AbstractPersistentObject.colunas.put(this.getClass().getName(), colunas);
        return colunas;
    }
    
    
  /**
   * @see br.com.gfpshare.db.PersistentObject#getPkNames()
   */
  public final ArrayList<String> getPkNames()
  {
      ArrayList<String> pks = AbstractPersistentObject.pks.get(this.getClass().getName());
      if (pks != null)
        return pks;
      pks = new ArrayList<String>();
      
        ArrayList<Field> fields = getAllDeclaredFields(Column.class);
        for (Field field : fields)
        {
            Column column = field.getAnnotation(Column.class);
            if (column.isPk())
            {
                pks.add(column.nome());
            }
        }
      
      AbstractPersistentObject.pks.put(this.getClass().getName(), pks);
        return pks;
  }
  
    /**
     * Retorna todos campos da calsse (incluindo superclasses) 
     * que possuam a anotao passada como parametro
     * @param annotation Anotao que os campos devem possuir para 
     *        retornarem no ArrayList
     * @return ArrayList com os atributos que atendem ao critrio
     */
    private ArrayList<Field> getAllDeclaredFields(Class<Column> annotation)
    {
        ArrayList<Field> fields = new ArrayList<Field>();
        Class<?> classe = getClass();
        
        while(classe.isAnnotationPresent(Table.class))
        {
            Field[] campo = classe.getDeclaredFields(); 
            for (int i = 0; i < campo.length; i++)
            {
                campo[i].getAnnotation(Column.class);
                if (campo[i].isAnnotationPresent(annotation))
                {
                    fields.add(campo[i]);
                }
            }
            classe = classe.getSuperclass();
            if (classe == null)
                throw new InvalidSubClassException("Your class must define a @Tabela anotation");
        }
        return fields;
    }
  
  /**
   * @see br.com.gfpshare.db.PersistentObject#getTableName()
   */
  public final String getTableName()
  {
        Class<?> classe = getClass();
        while(!classe.isAnnotationPresent(Table.class))
        {
            classe = classe.getSuperclass();
            if (classe == null)
                throw new InvalidSubClassException("Your class must define a @Tabela anotation");
        }
    return classe.getAnnotation(Table.class).name();
  }
  
    /**
     * @see br.com.gfpshare.db.PersistentObject#getAsMap()
     */
    public final Map<String, Object> getAsMap() throws DataAccessException 
    {
        HashMap<String, Object> dados = new HashMap<String, Object>();
        try{
            ArrayList<Field> fields = getAllDeclaredFields(Column.class);
            for (Field field : fields)
            {
                Column colunaAnnotation = field.getAnnotation(Column.class);
                dados.put(colunaAnnotation.nome(), getClass().getMethod(colunaAnnotation.readMethodName(),new Class[]{}).invoke(this,(Object[])null));
            }
    } catch (Exception e)
    {
      throw new DataAccessException("Problemas ao converter objeto para Map.", e);
    }
        return dados;
    }
    
    /**
     * @see br.com.gfpshare.db.PersistentObject#setDados(java.util.Map)
     */
    public void setDados(Map<String, Object> dados) throws DataAccessException
    {
        ArrayList<Field> fields = getAllDeclaredFields(Column.class);
      for (Field field: fields)
    {
            try{
                Column colunaAnnotation = field.getAnnotation(Column.class);

                Object valor = null;
                if ((valor = dados.get(colunaAnnotation.nome())) != null)
        {
                    //Os campos Float so uma exceo, caso ns no faamos a converso 
                    //explicita a JVM vai tentar pass-lo como Double para o mtodo causando uma exceo
                    if (field.getType().isAssignableFrom(Float.class))
                        getClass().getMethod(colunaAnnotation.writeMethodName(), Float.class).invoke(this,Float.valueOf(valor.toString()));
                    else
            getClass().getMethod(colunaAnnotation.writeMethodName(), field.getType()).invoke(this,valor);
        }
            } catch (Exception e)
            {
                throw new DataAccessException("Problemas ao converter Map para objeto, campo: " + field.getName(), e);
            }
    }
    }
    
    /**
     * @param sql
     * @param incluirWhere
     * @param incluirOrderBy
     * @return String
     */
    public String getSQL(String sql, boolean incluirWhere, boolean incluirOrderBy)
    {
        currentStatement = new ParsedPreparedStatement();
        if (incluirWhere)
        {
            ParsedPreparedStatement temp = ((AbstractSQLParser)getSqlParser()).getWhere(getAsMap(), AbstractPersistentObject.allColumns.get(this.getClass().getName()), " and ",  condicoesExtras);
            currentStatement.sql = sql + " " + temp.sql +
                (incluirOrderBy ? ((AbstractSQLParser)getSqlParser()).getOrderBy(getOrderBy(), crescente) : "");
            currentStatement.params = temp.params;
        }
        else
        {
            currentStatement.sql = sql + " " + 
                (incluirOrderBy ? ((AbstractSQLParser)getSqlParser()).getOrderBy(getOrderBy(), crescente) : "");
        }
    return getSqlParser().parse(currentStatement).sql;
    }
    
    public void clearAllFields()
    {
        currentStatement = new ParsedPreparedStatement();
        ArrayList<Field> fields = new ArrayList<Field>();
        Class classe = getClass();
        while(classe != AbstractPersistentObject.class)
        {
            Field[] campo = classe.getDeclaredFields(); 
            for (int i = 0; i < campo.length; i++)
            {
                fields.add(campo[i]);
            }
            classe = classe.getSuperclass();
            if (classe == null)
                throw new InvalidSubClassException("Your class must define a @Tabela anotation");
        }

        for (int i = 0; i < fields.size(); i++)
        {
            if (Modifier.isFinal(fields.get(i).getModifiers()))
                continue;
            fields.get(i).setAccessible(true);
            try
            {
                fields.get(i).set(this, null);
            }
            catch (IllegalArgumentException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IllegalAccessException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.