/******************************************************************************* * * Copyright 2010 Alexandru Craciun, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. ******************************************************************************/ package org.netxilia.api.reference; /** * This is R1C1 style reference. By default the reference is absolute. If the reference is relative (or mixed), a * context cell is needed to transform it in an absolute reference. * * @author <a href='mailto:ax.craciun@gmail.com'>Alexandru Craciun</a> * */ public final class RCCellReference { private final String sheetName; // if null, it's a reference to a local cell private final int rowIndex; private final int columnIndex; private final boolean absoluteRow; private final boolean absoluteColumn; public RCCellReference(int rowIndex, int columnIndex) { this(rowIndex, columnIndex, true, true); } public RCCellReference(int rowIndex, int columnIndex, boolean absoluteRow, boolean absoluteColumn) { this(null, rowIndex, columnIndex, absoluteRow, absoluteColumn); } public RCCellReference(String sheetName, int rowIndex, int columnIndex, boolean absoluteRow, boolean absoluteColumn) { this.sheetName = sheetName; this.rowIndex = rowIndex; this.columnIndex = columnIndex; this.absoluteRow = absoluteRow; this.absoluteColumn = absoluteColumn; } public RCCellReference(CellReference contextCell, CellReference ref) { this.absoluteColumn = ref.isAbsoluteColumn(); this.absoluteRow = ref.isAbsoluteRow(); this.sheetName = ref.getSheetName() != null ? ref.getSheetName() : contextCell.getSheetName(); this.rowIndex = this.absoluteRow || ref.isInfiniteRow() ? ref.getRowIndex() : ref.getRowIndex() - contextCell.getRowIndex(); this.columnIndex = this.absoluteColumn || ref.isInfiniteColumn() ? ref.getColumnIndex() : ref.getColumnIndex() - contextCell.getColumnIndex(); } public String getSheetName() { return sheetName; } public int getRowIndex() { return rowIndex; } public int getColumnIndex() { return columnIndex; } public boolean isAbsoluteRow() { return absoluteRow; } public boolean isAbsoluteColumn() { return absoluteColumn; } /** * Infinite columns are for full row ranges * * @return true if the columnIndex value has exactly the maximum value */ public boolean isInfiniteColumn() { return columnIndex == CellReference.MAX_COLUMN_INDEX; } /** * Infinite rows are for full column ranges * * @return true if the rowIndex value has exactly the maximum value */ public boolean isInfiniteRow() { return rowIndex == CellReference.MAX_ROW_INDEX; } public CellReference getAbsoluteReference(CellReference contextCell) { int row = absoluteRow || isInfiniteRow() ? rowIndex : contextCell.getRowIndex() + rowIndex; int column = absoluteColumn || isInfiniteColumn() ? columnIndex : contextCell.getColumnIndex() + columnIndex; String sheetName = this.sheetName != null ? this.sheetName : contextCell.getSheetName(); return new CellReference(sheetName, row, column, absoluteRow, absoluteColumn); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (absoluteColumn ? 1231 : 1237); result = prime * result + (absoluteRow ? 1231 : 1237); result = prime * result + columnIndex; result = prime * result + rowIndex; result = prime * result + ((sheetName == null) ? 0 : sheetName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } RCCellReference other = (RCCellReference) obj; if (absoluteColumn != other.absoluteColumn) { return false; } if (absoluteRow != other.absoluteRow) { return false; } if (columnIndex != other.columnIndex) { return false; } if (rowIndex != other.rowIndex) { return false; } if (sheetName == null) { if (other.sheetName != null) { return false; } } else if (!sheetName.equals(other.sheetName)) { return false; } return true; } @Override public String toString() { return toString(true); } public String toString(boolean withSheet) { StringBuilder sb = new StringBuilder(); if (withSheet && sheetName != null) { sb.append(sheetName).append("!"); } if (!isInfiniteRow()) { if (absoluteRow) { sb.append("R").append(rowIndex); } else { sb.append("R[").append(rowIndex).append("]"); } } if (!isInfiniteColumn()) { if (absoluteColumn) { sb.append("C").append(columnIndex); } else { sb.append("C[").append(columnIndex).append("]"); } } return sb.toString(); } }