Package com.scooterframework.orm.util

Source Code of com.scooterframework.orm.util.DataAccessUtil

/*
*   This software is distributed under the terms of the FSF
*   Gnu Lesser General Public License (see lgpl.txt).
*
*   This program is distributed WITHOUT ANY WARRANTY. See the
*   GNU General Public License for more details.
*/
package com.scooterframework.orm.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import com.scooterframework.admin.EnvConfig;
import com.scooterframework.common.util.BeanUtil;
import com.scooterframework.common.util.Converters;
import com.scooterframework.common.util.Message;
import com.scooterframework.common.validation.ValidationResults;
import com.scooterframework.orm.activerecord.ActiveRecord;
import com.scooterframework.orm.activerecord.ReferenceData;
import com.scooterframework.orm.activerecord.ReferenceDataStore;
import com.scooterframework.orm.sqldataexpress.object.ColumnInfo;
import com.scooterframework.orm.sqldataexpress.object.RESTified;
import com.scooterframework.orm.sqldataexpress.object.RowData;
import com.scooterframework.orm.sqldataexpress.object.RowInfo;
import com.scooterframework.orm.sqldataexpress.object.TableData;
import com.scooterframework.orm.sqldataexpress.object.TableInfo;

/**
* DataAccessUtil class has helper methods for objects including ActiveRecord
* and SQL data express related instances.
*
* @author (Fei) John Chen
*/
public class DataAccessUtil {
   
    /**
     * Gets property value from the object. The object can be of type
     * <tt>ActiveRecord</tt>, <tt>RowData</tt>, <tt>Properties</tt>,
     * <tt>Map</tt>, or simply a java bean (POJO).
     *
     * <p>
     * If the object is an ActiveRecord instance, and the property string
     * consists of dots, this method will treat the dotted string as a path
     * in association.
     * </p>
     *
     * <pre>
     * Examples:
     *     //post belongsTo user
     *     getProperty(post, "user.first_name")
     *     => returns first name of the post author
     *    
     *     //lineitem belongsTo order belongsTo customer
     *     getProperty(lineitem, "order.customer.first_name")
     *     => returns first name of the customer who ordered the line item
     * </pre>
     *
     * <p>
     * It is not recommended to use dotted property string unless you are sure
     * the object is in a belongs-to or has-one relation chain among all
     * elements of the dotted property string.
     * </p>
     *
     * @param object
     * @param property
     * @return Object
     */
    public static Object getProperty(Object object, String property) {
        if (object == null) return null;
        if (property == null) return object;
       
        Object data = null;
        if (object instanceof ActiveRecord) {
            data = getActiveRecordField((ActiveRecord)object, property);
        }
        else if (object instanceof RowData) {
            data = ((RowData)object).getField(property);
        }
        else if (object instanceof Properties) {
            data = ((Properties)object).getProperty(property);
        }
        else if (object instanceof Map) {
            data = ((Map<?, ?>)object).get(property);
        }
        else {
            data = BeanUtil.getBeanProperty(object, property);
        }
       
        return data;
    }
   
    /**
     * </p>
     * Returns field value of a record. If the property string consists of dots,
     * this method will treat the dotted string as a path in association.
     * </p>
     *
     * <pre>
     * Examples:
     *     //post belongsTo user
     *     getActiveRecordField(post, "user.first_name")
     *     => returns first name of the post author
     *    
     *     //lineitem belongsTo order belongsTo customer
     *     getActiveRecordField(lineitem, "order.customer.first_name")
     *     => returns first name of the customer who ordered the line item
     * </pre>
     *
     * <p>
     * It is not recommended to use dotted property string unless you are sure
     * the object is in a belongs-to or has-one relation chain among all
     * elements of the dotted property string.
     * </p>
     *
     * @param record
     * @param property
     * @return value of the property of the record
     */
    private static Object getActiveRecordField(ActiveRecord record, String property) {
        if (record == null) return null;
        if (property.indexOf('.') == -1) return record.getField(property);
       
        StringTokenizer st = new StringTokenizer(property, " .");
        int total = st.countTokens();
        Object tmp = null;
        int count = 0;
        ActiveRecord r = record;
        while(st.hasMoreTokens()) {
            String token = st.nextToken();
            count = count + 1;
            if (count == total) {
                tmp = r.getField(token);//The last token is a field name.
                break;
            }
            else {
                r = r.associated(token).getRecord();
            }
        }
       
        return tmp;
    }
   
