• R/O
  • SSH
  • HTTPS

jpicosheet: Commit


Commit MetaInfo

Revisão81 (tree)
Hora2019-03-27 23:48:44
Autorki-chi

Mensagem de Log

Tableの実装を大きく変更

Mudança Sumário

Diff

--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Cell.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Cell.java (revision 81)
@@ -44,7 +44,7 @@
4444 * @author yusuke nishikawa
4545 *
4646 */
47-public class Cell implements Comparable<Cell> {
47+public abstract class Cell implements Comparable<Cell> {
4848
4949 static {
5050 // 空のセル値のため、空のエレメントを作成
@@ -54,9 +54,9 @@
5454 /**
5555 * 空を表すエレメント
5656 */
57- private static Element emptyElement;
57+ protected static Element emptyElement;
5858
59- private static final String EMPTY_LABEL = "";
59+ protected static final String EMPTY_LABEL = "";
6060
6161 // セルの状態を表す
6262 public enum CellStatus {
@@ -109,101 +109,49 @@
109109 /**
110110 * 式(中置記法)
111111 */
112- private String _formula;
112+ protected String _formula;
113+
113114 /**
114115 * 式(逆ポーランド式、Element配列)
115116 */
116- private Element[] _formulaRPN;
117- /**
118- * セル名
119- */
120- private String _name;
117+ protected Element[] _formulaRPN;
121118
122119 /**
123- * セルのラベル
124- */
125- private String _label;
126-
127- /**
128- * このセルを持っているSheetオブジェクトへの参照
129- */
130- private Sheet _sheet;
131-
132- /**
133120 * このセルのタイプ
134121 */
135- private CellType _cellType = CellType.EMPTY;
122+ protected CellType _cellType = CellType.EMPTY;
136123 /**
137124 * このセルの状態
138125 */
139- private CellStatus _status = CellStatus.CALCULATED;
126+ protected CellStatus _status = CellStatus.CALCULATED;
140127
141128 /**
142129 * このセルの値
143130 */
144- private Element _value;
131+ protected Element _value;
145132
146133 /**
147134 * セル名のパターン文字列
148135 */
149136
150- static final String CELL_NAME_PATTERN = "[a-zA-Z_][a-zA-Z0-9_]*";
137+ protected static final String CELL_NAME_PATTERN = "[a-zA-Z_][a-zA-Z0-9_]*";
138+
151139 /**
152140 * セル名の正規表現パターン
153141 */
154- private static Pattern _cellNamePattern = Pattern.compile(CELL_NAME_PATTERN);
142+ protected static Pattern _cellNamePattern = Pattern.compile(CELL_NAME_PATTERN);
155143
156144 /**
157145 * 完全修飾セル名のパターン文字列
158146 */
159- static final String FULLY_QUALIFIED_CELL_NAME_PATTERN = Sheet.SHEET_NAME_PATTERN + "!" + "[a-zA-Z_][a-zA-Z0-9_]*";
147+ protected static final String FULLY_QUALIFIED_CELL_NAME_PATTERN = Sheet.SHEET_NAME_PATTERN + "!" + "[a-zA-Z_][a-zA-Z0-9_]*";
160148
161149 /**
162150 * 完全修飾セル名の正規表現パターン
163151 */
164- private static Pattern _fullyQualifiedCellNamePattern = Pattern.compile(FULLY_QUALIFIED_CELL_NAME_PATTERN);
152+ protected static Pattern _fullyQualifiedCellNamePattern = Pattern.compile(FULLY_QUALIFIED_CELL_NAME_PATTERN);
165153
166154 /**
167- * セル名、シートを指定してオブジェクトを作成します
168- *
169- * @param cellName セル名
170- * @param sheet このセルが属するシートオブジェクト
171- * @throws IllegalArgumentException セル名が正しくない場合
172- */
173- Cell(String cellName, Sheet sheet) throws IllegalArgumentException {
174- this(cellName, sheet, false);
175- }
176-
177- /**
178- * セル名、シートを指定してオブジェクトを作成します
179- * @param cellName セル名
180- * @param sheet このセルが属するシートオブジェクト
181- * @param createForTableCell テーブル用のセルを作成する場合true、そうでない場合falseを指定
182- * @throws IllegalArgumentException
183- * セル名が正しくない場合
184- */
185- Cell(String cellName, Sheet sheet, boolean createForTableCell) throws IllegalArgumentException {
186-
187- // createForTableCellによってTable用の名前チェックを行うか否か決定する
188- if (createForTableCell) {
189- if (!Table.isValidTableNameWithAddress(cellName)) {
190- throw new IllegalArgumentException("invalid cell name for Table \"" + cellName + "\"");
191- }
192- } else {
193- if (!isValidCellName(cellName)) {
194- throw new IllegalArgumentException("invalid cell name \"" + cellName + "\"");
195- }
196- }
197-
198- // メンバに値をセット
199- this._name = cellName;
200- this._label = EMPTY_LABEL;
201- this._formula = null;
202- this._value = emptyElement;
203- this._sheet = sheet;
204- }
205-
206- /**
207155 * 式を返します。返される文字列にはこの文字列が式であることを明示する"="が先頭に付けられます。<br>
208156 * このセルが CellType.FORMULA でない場合、nullを返します。
209157 *
@@ -232,24 +180,18 @@
232180 *
233181 * @return セルの名前
234182 */
235- public String getName() {
236- return _name;
237- }
183+ public abstract String getName();
238184
239185 /**
240186 * このセルのラベルを返します
241187 * @return セルのラベル
242188 */
243- public String getLabel() {
244- return _label;
245- }
189+ public abstract String getLabel();
246190 /**
247191 * このセルの完全修飾名を返します
248192 * @return セルの完全修飾名
249193 */
250- public String getFullyQualifiedName() {
251- return _sheet.getName() + "!" + _name;
252- }
194+ public abstract String getFullyQualifiedName();
253195
254196 /**
255197 * このセルを持っているシートへの参照を返します
@@ -256,9 +198,7 @@
256198 *
257199 * @return このセルを持っているシートへの参照
258200 */
259- public Sheet getSheet() {
260- return this._sheet;
261- }
201+ public abstract Sheet getSheet();
262202
263203 /**
264204 * このセルのステータスを返します
@@ -339,9 +279,7 @@
339279 * @param cellName 新しいセル名
340280 * @throws IllegalArgumentException セル名として正しくない名前が渡された場合
341281 */
342- void setName(String cellName) {
343- setName(cellName, false);
344- }
282+ abstract void setName(String cellName);
345283
346284 /**
347285 * セル名をセットします
@@ -350,20 +288,7 @@
350288 * @param createForTableCell テーブル用のセルを作成する場合true、そうでない場合falseを指定
351289 * @throws IllegalArgumentException セル名として正しくない名前が渡された場合
352290 */
353- void setName(String cellName, boolean createForTableCell) throws IllegalArgumentException {
354- // 正しいセル名かチェック
355- // createForTableCellによってTable用の名前チェックを行うか否か決定する
356- if (createForTableCell) {
357- if (!Table.isValidTableNameWithAddress(cellName)) {
358- throw new IllegalArgumentException("invalid cell name for Table \"" + cellName + "\"");
359- }
360- } else {
361- if (!isValidCellName(cellName)) {
362- throw new IllegalArgumentException("invalid cell name \"" + cellName + "\"");
363- }
364- }
365- _name = cellName;
366- }
291+ abstract void setName(String cellName, boolean createForTableCell) throws IllegalArgumentException;
367292
368293 /**
369294 * ラベルをセットします
@@ -370,10 +295,7 @@
370295 * @param newLabel 新しいラベル
371296 * @return このセルオブジェクトへの参照
372297 */
373- public Cell setLabel(String newLabel) {
374- _label = newLabel;
375- return this;
376- }
298+ public abstract Cell setLabel(String newLabel);
377299
378300 /**
379301 * セルのステータスをセットします
@@ -443,7 +365,7 @@
443365 return this;
444366 }
445367
446- Resolver resolver = _sheet.getBook().getResolver();
368+ Resolver resolver = getSheet().getBook().getResolver();
447369 for (Element elem: getFormulaRPN()) {
448370 // エレメントがセル参照の場合
449371 if (elem.getType() == ElementType.REFERENCE) {
@@ -450,11 +372,11 @@
450372 String refName = elem.getCellReference();
451373 if (resolver.isFullyQualifiedName(refName)) {
452374 // セル参照が完全修飾セル名の場合、該当シートにセルを追加
453- Sheet otherSheet = _sheet.getBook().getSheet(resolver.getSheetNameFromFullyQualifiedName(refName));
375+ Sheet otherSheet = getSheet().getBook().getSheet(resolver.getSheetNameFromFullyQualifiedName(refName));
454376 otherSheet.addCell(refName);
455377 } else {
456378 // そうでない場合、このシートにセルを追加
457- _sheet.addCell(refName);
379+ getSheet().addCell(refName);
458380 }
459381 }
460382 }
@@ -464,7 +386,7 @@
464386 getCalculator().calc(this);
465387
466388 // 計算済み…シートのエラーセルからこのセルを削除(もしあれば)
467- this._sheet.removeErrorCell(this);
389+ getSheet().removeErrorCell(this);
468390 return this;
469391 }
470392
@@ -531,7 +453,7 @@
531453 removeReferenceFromResolver();
532454
533455 // 値をセット
534- this._value = Element.newElement(ElementType.NUMBER, new BigDecimal(numString, this._sheet.getMathContext()));
456+ this._value = Element.newElement(ElementType.NUMBER, new BigDecimal(numString, getSheet().getMathContext()));
535457 // このセルを参照しているセルについて再計算が必要
536458 getCalculator().calc(this);
537459
@@ -637,12 +559,12 @@
637559 // 式を格納
638560 this._formula = formula;
639561 // 式をElementの配列に変換
640- Element[] infixElem = FormulaParser.split(this._formula, this._sheet.getMathContext(), getCalculator().getFunctionFactory());
562+ Element[] infixElem = FormulaParser.split(this._formula, getSheet().getMathContext(), getCalculator().getFunctionFactory());
641563 // 要素数1で、0番目のElementがエラーの場合、変換時にエラー
642564 if (infixElem.length == 1 && infixElem[0].getType() == ElementType.ERROR) {
643565 this._status = CellStatus.ERROR;
644566 this._value = infixElem[0];
645- this._sheet.addErrorCell(this);
567+ getSheet().addErrorCell(this);
646568 getCalculator().recalcReferencingCells(this);
647569 return this;
648570 }
@@ -653,25 +575,25 @@
653575 if (errorElem != null) {
654576 this._status = CellStatus.ERROR;
655577 this._value = errorElem;
656- this._sheet.addErrorCell(this);
578+ getSheet().addErrorCell(this);
657579 getCalculator().recalcReferencingCells(this);
658580 return this;
659581 }
660582
661583 // 式を逆ポーランド記法に変換して格納する
662- this._formulaRPN = FormulaParser.infixToRPN(infixElem, this._sheet.getMathContext());
584+ this._formulaRPN = FormulaParser.infixToRPN(infixElem, getSheet().getMathContext());
663585 // 要素数1で、0番目のElementがエラーの場合、変換時にエラー
664586 if (this._formulaRPN.length == 1 && this._formulaRPN[0].getType() == ElementType.ERROR) {
665587 this._status = CellStatus.ERROR;
666588 this._value = this._formulaRPN[0];
667589 this._formulaRPN = null;
668- this._sheet.addErrorCell(this);
590+ getSheet().addErrorCell(this);
669591 getCalculator().recalcReferencingCells(this);
670592 return this;
671593 }
672594
673595 // 式の中にセル参照が含まれる場合、参照していることを登録する
674- Resolver resolver = this._sheet.getBook().getResolver();
596+ Resolver resolver = getSheet().getBook().getResolver();
675597 for (Element elem : this._formulaRPN) {
676598 switch (elem.getType()) {
677599 case REFERENCE:
@@ -694,7 +616,8 @@
694616 getCalculator().calc(this);
695617
696618 // 計算済み…シートのエラーセルからこのセルを削除(もしあれば)
697- this._sheet.removeErrorCell(this);
619+ //TODO: 上の計算処理はdisableで計算されないことがある。エラーセルからの削除はこのセルが計算済みステータス、エラーか否かを判断して行うべき。
620+ getSheet().removeErrorCell(this);
698621 return this;
699622 }
700623
@@ -746,13 +669,13 @@
746669 public static boolean isValidFullyQualifiedCellName(String fullyQualifiedCellName) {
747670 return _fullyQualifiedCellNamePattern.matcher(fullyQualifiedCellName).matches();
748671 }
749-
672+
750673 /**
751674 * 計算機オブジェクトを返します
752675 * @return 計算機オブジェクト
753676 */
754677 private Calculator getCalculator() {
755- return this._sheet.getBook().getCalculator();
678+ return getSheet().getBook().getCalculator();
756679 }
757680
758681 /**
@@ -768,7 +691,7 @@
768691 */
769692 @Override
770693 public String toString() {
771- return _name + "=" + _value.toString();
694+ return getName() + "=" + _value.toString();
772695 }
773696
774697 /* (非 Javadoc)
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/ConcurrentBookWrapper.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/ConcurrentBookWrapper.java (revision 81)
@@ -139,6 +139,99 @@
139139 }
140140
141141 /**
142+ * テーブルを追加します。<br>
143+ * 指定したテーブル名がすでに存在する場合は何もしません。
144+ * @param sheetName シート名。存在しない場合は新しく作成する。
145+ * @param tableName テーブル名
146+ * @param rowSize テーブルの行数
147+ * @param colSize テーブルの列数
148+ */
149+ public void addTable(String sheetName, String tableName, int rowSize, int colSize) {
150+ try {
151+ _writeLock.lock();
152+ _book.addSheet(sheetName).addTable(tableName, rowSize, colSize);
153+ } finally {
154+ _writeLock.unlock();
155+ }
156+ }
157+
158+ /**
159+ * テーブルを削除します。<br>
160+ * 指定したシートが存在しない場合、ReferenceNotFoundExceptionが発生します。指定したテーブル名が存在しない場合は何もしません。
161+ * @param sheetName シート名
162+ * @param tableName 削除対象のテーブル名
163+ */
164+ public void deleteTable(String sheetName, String tableName) {
165+ try {
166+ _writeLock.lock();
167+ _book.getSheet(sheetName).deleteTable(tableName);
168+ } finally {
169+ _writeLock.unlock();
170+ }
171+ }
172+
173+ /**
174+ * グループを追加します。<br>
175+ * 指定したグループ名がすでに存在する場合は何もしません。
176+ * @param sheetName シート名。存在しない場合は新しく作成する。
177+ * @param groupName グループ名
178+ */
179+ public void addGroup(String sheetName, String groupName) {
180+ try {
181+ _writeLock.lock();
182+ _book.addSheet(sheetName).addGroup(groupName);
183+ } finally {
184+ _writeLock.unlock();
185+ }
186+ }
187+
188+ /**
189+ * グループを削除します。<br>
190+ * 指定したシートが存在しない場合、ReferenceNotFoundExceptionが発生します。指定したグループ名が存在しない場合は何もしません。
191+ * @param sheetName シート名
192+ * @param groupName 削除対象のグループ名
193+ */
194+ public void deleteGroup(String sheetName, String groupName) {
195+ try {
196+ _writeLock.lock();
197+ _book.getSheet(sheetName).deleteGroup(groupName);
198+ } finally {
199+ _writeLock.unlock();
200+ }
201+ }
202+
203+ /**
204+ * 指定したグループにセルを追加します。
205+ * @param sheetName シート名。存在しない場合は新しく作成する。
206+ * @param groupName グループ名
207+ * @param cellNames 追加するセル名
208+ */
209+ public void addCellsToGroup(String sheetName, String groupName, String[] cellNames) {
210+ try {
211+ _writeLock.lock();
212+ _book.addSheet(sheetName).getGroup(groupName).addCells(cellNames);
213+ } finally {
214+ _writeLock.unlock();
215+ }
216+ }
217+
218+ /**
219+ * 指定したグループからセルを削除します。
220+ * 指定したシート、グループが存在しない場合、ReferenceNotFoundExceptionが発生します。指定したセル名が存在しない場合は何もしません。
221+ * @param sheetName シート名
222+ * @param groupName グループ名
223+ * @param cellNames 削除対象のセル名の配列
224+ */
225+ public void deleteCellsToGroup(String sheetName, String groupName, String[] cellNames) {
226+ try {
227+ _writeLock.lock();
228+ _book.getSheet(sheetName).getGroup(groupName).removeCells(cellNames);
229+ } finally {
230+ _writeLock.unlock();
231+ }
232+ }
233+
234+ /**
142235 * 既存のシートのシート名を変更します。<br>
143236 * 変更前のシートが存在しない場合、ReferenceNotFoundExceptionが発生します。<br>
144237 * 変更後のシート名を持つシートがすでに存在していた場合、そのシートは削除されます。
@@ -184,8 +277,31 @@
184277 }
185278 }
186279
280+ /**
281+ * セル値の変更による自動再計算を有効化します。
282+ */
283+ public void recalcEnable() {
284+ try {
285+ _writeLock.lock();
286+ _book.recalcEnable();
287+ } finally {
288+ _writeLock.unlock();
289+ }
290+ }
187291
188292 /**
293+ * セル値の変更による自動再計算を無効化します。
294+ */
295+ public void recalcDisable() {
296+ try {
297+ _writeLock.lock();
298+ _book.recalcDisable();
299+ } finally {
300+ _writeLock.unlock();
301+ }
302+ }
303+
304+ /**
189305 * セルの値をセットします。<br>
190306 * 値として渡された文字列をチェックし、適切な型の値として保存します。<br>
191307 * セル名が シート名!セル名 の形式で渡された場合、指定されたシートの指定されたセルに対して値をセットします。
@@ -249,6 +365,11 @@
249365 * @param cellName 追加するセル名
250366 */
251367 public void addCell(String cellName) {
368+ // テーブルに対するセル追加は不要
369+ if (Table.isValidFullyQualifiedTableNameWithAddress(cellName)) {
370+ return;
371+ }
372+
252373 try {
253374 _writeLock.lock();
254375 Resolver resolver = _book.getResolver();
@@ -259,7 +380,7 @@
259380 sheetName = resolver.getCurrentSheet().getName();
260381 }
261382 addSheet(sheetName);
262- _book.getSheet(sheetName).addCell(cellName);
383+ _book.getSheet(sheetName).addCell(cellName);
263384 } finally {
264385 _writeLock.unlock();
265386 }
@@ -355,7 +476,11 @@
355476 * <code>getWriteLock()</code>で取得した書き込みロックを開放します。
356477 */
357478 public void releaseWriteLock() {
358- _writeLock.unlock();
479+ if (_writeLock.isHeldByCurrentThread()) {
480+ _writeLock.unlock();
481+ } else {
482+ _writeLock.unlock();
483+ }
359484 }
360485
361486 /**
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Group.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Group.java (revision 81)
@@ -186,7 +186,6 @@
186186 * 指定したセルがグループに存在しない場合は何もしません
187187 * @param cellName 削除するセル名
188188 * @return このグループ
189- * @throws ReferenceNotFoundException 指定したセルが存在しない場合
190189 */
191190 public Group removeCell(String cellName) {
192191 try {
@@ -198,6 +197,19 @@
198197 return this;
199198 }
200199
200+ /**
201+ * グループからセルを削除します<br>
202+ * 指定したセルがグループに存在しない場合は何もしません
203+ * @param cellNames 削除するセル名の配列
204+ * @return このグループ
205+ */
206+ public Group removeCells(String[] cellNames ) {
207+ for (String cellName: cellNames) {
208+ removeCell(cellName);
209+ }
210+ return this;
211+ }
212+
201213 /* (非 Javadoc)
202214 * @see com.nissy_ki_chi.jpicosheet.core.CellGroupReference#getCells()
203215 */
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/PlainCell.java (nonexistent)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/PlainCell.java (revision 81)
@@ -0,0 +1,224 @@
1+/**
2+ * JPicosheet: Spreadsheet engine for Java Applications
3+ * Copyright (C) 2011 yusuke nishikawa
4+ *
5+ * This library is free software; you can redistribute it and/or
6+ * modify it under the terms of the GNU Lesser General Public
7+ * License as published by the Free Software Foundation; either
8+ * version 2.1 of the License, or (at your option) any later version.
9+ *
10+ * This library is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+ * Lesser General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU Lesser General Public
16+ * License along with this library; if not, write to the Free Software
17+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18+ */
19+package com.nissy_ki_chi.jpicosheet.core;
20+
21+/**
22+ * 値の保持、他のセルの参照や計算を行う"セル"です。<br>
23+ *
24+ * セルにはいくつかの種類および状態があります。
25+ * セルの種類には空、数値、文字列、日時、式があります。種類の情報は<code>getCellType()</code>で得ることができます。<br>
26+ * セルの状態には計算必要、計算中、計算済み、エラーがあります。状態の情報は<code>getCellStatus()</code>で得ることができます。<br>
27+ *
28+ * セルの値は保持しているデータの種類や式の計算結果によって変化しますが、<code>getValue()</code>で得ることができるのはElement型オブジェクトです。
29+ * Element型オブジェクトはセルの値を表す汎用のデータ型です。<br>
30+ *
31+ * セルは必ずいずれかのシートに属します。アプリケーションがセルオブジェクトを単体で作成することはできず、Sheetクラスの
32+ * <code>addCell()</code>メソッドによって作成します。
33+ *
34+ * @author yusuke nishikawa
35+ *
36+ */
37+public class PlainCell extends Cell implements Comparable<Cell> {
38+
39+ /**
40+ * セル名
41+ */
42+ private String _name;
43+
44+ /**
45+ * セルのラベル
46+ */
47+ private String _label;
48+
49+ /**
50+ * このセルを持っているSheetオブジェクトへの参照
51+ */
52+ private Sheet _sheet;
53+
54+ /**
55+ * セル名、シートを指定してオブジェクトを作成します
56+ *
57+ * @param cellName セル名
58+ * @param sheet このセルが属するシートオブジェクト
59+ * @throws IllegalArgumentException セル名が正しくない場合
60+ */
61+ PlainCell(String cellName, Sheet sheet) throws IllegalArgumentException {
62+ this(cellName, sheet, false);
63+ }
64+
65+ /**
66+ * セル名、シートを指定してオブジェクトを作成します
67+ * @param cellName セル名
68+ * @param sheet このセルが属するシートオブジェクト
69+ * @param createForTableCell テーブル用のセルを作成する場合true、そうでない場合falseを指定
70+ * @throws IllegalArgumentException
71+ * セル名が正しくない場合
72+ */
73+ PlainCell(String cellName, Sheet sheet, boolean createForTableCell) throws IllegalArgumentException {
74+
75+ // createForTableCellによってTable用の名前チェックを行うか否か決定する
76+ if (createForTableCell) {
77+ if (!Table.isValidTableNameWithAddress(cellName)) {
78+ throw new IllegalArgumentException("invalid cell name for Table \"" + cellName + "\"");
79+ }
80+ } else {
81+ if (!isValidCellName(cellName)) {
82+ throw new IllegalArgumentException("invalid cell name \"" + cellName + "\"");
83+ }
84+ }
85+
86+ // メンバに値をセット
87+ this._name = cellName;
88+ this._label = EMPTY_LABEL;
89+ this._formula = null;
90+ this._value = emptyElement;
91+ this._sheet = sheet;
92+ }
93+
94+ /**
95+ * このセルの名前を返します
96+ *
97+ * @return セルの名前
98+ */
99+ @Override
100+ public String getName() {
101+ return _name;
102+ }
103+
104+ /**
105+ * このセルのラベルを返します
106+ * @return セルのラベル
107+ */
108+ @Override
109+ public String getLabel() {
110+ return _label;
111+ }
112+
113+ /**
114+ * このセルの完全修飾名を返します
115+ * @return セルの完全修飾名
116+ */
117+ @Override
118+ public String getFullyQualifiedName() {
119+ return _sheet.getName() + "!" + _name;
120+ }
121+
122+ /**
123+ * このセルを持っているシートへの参照を返します
124+ *
125+ * @return このセルを持っているシートへの参照
126+ */
127+ @Override
128+ public Sheet getSheet() {
129+ return this._sheet;
130+ }
131+
132+ /**
133+ * セル名をセットします
134+ *
135+ * @param cellName 新しいセル名
136+ * @throws IllegalArgumentException セル名として正しくない名前が渡された場合
137+ */
138+ @Override
139+ void setName(String cellName) {
140+ setName(cellName, false);
141+ }
142+
143+ /**
144+ * セル名をセットします
145+ *
146+ * @param cellName 新しいセル名
147+ * @param createForTableCell テーブル用のセルを作成する場合true、そうでない場合falseを指定
148+ * @throws IllegalArgumentException セル名として正しくない名前が渡された場合
149+ */
150+ @Override
151+ void setName(String cellName, boolean createForTableCell) throws IllegalArgumentException {
152+ // 正しいセル名かチェック
153+ // createForTableCellによってTable用の名前チェックを行うか否か決定する
154+ if (createForTableCell) {
155+ if (!Table.isValidTableNameWithAddress(cellName)) {
156+ throw new IllegalArgumentException("invalid cell name for Table \"" + cellName + "\"");
157+ }
158+ } else {
159+ if (!isValidCellName(cellName)) {
160+ throw new IllegalArgumentException("invalid cell name \"" + cellName + "\"");
161+ }
162+ }
163+ _name = cellName;
164+ }
165+
166+ /**
167+ * ラベルをセットします
168+ * @param newLabel 新しいラベル
169+ * @return このセルオブジェクトへの参照
170+ */
171+ @Override
172+ public Cell setLabel(String newLabel) {
173+ _label = newLabel;
174+ return this;
175+ }
176+
177+ /* (非 Javadoc)
178+ * @see java.lang.Object#toString()
179+ */
180+ @Override
181+ public String toString() {
182+ return _name + "=" + _value.toString();
183+ }
184+
185+ /* (非 Javadoc)
186+ * @see java.lang.Comparable#compareTo(java.lang.Object)
187+ */
188+ public int compareTo(Cell o) {
189+ return (this.getFullyQualifiedName().compareTo(o.getFullyQualifiedName()));
190+ }
191+
192+ /* (非 Javadoc)
193+ * @see java.lang.Object#equals(java.lang.Object)
194+ */
195+ @Override
196+ public boolean equals(Object obj) {
197+ if (obj instanceof Cell) {
198+ Cell c = (Cell)obj;
199+ if (this.getCellType() == c.getCellType()) {
200+ if (this.getCellType() == CellType.FORMULA) {
201+ for (int i = 0; i < this._formulaRPN.length; i++) {
202+ if (!(this._formulaRPN[i].equals(c._formulaRPN[i]))) {
203+ return false;
204+ }
205+ }
206+ return true;
207+ } else {
208+ if (this.getValueString().equals(c.getValueString())) {
209+ return true;
210+ }
211+ }
212+ }
213+ }
214+ return false;
215+ }
216+
217+ /* (非 Javadoc)
218+ * @see java.lang.Object#hashCode()
219+ */
220+ @Override
221+ public int hashCode() {
222+ return this.getFullyQualifiedName().hashCode();
223+ }
224+}
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Row.java (nonexistent)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Row.java (revision 81)
@@ -0,0 +1,81 @@
1+package com.nissy_ki_chi.jpicosheet.core;
2+
3+import java.util.Arrays;
4+
5+public class Row {
6+
7+ private int _colSize = 0;
8+ private Cell[] _cols;
9+ private RowsChunk _chunk;
10+
11+ /**
12+ * このオブジェクトが属すRowsChunkオブジェクトと、このオブジェクトのカラムサイズを指定してオブジェクトを初期化します。
13+ * @param belongTo このオブジェクトが属すRowsChunkオブジェクト
14+ * @param colSize カラムサイズ
15+ */
16+ Row(RowsChunk belongTo, int colSize) {
17+ if (belongTo == null) throw new NullPointerException("chunkがnullです。");
18+ if (colSize < 0) throw new IllegalArgumentException("colSizeは1以上でなければなりません。");
19+ _colSize = colSize;
20+ _chunk = belongTo;
21+ _cols = new Cell[_colSize];
22+ for (int i = 0; i < _colSize; i++) {
23+ _cols[i] = new TableCell(this);
24+ }
25+ }
26+
27+ /**
28+ * このオブジェクトが保持しているカラム配列のコピーを返します。
29+ * @return カラム配列のコピー
30+ */
31+ Cell[] getCols() {
32+ return Arrays.copyOf(_cols, _colSize);
33+ }
34+
35+ /**
36+ * 指定したカラム位置のセルを返します。
37+ * @param colIndex カラム位置
38+ * @return セルオブジェクト
39+ */
40+ Cell getCell(int colIndex) {
41+ return _cols[colIndex];
42+ }
43+
44+ /**
45+ * このオブジェクトが属しているRowsChunkオブジェクトを返します。
46+ * @return このオブジェクトの属すRowsChunkオブジェクト
47+ */
48+ RowsChunk getChunk() {
49+ return _chunk;
50+ }
51+
52+ /**
53+ * このオブジェクトのカラム数を返します。
54+ * @return カラム数
55+ */
56+ int getColSize() {
57+ return _colSize;
58+ }
59+
60+ /**
61+ * このオブジェクトの指定したカラム位置に、指定した数のカラムを挿入します。<br>
62+ * @param pos カラムを挿入する位置
63+ * @param size 挿入するカラム数
64+ */
65+ void insertColumn(int pos, int size) {
66+ Cell[] newColumns = new Cell[_colSize + size];
67+ _colSize = newColumns.length;
68+ for (int i = 0; i < pos; i++) {
69+ newColumns[i] = _cols[i];
70+ }
71+ for (int i = pos; i < pos + size; i++) {
72+ newColumns[i] = new TableCell(this);
73+ }
74+ int copyFromPos = pos;
75+ for (int i = pos + size; i < newColumns.length; i++) {
76+ newColumns[i]= _cols[copyFromPos];
77+ copyFromPos++;
78+ }
79+ _cols = newColumns;
80+ }
81+}
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/RowsChunk.java (nonexistent)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/RowsChunk.java (revision 81)
@@ -0,0 +1,203 @@
1+package com.nissy_ki_chi.jpicosheet.core;
2+
3+public class RowsChunk {
4+
5+ final int ROW_SIZE = 20;
6+ final Row[] _rows = new Row[ROW_SIZE];
7+
8+ private int _beginRowNum = 0;
9+ private int _filledCount = 0;
10+ private Table _table;
11+ private RowsChunk _before = null;
12+ private RowsChunk _after = null;
13+
14+
15+ /**
16+ * 新しいオブジェクトを作成します。
17+ * @param table このオブジェクトを持つTableオブジェクト
18+ * @param beginRowNum このオブジェクトがTableの何行目からの行を持っているかを示す番号
19+ * @param beforeChunk このオブジェクトの前のRowsChunkオブジェクト
20+ */
21+ RowsChunk(Table table, int beginRowNum, RowsChunk beforeChunk) {
22+ if (table == null) throw new NullPointerException("tableがnullです。");
23+ if (beginRowNum < 0) throw new IllegalArgumentException("beginRowNumは0以上でなければなりません。");
24+ _table = table;
25+ _beginRowNum = beginRowNum;
26+ _before = beforeChunk;
27+ if (_before != null) _before.setAfter(this);
28+ }
29+
30+ /**
31+ * このオブジェクトの前のRowsChunkオブジェクトから、、そのオブジェクトの指定インデックス番号以降の行データをコピーして新しいオブジェクトを作成します。
32+ * @param table このオブジェクトを持つTableオブジェクト
33+ * @param beginRowNum このオブジェクトがTableの何行目からの行を持っているかを示す番号
34+ * @param beforeChunk このオブジェクトの前のRowsChunkオブジェクト
35+ * @param copyFromIndex このオブジェクトの前のRowsChunkオブジェクトの、何番目の行からコピーするかを示すインデックス。
36+ */
37+ RowsChunk(Table table, int beginRowNum, RowsChunk beforeChunk, int copyFromIndex) {
38+ if (table == null) throw new NullPointerException("tableがnullです。");
39+ if (beginRowNum < 0) throw new IllegalArgumentException("beginRowNumは0以上でなければなりません。");
40+ if (beforeChunk == null) throw new NullPointerException("beforeChunkがnullです。");
41+ if (copyFromIndex < 0) throw new IllegalArgumentException("copyFromIndexは0以上でなければなりません。");
42+ _table = table;
43+ _beginRowNum = beforeChunk.getBeginRowNum() + copyFromIndex;
44+ _before = beforeChunk;
45+ _after = beforeChunk.getAfter();
46+ _before.setAfter(this);
47+ for (int i = copyFromIndex; (_before._rows[i] != null) && (i < ROW_SIZE); i++) {
48+ this._rows[_filledCount] = _before._rows[i];
49+ _filledCount++;
50+ }
51+
52+ }
53+
54+ /**
55+ * このオブジェクトに続くRowsChunkオブジェクトを指定します。
56+ * @param after
57+ */
58+ void setAfter(RowsChunk after) {
59+ this._after = after;
60+ }
61+
62+ /**
63+ * このオブジェクトの次のRowsChunkオブジェクトを返します。
64+ */
65+ RowsChunk getAfter() {
66+ return this._after;
67+ }
68+
69+ int getRowNumber(Row row) {
70+ for (int i = 0; i < ROW_SIZE; i++) {
71+ // nullを検索してしまう前に見つかるはず
72+ assert (_rows[i] != null);
73+ if (_rows[i] == row) return i + _beginRowNum;
74+ }
75+ return -1;
76+ }
77+
78+ /**
79+ * このテーブルの末尾に、addRowCountで指定した行数を追加します。
80+ * @param addRowCount 追加する行数。
81+ */
82+ /**
83+ * このテーブルの末尾に、addRowCountで指定した行数を追加します。
84+ * @param addRowCount 追加する行数。
85+ * @return チェーン末尾のRowsChunkオブジェクト
86+ */
87+ RowsChunk addRow(int addRowCount) {
88+ if (addRowCount < 1) throw new IllegalArgumentException("追加する行数は1以上でなければなりません。");
89+
90+ int remainingRows = ROW_SIZE - _filledCount;
91+ if (addRowCount <= remainingRows) {
92+ // このRowsChunkの残りの空き行数が足りている
93+ addRowToThis(addRowCount);
94+ return this;
95+ } else {
96+ // 空き行数が足りない。新しいRowsChunkを追加する
97+ addRowToThis(remainingRows);
98+ int moreNeed = addRowCount - remainingRows;
99+ RowsChunk newLastChunk;
100+ int newChunkCnt = moreNeed / ROW_SIZE + 1;
101+ int lastChunkRows = moreNeed % ROW_SIZE;
102+ newLastChunk = addFullFilledChunk(newChunkCnt);
103+ if (lastChunkRows > 0) {
104+ newLastChunk = addHalfFilledChunk(newLastChunk, lastChunkRows);
105+ }
106+ return newLastChunk;
107+ }
108+ }
109+
110+ private void addRowToThis(int addRowCount) {
111+ for (int i = _filledCount; i < addRowCount; i++) {
112+ _rows[i] = new Row(this, this._table.getColSize());
113+ _filledCount++;
114+ }
115+ }
116+
117+ private RowsChunk addFullFilledChunk(int chunkCount) {
118+ RowsChunk beforeChunk = this;
119+ int beginRowNum = this._beginRowNum + this._filledCount;
120+ RowsChunk lastChunk = this;
121+ for (int i = 0; i < chunkCount; i++) {
122+ RowsChunk newChunk = new RowsChunk(this._table, beginRowNum + (ROW_SIZE * i), beforeChunk);
123+ newChunk.addRowToThis(ROW_SIZE);
124+ beforeChunk.setAfter(newChunk);
125+ lastChunk = newChunk;
126+ }
127+ return lastChunk;
128+ }
129+
130+ private RowsChunk addHalfFilledChunk(RowsChunk lastChunk, int addRowCount) {
131+ // 0行追加なら何もしない
132+ if (addRowCount == 0) return this;
133+
134+ RowsChunk beforeChunk = lastChunk;
135+ RowsChunk newLastChunk = new RowsChunk(this._table, lastChunk.getLastRowNum() + 1, beforeChunk);
136+ newLastChunk.addRowToThis(addRowCount);
137+ return newLastChunk;
138+ }
139+
140+
141+
142+ /**
143+ * このオブジェクトの最初のRowが、Tableの何行目であるかを指定します。
144+ * @param newRownum
145+ */
146+ void setBeginRowNum(int newRownum) {
147+ _beginRowNum = newRownum;
148+ }
149+
150+ /**
151+ * このオブジェクトの最初のRowが、Tableの何行目であるかを返します。
152+ * @return
153+ */
154+ int getBeginRowNum() {
155+ return _beginRowNum;
156+ }
157+
158+ /**
159+ * このオブジェクトの最後のRowが、Tableの何行目であるかを返します。
160+ * @return
161+ */
162+ int getLastRowNum() {
163+ return _beginRowNum + _filledCount - 1;
164+ }
165+
166+
167+ /**
168+ * このオブジェクトに作成されたRowオブジェクトの最大のインデックス番号を返します。
169+ * @return Rowオブジェクトの最大のインデックス番号
170+ */
171+ int getFilledCount() {
172+ return _filledCount;
173+ }
174+
175+ /**
176+ * 指定されたインデックス番号のRowオブジェクトを返します。
177+ * @param index 取得するRowオブジェクトの、このオブジェクトにおけるインデックス番号
178+ * @return Rowオブジェクト
179+ */
180+ Row getRow(int index) {
181+ if (index < 0) throw new IllegalArgumentException("indexは0以上でなければなりません。");
182+ return _rows[index];
183+ }
184+
185+ /**
186+ * このオブジェクトを持つTableオブジェクトを返します。
187+ * @return このオブジェクトを持つTableオブジェクト
188+ */
189+ Table getTable() {
190+ return _table;
191+ }
192+
193+ /**
194+ * 指定されたインデックス番号以降のRowオブジェクトを削除します。
195+ * @param index 削除するRowオブジェクトのインデックス
196+ */
197+ void eraseRowsAfter(int index) {
198+ for (int i = index; i < _filledCount; i++) {
199+ _rows[i] = null;
200+ }
201+ _filledCount = index;
202+ }
203+}
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Sheet.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Sheet.java (revision 81)
@@ -28,8 +28,6 @@
2828 import com.nissy_ki_chi.jpicosheet.core.Cell.CellStatus;
2929 import com.nissy_ki_chi.jpicosheet.core.Cell.CellType;
3030
31-
32-
3331 /**
3432 * 複数のセル、グループを持つことのできる"シート"です。<br>
3533 *
@@ -232,7 +230,7 @@
232230 return this._cells.get(shortName);
233231 } else {
234232 // そうでない場合、新しいセルを作成し、返す
235- Cell cell = new Cell(shortName, this, forTableCell);
233+ Cell cell = new PlainCell(shortName, this, forTableCell);
236234 this._cells.put(shortName, cell);
237235 return cell;
238236 }
@@ -247,15 +245,38 @@
247245 public Cell getCell(String cellName) {
248246
249247 String shortName = getShortName(cellName);
250- // 指定されたセルを返す
248+ // 普通のセルから探す
251249 if (this._cells.containsKey(shortName)) {
252250 return this._cells.get(shortName);
253- } else {
254- // セルが存在しなかった場合、例外をスロー
255- throw new ReferenceNotFoundException("cellname " + cellName + " is not found");
256251 }
252+ // 見つからなかったらテーブルから探す
253+ Cell tableCell = getCellFromTablesCell(cellName);
254+ if(tableCell != null) {
255+ return tableCell;
256+ }
257+ // セルが存在しなかった場合、例外をスロー
258+ throw new ReferenceNotFoundException("cellname " + cellName + " is not found");
257259 }
258260
261+ private Cell getCellFromTablesCell(String tableCellName) {
262+ if (!Table.isValidTableNameWithAddress(tableCellName)) {
263+ return null;
264+ }
265+ int sharpIndex = tableCellName.lastIndexOf('#');
266+ String tableName = tableCellName.substring(0, sharpIndex + 1);
267+ String[] address = tableCellName.substring(sharpIndex + 2).split("[RrCc]");
268+ int row = Integer.parseInt(address[0]);
269+ int col = Integer.parseInt(address[1]);
270+ Table targetTable = _tables.get(tableName);
271+ if (targetTable != null) {
272+ if ((col < targetTable.getColSize()) && (row < targetTable.getRowSize())) {
273+ return _tables.get(tableName).getCell(row, col);
274+ }
275+ }
276+ return null;
277+ }
278+
279+
259280 /**
260281 * このシートが保持しているすべてのセルへの参照を返します
261282 * @return シートが保持しているすべてのセルへの参照
@@ -553,7 +574,8 @@
553574 return this._tables.get(shortTableName);
554575 } else {
555576 // そうでない場合、新しいテーブルを作成
556- Table table = new Table(shortTableName, rowSize, colSize, this);
577+ Table table = new Table(shortTableName, colSize, this);
578+ table.addRow(rowSize);
557579 this._tables.put(shortTableName, table);
558580
559581 // // このテーブルを参照している(そして参照できていなかった)セルがある場合、それらのセルを再計算する
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Table.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Table.java (revision 81)
@@ -49,15 +49,10 @@
4949 private String _name;
5050
5151 /**
52- * このテーブルの行
53- */
54- private List<List<Cell>> _rows;
55-
56- /**
5752 * このテーブルを持っているSheetオブジェクトへの参照
5853 */
5954 private Sheet _sheet;
60-
55+
6156 /**
6257 * このテーブルのカラムサイズ
6358 */
@@ -86,7 +81,7 @@
8681 /**
8782 * アドレスのパターン文字列
8883 */
89- static final String ADDRESS_PATTERN = "(R[0-9]+C[0-9]+)";
84+ static final String ADDRESS_PATTERN = "(R[1-9]?[0-9]*C[1-9]?[0-9]+)";
9085
9186 /**
9287 * アドレスの正規表現パターン
@@ -166,34 +161,40 @@
166161 private static Pattern _fullyQualifiedtableNameWithRangePattern = Pattern.compile(FULLY_QUALIFIED_TABLE_NAME_WITH_RANGE_PATTERN);
167162
168163 /**
169- * テーブル名とシートオブジェクトを指定してオブジェクトを作成します
164+ * テーブルの行方向のデータを保持するオブジェクトチェーンの、最初の要素
165+ */
166+ private RowsChunk _rowsChunkHead;
167+
168+ /**
169+ * テーブルの行方向のデータを保持するオブジェクトチェーンの、最後の要素
170+ */
171+ private RowsChunk _rowsChunkTail;
172+
173+
174+ /**
175+ * テーブル名とシートオブジェクト、カラムサイズを指定してオブジェクトを作成します。
170176 * @param tableName テーブル名
171- * @param rowSize テーブルの行数
172177 * @param colSize テーブルの列数
173178 * @param sheet このテーブルを持っているSheetオブジェクトへの参照
179+ * @throws IllegalArgumentException
174180 */
175- Table(String tableName, int rowSize, int colSize, Sheet sheet) throws IllegalArgumentException {
181+ Table(String tableName, int colSize, Sheet sheet) throws IllegalArgumentException {
176182
177183 validateTableName(tableName);
178184
179- // rowSize, colSizeは1以上でなければならない
180- if (rowSize <= 0 || colSize <= 0) {
181- throw new IllegalArgumentException("invalid row/col size. " +
182- "row=" + Integer.toString(rowSize) +" col=" + Integer.toString(colSize));
185+ // colSizeは1以上でなければならない
186+ if (colSize < 1) {
187+ throw new IllegalArgumentException("invalid col size. " +
188+ " col=" + Integer.toString(colSize));
183189 }
184190
185191 _name = tableName;
186192 _colSize = colSize;
193+ _rowsChunkHead = new RowsChunk(this, 0, null);
194+ _rowsChunkTail = _rowsChunkHead;
187195 _sheet = sheet;
188-
189- // 引数で指定されたサイズのテーブルを作成する。セルも同時に作成する
190- _rows = new ArrayList<List<Cell>>(rowSize);
191- for (int row = 0; row < rowSize; row++) {
192- _rows.add(createRow(row));
193- }
194196 }
195-
196-
197+
197198 /**
198199 * 渡された文字列がテーブル名として正しいかチェックします。<br>
199200 * 正しくない場合、例外がスローされます。
@@ -294,6 +295,14 @@
294295 }
295296
296297 /**
298+ * このオブジェクトを持つSheetオブジェクトを返します。
299+ * @return このオブジェクトを持つSheetオブジェクト
300+ */
301+ Sheet getSheet() {
302+ return _sheet;
303+ }
304+
305+ /**
297306 * このテーブルの名前を返します
298307 * @return テーブルの名前
299308 */
@@ -337,106 +346,110 @@
337346 * このテーブルの行方向の末尾に新しい行を指定した行数だけ追加します。
338347 * @param addRowCount 追加する行数
339348 * @return このテーブル
340- * @throws IllegalArgumentException 行数の指定が0未満の場合
349+ * @throws IllegalArgumentException 行数の指定が1未満の場合
341350 */
342351 public Table addRow(int addRowCount) {
343352
344- if (addRowCount < 0) {
353+ if (addRowCount < 1) {
345354 throw new IllegalArgumentException("invalid addRowCount: " + Integer.toString(addRowCount));
346355 }
347356
348- for (int i = 0; i < addRowCount; i++) {
349- _rows.add(createRow(_rows.size()));
350- }
357+ _rowsChunkTail = _rowsChunkTail.addRow(addRowCount);
351358 return this;
352359 }
353360
354- /**
355- * このテーブルの列方向の末尾に新しい列を1列追加します。
361+// /**
362+// * このテーブルの列方向の末尾に新しい列を1列追加します。
363+// * @return このテーブル
364+// */
365+// public Table addColumn() {
366+// return addColumn(1);
367+// }
368+//
369+// /**
370+// * このテーブルの列方向の末尾に新しい列を指定した列数だけ追加します。
371+// * @param addColumnCount 追加する列数
372+// * @return このテーブル
373+// * @throws IllegalArgumentException 列数の指定が0未満の場合
374+// */
375+// public Table addColumn(int addColumnCount) {
376+//
377+// if (addColumnCount < 0) {
378+// throw new IllegalArgumentException("invalid addColumnCount: " + Integer.toString(addColumnCount));
379+// }
380+//
381+// for (int i = 0; i < _rows.size(); i++) {
382+// for (int o = 0; o < addColumnCount; o++) {
383+// String newCellName = _name + "R" + Integer.toString(i) + "C" + Integer.toString(_rows.get(i).size());
384+// Cell cell = _sheet.addCell(newCellName, true);
385+// _rows.get(i).add(cell);
386+// }
387+// }
388+// return this;
389+// }
390+//
391+
392+
393+
394+ /**このテーブルの指定した位置に、指定した行数の行を挿入します。
395+ * @param rowPos 挿入する位置
396+ * @param insertRowCount 挿入する行数
356397 * @return このテーブル
357398 */
358- public Table addColumn() {
359- return addColumn(1);
360- }
399+ public Table insertRow(int rowPos, int insertRowCount) {
400+
401+ if (rowPos < 0) throw new IllegalArgumentException("rowPosは0以上でなければなりません。");
402+ if (insertRowCount < 1) throw new IllegalArgumentException("insertRowCountは0以上でなければなりません。");
361403
362- /**
363- * このテーブルの列方向の末尾に新しい列を指定した列数だけ追加します。
364- * @param addColumnCount 追加する列数
365- * @return このテーブル
366- * @throws IllegalArgumentException 列数の指定が0未満の場合
367- */
368- public Table addColumn(int addColumnCount) {
369-
370- if (addColumnCount < 0) {
371- throw new IllegalArgumentException("invalid addColumnCount: " + Integer.toString(addColumnCount));
404+ RowsChunk targetChunk = this._rowsChunkHead;
405+ while (targetChunk != null) {
406+ // 目的の行を含むRowsChunkが見つかるか、最後のRowsChunkまで来たらtargetChunk決定
407+ if (rowPos <= targetChunk.getLastRowNum()) break;
408+ if (targetChunk.getAfter() == null) break;
409+ targetChunk = targetChunk.getAfter();
372410 }
411+
412+ // このRowsChunkの挿入ポイントより後ろにRowがあれば、それを新しいRowsChunkに移す
413+ int cutPoint = rowPos - targetChunk.getBeginRowNum();
414+ RowsChunk devidedChunk = null;
415+ if (cutPoint < targetChunk.getFilledCount()) {
416+ devidedChunk = new RowsChunk(this, rowPos, targetChunk, cutPoint);
417+ targetChunk.eraseRowsAfter(cutPoint);
418+ }
419+
420+ // 行を挿入…targetChunkに対して行の追加を行う
421+ RowsChunk addRowLast = targetChunk.addRow(insertRowCount);
373422
374- for (int i = 0; i < _rows.size(); i++) {
375- for (int o = 0; o < addColumnCount; o++) {
376- String newCellName = _name + "R" + Integer.toString(i) + "C" + Integer.toString(_rows.get(i).size());
377- Cell cell = _sheet.addCell(newCellName, true);
378- _rows.get(i).add(cell);
379- }
423+ // 挿入ポイント以降の行番号情報をずらす
424+ RowsChunk renumTarget;
425+ if (devidedChunk != null) {
426+ addRowLast.setAfter(devidedChunk);
427+ renumTarget = devidedChunk;
428+ } else {
429+ addRowLast.setAfter(targetChunk.getAfter());
430+ renumTarget = addRowLast;
380431 }
432+ do {
433+ renumTarget.setBeginRowNum(renumTarget.getBeginRowNum() + insertRowCount);
434+ _rowsChunkTail = renumTarget;
435+ } while ((renumTarget = renumTarget.getAfter()) != null);
436+
381437 return this;
382438 }
383-
439+
440+
441+
384442 /**
385- * このテーブルの指定した位置に1行挿入します。
443+ * このテーブルの指定した位置に1行挿入します。挿入位置がテーブルの行数より大きい場合、テーブルの末尾に1行追加されます。
386444 * @param rowPos 挿入する位置
387445 * @return このテーブル
388446 */
389447 public Table insertRow(int rowPos) {
390-
448+ if ((0 <= rowPos) && (this.getRowSize() < rowPos)) return addRow();
391449 return insertRow(rowPos, 1);
392450 }
393451
394- /**このテーブルの指定した位置に、指定した行数の行を挿入します。
395- * @param rowPos 挿入する位置
396- * @param insertRowCount 挿入する行数
397- * @return このテーブル
398- */
399- public Table insertRow(int rowPos, int insertRowCount) {
400- // rowPosがマイナスであってはならない
401- if (rowPos < 0) {
402- throw new IllegalArgumentException("ingalid rowPos: " + Integer.toString(rowPos));
403- }
404- // rowPosがテーブルの最大行以上であってはならない
405- if (_rows.size() <= rowPos) {
406- throw new IllegalArgumentException("ingalid rowPos: " + Integer.toString(rowPos) + " table rowsize: " + Integer.toString(_rows.size()));
407- }
408- // insertRowCountが1以下であってはならない
409- if (insertRowCount < 1) {
410- throw new IllegalArgumentException("ingalid insertRowCount: " + Integer.toString(insertRowCount));
411- }
412452
413- // rowPosより後ろの行のセルの、セル名をリネームする 名前が重複しないよう行末からリネーム
414- StringBuilder cellName = new StringBuilder();
415- StringBuilder newCellName = new StringBuilder();
416- for (int rowIndex = _rows.size() - 1; rowPos <= rowIndex ; rowIndex--) {
417- for (int colIndex = _rows.get(0).size() - 1; 0 <= colIndex; colIndex--) {
418- cellName.delete(0, cellName.length());
419- newCellName.delete(0, newCellName.length());
420- cellName.append(_name).append("R").append(rowIndex).append("C").append(colIndex);
421- newCellName.append(_name).append("R").append(rowIndex + insertRowCount).append("C").append(colIndex);
422- try {
423- _sheet.renameCell(cellName.toString(), newCellName.toString());
424- } catch (ReferenceNotFoundException e) {
425- // これが発生するということは、この処理での名前の指定が悪いということ
426- assert false: "Cell not found: " + cellName.toString();
427- }
428- }
429- }
430-
431- // rowPosで指定された位置にinsertRowCount行だけ行を挿入する
432- for (int rowIndex = rowPos; rowIndex < rowPos + insertRowCount; rowIndex++) {
433- _rows.add(rowIndex, createRow(rowIndex));
434- }
435-
436- return this;
437- }
438-
439-
440453 /**このテーブルの指定した位置に1列挿入します。
441454 * @param rowPos 挿入する位置
442455 * @return このテーブル
@@ -448,49 +461,34 @@
448461
449462 /**このテーブルの指定した位置に、指定した列数の列を挿入します。
450463 * @param columnPos 挿入する位置
451- * @param insertColumnCount 挿入する列数
464+ * @param size 挿入する列数
452465 * @return このテーブル
453466 */
454- public Table insertColumn(int columnPos, int insertColumnCount) {
467+ public Table insertColumn(int columnPos, int size) {
455468 // columnPosがマイナスであってはならない
456469 if (columnPos < 0) {
457470 throw new IllegalArgumentException("ingalid columnPos: " + Integer.toString(columnPos));
458471 }
459472 // columnPosがテーブルの最大列以上であってはならない
460- if (_rows.get(0).size() <= columnPos) {
461- throw new IllegalArgumentException("ingalid columnPos: " + Integer.toString(columnPos) + " table columnsize: " + Integer.toString(_rows.get(0).size()));
473+ if (_colSize <= columnPos) {
474+ throw new IllegalArgumentException("ingalid columnPos: " + Integer.toString(columnPos) + " table columnsize: " + Integer.toString(_colSize));
462475 }
463476 // insertColumnCountが1以下であってはならない
464- if (insertColumnCount < 1) {
465- throw new IllegalArgumentException("ingalid insertColumnCount: " + Integer.toString(insertColumnCount));
477+ if (size < 1) {
478+ throw new IllegalArgumentException("ingalid insertColumnCount: " + Integer.toString(size));
466479 }
467-
480+
468481 // すべての行に対し、指定位置に列を挿入する
469- StringBuilder cellName = new StringBuilder();
470- StringBuilder newCellName = new StringBuilder();
471- // 行ぶんループ
472- for (int rowIndex = 0; rowIndex < _rows.size(); rowIndex++) {
473- // 挿入位置より後ろの列をリネーム。リネームを行うため、末尾から操作する
474- for (int colIndex = _rows.get(rowIndex).size() - 1; columnPos <= colIndex; colIndex--) {
475- cellName.delete(0, cellName.length());
476- newCellName.delete(0, newCellName.length());
477- cellName.append(_name).append("R").append(rowIndex).append("C").append(colIndex);
478- newCellName.append(_name).append("R").append(rowIndex).append("C").append(colIndex + insertColumnCount);
479- try {
480- _sheet.renameCell(cellName.toString(), newCellName.toString());
481- } catch (ReferenceNotFoundException e) {
482- // これが発生するということは、この処理での名前の指定が悪いということ
483- assert false: "Cell not found: " + cellName.toString();
484- }
482+ _colSize += size;
483+ RowsChunk targetChunk = _rowsChunkHead;
484+ while (targetChunk != null) {
485+ Row targetRow;
486+ for (int i = 0; i < targetChunk.getFilledCount(); i++) {
487+ targetRow = targetChunk.getRow(i);
488+ targetRow.insertColumn(columnPos, size);
485489 }
486- // 指定された列位置にセルを挿入する
487- for (int i = 0; i < insertColumnCount; i++) {
488- String addCellName = _name + "R" + Integer.toString(rowIndex) + "C" + Integer.toString(columnPos + i);
489- Cell cell = _sheet.addCell(addCellName, true);
490- _rows.get(rowIndex).add(columnPos + i, cell);
491- }
490+ targetChunk = targetChunk.getAfter();
492491 }
493-
494492 return this;
495493 }
496494
@@ -500,7 +498,7 @@
500498 * @return このテーブルの行数
501499 */
502500 public int getRowSize() {
503- return _rows.size();
501+ return this._rowsChunkTail.getLastRowNum() + 1;
504502 }
505503
506504 /**
@@ -586,7 +584,7 @@
586584 // RnCxあるいはRxCnの場合、1行もしくは1列選択
587585 if (rowFromStr.equals("x")) {
588586 rowFrom = 0;
589- rowTo = _rows.size() - 1;
587+ rowTo = _rowsChunkTail.getLastRowNum();
590588 } else {
591589 rowFrom = Integer.parseInt(rowFromStr);
592590 rowTo = rowFrom;
@@ -612,7 +610,7 @@
612610 colFrom = Integer.parseInt(colFromStr);
613611 // To側は空の指定の場合がある
614612 if (rowToStr.equals("x")) {
615- rowTo = _rows.size() - 1;
613+ rowTo = _rowsChunkTail.getLastRowNum();
616614 } else {
617615 rowTo = Integer.parseInt(rowToStr);
618616 }
@@ -637,7 +635,20 @@
637635 * @return 指定された位置のCellオブジェクト
638636 */
639637 public Cell getCell(int rowIndex, int colIndex) {
640- return _rows.get(rowIndex).get(colIndex);
638+ if (getRowSize() < rowIndex) throw new IllegalArgumentException("rowIndexが大きすぎます。");
639+ if (_colSize <= colIndex) throw new IllegalArgumentException("colIndexが大きすぎます。");
640+
641+ RowsChunk targetChunk = this._rowsChunkHead;
642+ while (targetChunk != null) {
643+ if (rowIndex <= targetChunk.getLastRowNum()) {
644+ Row row = targetChunk.getRow(rowIndex - targetChunk.getBeginRowNum());
645+ return row.getCell(colIndex);
646+ }
647+ targetChunk = targetChunk.getAfter();
648+ }
649+ // ここには来ない
650+ assert(false);
651+ return null;
641652 }
642653
643654
@@ -645,38 +656,43 @@
645656 * @see com.nissy_ki_chi.jpicosheet.core.CellGroupReference#getCells()
646657 */
647658 public Collection<Cell> getCells() {
648- List<Cell> cells = new ArrayList<Cell>(_rows.size() * _rows.get(0).size());
649- for (int i = 0; i < _rows.size(); i++) {
650- for (int o = 0; o < _rows.get(0).size(); o++) {
651- cells.add(_rows.get(i).get(o));
659+ List<Cell> cells = new ArrayList<Cell>(this._colSize * this._rowsChunkTail.getLastRowNum());
660+ RowsChunk targetChunk = this._rowsChunkHead;
661+ while (targetChunk != null) {
662+ for (int i = 0; i < targetChunk.getFilledCount(); i++) {
663+ Row row = targetChunk.getRow(i);
664+ for (Cell c: row.getCols()) {
665+ cells.add(c);
666+ }
652667 }
668+ targetChunk = targetChunk.getAfter();
653669 }
654670 return cells;
655671 }
656672
657- /* (非 Javadoc)
658- * @see java.lang.Object#equals(java.lang.Object)
659- */
660- @Override
661- public boolean equals(Object obj) {
662- if (obj instanceof Table) {
663- Table t = (Table) obj;
664- if (this._colSize == t._colSize) {
665- if (this._rows.size() == t._rows.size()) {
666- // テーブル内のすべてのセルを比較 サイズが大きいととても効率が悪い
667- for (int rowNum = 0; rowNum < this._rows.size(); rowNum++) {
668- List<Cell> myRow = _rows.get(rowNum);
669- List<Cell> tRow = t._rows.get(rowNum);
670- for (int colNum = 0; colNum < myRow.size(); colNum++) {
671- if (! myRow.get(colNum).equals(tRow.get(colNum))) {
672- return false;
673- }
674- }
675- }
676- return true;
677- }
678- }
679- }
680- return false;
681- }
673+// /* (非 Javadoc)
674+// * @see java.lang.Object#equals(java.lang.Object)
675+// */
676+// @Override
677+// public boolean equals(Object obj) {
678+// if (obj instanceof Table) {
679+// Table t = (Table) obj;
680+// if (this._colSize == t._colSize) {
681+// if (this._rows.size() == t._rows.size()) {
682+// // テーブル内のすべてのセルを比較 サイズが大きいととても効率が悪い
683+// for (int rowNum = 0; rowNum < this._rows.size(); rowNum++) {
684+// List<Cell> myRow = _rows.get(rowNum);
685+// List<Cell> tRow = t._rows.get(rowNum);
686+// for (int colNum = 0; colNum < myRow.size(); colNum++) {
687+// if (! myRow.get(colNum).equals(tRow.get(colNum))) {
688+// return false;
689+// }
690+// }
691+// }
692+// return true;
693+// }
694+// }
695+// }
696+// return false;
697+// }
682698 }
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/TableCell.java (nonexistent)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/TableCell.java (revision 81)
@@ -0,0 +1,83 @@
1+package com.nissy_ki_chi.jpicosheet.core;
2+
3+public class TableCell extends Cell {
4+
5+ /**
6+ * このセルを保持しているRowオブジェクト
7+ */
8+ Row _row;
9+
10+ /**
11+ * 行オブジェクトを指定してオブジェクトを作成します
12+ * @param row このセルオブジェクトが属する行を表すオブジェクト
13+ */
14+ TableCell(Row row) throws IllegalArgumentException {
15+
16+ this._row = row;
17+
18+ // メンバに値をセット
19+ this._formula = null;
20+ this._value = emptyElement;
21+ }
22+
23+ @Override
24+ public String getName() {
25+ StringBuilder sb = new StringBuilder(_row.getChunk().getTable().getName());
26+ sb.append("R").append(getRowNumber()).append("C").append(getColNumber());
27+ return sb.toString();
28+ }
29+
30+ @Override
31+ public String getLabel() {
32+ // ラベルは付けられない
33+ return null;
34+ }
35+
36+ @Override
37+ public String getFullyQualifiedName() {
38+ return getSheet().getName() + "!" + getName();
39+ }
40+
41+ @Override
42+ public Sheet getSheet() {
43+ return this._row.getChunk().getTable().getSheet();
44+ }
45+
46+ @Override
47+ void setName(String cellName) {
48+ // セル名は変更不可。何もしない
49+ }
50+
51+ @Override
52+ void setName(String cellName, boolean createForTableCell) throws IllegalArgumentException {
53+ // セル名は変更不可。何もしない
54+ }
55+
56+ @Override
57+ public Cell setLabel(String newLabel) {
58+ // ラベルは指定不可。何もしない
59+ return null;
60+ }
61+
62+ public static boolean isValidCellName(String cellName) {
63+ return true;
64+ }
65+
66+ public static boolean isValidFullyQualifiedCellName(String fullyQualifiedCellName) {
67+ return true;
68+ }
69+
70+ private int getColNumber() {
71+ for (int i = 0; i < _row.getColSize(); i++) {
72+ if (_row.getCols()[i] == this) return i;
73+ }
74+ // ここには来ないはず
75+ assert(false);
76+ return -1;
77+ }
78+
79+ private int getRowNumber() {
80+ return _row.getChunk().getRowNumber(_row);
81+ }
82+
83+}
--- trunk/src/com/nissy_ki_chi/jpicosheet/util/SimpleReader.java (revision 80)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/util/SimpleReader.java (revision 81)
@@ -54,11 +54,12 @@
5454
5555
5656 try {
57- WriteLock writeLock = _bookWrapper.getWriteLock();
58- Book book = _bookWrapper.getBook(writeLock);
57+// WriteLock writeLock = _bookWrapper.getWriteLock();
58+// Book book = _bookWrapper.getBook(writeLock);
59+// Book book = _bookWrapper.getBook();
5960
60- book.recalcDisable();
61-
61+// book.recalcDisable();
62+ _bookWrapper.recalcDisable();
6263 while(true) {
6364 // 行を読み込むと同時にエスケープ文字を復元
6465 String readLine = revertingEscapedChars(br.readLine());
@@ -66,7 +67,7 @@
6667 break;
6768 } else {
6869 if (readLine.charAt(0) == '@') {
69- doAtmarkLine(book, readLine);
70+ doAtmarkLine(readLine);
7071 } else {
7172 String cellName = readLine.substring(0, readLine.indexOf("\t"));
7273 String cellValue = readLine.substring(readLine.indexOf("\t")+1);
@@ -76,10 +77,11 @@
7677
7778 }
7879
79- book.recalcEnable();
80+
8081
8182 } finally {
82- _bookWrapper.releaseWriteLock();
83+ _bookWrapper.recalcEnable();
84+// _bookWrapper.releaseWriteLock();
8385 }
8486 }
8587
@@ -122,11 +124,11 @@
122124 * @param book ブックオブジェクト
123125 * @param line アットマーク付きのテキスト行
124126 */
125- private void doAtmarkLine(Book book, String line){
127+ private void doAtmarkLine(String line){
126128
127- if (line.equals("@Book:name\t.*")) {
129+ if (line.matches("@Book:name\t.*")) {
128130 String bookName = splitAtmarkValue(line);
129- book.setName(bookName);
131+ _bookWrapper.setBookName(bookName);
130132 return;
131133 }
132134
@@ -133,14 +135,15 @@
133135 if (line.matches("@[^:]+:MathContext\t.*")) {
134136 String mathContextString = splitAtmarkValue(line);
135137 String sheetName = line.substring(1, line.indexOf(':'));
136- book.addSheet(sheetName).setMathContext(new MathContext(mathContextString));
138+ _bookWrapper.addSheet(sheetName);
139+ _bookWrapper.setMathContext(sheetName, new MathContext(mathContextString));
137140 return;
138141 }
139142
140143 if (line.matches("@[^:]+:Label\t.*")) {
141144 String labelString = splitAtmarkValue(line);
142- String[] sheetCellName = line.substring(1, line.indexOf(':')).split("!");
143- book.addSheet(sheetCellName[0]).addCell(sheetCellName[1]).setLabel(labelString);
145+ String sheetCellName = line.substring(1, line.indexOf(':'));
146+ _bookWrapper.setCellLabel(sheetCellName, labelString);
144147 return;
145148 }
146149
@@ -149,13 +152,14 @@
149152 int rowSize = Integer.parseInt(rowcolStr[0]);
150153 int colSize = Integer.parseInt(rowcolStr[1]);
151154 String[] sheetTableName = line.substring(1, line.indexOf(':')).split("!");
152- book.addSheet(sheetTableName[0]).addTable(sheetTableName[1], rowSize, colSize);
155+ _bookWrapper.addTable(sheetTableName[0], sheetTableName[1], rowSize, colSize);
153156 }
154157
155158 if (line.matches("@[^:]+:Group\t.*")) {
156- String[] groupString = splitAtmarkValue(line).split(",");
159+ String[] cellToAdd = splitAtmarkValue(line).split(",");
157160 String[] sheetGroupName = line.substring(1, line.indexOf(':')).split("!");
158- book.addSheet(sheetGroupName[0]).addGroup(sheetGroupName[1]).addCells(groupString);
161+ _bookWrapper.addGroup(sheetGroupName[0], sheetGroupName[1]);
162+ _bookWrapper.addCellsToGroup(sheetGroupName[0], sheetGroupName[1], cellToAdd);
159163 }
160164 }
161165
--- trunk/src/test/AllTests.java (revision 80)
+++ trunk/src/test/AllTests.java (revision 81)
@@ -39,6 +39,7 @@
3939 suite.addTestSuite(TextLoaderTest.class);
4040 suite.addTestSuite(ConcurrentBookWrapperTest.class);
4141 suite.addTestSuite(SimpleWriterTest.class);
42+ suite.addTestSuite(XMLReaderTest.class);
4243 //$JUnit-END$
4344 return suite;
4445 }
--- trunk/src/test/ElementTest.java (revision 80)
+++ trunk/src/test/ElementTest.java (revision 81)
@@ -57,7 +57,7 @@
5757 // OK
5858 return;
5959 }
60- Assert.fail();
60+ fail();
6161 }
6262
6363 public void testElementNumber() {
@@ -103,7 +103,7 @@
103103 // OK
104104 return;
105105 }
106- Assert.fail();
106+ fail();
107107 }
108108
109109
@@ -132,7 +132,7 @@
132132 // OK
133133 return;
134134 }
135- Assert.fail();
135+ fail();
136136 }
137137
138138 public void testElementDate() throws ParseException {
@@ -215,7 +215,7 @@
215215 // OK
216216 return;
217217 }
218- Assert.fail();
218+ fail();
219219 }
220220
221221 public void testElementOperator() {
@@ -243,7 +243,7 @@
243243 // OK
244244 return;
245245 }
246- Assert.fail();
246+ fail();
247247 }
248248
249249 public void testElementError() {
@@ -269,7 +269,7 @@
269269 elem.getErrorType();
270270 } catch (IllegalStateException e) {
271271 // NG
272- Assert.fail();
272+ fail();
273273 }
274274 }
275275
@@ -299,7 +299,7 @@
299299 // OK
300300 return;
301301 }
302- Assert.fail();
302+ fail();
303303 }
304304
305305 public void testElementReference() {
@@ -327,7 +327,7 @@
327327 // OK
328328 return;
329329 }
330- Assert.fail();
330+ fail();
331331 }
332332
333333 public void testElementGroupReference() {
@@ -355,7 +355,7 @@
355355 // OK
356356 return;
357357 }
358- Assert.fail();
358+ fail();
359359 }
360360
361361 public void testElementTableReference() {
@@ -383,7 +383,7 @@
383383 // OK
384384 return;
385385 }
386- Assert.fail();
386+ fail();
387387 }
388388
389389
--- trunk/src/test/FunctionTest.java (revision 80)
+++ trunk/src/test/FunctionTest.java (revision 81)
@@ -129,7 +129,7 @@
129129 sheet.addCell("ref2").setNumberValue("200");
130130 sheet.addCell("ref3").setFormula("ref2");
131131 sheet.addCell("formula").setFormula("AVERAGE(ref1, ref3)");
132- assertEquals(new BigDecimal(300), sheet.getCell("formula").getValue().getNumber());
132+ assertEquals(new BigDecimal(150), sheet.getCell("formula").getValue().getNumber());
133133 }
134134
135135 public void testABS() {
--- trunk/src/test/HogeShellTest.java (revision 80)
+++ trunk/src/test/HogeShellTest.java (revision 81)
@@ -98,7 +98,7 @@
9898 "n A3 3\n" +
9999 "n A4 4\n" +
100100 "n A5 5\n" +
101- "f A6 sum(A1,A2,A3,A4,A5)\n";
101+ "f A6 SUM(A1,A2,A3,A4,A5)\n";
102102 textArray = text.split("\\n");
103103
104104 hogeShell.setCellFromText(textArray);
--- trunk/src/test/SimpleReaderTest_input1.txt (nonexistent)
+++ trunk/src/test/SimpleReaderTest_input1.txt (revision 81)
@@ -0,0 +1,38 @@
1+
2+
3+context=book
4+name=book1
5+context=sheet
6+name=sheet1&precision=12&roundingmode=CEILING
7+context=cell
8+name=cell1&type=str&val=hoge
9+name=cell1&type=str&val=fuga
10+
11+
12+
13+
14+
15+context=book
16+name=book1
17+
18+context=sheet&name=sheet1&precision=12&roundingmode=CEILING
19+
20+context=cell&sheet=sheet1&name=cell1&type=str&value=hoge
21+sheet=sheet1&name=cell1&type=str&value=fuga
22+
23+context=sheet
24+name=sheet2&precision=4&roundingmode=FLOOR
25+
26+context=cell
27+sheet=sheet2&name=mycell&type=formula&value=sheet1!cell1+2.34
28+
29+context=table
30+sheet=sheet2&name=myTable&col=5&row=10
31+
32+context=tablecell
33+sheet=sheet2&name=myTable&col=0&row=0&value=123.456
34+sheet=sheet2&name=myTable&col=1&row=0&value=名前です
35+
36+context=cell
37+sheet=sheet1&name=summary&type=formula&value=sum(sheet2!myTable#)
38+
--- trunk/src/test/TableTest.java (revision 80)
+++ trunk/src/test/TableTest.java (revision 81)
@@ -182,23 +182,22 @@
182182 fail();
183183 }
184184
185- public void testAddColumn() {
186- // テーブルに列を追加できること
187- table.addColumn();
188- table.getCell(0, 10);
189- table.getCell(10, 10);
190- table.getCell(14, 10);
191- table.addColumn(1);
192- table.addColumn(100);
193- try {
194- table.addColumn(-1);
195- } catch (IllegalArgumentException e) {
196- // OK
197- return;
198- }
199- }
185+// public void testAddColumn() {
186+// // テーブルに列を追加できること
187+// table.addColumn(0);
188+// table.getCell(0, 10);
189+// table.getCell(10, 10);
190+// table.getCell(14, 10);
191+// table.addColumn(1);
192+// table.addColumn(100);
193+// try {
194+// table.addColumn(-1);
195+// } catch (IllegalArgumentException e) {
196+// // OK
197+// return;
198+// }
199+// }
200200
201-
202201 public void testInsertRow() throws IllegalStateException, ReferenceNotFoundException {
203202 // テーブルに行を挿入できること
204203 table.getCell(0, 0).setNumberValue("10");
@@ -225,15 +224,17 @@
225224 }
226225
227226 public void testInsertRow3() {
228- // テーブルの行数より大きな挿入位置指定でエラーになること
227+ // テーブルの行数より大きな挿入位置指定でエラーにならないこと
229228 try {
230- table.insertRow(16);
229+ int rowSize = table.getRowSize();
230+ // 末尾に1行追加
231+ table.insertRow(rowSize + 10);
231232 } catch (IllegalArgumentException e) {
232- // OK
233- return;
233+ // NG
234+ fail();
234235 }
235- // NG
236- fail();
236+ // OK
237+ return;
237238 }
238239
239240
@@ -266,18 +267,6 @@
266267 fail();
267268 }
268269
269- public void testInsertRow6() {
270- // テーブルの行数より大きな挿入位置指定でエラーになること
271- try {
272- table.insertRow(16, 1);
273- } catch (IllegalArgumentException e) {
274- // OK
275- return;
276- }
277- // NG
278- fail();
279- }
280-
281270 public void testInsertRow7() {
282271 // 不正な挿入行数指定でエラーになること
283272 try {
--- trunk/src/test/XMLReaderTest_input2.xml (nonexistent)
+++ trunk/src/test/XMLReaderTest_input2.xml (revision 81)
@@ -0,0 +1,59 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<book name="myBook">
3+<sheet name="sheet1" precision="12" roundingMode="CEILING">
4+<cell name="cell1" type="str"><![CDATA[mytext]]></cell>
5+<cell name="cell2" type="num"><![CDATA[1234.56]]></cell>
6+<cell name="cell3" type="num"><![CDATA[100]]></cell>
7+<cell name="cell4" type="formula"><![CDATA[=cell2+cell3]]></cell>
8+<cell name="cell5" type="date"><![CDATA[2014/05/24 23:06:00.0000]]></cell>
9+<cell name="mySummary" type="formula"><![CDATA[=sum(myGroup@)]]></cell>
10+<table col="3" name="newTable#" row="5">
11+<row num="0">
12+<col num="0" type="num"><![CDATA[10]]></col>
13+<col num="1" type="num"><![CDATA[20]]></col>
14+<col num="2" type="num"><![CDATA[30]]></col>
15+</row>
16+<row num="1">
17+<col num="0" type="formula"><![CDATA[=newTable#R0C0]]></col>
18+<col num="1" type="formula"><![CDATA[=newTable#R0C1]]></col>
19+<col num="2" type="formula"><![CDATA[=newTable#R0C2]]></col>
20+</row>
21+<row num="2">
22+<col num="0" type="formula"><![CDATA[=newTable#R1C0*12.5]]></col>
23+<col num="1" type="formula"><![CDATA[=newTable#R0C0+newTable#R0C1+newTable#R0C1]]></col>
24+<col num="2" type="formula"><![CDATA[=1+2+3+4+5+6+7+8+9+10]]></col>
25+</row>
26+<row num="3">
27+<col num="0" type="num"><![CDATA[10]]></col>
28+<col num="1" type="num"><![CDATA[10]]></col>
29+<col num="2" type="num"><![CDATA[10]]></col>
30+</row>
31+<row num="4">
32+<col num="0" type="num"><![CDATA[10]]></col>
33+<col num="1" type="num"><![CDATA[10]]></col>
34+<col num="2" type="num"><![CDATA[10]]></col>
35+</row>
36+</table>
37+<group name="myGroup@">
38+<cell name="cell4"/>
39+<cell name="cell1"/>
40+<cell name="newTable#R1C1"/>
41+</group>
42+</sheet>
43+<sheet name="sheet2" precision="12" roundingMode="FLOOR">
44+<cell name="cell1" type="str"><![CDATA[日本語です]]></cell>
45+<cell name="cell2" type="num"><![CDATA[1234.56]]></cell>
46+<cell name="cell3" type="num"><![CDATA[100]]></cell>
47+<cell name="cell4" type="formula"><![CDATA[=cell2-cell3]]></cell>
48+<table col="3" name="newTable2#" row="5">
49+<row num="0">
50+<col num="0" type="num"><![CDATA[10]]></col>
51+<col num="1" type="num"><![CDATA[20]]></col>
52+</row>
53+<row num="2">
54+<col num="1" type="num"><![CDATA[10]]></col>
55+<col num="2" type="num"><![CDATA[10]]></col>
56+</row>
57+</table>
58+</sheet>
59+</book>
--- trunk/src/test/XMLReaderTest_output1.xml (nonexistent)
+++ trunk/src/test/XMLReaderTest_output1.xml (revision 81)
@@ -0,0 +1,59 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<book name="myBook">
3+<sheet name="sheet1" precision="12" roundingMode="CEILING">
4+<cell name="cell1" type="str"><![CDATA[myText]]></cell>
5+<cell name="cell2" type="num"><![CDATA[1234.56]]></cell>
6+<cell name="cell3" type="num"><![CDATA[100]]></cell>
7+<cell name="cell4" type="formula"><![CDATA[=cell2+cell3]]></cell>
8+<cell name="cell5" type="date"><![CDATA[2014/05/24 23:06:00.0000]]></cell>
9+<cell name="mySummary" type="formula"><![CDATA[=sum(myGroup@)]]></cell>
10+<table col="3" name="newTable#" row="5">
11+<row num="0">
12+<col num="0" type="num"><![CDATA[10]]></col>
13+<col num="1" type="num"><![CDATA[20]]></col>
14+<col num="2" type="num"><![CDATA[30]]></col>
15+</row>
16+<row num="1">
17+<col num="0" type="formula"><![CDATA[=newTable#R0C0]]></col>
18+<col num="1" type="formula"><![CDATA[=newTable#R0C1]]></col>
19+<col num="2" type="formula"><![CDATA[=newTable#R0C2]]></col>
20+</row>
21+<row num="2">
22+<col num="0" type="formula"><![CDATA[=newTable#R1C0*12.5]]></col>
23+<col num="1" type="formula"><![CDATA[=newTable#R0C0+newTable#R0C1+newTable#R0C1]]></col>
24+<col num="2" type="formula"><![CDATA[=1+2+3+4+5+6+7+8+9+10]]></col>
25+</row>
26+<row num="3">
27+<col num="0" type="num"><![CDATA[10]]></col>
28+<col num="1" type="num"><![CDATA[10]]></col>
29+<col num="2" type="num"><![CDATA[10]]></col>
30+</row>
31+<row num="4">
32+<col num="0" type="num"><![CDATA[10]]></col>
33+<col num="1" type="num"><![CDATA[10]]></col>
34+<col num="2" type="num"><![CDATA[10]]></col>
35+</row>
36+</table>
37+<group name="myGroup@">
38+<cell name="cell4"/>
39+<cell name="newTable#R1C1"/>
40+<cell name="cell1"/>
41+</group>
42+</sheet>
43+<sheet name="sheet2" precision="12" roundingMode="FLOOR">
44+<cell name="cell1" type="str"><![CDATA[日本語です]]></cell>
45+<cell name="cell2" type="num"><![CDATA[1234.56]]></cell>
46+<cell name="cell3" type="num"><![CDATA[100]]></cell>
47+<cell name="cell4" type="formula"><![CDATA[=cell2-cell3]]></cell>
48+<table col="3" name="newTable2#" row="5">
49+<row num="0">
50+<col num="0" type="num"><![CDATA[10]]></col>
51+<col num="1" type="num"><![CDATA[20]]></col>
52+</row>
53+<row num="2">
54+<col num="1" type="num"><![CDATA[10]]></col>
55+<col num="2" type="num"><![CDATA[10]]></col>
56+</row>
57+</table>
58+</sheet>
59+</book>
Show on old repository browser