DynamicColumn.java
/*
* CSVeed (https://github.com/42BV/CSVeed)
*
* Copyright 2013-2023 CSVeed.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of The Apache Software License,
* Version 2.0 which accompanies this distribution, and is available at
* https://www.apache.org/licenses/LICENSE-2.0.txt
*/
package org.csveed.bean;
import org.csveed.common.Column;
/**
* <p>
* The concept of dynamic columns comes into play when a sheet contains columns that are not really part of the columns,
* but should have been separate rows. For example, let's say you have a table that looks like this:
* </p>
* <code>
* | name | town | jan 14 | jan 15 | jan 16 |
* | Rob | Leiden | 4 | 1 | 7 |
* | Rob | Delft | 0 | 3 | 8 |
* | Erik | Leiden | 2 | 4 | 1 |
* | Erik | Sneek | 1 | 0 | 9 |
* </code>
* <p>
* Let's say you want to compact this table into the following, normalized format: <code>
* | name | town | date | visits |
* | Rob | Leiden | jan 14 | 4 |
* | Rob | Leiden | jan 15 | 1 |
* | Rob | Leiden | jan 16 | 7 |
* | Rob | Delft | jan 14 | 0 |
* | Rob | Delft | jan 15 | 3 |
* | Rob | Delft | jan 16 | 8 |
* | Erik | Leiden | jan 14 | 2 |
* | Erik | Leiden | jan 15 | 4 |
* | Erik | Leiden | jan 16 | 1 |
* | Erik | Sneek | jan 14 | 1 |
* | Erik | Sneek | jan 15 | 0 |
* | Erik | Sneek | jan 16 | 9 |
* </code>
* <p>
* In order to realize this goal, you need to make that startIndexDynamicColumns is set to 3 on @CsvFile. This will
* assume the columns starting with the third and all thereafter are dynamic. For every dynamic column, a new bean will
* be created. All static columns will be copied into every created bean.
* </p>
* <p>
* The header name and the cell value can be copied into bean properties. In the example, the bean requires two fields
* date and visits. date must be annotated with @CsvHeaderName and visits with @CsvHeaderValue.
* </p>
*/
public class DynamicColumn {
/** The start column. */
private Column startColumn;
/** The current column. */
private Column currentColumn;
/**
* Instantiates a new dynamic column.
*
* @param configuredStartColumn
* the configured start column
*/
public DynamicColumn(Column configuredStartColumn) {
this.startColumn = configuredStartColumn == null ? null : new Column(configuredStartColumn);
this.currentColumn = configuredStartColumn == null ? null : new Column(configuredStartColumn);
}
/**
* Check for reset.
*
* @param numberOfColumns
* the number of columns
*/
public void checkForReset(int numberOfColumns) {
if (lastDynamicColumnPassed(numberOfColumns)) {
reset();
}
}
/**
* Reset.
*/
protected void reset() {
this.currentColumn = new Column(this.startColumn);
}
/**
* Last dynamic column passed.
*
* @param numberOfColumns
* the number of columns
*
* @return true, if successful
*/
protected boolean lastDynamicColumnPassed(int numberOfColumns) {
return this.currentColumn != null && this.currentColumn.getColumnIndex() > numberOfColumns;
}
/**
* At first dynamic column.
*
* @return true, if successful
*/
public boolean atFirstDynamicColumn() {
return this.startColumn == null || this.startColumn.equals(this.currentColumn);
}
/**
* Advance dynamic column.
*/
public void advanceDynamicColumn() {
if (currentColumn == null) {
return;
}
this.currentColumn = currentColumn.nextColumn();
}
/**
* Checks if is dynamic column active.
*
* @param currentColumn
* the current column
*
* @return true, if is dynamic column active
*/
public boolean isDynamicColumnActive(Column currentColumn) {
return this.currentColumn != null && this.currentColumn.getColumnIndex() == currentColumn.getColumnIndex();
}
}