org.datanucleus.store.excel.query.ExcelCandidateList.java Source code

Java tutorial

Introduction

Here is the source code for org.datanucleus.store.excel.query.ExcelCandidateList.java

Source

/**********************************************************************
Copyright (c) 2009 Andy Jefferson and others. All rights reserved.
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.
    
Contributors:
   ...
**********************************************************************/
package org.datanucleus.store.excel.query;

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

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.datanucleus.ExecutionContext;
import org.datanucleus.FetchPlan;
import org.datanucleus.identity.IdentityUtils;
import org.datanucleus.identity.SCOID;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.FieldValues;
import org.datanucleus.store.connection.ManagedConnection;
import org.datanucleus.store.excel.ExcelStoreManager;
import org.datanucleus.store.excel.fieldmanager.FetchFieldManager;
import org.datanucleus.store.query.AbstractCandidateLazyLoadList;
import org.datanucleus.store.schema.table.Table;

/**
 * Wrapper for a List of candidate instances from Excel. Loads the instances from the workbook lazily.
 */
public class ExcelCandidateList extends AbstractCandidateLazyLoadList {
    ManagedConnection mconn;

    boolean ignoreCache;

    /** Number of objects per class, in same order as class meta-data. */
    List<Integer> numberInstancesPerClass = null;

