Package org.apache.isis.objectstore.sql.auto

Source Code of org.apache.isis.objectstore.sql.auto.PolymorphicForeignKeyInChildCollectionMapper

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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.apache.isis.objectstore.sql.auto;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.objectstore.sql.DatabaseConnector;
import org.apache.isis.objectstore.sql.FieldMappingLookup;
import org.apache.isis.objectstore.sql.IdMappingAbstract;
import org.apache.isis.objectstore.sql.ObjectMapping;
import org.apache.isis.objectstore.sql.ObjectMappingLookup;
import org.apache.isis.objectstore.sql.VersionMapping;
import org.apache.isis.objectstore.sql.mapping.FieldMapping;

/**
* Used to map 1-to-many collections by creating, in the child table, 1 column
* per parent collection. The column is named by combining the final part of the
* parent class name and the collection variable name.
*
* You have a choice between this class and
* {@link PolymorphicForeignKeyInChildCollectionBaseMapper}
*
* @author Kevin
*/
public class PolymorphicForeignKeyInChildCollectionMapper extends ForeignKeyInChildCollectionMapper {

    private static final Logger LOG = LoggerFactory.getLogger(PolymorphicForeignKeyInChildCollectionMapper.class);

    private final ObjectAssociation baseField;
    private final List<String> tables;
    private final List<ObjectSpecification> tableSpecifications;
    private final List<ObjectMapping> subClassMappers;

    // For iterating through the subclasses
    private ObjectSpecification currentTableSpecification;
    private Iterator<ObjectAdapter> currentIterator;
    private List<ObjectAdapter> currentCollection;
    private int currentIndexStart;
    private int currentIndex;

    // Store for passing on to other mappers
    final String parameterBase;
    final FieldMappingLookup lookup;
    final ObjectMappingLookup objectMapperLookup;
    final String fieldClassName;

    public PolymorphicForeignKeyInChildCollectionMapper(final ObjectAssociation objectAssociation, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup, final AbstractAutoMapper abstractAutoMapper, final ObjectAssociation field) {

        super(lookup, abstractAutoMapper, field);

        fieldClassName = className;

        baseField = objectAssociation;
        tables = new ArrayList<String>();
        tableSpecifications = new ArrayList<ObjectSpecification>();
        subClassMappers = new ArrayList<ObjectMapping>();

        // Capture for use in creating subclass mappers.
        this.parameterBase = parameterBase;
        this.lookup = lookup;
        this.objectMapperLookup = objectMapperLookup;

        addSubSpecificationsToTable(specification);
    }

    protected void addSubSpecificationsToTable(final ObjectSpecification objectSpecification) {
        if (objectSpecification.isAbstract() == false) {
            final String tableNameFromSpecification = getTableNameFromSpecification(objectSpecification);
            tables.add(tableNameFromSpecification);
            tableSpecifications.add(objectSpecification);

            final ObjectMapping autoMapper = objectMapperLookup.getMapping(objectSpecification, null);
            subClassMappers.add(autoMapper);
        }
        if (objectSpecification.hasSubclasses()) {
            for (final ObjectSpecification subSpecification : objectSpecification.subclasses()) {
                addSubSpecificationsToTable(subSpecification);
            }
        }
    }

    @Override
    public boolean needsTables(final DatabaseConnector connection) {
        for (final String subTableName : tables) {
            table = subTableName;
            if (super.needsTables(connection)) {
                // Stop on first table that is needed.
                return true;
            }
        }
        return false;
    }

    @Override
    public void createTables(final DatabaseConnector connection) {
        for (final String subTableName : tables) {
            table = subTableName;
            if (super.needsTables(connection)) {
                super.createTables(connection);
            }
        }
    }

    @Override
    protected Iterator<ObjectAdapter> getElementsForCollectionAsIterator(final ObjectAdapter collection) {
        return currentIterator;
    }

    @Override
    public void saveInternalCollection(final DatabaseConnector connector, final ObjectAdapter parent) {
        final ObjectAdapter collection = baseField.get(parent);
        LOG.debug("Saving polymorphic internal collection " + collection);

        currentCollection = new ArrayList<ObjectAdapter>();
        currentIterator = super.getElementsForCollectionAsIterator(collection);
        for (; currentIterator.hasNext();) {
            final ObjectAdapter item = currentIterator.next();
            currentCollection.add(item);
        }

        for (int i = 0; i < tables.size(); i++) {
            currentTableSpecification = tableSpecifications.get(i);
            currentIndex = 0;
            currentIndexStart = 0;

            currentIterator = new Iterator<ObjectAdapter>() {
                @Override
                public boolean hasNext() {
                    for (int i = currentIndexStart; i < currentCollection.size(); i++) {
                        final ObjectAdapter thisObjectAdapter = currentCollection.get(i);
                        if (thisObjectAdapter.getSpecification().isOfType(currentTableSpecification)) {
                            currentIndexStart = currentIndex = i;
                            return true;
                        }
                    }
                    return false;
                }

                @Override
                public ObjectAdapter next() {
                    currentIndexStart = currentIndex + 1;
                    return currentCollection.get(currentIndex);
                }

                @Override
                public void remove() {
                }
            };

            // Provide replacement table and column definitions here
            table = tables.get(i);
            super.saveInternalCollection(connector, parent);
        }
    }

    @Override
    protected void loadCollectionIntoList(final DatabaseConnector connector, final ObjectAdapter parent, final String table, final ObjectSpecification specification, final IdMappingAbstract idMappingAbstract, final Map<ObjectAssociation, FieldMapping> fieldMappingByField, final VersionMapping versionMapping,
            final List<ObjectAdapter> superList) {
        final List<ObjectAdapter> list = Lists.newArrayList();
       
        for (int i = 0; i < tables.size(); i++) {
            currentTableSpecification = tableSpecifications.get(i);
            final AutoMapper mapper = (AutoMapper) subClassMappers.get(i);
            final String mapperTable = tables.get(i);

            super.loadCollectionIntoList(connector, parent, mapperTable, currentTableSpecification, mapper.getIdMapping(), mapper.fieldMappingByField, mapper.getVersionMapping(), list);

            superList.addAll(list);
            list.clear();
        }

    }

}
TOP

Related Classes of org.apache.isis.objectstore.sql.auto.PolymorphicForeignKeyInChildCollectionMapper

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.