Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014-2015 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.s2dao.extension;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
The DBFlute extension of relation row creator.

Author(s):
jflute
 
 
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           =========
     protected final TnRelationRowOptionalHandler _optionalHandler;
 
     // ===================================================================================
     //                                                                         Constructor
     //                                                                         ===========
     public TnRelationRowCreatorExtension(TnRelationRowOptionalHandler optionalHandler) {
          = optionalHandler;
     }
 
         return new TnRelationRowCreatorExtension(optionalHandler);
     }
 
     // ===================================================================================
     //                                                             Relation KeyValue Setup
     //                                                             =======================
     @Override
     protected void setupRelationKeyValue(TnRelationRowCreationResource res) {
         // /= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
         // setup of relation key is handled at all-value setup marked as '#RELKEY'
         // so only entity instance creation exists in this method
         // = = = = = = = = = =/
         final TnRelationPropertyType rpt = res.getRelationPropertyType();
         final TnBeanMetaData yourBmd = rpt.getYourBeanMetaData();
         if (!res.hasRowInstance()) { // always no instance here (check just in case)
             final DBMeta dbmeta = yourBmd.getDBMeta();
             final Object row = newRelationRow(rptres.getRelationSelector(), res.getRelationNoSuffix(), dbmeta);
             res.setRow(row);
         }
     }
 
     protected Object newRelationRow(TnRelationPropertyType rptTnRelationSelector selectorString relationNoSuffixDBMeta dbmeta) {
         final Object row;
         if (dbmeta != null) {
             final Entity entity = dbmeta.newEntity();
             reflectConditionBeanOptionToEntity(selectorrelationNoSuffixentity);
             row = entity;
         } else { // no way (relation of DBFlute entity is only supported)
             row = newNonEntityRelationRow(rpt);
         }
         return row;
     }
 
     protected void reflectConditionBeanOptionToEntity(TnRelationSelector selectorString relationNoSuffixEntity entity) {
         // unlock access to undefined classification if allowed in condition-bean
         // this should be set before mapping values (and also base-point table's creator)
         if (selector.isUndefinedClassificationSelectAllowed(relationNoSuffix)) {
             entity.myunlockUndefinedClassificationAccess();
        }
    }
    protected Object newNonEntityRelationRow(TnRelationPropertyType rpt) { // for non DBFlute entity
        return DfReflectionUtil.newInstance(rpt.getPropertyDesc().getPropertyType());
    }
    // ===================================================================================
    //                                                             Relation AllValue Setup
    //                                                             =======================
    @Override
    protected void setupRelationAllValue(TnRelationRowCreationResource resthrows SQLException {
        final Map<StringTnPropertyMappingpropertyCacheElement = res.extractPropertyCacheElement();
        for (Entry<StringTnPropertyMappingentry : propertyCacheElement.entrySet()) {
            final TnPropertyMapping pt = entry.getValue();
            res.setCurrentPropertyType(pt);
            if (!isValidRelationPerPropertyLoop(res)) { // no way unless the method is overridden
                res.clearRowInstance();
                return;
            }
            setupRelationProperty(res);
        }
        if (!isValidRelationAfterPropertyLoop(res)) { // e.g. when all values are null
            res.clearRowInstance();
            return;
        }
        res.clearValidValueCount();
        if (res.isStopNextRelationMapping()) {
            return;
        }
        setupNextRelationRow(res);
    }
    protected void setupRelationProperty(TnRelationRowCreationResource resthrows SQLException {
        final String columnName = res.buildRelationColumnName();
        // already created here, this is old S2Dao logic 
        //if (!res.hasRowInstance()) {
        //    res.setRow(newRelationRow(res));
        //}
        registerRelationValue(rescolumnName);
    }
    protected void registerRelationValue(TnRelationRowCreationResource resString columnNamethrows SQLException {
        final TnPropertyMapping mapping = res.getCurrentPropertyMapping();
        Object value = null;
        if (res.containsRelationKeyColumn(columnName)) { // #RELKEY
            // if this column is relation key, it gets the value from relation key values
            // for performance and avoiding twice getting same column value
            value = res.extractRelationKeyValue(columnName);
        } else {
            final ValueType valueType = mapping.getValueType();
            final Map<StringMap<StringInteger>> selectIndexMap = res.getSelectIndexMap();
            final ResultSet rs = res.getResultSet();
            if (selectIndexMap != null) {
                final String relationNoSuffix = res.getRelationNoSuffix();
                value = ResourceContext.getRelationValue(rsrelationNoSuffixcolumnNamevalueTypeselectIndexMap);
            } else {
                value = valueType.getValue(rscolumnName);
            }
        }
        handleRelationValueRegistration(resmappingvalue);
    }
        if (value != null) {
            res.incrementValidValueCount();
        }
        // null is also set to trace modified properties for specified properties
        // little performance cost because only setupSelect and specified columns are here
        // (no setupSelect relation does not come here: old days, S2Dao might be possible)
        doRegisterRelationValue(resmappingvalue);
    }
    protected void doRegisterRelationValue(TnRelationRowCreationResource resTnPropertyMapping mappingObject value) {
        final ColumnInfo columnInfo = mapping.getEntityColumnInfo();
        if (columnInfo != null) {
            columnInfo.write((Entityres.getRow(), value);
        } else {
            mapping.getPropertyAccessor().setValue(res.getRow(), value);
        }
    }
    // -----------------------------------------------------
    //                                         Next Relation
    //                                         -------------
    protected void setupNextRelationRow(TnRelationRowCreationResource resthrows SQLException {
        final TnBeanMetaData nextBmd = res.getRelationBeanMetaData();
        final Object row = res.getRow();
        res.prepareNextLevelMapping();
        try {
            final List<TnRelationPropertyTypenextRptList = nextBmd.getRelationPropertyTypeList();
            for (TnRelationPropertyType nextRpt : nextRptList) {
                setupNextRelationRowElement(resrownextRpt);
            }
        } finally {
            res.setRow(row);
            res.closeNextLevelMapping();
        }
    }
            throws SQLException {
        res.prepareNextRelationProperty(nextRpt);
        try {
            mappingNextRelation(resrow);
        } finally {
            res.closeNextRelationProperty();
        }
    }

    
Do mapping next relation row.
This logic is similar to first relation mapping in org.dbflute.s2dao.rshandler.TnBeanListResultSetHandler.
So you should check it when this logic has modification.

Parameters:
res The resource of relation row creation. (NotNull)
row The base point row, which is previous relation row. (NotNull)
Throws:
java.sql.SQLException When it fails to handle the SQL.
    protected void mappingNextRelation(TnRelationRowCreationResource resObject rowthrows SQLException {
        if (res.isStopCurrentRelationMapping()) {
            return;
        }
        final TnRelationKey relKey = res.prepareRelationKey(); // also saves it in resource
        final TnRelationPropertyType rpt = res.getRelationPropertyType();
        Object relationRow = null;
        if (relKey != null) {
            final String relationNoSuffix = res.getRelationNoSuffix();
            final boolean canUseRelationCache = res.canUseRelationCache();
            TnRelationRowCache relRowCache = null;
            if (canUseRelationCache) {
                relRowCache = res.getRelRowCache();
                relationRow = relRowCache.getRelationRow(relationNoSuffixrelKey);
            }
            if (relationRow == null) { // when no cache
                relationRow = createRelationRow(res);
                if (relationRow != null) { // is new created relation row
                    adjustCreatedRelationRow(relationRowres.getRelationNoSuffix(), res.getRelationSelector(), rpt);
                    if (canUseRelationCache) {
                        relRowCache.addRelationRow(relationNoSuffixrelKeyrelationRow);
                    }
                }
            }
        }
        // if exists, optional or plain value
        // if null, empty optional or nothing
        relationRow = filterOptionalRelationRowIfNeeds(rowrptrelationRow);
        if (relationRow != null) { // exists or empty optional
            rpt.getPropertyAccessor().setValue(rowrelationRow);
        }
    }

    
Adjust created row for relation tables.

Parameters:
relationRow The relation row of tables related to the base-point table. (NotNull)
relationNoSuffix The suffix of relation no, e.g. _0, _1_3. (NotNull)
relSelector The selector of relation, which has various determination. (NotNull)
rpt The property type of the relation. (NotNull)
    public static void adjustCreatedRelationRow(Object relationRowString relationNoSuffixTnRelationSelector relSelector,
            TnRelationPropertyType rpt) {
        // static for also handler calling
        // *similar implementation for base-point row exists, see it for the details
        if (relationRow instanceof Entity) {
            final Entity entity = (EntityrelationRow;
            // check access to non-specified-column
            if (!relSelector.isNonSpecifiedColumnAccessAllowed(relationNoSuffix// not allowed
                    && relSelector.isUsingSpecifyColumnInRelation(relationNoSuffix)) { // and use SpecifyColumn
                entity.modifiedToSpecified(); // so check it
                // adjust specification for column null object handling
                final Set<ColumnInfonullObjectColumnSet = relSelector.getRelationSpecifiedNullObjectColumnSet(relationNoSuffix);
                for (ColumnInfo columnInfo : nullObjectColumnSet) { // might be empty loop if no null object
                    entity.myspecifyProperty(columnInfo.getPropertyName());
                }
            }
            // enable the handling of column null object if allowed and object-able
            if (relSelector.isColumnNullObjectEnabled(relationNoSuffix) && entity instanceof ColumnNullObjectable) {
                ((ColumnNullObjectableentity).enableColumnNullObject();
            }
            // clear modified properties for update process using selected entity
            entity.clearModifiedInfo();
            // mark as select to determine the entity is selected or user-created
            // basically for e.g. determine columns of batch insert
            entity.markAsSelect();
        } else { // not DBFlute entity
            // actually any bean meta data can be accepted
            // because only it gets modified properties
            rpt.getYourBeanMetaData().getModifiedPropertyNames(relationRow).clear();
        }
    }
    // ===================================================================================
    //                                                                Property Cache Setup
    //                                                                ====================
    @Override
    protected void setupPropertyCache(TnRelationRowCreationResource resthrows SQLException {
        // - - - - - - - - - - - 
        // Recursive Call Point!
        // - - - - - - - - - - -
        if (res.isStopCurrentRelationMapping()) {
            return;
        }
        // set up property cache about current bean meta data
        final TnBeanMetaData nextBmd = res.getRelationBeanMetaData();
        final List<TnPropertyTypeptList = nextBmd.getPropertyTypeList();
        for (TnPropertyType pt : ptList) { // already been filtered as target only
            res.setCurrentPropertyType(pt);
            setupPropertyCacheElement(res);
        }
        // set up next level relation's property cache
        if (res.isStopNextRelationMapping()) {
            return;
        }
        res.prepareNextLevelMapping();
        try {
            setupNextPropertyCache(resnextBmd);
        } finally {
            res.closeNextLevelMapping();
        }
    }
    // -----------------------------------------------------
    //                                         Next Relation
    //                                         -------------
    protected void setupNextPropertyCache(TnRelationRowCreationResource resTnBeanMetaData nextBmdthrows SQLException {
        final List<TnRelationPropertyTypenextRptList = nextBmd.getRelationPropertyTypeList();
        for (TnRelationPropertyType nextRpt : nextRptList) {
            setupNextPropertyCacheElement(resnextRpt);
        }
    }
        res.prepareNextRelationProperty(nextRpt);
        try {
            setupPropertyCache(res); // recursive call
        } finally {
            res.closeNextRelationProperty();
        }
    }
    // ===================================================================================
    //                                                                     Option Override
    //                                                                     ===============
    @Override
    protected boolean isCreateDeadLink() {
        return false// DBFlute does not create dead-link relation, treated as null
    }
    @Override
    protected int getLimitRelationNestLevel() {
        // basically unused on DBFlute because only ConditionBean uses relation row,
        // and ConditionBean supports unlimited relation nest level
        // so this limit size is always used after hasConditionBean()
        return 2; // for Compatible (old parameter)
    }
    // ===================================================================================
    //                                                                   Optional Handling
    //                                                                   =================
    public Object filterOptionalRelationRowIfNeeds(Object rowTnRelationPropertyType rptObject relationRow) {
        return .filterOptionalRelationRowIfNeeds(rowrptrelationRow);
    }
New to GrepCode? Check out our FAQ X