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.io; 017 018 import java.sql.Connection; 019 // import java.sql.Date; 020 import java.sql.ResultSet; 021 import java.sql.ResultSetMetaData; 022 import java.sql.SQLException; 023 import java.sql.Statement; 024 // import java.sql.Types; 025 // import java.util.Locale; 026 027 import org.opengion.fukurou.util.Closer; 028 import org.opengion.fukurou.util.LogWriter; 029 030 import org.jfree.data.time.TimeSeriesCollection; 031 import org.jfree.data.time.TimeSeries; 032 import org.jfree.data.time.RegularTimePeriod; 033 // import org.jfree.data.time.Year; // Year (int year) 034 // import org.jfree.data.time.Month; // Month (int month, int year) 035 // import org.jfree.data.time.Day; // Day (int day, int month, int year) 036 // import org.jfree.data.time.Hour; // Hour (int hour, int day, int month, int year) 037 // import org.jfree.data.time.Minute; // Minute(int minute, int hour, int day, int month, int year) 038 import org.jfree.data.time.Second; // Second(int second, int minute, int hour, int day, int month, int year) 039 040 /** 041 * HybsTimeSeriesCollection は、org.jfree.data.time.TimeSeriesCollection を継承したサブクラスで? 042 * オブジェクト作?とともに JDBC接続して、TimeSeries ??タを作?し?セ?します? 043 * TimeSeriesCollection は、XYDataset のサブクラスです? 044 * 045 * TimeSeriesLineV、TimeSeriesBarV、StackedTimeSeriesLineV の場合?縦持です? 046 * ?.select series,x(時間),y(値) from XX order by series,x(時間) の縦持ちで、series のキーブレイク処? 047 * TimeSeriesLineH、TimeSeriesBarH、StackedTimeSeriesLineH の場合?横持です? 048 * ?.select x(時間),y1(値),y2(値),・・・ from XX order by x(時間) の横? 049 * series のキーブレイク処?れます? 050 * 051 * Stacked**** は、各シリーズのy(値)を?次??します??間で実績数をセ?し??時刻に 052 * どれだけ?来上がったかを表示するのに便利です? 053 * 054 * @og.rev 5.6.1.0 (2013/02/01) 新規作? 055 * 056 * @version 0.9.0 2001/05/05 057 * @author Kazuhiko Hasegawa 058 * @since JDK1.1, 059 */ 060 public class HybsTimeSeriesCollection extends TimeSeriesCollection { 061 private static final long serialVersionUID = 561020130201L ; 062 063 private final boolean vhFlag ; // select? series を縦持V(true)か横持H(false)かを?? 064 private final boolean isStacked ; // ??タの???行うかど??? true:行う/false:行わな? 065 066 /** 067 * チャートタイプを引数にとる?コンストラクター 068 * 069 * TimeSeriesLineV、TimeSeriesBarV、StackedTimeSeriesLineV の場合?縦持です? 070 * ?.select series,x(時間),y(値) from XX order by series,x(時間) の縦持ちで、series のキーブレイク処? 071 * TimeSeriesLineH、TimeSeriesBarH、StackedTimeSeriesLineH の場合?横持です? 072 * ?.select x(時間),y1(値),y2(値),・・・ from XX order by x(時間) の横? 073 * series のキーブレイク処?れます? 074 * 075 * Stacked**** は、各シリーズのy(値)を?次??します??間で実績数をセ?し??時刻に 076 * どれだけ?来上がったかを表示するのに便利です? 077 * 078 * @param type チャートタイ? 079 */ 080 public HybsTimeSeriesCollection( final String type ) { 081 super(); 082 vhFlag = ( type.endsWith( "V" ) ) ; // V:縦?= true / H:横?= false 083 isStacked = ( type.startsWith( "Stacked" ) ) ; // Stacked:積み上げ = true 084 } 085 086 /** 087 * HybsTimeSeriesCollection オブジェクト??に、DB検索結果の??タを設定します? 088 * 089 * こ?メソ?は、series の 縦?横持を、コンストラクターで判定して?す? 090 * TimeSeriesLineV、TimeSeriesBarV、StackedTimeSeriesLineV の場合?縦持です? 091 * ?.select series,x(時間),y(値) from XX order by series,x(時間) の縦持ちで、series のキーブレイク処? 092 * TimeSeriesLineH、TimeSeriesBarH、StackedTimeSeriesLineH の場合?横持です? 093 * ?.select x(時間),y1(値),y2(値),・・・ from XX order by x(時間) の横? 094 * series のキーブレイク処?れます? 095 * 096 * @param con the connection. 097 * @param query the query. 098 * @throws SQLException ??タベ?ス実行エラーが発生した?? 099 * 100 */ 101 public void executeQuery( final Connection con, final String query ) throws SQLException { 102 if( vhFlag ) { innerQueryV( con,query ); } 103 else { innerQueryH( con,query ); } 104 } 105 106 /** 107 * HybsTimeSeriesCollection オブジェクト??に、DB検索結果の??タを設定しま?縦?? 108 * こ?メソ?が呼ばれるのは、TimeSeriesLineV、TimeSeriesBarV、StackedTimeSeriesLineV の場合です? 109 * 110 * こ?メソ?は、series の 縦持を想定して?す? 111 * ?.select series,x(時間),y(値) from XX order by series,x(時間) の縦持ちで、series のキーブレイク処? 112 * series のキーブレイク処?れます? 113 * 114 * @param con the connection. 115 * @param query the query. 116 * 117 */ 118 private void innerQueryV( final Connection con, final String query ) throws SQLException { 119 120 Statement statement = null; 121 ResultSet resultSet = null; 122 try { 123 statement = con.createStatement(); 124 resultSet = statement.executeQuery(query); 125 ResultSetMetaData metaData = resultSet.getMetaData(); 126 127 int columnCount = metaData.getColumnCount(); 128 129 if(columnCount < 3) { 130 String errMsg = "HybsTimeSeriesCollection.innerQueryV() : 実行できません?n" 131 + "select series,x(時間),y(値) は、最低?です?それ以降?無視します?" 132 + " SQL=" + query ; 133 throw new SQLException( errMsg ); 134 } 135 136 String bkSeries = null; // キーブレイクのための過去のSeries 137 double bkyn = 0.0; 138 139 TimeSeries timeSeries = null; 140 while (resultSet.next()) { 141 // first column contains the row key... 142 String seriVal = resultSet.getString(1); // 縦持ちの場合?、データの値がシリーズ名になる? 143 if( seriVal != null && !seriVal.equals( bkSeries ) ) { 144 if( timeSeries != null ) { addSeries( timeSeries ); } // キーブレイクでセ? 145 timeSeries = new TimeSeries( seriVal ); 146 bkSeries = seriVal ; 147 bkyn = 0.0; 148 } 149 150 String dateVal = resultSet.getString(2); // x(時間) 151 RegularTimePeriod timep = getTimePeriod( dateVal ); 152 153 double yn = resultSet.getDouble(3); // y(値) 154 bkyn = ( isStacked ) ? bkyn + yn : yn ; // isStacked = true の場合?、加算して? 155 156 timeSeries.add( timep, bkyn ); 157 } 158 if( timeSeries != null ) { addSeries( timeSeries ); } // キーブレイクでセ? 159 } 160 finally { 161 Closer.resultClose( resultSet ) ; 162 Closer.stmtClose( statement ) ; 163 } 164 } 165 166 /** 167 * HybsTimeSeriesCollection オブジェクト??に、DB検索結果の??タを設定しま?横?? 168 * こ?メソ?が呼ばれるのは、TimeSeriesLineH、TimeSeriesBarH、StackedTimeSeriesLineH の場合です? 169 * 170 * こ?メソ?は、series の 横持を想定して?す? 171 * ?.select x(時間),y1(値),y2(値),・・・ from XX order by x(時間) の横? 172 * で、y1, y2 ・・・ ?series として処?れます? 173 * series のラベルは、y1, y2 ・・・のカラ?になります? 174 * 175 * @param con the connection. 176 * @param query the query. 177 */ 178 private void innerQueryH( final Connection con, final String query ) throws SQLException { 179 180 Statement statement = null; 181 ResultSet resultSet = null; 182 try { 183 statement = con.createStatement(); 184 resultSet = statement.executeQuery(query); 185 ResultSetMetaData metaData = resultSet.getMetaData(); 186 187 int columnCount = metaData.getColumnCount(); 188 189 if(columnCount < 2) { 190 String errMsg = "HybsTimeSeriesCollection.innerQueryH() : 実行できません?n" 191 + "select x(時間),y1(値),y2(値) , ・・・・ は、最低?です?" 192 + " SQL=" + query ; 193 throw new SQLException( errMsg ); 194 } 195 196 // ?リーズに対するカラ?イプを先に求めておく 197 int seriSu = columnCount-1; // カラ?-1( x(時間) ) 198 TimeSeries[] timeSeries = new TimeSeries[seriSu]; 199 double[] bkyn = new double[seriSu]; 200 for( int j=0; j<seriSu; j++ ) { 201 timeSeries[j] = new TimeSeries( metaData.getColumnLabel(j+2) ); // 横持?場合?、カラ?をシリーズ名にする? 202 bkyn[j] = 0.0; 203 } 204 205 while (resultSet.next()) { 206 // first column contains the row key... 207 String dateVal = resultSet.getString(1); // x(時間) 208 RegularTimePeriod timep = getTimePeriod( dateVal ); 209 210 for( int j=0; j<seriSu; j++ ) { 211 double yn = resultSet.getDouble(j+2); 212 bkyn[j] = ( isStacked ) ? bkyn[j] + yn : yn ; // isStacked = true の場合?、加算して? 213 timeSeries[j].add( timep, bkyn[j] ); 214 } 215 } 216 217 for( int j=0; j<seriSu; j++ ) { 218 addSeries( timeSeries[j] ); 219 } 220 } 221 finally { 222 Closer.resultClose( resultSet ) ; 223 Closer.stmtClose( statement ) ; 224 } 225 } 226 227 /** 228 * 日付文字? から、RegularTimePeriodオブジェク?を生成します? 229 * 230 * こ?メソ?では、日付文字? として?yyyyMMdd" 形式と "yyyyMMddhhmmss" 形式?み認めて?す? 231 * ?.8文字以上ある?合?yyyyMMdd 部??出して、年月日??を作?します? 232 * ?.14文字以上ある?合?残りの、hhmmss 部??出して、時?情報を作?します? 233 * ?.それ以外?場合??20100101000000" として、??ます? 234 * 235 * @param dateVal 日付文字?(yyyyMMddhhmmss 形? 236 * 237 * @return RegularTimePeriodオブジェク?Secondオブジェク? 238 */ 239 private RegularTimePeriod getTimePeriod( final String dateVal ) { 240 int second=0, minute=0, hour=0, day=1, month=1, year=2010 ; 241 if( dateVal != null ) { 242 if( dateVal.length() >= 8 ) { 243 year = Integer.parseInt( dateVal.substring( 0,4 ) ); 244 month = Integer.parseInt( dateVal.substring( 4,6 ) ); 245 day = Integer.parseInt( dateVal.substring( 6,8 ) ); 246 } 247 if( dateVal.length() >= 14 ) { 248 hour = Integer.parseInt( dateVal.substring( 8,10 ) ); 249 minute = Integer.parseInt( dateVal.substring( 10,12 ) ); 250 second = Integer.parseInt( dateVal.substring( 12,14 ) ); 251 } 252 } 253 254 return new Second( second,minute,hour,day,month,year ) ; 255 } 256 257 // private Number getNumber( final Object objVal , final int columnType ) { 258 // Number value = null; 259 // 260 // switch (columnType) { 261 // case Types.TINYINT: 262 // case Types.SMALLINT: 263 // case Types.INTEGER: 264 // case Types.BIGINT: 265 // case Types.FLOAT: 266 // case Types.DOUBLE: 267 // case Types.DECIMAL: 268 // case Types.NUMERIC: 269 // case Types.REAL: { 270 // value = (Number)objVal; 271 // break; 272 // } 273 // case Types.DATE: 274 // case Types.TIME: 275 // case Types.TIMESTAMP: { 276 // Date date = (Date) objVal; 277 // value = Long.valueOf(date.getTime()); 278 // break; 279 // } 280 // case Types.CHAR: 281 // case Types.VARCHAR: 282 // case Types.LONGVARCHAR: { 283 // String string = (String)objVal; 284 // try { 285 // value = Double.valueOf(string); 286 // } 287 // catch (NumberFormatException ex) { 288 // // LogWriter.log( ex ); 289 // // suppress (value defaults to null) 290 // } 291 // break; 292 // } 293 // default: 294 // // not a value, can't use it (defaults to null) 295 // break; 296 // } 297 // return value; 298 // } 299 }