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 }