    /**
     * Gets all the associated records of an ActiveRecord instance.
     *
     * <p>
     * If the <tt>associationName</tt> string consists of dots, this method
     * will treat the dotted string as a path in association.
     * </p>
     *
     * <pre>
     * Examples:
     *     //customer hasMany orders
     *     allAssociatedRecordsOf(customer, "orders")
     *     => returns a list of orders of the customer
     *    
     *     //customer hasMany orders hasMany lineitems
     *     allAssociatedRecordsOf(customer, "orders.lineitems")
     *     => returns a list of lineitems for all orders of the customer
     * </pre>
     *
     * <p>
     * It is not recommended to use dotted <tt>allAssociatedRecordsOf</tt> string
     * unless you are sure the object is in a hasMany or hasManyThrough relation
     * chain among all elements of the dotted string.
     * </p>
     *
     * @param record an ActiveRecord instance.
     * @param associationName association name.
     * @return list of associated records.
     */
    public static List<ActiveRecord> allAssociatedRecordsOf(ActiveRecord record, String associationName) {
        return allAssociatedRecordsOf(record, associationName, false);
    }
   
    /**
     * Gets all the associated records of an ActiveRecord instance.
     *
     * <p>See description of {@link #allAssociatedRecordsOf(com.scooterframework.orm.activerecord.ActiveRecord,
     * java.lang.String)} method for more details and examples.</p>
     *
     * @param record an ActiveRecord instance.
     * @param associationName association name.
     * @param refresh true if reload database data
     * @return list of associated records.
     */
    public static List<ActiveRecord> allAssociatedRecordsOf(ActiveRecord record, String associationName, boolean refresh) {
        if (record == null || associationName == null) return null;
        if (associationName.indexOf('.') == -1) return record.allAssociated(associationName, refresh).getRecords();
       
        List<String> associations = Converters.convertStringToList(associationName, ".");
        int totalAssociations = associations.size();
        List<ActiveRecord> records = record.allAssociated((String)associations.get(0), refresh).getRecords();
        if (records == null) return null;
       
        for (int i = 1; i < totalAssociations; i++) {
            String associationId = associations.get(i);
            List<ActiveRecord> tmp = new ArrayList<ActiveRecord>();
            int totalRecords = records.size();
            for (int j = 0; j < totalRecords; j++) {
              ActiveRecord r = records.get(j);
              if (r == null) continue;
                List<ActiveRecord> rds = r.allAssociated(associationId, refresh).getRecords();
                if (rds != null && rds.size() > 0) tmp.addAll(rds);
            }
            records = tmp;
        }
       
        return records;
    }
   
    /**
     * Gets the associated record of an ActiveRecord instance.
     *
     * <p>
     * If the <tt>associationName</tt> string consists of dots, this method
     * will treat the dotted string as a path in association.
     * </p>
     *
     * <pre>
     * Examples:
     *     //post belongsTo user
     *     associatedRecordOf(post, "user")
     *     => returns the post author
     *    
     *     //lineitem belongsTo order belongsTo customer
     *     associatedRecordOf(lineitem, "order.customer")
     *     => returns the customer who ordered the line item
     * </pre>
     *
     * <p>
     * It is not recommended to use dotted <tt>associationName</tt> string
     * unless you are sure the object is in a belongs-to or has-one relation
     * chain among all elements of the dotted string.
     * </p>
     *
     * @param record an ActiveRecord instance.
     * @param associationName association name.
     * @return the associated record
     */
    public static ActiveRecord associatedRecordOf(ActiveRecord record, String associationName) {
        return associatedRecordOf(record, associationName, false);
    }
   
    /**
     * Gets the associated record of an ActiveRecord instance.
     *
     * <p>See description of {@link #associatedRecordOf(com.scooterframework.orm.activerecord.ActiveRecord,
     * java.lang.String)} method for more details and examples.</p>
     *
     * @param record an ActiveRecord instance.
     * @param associationName association name.
     * @param refresh true if reload database data
     * @return the associated record
     */
    public static ActiveRecord associatedRecordOf(ActiveRecord record, String associationName, boolean refresh) {
        if (record == null || associationName == null) return null;
       
        if (associationName.indexOf('.') == -1) return record.associated(associationName, refresh).getRecord();
       
        StringTokenizer st = new StringTokenizer(associationName, ".");
        int total = st.countTokens();
        int count = 0;
        ActiveRecord r = record;
        while(st.hasMoreTokens()) {
            String token = st.nextToken();
            r = r.associated(token, refresh).getRecord();
           
            count = count + 1;
            if (count == total) {
                break;
            }
        }
       
        return r;
    }
   
