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 * 099 */ 100 public void executeQuery( final Connection con, final String query ) throws SQLException { 101 if( vhFlag ) { innerQueryV( con,query ); } 102 else { innerQueryH( con,query ); } 103 } 104 105 /** 106 * HybsTimeSeriesCollection オブジェクト??に、DB検索結果の??タを設定しま?縦?? 107 * こ?メソ?が呼ばれるのは、TimeSeriesLineV、TimeSeriesBarV、StackedTimeSeriesLineV の場合です? 108 * 109 * こ?メソ?は、series の 縦持を想定して?す? 110 * ?.select series,x(時間),y(値) from XX order by series,x(時間) の縦持ちで、series のキーブレイク処? 111 * series のキーブレイク処?れます? 112 * 113 * @param con the connection. 114 * @param query the query. 115 * 116 */ 117 private void innerQueryV( final Connection con, final String query ) throws SQLException { 118 119 Statement statement = null; 120 ResultSet resultSet = null; 121 try { 122 statement = con.createStatement(); 123 resultSet = statement.executeQuery(query); 124 ResultSetMetaData metaData = resultSet.getMetaData(); 125 126 int columnCount = metaData.getColumnCount(); 127 128 if(columnCount < 3) { 129 String errMsg = "HybsTimeSeriesCollection.innerQueryV() : 実行できません?n" 130 + "select series,x(時間),y(値) は、最低?です?それ以降?無視します?" 131 + " SQL=" + query ; 132 throw new SQLException( errMsg ); 133 } 134 135 String bkSeries = null; // キーブレイクのための過去のSeries 136 double bkyn = 0.0; 137 138 TimeSeries timeSeries = null; 139 while (resultSet.next()) { 140 // first column contains the row key... 141 String seriVal = resultSet.getString(1); // 縦持ちの場合?、データの値がシリーズ名になる? 142 if( seriVal != null && !seriVal.equals( bkSeries ) ) { 143 if( timeSeries != null ) { addSeries( timeSeries ); } // キーブレイクでセ? 144 timeSeries = new TimeSeries( seriVal ); 145 bkSeries = seriVal ; 146 bkyn = 0.0; 147 } 148 149 String dateVal = resultSet.getString(2); // x(時間) 150 RegularTimePeriod timep = getTimePeriod( dateVal ); 151 152 double yn = resultSet.getDouble(3); // y(値) 153 bkyn = ( isStacked ) ? bkyn + yn : yn ; // isStacked = true の場合?、加算して? 154 155 timeSeries.add( timep, bkyn ); 156 } 157 if( timeSeries != null ) { addSeries( timeSeries ); } // キーブレイクでセ? 158 } 159 finally { 160 Closer.resultClose( resultSet ) ; 161 Closer.stmtClose( statement ) ; 162 } 163 } 164 165 /** 166 * HybsTimeSeriesCollection オブジェクト??に、DB検索結果の??タを設定しま?横?? 167 * こ?メソ?が呼ばれるのは、TimeSeriesLineH、TimeSeriesBarH、StackedTimeSeriesLineH の場合です? 168 * 169 * こ?メソ?は、series の 横持を想定して?す? 170 * ?.select x(時間),y1(値),y2(値),・・・ from XX order by x(時間) の横? 171 * で、y1, y2 ・・・ ?series として処?れます? 172 * series のラベルは、y1, y2 ・・・のカラ?になります? 173 * 174 * @param con the connection. 175 * @param query the query. 176 */ 177 private void innerQueryH( final Connection con, final String query ) throws SQLException { 178 179 Statement statement = null; 180 ResultSet resultSet = null; 181 try { 182 statement = con.createStatement(); 183 resultSet = statement.executeQuery(query); 184 ResultSetMetaData metaData = resultSet.getMetaData(); 185 186 int columnCount = metaData.getColumnCount(); 187 188 if(columnCount < 2) { 189 String errMsg = "HybsTimeSeriesCollection.innerQueryH() : 実行できません?n" 190 + "select x(時間),y1(値),y2(値) , ・・・・ は、最低?です?" 191 + " SQL=" + query ; 192 throw new SQLException( errMsg ); 193 } 194 195 // ?リーズに対するカラ?イプを先に求めておく 196 int seriSu = columnCount-1; // カラ?-1( x(時間) ) 197 TimeSeries[] timeSeries = new TimeSeries[seriSu]; 198 double[] bkyn = new double[seriSu]; 199 for( int j=0; j<seriSu; j++ ) { 200 timeSeries[j] = new TimeSeries( metaData.getColumnLabel(j+2) ); // 横持?場合?、カラ?をシリーズ名にする? 201 bkyn[j] = 0.0; 202 } 203 204 while (resultSet.next()) { 205 // first column contains the row key... 206 String dateVal = resultSet.getString(1); // x(時間) 207 RegularTimePeriod timep = getTimePeriod( dateVal ); 208 209 for( int j=0; j<seriSu; j++ ) { 210 double yn = resultSet.getDouble(j+2); 211 bkyn[j] = ( isStacked ) ? bkyn[j] + yn : yn ; // isStacked = true の場合?、加算して? 212 timeSeries[j].add( timep, bkyn[j] ); 213 } 214 } 215 216 for( int j=0; j<seriSu; j++ ) { 217 addSeries( timeSeries[j] ); 218 } 219 } 220 finally { 221 Closer.resultClose( resultSet ) ; 222 Closer.stmtClose( statement ) ; 223 } 224 } 225 226 /** 227 * 日付文字? から、RegularTimePeriodオブジェク?を生成します? 228 * 229 * こ?メソ?では、日付文字? として?yyyyMMdd" 形式と "yyyyMMddhhmmss" 形式?み認めて?す? 230 * ?.8文字以上ある?合?yyyyMMdd 部??出して、年月日??を作?します? 231 * ?.14文字以上ある?合?残りの、hhmmss 部??出して、時?情報を作?します? 232 * ?.それ以外?場合??20100101000000" として、??ます? 233 * 234 * @param dateVal 日付文字?(yyyyMMddhhmmss 形? 235 * 236 * @return RegularTimePeriodオブジェク?Secondオブジェク? 237 */ 238 private RegularTimePeriod getTimePeriod( final String dateVal ) { 239 int second=0, minute=0, hour=0, day=1, month=1, year=2010 ; 240 if( dateVal != null ) { 241 if( dateVal.length() >= 8 ) { 242 year = Integer.parseInt( dateVal.substring( 0,4 ) ); 243 month = Integer.parseInt( dateVal.substring( 4,6 ) ); 244 day = Integer.parseInt( dateVal.substring( 6,8 ) ); 245 } 246 if( dateVal.length() >= 14 ) { 247 hour = Integer.parseInt( dateVal.substring( 8,10 ) ); 248 minute = Integer.parseInt( dateVal.substring( 10,12 ) ); 249 second = Integer.parseInt( dateVal.substring( 12,14 ) ); 250 } 251 } 252 253 return new Second( second,minute,hour,day,month,year ) ; 254 } 255 256 // private Number getNumber( final Object objVal , final int columnType ) { 257 // Number value = null; 258 // 259 // switch (columnType) { 260 // case Types.TINYINT: 261 // case Types.SMALLINT: 262 // case Types.INTEGER: 263 // case Types.BIGINT: 264 // case Types.FLOAT: 265 // case Types.DOUBLE: 266 // case Types.DECIMAL: 267 // case Types.NUMERIC: 268 // case Types.REAL: { 269 // value = (Number)objVal; 270 // break; 271 // } 272 // case Types.DATE: 273 // case Types.TIME: 274 // case Types.TIMESTAMP: { 275 // Date date = (Date) objVal; 276 // value = Long.valueOf(date.getTime()); 277 // break; 278 // } 279 // case Types.CHAR: 280 // case Types.VARCHAR: 281 // case Types.LONGVARCHAR: { 282 // String string = (String)objVal; 283 // try { 284 // value = Double.valueOf(string); 285 // } 286 // catch (NumberFormatException ex) { 287 // // LogWriter.log( ex ); 288 // // suppress (value defaults to null) 289 // } 290 // break; 291 // } 292 // default: 293 // // not a value, can't use it (defaults to null) 294 // break; 295 // } 296 // return value; 297 // } 298 }