<commit_before>/*
 * Copyright 2015 <NAME> (<EMAIL>).
 *
 * 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 com.dua3.meja.model.poi;

import com.dua3.meja.model.Cell;
import com.dua3.meja.model.Row;
import com.dua3.meja.util.Cache;
import com.dua3.meja.util.MejaHelper;
import com.dua3.meja.util.RectangularRegion;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author axel
 */
public class PoiRow implements Row {

    protected final PoiSheet sheet;
    protected final org.apache.poi.ss.usermodel.Row poiRow;
    protected final int rowNumber;
    protected final List<RectangularRegion> mergedRegions = new ArrayList<>();

    public PoiRow(PoiSheet sheet, org.apache.poi.ss.usermodel.Row row) {
        this.sheet = sheet;
        this.poiRow = row;
        this.rowNumber = poiRow.getRowNum();
        update();
    }

    private void update() {
        this.mergedRegions.clear();
        for (RectangularRegion r: getSheet().getMergedRegions()) {
            if (r.getFirstRow()<=rowNumber&&rowNumber<=r.getLastRow()) {
                this.mergedRegions.add(r);
            }
        }
    }

    @Override
    public PoiSheet getSheet() {
        return sheet;
    }

    @Override
    public PoiWorkbook getWorkbook() {
        return sheet.getWorkbook();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PoiRow) {
            return Objects.equals(poiRow, ((PoiRow) obj).poiRow);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return poiRow.hashCode();
    }

    @Override
    public int getRowNumber() {
        return rowNumber;
    }

    @Override
    public Iterator<Cell> iterator() {
        return MejaHelper.createCellIterator(this);
    }

    @Override
    public int getFirstCellNum() {
        return poiRow.getFirstCellNum();
    }

    @Override
    public int getLastCellNum() {
        return poiRow.getLastCellNum()-1;
    }

    RectangularRegion getMergedRegion(int columnIndex) {
        for (RectangularRegion r: mergedRegions) {
            if (r.getFirstColumn()<=columnIndex&&columnIndex<=r.getLastColumn()) {
                return r;
            }
        }
        return null;
    }

    private final Cache<org.apache.poi.ss.usermodel.Cell, PoiCell> cache = new Cache<org.apache.poi.ss.usermodel.Cell, PoiCell>(Cache.Type.WEAK_KEYS) {
        @Override
        protected PoiCell create(org.apache.poi.ss.usermodel.Cell poiCell) {
            return new PoiCell(PoiRow.this, poiCell);
        }
    };


    @Override
    public PoiCell getCell(int col) {
        org.apache.poi.ss.usermodel.Cell poiCell = poiRow.getCell(col, org.apache.poi.ss.usermodel.Row.CREATE_NULL_AS_BLANK);
        return cache.get(poiCell);
    }

    @Override
    public PoiCell getCellIfExists(int col) {
        org.apache.poi.ss.usermodel.Cell poiCell = poiRow.getCell(col);
        return poiCell==null ? null : cache.get(poiCell);
    }

    @Override
    public void copy(Row other) {
        for (Cell cell: other) {
            getCell(cell.getColumnNumber()).copy(cell);
        }
    }

    /**
     * Update first and last column numbers.
     * @param columnNumber <commit_msg>-disable cell caching for rows: directly allocating object for all cells in a row is faster, and the only reason would be allowing to add/remove cells from outside of meja (directly calling POI mathods) which will lead to problems anyway<commit_after>/*
 * Copyright 2015 <NAME> (<EMAIL>).
 *
 * 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 com.dua3.meja.model.poi;

import com.dua3.meja.model.Cell;
import com.dua3.meja.model.Row;
import com.dua3.meja.util.MejaHelper;
import com.dua3.meja.util.RectangularRegion;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author axel
 */
public class PoiRow implements Row {

    protected final PoiSheet sheet;
    protected final org.apache.poi.ss.usermodel.Row poiRow;
    protected final int rowNumber;
    protected final List<RectangularRegion> mergedRegions;
    protected final List<PoiCell> cells;

    public PoiRow(PoiSheet sheet, org.apache.poi.ss.usermodel.Row row) {
        this.sheet = sheet;
        this.poiRow = row;
        this.rowNumber = poiRow.getRowNum();
        this.mergedRegions = new ArrayList<>();
        this.cells = new ArrayList<>(Math.max(10,poiRow.getLastCellNum()));
        
        // init list of merged regions
        for (RectangularRegion r: getSheet().getMergedRegions()) {
            if (r.getFirstRow()<=rowNumber&&rowNumber<=r.getLastRow()) {
                this.mergedRegions.add(r);
            }
        }

        // create cells
        for (int idx=poiRow.getFirstCellNum(); idx<poiRow.getLastCellNum(); idx++) {
            org.apache.poi.ss.usermodel.Cell poiCell = poiRow.getCell(idx);
            if (poiCell!=null) {
                int j = poiCell.getColumnIndex();
                reserve(j);
                cells.set(j, new PoiCell(this, poiCell));
                sheet.setColumnUsed(j);
            }
        }
    }
    
    private void reserve(int col) {
        if (col >= cells.size()) {
            for (int colNum = cells.size(); colNum <= col; colNum++) {
                cells.add(null);
            }
        }
    }

    @Override
    public PoiSheet getSheet() {
        return sheet;
    }

    @Override
    public PoiWorkbook getWorkbook() {
        return sheet.getWorkbook();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PoiRow) {
            return Objects.equals(poiRow, ((PoiRow) obj).poiRow);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return poiRow.hashCode();
    }

    @Override
    public int getRowNumber() {
        return rowNumber;
    }

    @Override
    public Iterator<Cell> iterator() {
        return MejaHelper.createCellIterator(this);
    }

    @Override
    public int getFirstCellNum() {
        return poiRow.getFirstCellNum();
    }

    @Override
    public int getLastCellNum() {
        return poiRow.getLastCellNum()-1;
    }

    RectangularRegion getMergedRegion(int columnIndex) {
        for (RectangularRegion r: mergedRegions) {
            if (r.getFirstColumn()<=columnIndex&&columnIndex<=r.getLastColumn()) {
                return r;
            }
        }
        return null;
    }

    @Override
    public PoiCell getCell(int col) {
        reserve(col);
        
        PoiCell cell = cells.get(col);
        if (cell==null) {
            cell = new PoiCell(this, poiRow.createCell(col));
            cells.set(col, cell);
            sheet.setColumnUsed(col);
        }
        
        return cell;
    }

    @Override
    public PoiCell getCellIfExists(int col) {
        return col<cells.size() ? cells.get(col) : null;
    }

    @Override
    public void copy(Row other) {
        for (Cell cell: other) {
            getCell(cell.getColumnNumber()).copy(cell);
        }
    }

    /**
     * Update first and last column numbers.
     * @param columnNumber 
{'fraction_non_alphanumeric': 0.10609344894026974, 'fraction_numerical': 0.003733140655105973, 'mean_word_length': 2.3760162601626016, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1359704', 'n_tokens_mistral': 2539, 'n_tokens_neox': 2491, 'n_words': 632}