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

org.dbflute.dbmeta.info.ReferrerInfo Maven / Gradle / Ivy

There is a newer version: 1.2.8
Show newest version
/*
 * Copyright 2014-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.dbflute.dbmeta.info;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.dbflute.Entity;
import org.dbflute.dbmeta.DBMeta;
import org.dbflute.dbmeta.property.PropertyMethodFinder;
import org.dbflute.util.DfReflectionUtil;
import org.dbflute.util.Srl;

/**
 * The information of referrer relation.
 * @author jflute
 */
public class ReferrerInfo implements RelationInfo {

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    protected final String _constraintName;
    protected final String _referrerPropertyName;
    protected final DBMeta _localDBMeta;
    protected final DBMeta _referrerDBMeta;
    protected final Map _localReferrerColumnInfoMap;
    protected final Map _referrerLocalColumnInfoMap;
    protected final Class _objectNativeType; // always entity type, provided by DB meta
    protected final Class _propertyAccessType; // basically list type
    protected final boolean _oneToOne;
    protected final String _reversePropertyName;
    protected final PropertyMethodFinder _propertyMethodFinder;
    protected final Method _readMethod;
    protected final Method _writeMethod;

    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    public ReferrerInfo(String constraintName, String referrerPropertyName // name
            , DBMeta localDBMeta, DBMeta referrerDBMeta // DB meta
            , Map localReferrerColumnInfoMap // relation attribute
            , Class propertyAccessType // property info (object native type is provided by DB meta)
            , boolean oneToOne // relation type
            , String reversePropertyName, PropertyMethodFinder propertyMethodFinder // various info
    ) { // big constructor
        assertObjectNotNull("constraintName", constraintName);
        assertObjectNotNull("referrerPropertyName", referrerPropertyName);
        assertObjectNotNull("localDBMeta", localDBMeta);
        assertObjectNotNull("referrerDBMeta", referrerDBMeta);
        assertObjectNotNull("localReferrerColumnInfoMap", localReferrerColumnInfoMap);
        assertObjectNotNull("propertyAccessType", propertyAccessType);
        assertObjectNotNull("propertyMethodFinder", propertyMethodFinder);
        _constraintName = constraintName;
        _referrerPropertyName = referrerPropertyName;
        _localDBMeta = localDBMeta;
        _referrerDBMeta = referrerDBMeta;
        _localReferrerColumnInfoMap = Collections.unmodifiableMap(localReferrerColumnInfoMap);
        final Map referrerLocalColumnInfoMap = new LinkedHashMap(4);
        for (Entry entry : localReferrerColumnInfoMap.entrySet()) {
            referrerLocalColumnInfoMap.put(entry.getValue(), entry.getKey());
        }
        _referrerLocalColumnInfoMap = Collections.unmodifiableMap(referrerLocalColumnInfoMap);
        _objectNativeType = referrerDBMeta.getEntityType();
        _propertyAccessType = propertyAccessType;
        _oneToOne = oneToOne;
        _reversePropertyName = reversePropertyName;
        // referrer property is not accessed in runtime so it doesn't need
        // (and don't want DB meta to be fat)
        //_propertyGateway = findPropertyGateway();
        _propertyMethodFinder = propertyMethodFinder;
        _readMethod = findReadMethod();
        _writeMethod = findWriteMethod();
    }

    // ===================================================================================
    //                                                                    Column Existence
    //                                                                    ================
    public boolean containsLocalColumn(ColumnInfo localColumn) {
        return doContainsLocalColumn(localColumn.getColumnDbName());
    }

    protected boolean doContainsLocalColumn(String columnName) {
        for (ColumnInfo columnInfo : _localReferrerColumnInfoMap.keySet()) {
            if (columnInfo.getColumnDbName().equals(columnName)) {
                return true;
            }
        }
        return false;
    }

    public boolean containsReferrerColumn(ColumnInfo referrerColumn) {
        return doContainsReferrerColumn(referrerColumn.getColumnDbName());
    }

    protected boolean doContainsReferrerColumn(String columnName) {
        for (ColumnInfo columnInfo : _referrerLocalColumnInfoMap.keySet()) {
            if (columnInfo.getColumnDbName().equals(columnName)) {
                return true;
            }
        }
        return false;
    }

    // ===================================================================================
    //                                                                      Column Mapping
    //                                                                      ==============
    public ColumnInfo findLocalByReferrer(String referrerColumnDbName) {
        final ColumnInfo keyColumnInfo = _referrerDBMeta.findColumnInfo(referrerColumnDbName);
        final ColumnInfo resultColumnInfo = (ColumnInfo) _referrerLocalColumnInfoMap.get(keyColumnInfo);
        if (resultColumnInfo == null) {
            String msg = "Not found by referrerColumnDbName in referrerLocalColumnInfoMap:";
            msg = msg + " referrerColumnDbName=" + referrerColumnDbName;
            msg = msg + " referrerLocalColumnInfoMap=" + _referrerLocalColumnInfoMap;
            throw new IllegalArgumentException(msg);
        }
        return resultColumnInfo;
    }

    public ColumnInfo findReferrerByLocal(String localColumnDbName) {
        final ColumnInfo keyColumnInfo = _localDBMeta.findColumnInfo(localColumnDbName);
        final ColumnInfo resultColumnInfo = (ColumnInfo) _localReferrerColumnInfoMap.get(keyColumnInfo);
        if (resultColumnInfo == null) {
            String msg = "Not found by localColumnDbName in localReferrerColumnInfoMap:";
            msg = msg + " localColumnDbName=" + localColumnDbName;
            msg = msg + " localReferrerColumnInfoMap=" + _localReferrerColumnInfoMap;
            throw new IllegalArgumentException(msg);
        }
        return resultColumnInfo;
    }