    /**
     * Returns all error messages associated with a record instance.
     *
     * @param record an ActiveRecord instance
     * @return List of error messages.
     */
    public static List<Message> getErrorMessages(ActiveRecord record) {
        if (record != null) {
            ValidationResults vr = record.getValidationResults();
            if (vr.failed()) {
                return vr.getErrorMessages();
            }
        }
        return null;
    }
   
    /**
     * Gets a list of ReferenceData instances for a certain type.
     *
     * @return List
     */
    public static List<ReferenceData> getReferenceDataList(String type) {
        return ReferenceDataStore.getReferenceDataList(type);
    }
   
    /**
     * Gets ReferenceData by type and key
     *
     * @return  ReferenceData
     */
    public static ReferenceData getReferenceDataByTypeAndKey(String type, String keyData) {
        return ReferenceDataStore.getReferenceDataByTypeAndKey(type, keyData);
    }
   
    /**
     * Gets ReferenceData by type and value
     *
     * @return  ReferenceData
     */
    public static ReferenceData getReferenceDataByTypeAndValue(String type, Object valueData) {
        return ReferenceDataStore.getReferenceDataByTypeAndValue(type, valueData);
    }
   
    /**
     * Returns home instance of the model.
     *
     * @param model model name
     * @return home instance of the model
     */
    public static ActiveRecord homeInstance(String model) {
        return EnvConfig.getInstance().getHomeInstance(model);
    }
   
    /**
     * <p>
     * Returns an iterator of column names of the model. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param model model name
     * @return iterator
     */
    public static Iterator<String> columnNames(String model) {
        return columnNames(homeInstance(model));
    }
   
