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 }