001 /*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016 package org.opengion.hayabusa.html;
017
018 import org.opengion.fukurou.util.StringUtil ;
019
020 import java.util.Map;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.ArrayList;
024 import java.util.Arrays;
025
026 /**
027 * String[] 型キーにカラ??の連想記?を用?、クロス?データを管?るクラスです?
028 *
029 * クロス?では、カラ??が???タとして与えられる為、このクラス?で?
030 * ?カラ??の連想記?(Map)??タを作?し?実際の行データ登録時に??タ?
031 * 設定して?す?
032 * 取り出すとき?、?に取り出すことを?慮して???ArrayList)??タに
033 * 共有して?オブジェクトを取り出します?
034 *
035 * こ?実??同期化されません?
036 *
037 * @og.rev 3.5.4.0 (2003/11/25) 新規作?
038 * @og.group 画面表示
039 *
040 * @version 4.0
041 * @author Kazuhiko Hasegawa
042 * @since JDK5.0,
043 */
044 public final class CrossMap {
045 private final Map<String,String[]> row = new HashMap<String,String[]>() ;
046 private final Map<String,Integer> clm = new HashMap<String,Integer>() ;
047 private final List<String[]> list = new ArrayList<String[]>();
048 private final int headCount;
049 private final int sumCount;
050 private final int totalCols;
051
052 /**
053 * カラ?(クロス?部)を与えて新しく作?するコンストラクター
054 *
055 * クロス?を行うカラ?のみセ?します?
056 * 行?クロス?部のヘッ??キーは、引数の配?の?で、設定されます?
057 * こ?行?ヘッ??部となるデータは、addData 時にセ?します?
058 *
059 * @param clmData クロス?部のカラ?配?
060 * @param headCount HEADカラ??数
061 * @param sumCount 合計カラ??数
062 */
063 public CrossMap( final String[] clmData, final int headCount, final int sumCount ) {
064 if( headCount <= 0 ) {
065 String errMsg = "headCount は、ROWカラ?含?め??1以上?です?";
066 throw new IllegalArgumentException( errMsg );
067 }
068
069 this.headCount = headCount;
070 this.sumCount = sumCount;
071 int clmNum = clmData.length;
072 totalCols = headCount + clmNum * sumCount;
073 for( int i=0; i<clmNum; i++ ) {
074 clm.put( clmData[i],Integer.valueOf( i ) );
075 }
076 }
077
078 /**
079 * クロス???なる検索結果の行データを登録します?
080 *
081 * クロス?を行うカラ?のみ,セ?します?
082 * 行?ヘッ??部となるデータは、rowKeys と headCount で?します?
083 * 行?クロス?部のヘッ??キーは、clmKey で?し、?部で、?カラ?して
084 * 割り当てられます?割り当て?カラ??)は、コンストラクタでの clmData の
085 * 配?の?です?
086 *
087 * @param rowKeys 行データの配?( ?~headCount の値が行?キーとなります?)
088 */
089 public void add( final String[] rowKeys ) {
090 if( rowKeys.length < headCount + 1 + sumCount) {
091 String errMsg = "?? rowKeys の個数が不正です? rowKeys には、clmKey と data が?です?"
092 + " rowKeys=" + StringUtil.array2csv( rowKeys ) ; // 5.1.8.0 (2010/07/01) errMsg 修正
093 throw new ArrayIndexOutOfBoundsException( errMsg );
094 }
095
096 // 3.5.6.6 (2004/08/23) 修正
097 String clmKey = rowKeys[headCount]; // カラ??のクロス?部のキー(ヘッ??)
098 String[] data = new String[sumCount]; // クロス?表の値
099 for( int i=0; i<sumCount; i++ ) {
100 data[i] = rowKeys[headCount+1+i];
101 }
102
103 String rowKey ;
104 // 3.5.6.6 (2004/08/23) 修正
105 if( headCount == 1 ) { rowKey = rowKeys[0]; }
106 else {
107 StringBuilder rKey = new StringBuilder();
108 for( int i=0; i<headCount; i++ ) {
109 rKey.append( rowKeys[i] );
110 rKey.append( "_" );
111 }
112 rowKey = rKey.toString();
113 }
114 String[] clmData = row.get( rowKey );
115 if( clmData == null ) {
116 // 行データ+クロス行データ
117 clmData = new String[totalCols];
118 Arrays.fill( clmData,"" );
119 for( int i=0; i<headCount; i++ ) {
120 clmData[i] = rowKeys[i];
121 }
122 list.add( clmData ); // 生??ArrayList にセーブします?
123 }
124
125 for( int i=0; i<sumCount; i++ ) {
126 int no = headCount + (clm.get( clmKey )).intValue()*sumCount+i; // 列番号
127 clmData[no] = data[i];
128 }
129 row.put( rowKey,clmData ); // ArrayList と同じオブジェクトを検索用のMapにもセ?する?
130 }
131
132 /**
133 * クロス?結果の?行?列データを返します?
134 *
135 * @param row ??行番号( 0 .. getSize()-1 )
136 *
137 * @return 列データ配?
138 */
139 public String[] get( final int row ) {
140 return list.get( row );
141 }
142
143 /**
144 * クロス?結果の行数を返します?
145 *
146 * @return 行数を返します?
147 */
148 public int getSize() {
149 return list.size();
150 }
151 }