    /**
     * <p>
     * Returns an iterator of column names of the record. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param record an active record instance or home instance
     * @return iterator
     */
    public static Iterator<String> columnNames(ActiveRecord record) {
        return (record != null)?columnNames(record.getRowInfo()):(new ArrayList<String>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of column names. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param rowInfo a RowInfo instance
     * @return iterator
     */
    public static Iterator<String> columnNames(RowInfo rowInfo) {
        Iterator<String> it = null;
        if (rowInfo != null) {
            String[] columnNames = rowInfo.getColumnNames();
            it = Converters.convertArrayToList(columnNames).iterator();
        }
        else {
            it = (new ArrayList<String>()).iterator();
        }
        return it;
    }
   
    /**
     * <p>
     * Returns an iterator of column names. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param td a TableData instance
     * @return iterator
     */
    public static Iterator<String> columnNames(TableData td) {
        return (td != null)?columnNames(td.getHeader()):(new ArrayList<String>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of column names. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param rd a RowData instance
     * @return iterator
     */
    public static Iterator<String> columnNames(RowData rd) {
        return (rd != null)?columnNames(rd.getRowInfo()):(new ArrayList<String>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of column names. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param record    a restified record
     * @return iterator
     */
    public static Iterator<String> columnNames(RESTified record) {
        if (record != null) {
            if (record instanceof ActiveRecord) return columnNames((ActiveRecord)record);
            if (record instanceof RowData) return columnNames((RowData)record);
        }
        return (new ArrayList<String>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of column names of the record in the <tt>records</tt>
     * collection. This is a safe method. If input record is null, an empty
     * iterator is still returned.
     * </p>
     *
     * @param records a collection of records
     * @return iterator
     */
    public static Iterator<String> columnNames(Collection<?> records) {
        Object record = null;
        if (records != null) {
            Iterator<?> it = records.iterator();
            if (it.hasNext()) record = it.next();
        }
       
        if (record instanceof ActiveRecord) return columnNames((ActiveRecord)record);
        if (record instanceof RowData) return columnNames((RowData)record);
        return (new ArrayList<String>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances of the model. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param model model name
     * @return iterator
     */
    public static Iterator<ColumnInfo> columns(String model) {
        return columns(homeInstance(model));
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances of the record. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param record an ActiveRecord record instance or home instance
     * @return an iterator of ColumnInfo instances
     */
    public static Iterator<ColumnInfo> columns(ActiveRecord record) {
        return (record != null)?columns(record.getRowInfo()):(new ArrayList<ColumnInfo>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param rowInfo a RowInfo instance
     * @return iterator
     */
    public static Iterator<ColumnInfo> columns(RowInfo rowInfo) {
        Iterator<ColumnInfo> it = null;
        if (rowInfo != null) {
            it = rowInfo.columns().iterator();
        }
       
        if (it == null) {
            it = (new ArrayList<ColumnInfo>()).iterator();
        }
        return it;
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances of the record. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param record    a restified record
     * @return an iterator of ColumnInfo instances
     */
    public static Iterator<ColumnInfo> columns(RESTified record) {
        if (record != null) {
            if (record instanceof ActiveRecord) return columns((ActiveRecord)record);
            if (record instanceof RowData) return columns((RowData)record);
        }
        return (new ArrayList<ColumnInfo>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances of the record. This is a safe
     * method. If input record is null, an empty iterator is still returned.
     * </p>
     *
     * @param rd a RowData record instance
     * @return an iterator of ColumnInfo instances
     */
    public static Iterator<ColumnInfo> columns(RowData rd) {
        return (rd != null)?columns(rd.getRowInfo()):(new ArrayList<ColumnInfo>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of ColumnInfo instances of the <tt>records</tt>
     * collection. This is a safe method. If input record is null, an empty
     * iterator is still returned.
     * </p>
     *
     * @param records a collection of records
     * @return an iterator of ColumnInfo instances
     */
    public static Iterator<ColumnInfo> columns(Collection<?> records) {
        Object record = null;
        if (records != null) {
            Iterator<?> it = records.iterator();
            if (it.hasNext()) record = it.next();
        }
       
        if (record instanceof ActiveRecord) return columns((ActiveRecord)record);
        if (record instanceof RowData) return columns((RowData)record);
        return (new ArrayList<ColumnInfo>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of a collection. This is a safe method. If the
     * collection is null, an empty iterator is still returned.
     * </p>
     *
     * @param items a collection of items
     * @return an iterator of the collection
     */
    public static <T> Iterator<T> iteratorOf(Collection<T> items) {
        return (items != null)?items.iterator():(new ArrayList<T>()).iterator();
    }
   
    /**
     * <p>
     * Returns an iterator of a map. This is a safe method. If the
     * map is null, an empty iterator is still returned.
     * </p>
     *
     * @param map a map
     * @return an iterator of the collection
     */
    public static <K, V> Iterator<K> iteratorOf(Map<K, V> map) {
        return (map != null)?map.keySet().iterator():(new ArrayList<K>()).iterator();
    }
   
    /**
     * <p>
     * Returns a RowInfo instance of the model. This is a safe
     * method. If input model is null, an empty RowInfo instance is still returned.
     * </p>
     *
     * @param model model name
     * @return RowInfo for the model
     */
    public static RowInfo getRowInfo(String model) {
        RowInfo ri = homeInstance(model).getRowInfo();
        return (ri != null)?ri:(new RowInfo());
    }
   
    /**
     * Returns restful id of the record. If it is null, return empty string.
     *
     * @param record a RESTified record
     * @return restful id of the record.
     */
    public static String restfulIdOf(RESTified record) {
        return (record != null)?record.getRestfulId():"";
    }
   
    /**
     * Returns RowInfo attribute of the record.
     *
     * @param record a record object
     * @return RowInfo attribute of the record.
     */
    public static RowInfo rowInfoOf(ActiveRecord record) {
        return (record != null)?record.getRowInfo():(new RowInfo());
    }
   
    /**
     * Returns RowInfo attribute of the record.
     *
     * @param record a record object
     * @return RowInfo attribute of the record.
     */
    public static RowInfo rowInfoOf(RowData record) {
        return (record != null)?record.getRowInfo():(new RowInfo());
    }
   
    /**
     * Returns RowInfo attribute of the TableData instance.
     *
     * @param tableData a TableData object
     * @return RowInfo attribute of the record.
     */
    public static RowInfo rowInfoOf(TableData tableData) {
        return (tableData != null)?tableData.getHeader():(new RowInfo());
    }
   
    /**
     * Returns RowInfo attribute of the TableInfo instance.
     *
     * @param tableInfo a TableInfo object
     * @return RowInfo attribute of the record.
     */
    public static RowInfo rowInfoOf(TableInfo tableInfo) {
        return (tableInfo != null)?tableInfo.getHeader():(new RowInfo());
    }
}
TOP

Related Classes of com.scooterframework.orm.util.DataAccessUtil

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.