    // ===================================================================================
    //                                                                          Reflection
    //                                                                          ==========
    // -----------------------------------------------------
    //                                                  Read
    //                                                  ----
    /**
     * Read the value to the entity. 
* It returns plain value in entity as property access type. * @param The type of property, basically entity list. * @param localEntity The local entity of this column to read. (NotNull) * @return The read instance of referrer entity. (NullAllowed) */ @SuppressWarnings("unchecked") public PROPERTY read(Entity localEntity) { return (PROPERTY) invokeMethod(getReadMethod(), localEntity, new Object[] {}); } /** * Get the read method for entity reflection. * @return The read method, cached in this instance. (NotNull) */ public Method getReadMethod() { return _readMethod; } // ----------------------------------------------------- //  Write // ----- /** * Write the value to the entity.
* No converting to anything so check the property access type. * @param localEntity The local entity of this column to write. (NotNull) * @param referrerEntityList The written list of referrer entity. (NullAllowed: if null, null written) */ public void write(Entity localEntity, Object referrerEntityList) { invokeMethod(getWriteMethod(), localEntity, new Object[] { referrerEntityList }); } /** * Get the write method for entity reflection. * @return The writer method, cached in this instance. (NotNull) */ public Method getWriteMethod() { return _writeMethod; } // ----------------------------------------------------- // Finder // ------ protected Method findReadMethod() { final Class localType = _localDBMeta.getEntityType(); return _propertyMethodFinder.findReadMethod(localType, _referrerPropertyName, _propertyAccessType); } protected Method findWriteMethod() { final Class localType = _localDBMeta.getEntityType(); return _propertyMethodFinder.findWriteMethod(localType, _referrerPropertyName, _propertyAccessType); } // ----------------------------------------------------- // Invoker // ------- protected Object invokeMethod(Method method, Object target, Object[] args) { return DfReflectionUtil.invoke(method, target, args); } // =================================================================================== // Relation Implementation // ======================= public String getRelationPropertyName() { return getReferrerPropertyName(); } public DBMeta getTargetDBMeta() { return getReferrerDBMeta(); } public Map getLocalTargetColumnInfoMap() { return getLocalReferrerColumnInfoMap(); } public boolean isReferrer() { return true; } // =================================================================================== // General Helper // ============== protected String initCap(final String name) { return Srl.initCap(name); } protected void assertObjectNotNull(String variableName, Object value) { if (variableName == null) { String msg = "The value should not be null: variableName=null value=" + value; throw new IllegalArgumentException(msg); } if (value == null) { String msg = "The value should not be null: variableName=" + variableName; throw new IllegalArgumentException(msg); } } // =================================================================================== // Basic Override // ============== @Override public int hashCode() { return _referrerPropertyName.hashCode() + _localDBMeta.hashCode() + _referrerDBMeta.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof ReferrerInfo)) { return false; } final ReferrerInfo target = (ReferrerInfo) obj; if (!this._referrerPropertyName.equals(target.getReferrerPropertyName())) { return false; } if (!this._localDBMeta.equals(target.getLocalDBMeta())) { return false; } if (!this._referrerDBMeta.equals(target.getReferrerDBMeta())) { return false; } return true; } @Override public String toString() { return "{" + _localDBMeta.getTableDbName() + "." + _referrerPropertyName + "<-" + _referrerDBMeta.getTableDbName() + "}"; } // =================================================================================== // Accessor // ======== /** {@inheritDoc} */ public String getConstraintName() { return _constraintName; } /** * Get the property name of the foreign relation.
* This is unique name in the table.
* For example, if the relation MEMBER and PURCHASE, this returns 'purchaseList'. * @return The string for property name. (NotNull) */ public String getReferrerPropertyName() { return _referrerPropertyName; } /** {@inheritDoc} */ public DBMeta getLocalDBMeta() { return _localDBMeta; } /** * Get the DB meta of the referrer table.
* For example, if the relation MEMBER and PURCHASE, this returns PURCHASE's one. * @return The DB meta singleton instance. (NotNull) */ public DBMeta getReferrerDBMeta() { return _referrerDBMeta; } /** * Get the read-only map, key is a local column info, value is a referrer column info. * @return The read-only map. (NotNull) */ public Map getLocalReferrerColumnInfoMap() { return _localReferrerColumnInfoMap; } /** * Get the read-only map, key is a referrer column info, value is a column column info. * @return The read-only map. (NotNull) */ public Map getReferrerLocalColumnInfoMap() { return _referrerLocalColumnInfoMap; } /** {@inheritDoc} */ public Class getObjectNativeType() { return _objectNativeType; } /** {@inheritDoc} */ public Class getPropertyAccessType() { return _propertyAccessType; } /** * {@inheritDoc}
* But basically this returns false because DBFlute treats one-to-one relations as a foreign relation. */ public boolean isOneToOne() { return _oneToOne; } /** {@inheritDoc} */ public RelationInfo getReverseRelation() { return _reversePropertyName != null ? _referrerDBMeta.findRelationInfo(_reversePropertyName) : null; } /** {@inheritDoc} */ public boolean isCompoundKey() { return getLocalReferrerColumnInfoMap().size() > 1; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy