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 }