Package bm.mvc

Source Code of bm.mvc.DefaultFieldResolver

package bm.mvc;
/* -----------------------------------------------------------------------------
    OpenBaseMovil User Interface Library
    Copyright (C) 2004-2008 Elondra S.L.

    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, see <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>.
----------------------------------------------------------------------------- */

import bm.core.Properties;
import bm.core.mvc.View;
import bm.core.io.SerializationException;
import bm.db.*;
import bm.storage.RSException;

import bm.storage.RecordStoreFullException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
/*
* File Information
*
* Created on       : 15-abr-2007 12:39:17
* Created by       : narciso
* Last modified by : $Author$
* Last modified on : $Date$
* Revision         : $Revision$
*/

/**
* Default field resolver tries to resolve fields using the view attachments and
* a map of field names to table name and field name.<br/>
* The map can be feeded manually or by means of a property file, using the
* format:<br/>
* <pre>
* toresolve.table=target table name
* toresolve.field=source field name
* toresolve.realName=field real name on the target table
* </pre>
* Where <i>toresolve</i> is the field name to resolve, the target table is the
* table that contains that field, and the source field is the name of the field
* in the source table that points to the target row (the foreign key).<br/>
* <b>Before using the DefaultFieldResolver, you must set the working database.</b>
*
* @author <a href="mailto:narciso@elondra.com">Narciso Cerezo</a>
* @version $Revision$
*/
public class DefaultFieldResolver
    implements FieldResolver
{
    private static DefaultFieldResolver instance = new DefaultFieldResolver();

    private static Database database;
    private static Properties definitions = new Properties();
    private static Hashtable cache = new Hashtable( 10 );

    public static DefaultFieldResolver getInstance()
    {
        return instance;
    }

    protected DefaultFieldResolver()
    {
    }

    /**
     * Register a definition from a resource in the class path.
     * @param resource resource path
     * @throws IOException on errors
     */
    public static void registerDefinition( final String resource )
            throws IOException
    {
        final Properties aux = new Properties();
        aux.load( aux.getClass().getResourceAsStream( resource ) );
        definitions.putAll( aux );
    }

    /**
     * Load a definition from an input stream and add it to the current ones.
     *
     * @param is input stream
     * @throws IOException on errors
     */
    public static void registerDefinition( final InputStream is )
            throws IOException
    {
        final Properties aux = new Properties( is );
        definitions.putAll( aux );
    }

    /**
     * Get the working database.
     * @return working database
     */
    public static Database getDatabase()
    {
        return database;
    }

    /**
     * Set the working database.
     * @param database working database
     */
    public static synchronized void setDatabase( final Database database )
    {
        DefaultFieldResolver.database = database;
    }

    /**
     * Resolve the field name for a given row.
     *
     * @param view view requesting resolution
     * @param fieldName field name
     * @param source    the row @return value or null if not known
     * @throws DBException      on errors
     * @throws RecordStoreFullException if no space left
     * @throws RSException on errors
     * @return resolved object, null if not found
     */
    public Object resolve( final View view, String fieldName, Row source )
            throws DBException,
                   RecordStoreFullException,
                   RSException
    {
        try
        {
            final Object attachment = view.getAttachment( fieldName );
            if( attachment != null )
            {
                return attachment;
            }

            final Properties definitions = DefaultFieldResolver.definitions;
            Row target = null;
            if( definitions.containsKey( fieldName + ".table" ) )
            {
                target = getTarget( fieldName, source );
            }
            try
            {
                return target != null ? target.getField(
                        definitions.containsKey( fieldName + ".realName" ) ?
                            definitions.getProperty( fieldName + ".realName" ) :
                            fieldName
                ) : null;
            }
            catch( InvalidFieldException e )
            {
                return null;
            }
        }
        catch( SerializationException e )
        {
            throw new DBException( e.getErrorNumber(), e );
        }
    }

    private Row getTarget( final String fieldName, final Row source )
            throws SerializationException, RecordStoreFullException,
                   DBException, RSException
    {
        final Properties definitions = DefaultFieldResolver.definitions;
        final Long targetId = (Long) source.getField(
                definitions.getProperty( fieldName + ".field" )
        );
        final String tableName =
                definitions.getProperty( fieldName + ".table" );
        if( targetId == null || tableName == null )
        {
            return null;
        }
        Row target = (Row) cache.get( tableName );
        if( target != null && target.getId() != targetId.longValue() )
        {
            target = null;
        }
        if( target == null )
        {
            target = lookUpEntity(
                    tableName,
                    targetId
            );
            if( target != null )
            {
                cache.put( tableName, target );
            }
        }
        return target;
    }

    private static Row lookUpEntity( final String tableName, final Long id )
            throws SerializationException,
                   RecordStoreFullException,
                   DBException,
                   RSException
    {
        final Table table = database.getTable( tableName.toLowerCase() );
        if( table != null )
        {
            final RowSet rowSet = table.find( "remote_id", id );
            if( rowSet != null && rowSet.size() > 0 )
            {
                rowSet.next();
                return rowSet.getCurrent();
            }
            else
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }
}
TOP

Related Classes of bm.mvc.DefaultFieldResolver

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.