    /**
     * Constructor for the lazy loaded Excel candidate list.
     * @param cls The candidate class
     * @param subclasses Whether to include subclasses
     * @param ec execution context
     * @param cacheType Type of caching
     * @param mconn Connection to the datastore
     * @param ignoreCache Whether to ignore the cache on object retrieval
     */
    public ExcelCandidateList(Class cls, boolean subclasses, ExecutionContext ec, String cacheType,
            ManagedConnection mconn, boolean ignoreCache) {
        super(cls, subclasses, ec, cacheType);
        this.mconn = mconn;
        this.ignoreCache = ignoreCache;

        // Count the instances per class by scanning the associated worksheets
        numberInstancesPerClass = new ArrayList<Integer>();
        ExcelStoreManager storeMgr = (ExcelStoreManager) ec.getStoreManager();
        Iterator<AbstractClassMetaData> cmdIter = cmds.iterator();
        Workbook workbook = (Workbook) mconn.getConnection();
        while (cmdIter.hasNext()) {
            AbstractClassMetaData cmd = cmdIter.next();

            if (!storeMgr.managesClass(cmd.getFullClassName())) {
                // Make sure schema exists, using this connection
                storeMgr.manageClasses(new String[] { cmd.getFullClassName() }, ec.getClassLoaderResolver(),
                        workbook);
            }
            Table table = ec.getStoreManager().getStoreDataForClass(cmd.getFullClassName()).getTable();
            String sheetName = table.getName();
            Sheet sheet = workbook.getSheet(sheetName);
            int size = 0;
            if (sheet != null && sheet.getPhysicalNumberOfRows() > 0) {
                // Take the next row in this worksheet
                int idColIndex = -1;
                if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                    int[] pkFieldNums = cmd.getPKMemberPositions(); // TODO Check all pk cols?
                    AbstractMemberMetaData pkMmd = cmd
                            .getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
                    idColIndex = table.getMemberColumnMappingForMember(pkMmd).getColumn(0).getPosition();
                } else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                    idColIndex = table.getDatastoreIdColumn().getPosition();
                } else {
                    idColIndex = 0; // No id column with nondurable, so just take the first
                }

                for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
                    Row row = sheet.getRow(i);
                    if (row.getCell(idColIndex) != null) // Omit inactive rows
                    {
                        size++;
                    }
                }
            }
            numberInstancesPerClass.add(size);
        }
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.query.AbstractLazyLoadList#getSize()
     */
    protected int getSize() {
        int size = 0;

        Iterator<Integer> numberIter = numberInstancesPerClass.iterator();
        while (numberIter.hasNext()) {
            size += numberIter.next();
        }

        return size;
    }

    /* (non-Javadoc)
     * @see org.datanucleus.store.query.AbstractLazyLoadList#retrieveObjectForIndex(int)
     */
    protected Object retrieveObjectForIndex(int index) {
        if (index < 0 || index >= getSize()) {
            throw new NoSuchElementException();
        }

        Iterator<AbstractClassMetaData> cmdIter = cmds.iterator();
        Iterator<Integer> numIter = numberInstancesPerClass.iterator();
        int first = 0;
        int last = -1;
        while (cmdIter.hasNext()) {
            final AbstractClassMetaData cmd = cmdIter.next();
            int number = numIter.next();
            last = first + number;

            if (index >= first && index < last) {
                // Object is of this candidate type, so find the object
                Table table = ec.getStoreManager().getStoreDataForClass(cmd.getFullClassName()).getTable();
                String sheetName = table.getName();
                Workbook workbook = (Workbook) mconn.getConnection();
                final Sheet worksheet = workbook.getSheet(sheetName);
                if (worksheet != null) {
                    int idColIndex = -1;
                    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        int[] pkFieldNums = cmd.getPKMemberPositions(); // TODO Check all pk cols?
                        AbstractMemberMetaData pkMmd = cmd
                                .getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
                        idColIndex = table.getMemberColumnMappingForMember(pkMmd).getColumn(0).getPosition();
                    } else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                        idColIndex = table.getDatastoreIdColumn().getPosition();
                    } else {
                        idColIndex = 0; // No id column with nondurable, so just take the first
                    }

                    int current = first;
                    for (int i = worksheet.getFirstRowNum(); i <= worksheet.getLastRowNum(); i++) {
                        final Row row = worksheet.getRow(i);
                        if (row.getCell(idColIndex) != null) // Omit inactive rows
                        {
                            if (current == index) {
                                // This row equates to the required index
                                final int rowNumber = i;
                                if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                                    final FetchFieldManager fm = new FetchFieldManager(ec, cmd, worksheet,
                                            rowNumber, table);
                                    Object id = IdentityUtils.getApplicationIdentityForResultSetRow(ec, cmd, null,
                                            false, fm);

                                    return ec.findObject(id, new FieldValues() {
                                        // ObjectProvider calls the fetchFields method
                                        public void fetchFields(ObjectProvider op) {
                                            op.replaceFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public void fetchNonLoadedFields(ObjectProvider sm) {
                                            sm.replaceNonLoadedFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public FetchPlan getFetchPlanForLoading() {
                                            return null;
                                        }
                                    }, null, ignoreCache, false);
                                } else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                                    final FetchFieldManager fm = new FetchFieldManager(ec, cmd, worksheet,
                                            rowNumber, table);
                                    Object id = null;
                                    Cell idCell = row.getCell(idColIndex);
                                    int type = idCell.getCellType();
                                    if (type == Cell.CELL_TYPE_STRING) {
                                        String key = idCell.getRichStringCellValue().getString();
                                        id = ec.getNucleusContext().getIdentityManager()
                                                .getDatastoreId(cmd.getFullClassName(), key);
                                    } else if (type == Cell.CELL_TYPE_NUMERIC) {
                                        long key = (long) idCell.getNumericCellValue();
                                        id = ec.getNucleusContext().getIdentityManager()
                                                .getDatastoreId(cmd.getFullClassName(), key);
                                    }
                                    return ec.findObject(id, new FieldValues() {
                                        // ObjectProvider calls the fetchFields method
                                        public void fetchFields(ObjectProvider op) {
                                            op.replaceFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public void fetchNonLoadedFields(ObjectProvider op) {
                                            op.replaceNonLoadedFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public FetchPlan getFetchPlanForLoading() {
                                            return null;
                                        }
                                    }, null, ignoreCache, false);
                                } else {
                                    // Nondurable identity
                                    final FetchFieldManager fm = new FetchFieldManager(ec, cmd, worksheet,
                                            rowNumber, table);
                                    Object id = new SCOID(cmd.getFullClassName());
                                    return ec.findObject(id, new FieldValues() {
                                        // ObjectProvider calls the fetchFields method
                                        public void fetchFields(ObjectProvider op) {
                                            op.replaceFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public void fetchNonLoadedFields(ObjectProvider sm) {
                                            sm.replaceNonLoadedFields(cmd.getAllMemberPositions(), fm);
                                        }

                                        public FetchPlan getFetchPlanForLoading() {
                                            return null;
                                        }
                                    }, null, ignoreCache, false);
                                }
                            }

                            current++;
                        }
                    }
                }
            } else {
                first += number;
            }
        }

        return null;
    }
}