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.plugin.io;
017
018 import java.io.PrintWriter;
019 import java.util.List;
020 import java.util.Locale;
021 import java.util.Map ;
022 import java.util.LinkedHashMap ;
023
024 import org.opengion.fukurou.util.HybsEntry;
025 import org.opengion.hayabusa.db.DBTableModel;
026
027 /**
028 * TableWriter をJSON形式で出力する為の実?ラスです?
029 * DefaultTableWriter を継承して?す?で?ラベル?名前,データの出力部のみ
030 * オーバ?ライドして?JSON形式ファイルの出力機?を実現して?す?
031 *
032 * 出力?JSON形?JavaScript Object Notation)は、JavaScriptにおけ?
033 * オブジェクト?表記法をベ?スとした軽量な??タ記述?です?
034 * こ?クラスでは、基本?はすべてを文字?として処?ます?で?
035 * 数字や、true,false も??ルコー??ションでくくることになります?
036 * ただし?null の場合?、null 表記になりますが??常 空??"" になる?合もあります?
037 * 1レコード?みの場合でも?配?要?して取り扱?す?
038 * UTF-8 でエンコードし、MIMEタイプ?application/json、拡張子?json とするのが??す?
039 *
040 * [
041 * { "カラ?":"値1" , "カラ?":"値2" , … } , ?レコード目
042 * { "カラ?":"値1" , "カラ?":"値2" , … } , ?レコード目
043 * ・・・・
044 * { "カラ?":"値1" , "カラ?":"値2" , … } ?レコード目
045 * ]
046 *
047 * writeTableParamタグで、key="JsonName" value="パラメータ? を指定すると?
048 * JSON形式で??列をオブジェクトとしてまとめるパラメータを指定する事が可能です?
049 *
050 * {
051 * パラメータ?[
052 * { "カラ?":"値1" , "カラ?":"値2" , … } , ?レコード目
053 * { "カラ?":"値1" , "カラ?":"値2" , … } , ?レコード目
054 * ・・・・
055 * { "カラ?":"値1" , "カラ?":"値2" , … } ?レコード目
056 * ]
057 * }
058 *
059 * writeTableParamタグで、key="LowerCase" value="true" を指定すると?
060 * すべてのカラ?小文字で出力します??データ受信側の都合を配???
061 * 初期値は、false なので、基本?大?になります?
062 *
063 * @og.rev 5.6.0.3 (2012/01/24) 新規作?
064 * @og.group ファイル出?
065 *
066 * @version 4.0
067 * @author Kazuhiko Hasegawa
068 * @since JDK5.0,
069 */
070 public class TableWriter_JSON extends TableWriter_Default {
071 //* こ?プログラ??VERSION??を設定します? {@value} */
072 private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
073
074 // 5.6.6.1 (2013/07/12) keys の整合?チェ?を行います?
075 private static final Map<String,String> keysMap = new LinkedHashMap<String,String>();
076
077 static {
078 keysMap.put( "JSONNAME" , "JSON形式で??列をオブジェクトとしてまとめる場合に使? );
079 keysMap.put( "LOWERCASE" , "カラ?(=パラメータ?を小文字にする場合?true をセ?(初期値:false)" );
080 }
081
082 private String jsonName = null; // JSON形式で??列をオブジェクトとしてまとめるパラメータを指定する?合に使??
083 private boolean toLowerCase = false; // カラ?(=パラメータ?を小文字にする場合?true にセ?します?初期値は大??まま?
084
085 /**
086 * DBTableModel から ??タを作?して,PrintWriter に書き?します?
087 *
088 * @param writer PrintWriterオブジェク?
089 */
090 @Override
091 public void writeDBTable( final PrintWriter writer ) {
092 super.setHeaderSequence( "D" );
093 super.writeDBTable( writer );
094 }
095
096 /**
097 * PrintWriter に DBTableModelの??ブル??を書き込みます?
098 *
099 * 出力?XML形式?、ORACLE XDK での出力ファイルと同じ形式です?で、直接??タベ?スに
100 * 登録することができます?
101 *
102 * @og.rev 5.6.0.3 (2012/01/24) JSON形式?フォーマットを作?します?
103 * @og.rev 5.6.1.2 (2013/02/22) jsonName もダブルクオートで囲??
104 *
105 * @param table DBTableModelオブジェク?
106 * @param writer PrintWriterオブジェク?
107 */
108 @Override
109 protected void writeData( final DBTableModel table,final PrintWriter writer ) {
110 int numberOfRows = table.getRowCount();
111
112 String[] names = table.getNames();
113 if( toLowerCase ) {
114 for( int i=0; i<names.length; i++ ) {
115 // names[i] = names[i].toLowerCase(); 5.6.6.1 (2013/07/12)
116 names[i] = names[i].toLowerCase(Locale.JAPAN);
117 }
118 }
119
120 if( jsonName != null ) {
121 writer.println( "{" );
122 writer.print( "\"" ); // 5.6.1.2 (2013/02/22) jsonName もダブルクオートで囲??
123 writer.print( jsonName );
124 writer.print( "\":" ); // 5.6.1.2 (2013/02/22) jsonName もダブルクオートで囲??
125 }
126
127 writer.println( "[" );
128
129 for( int row=0; row<numberOfRows; row++ ) {
130 if( row > 0 ) { writer.print( "," ); } // ??以後?連結?? を使?
131 writer.print( "{" );
132 for( int i=0; i<numberOfColumns; i++ ) {
133 int clm = clmNo[i];
134 String val = table.getValue(row,clm);
135 // \(バックスラ?ュ) と "(?ルクオー?のエスケー?
136 if( val.contains( "\\" ) || val.contains( "\"" ) ) {
137 StringBuilder sb = new StringBuilder();
138 for( int j=0; j<val.length(); j++ ) {
139 char ch = val.charAt( j );
140 if( ch == '\\' || ch == '\"' ) { sb.append( '\\' ); }
141 sb.append( ch );
142 }
143 val = sb.toString();
144 }
145
146 if( i > 0 ) { writer.print( "," ); } // ??以後?連結?? を使?
147 writer.print( '"' );
148 writer.print( names[clm] );
149 writer.print( "\":\"" );
150 writer.print( val );
151 writer.print( '"' );
152 }
153 writer.println( "}" );
154 }
155
156 writer.println( "]" );
157
158 if( jsonName != null ) {
159 writer.println( "}" );
160 }
161 }
162
163 /**
164 * パラメーターリストをセ?します?
165 * JSONのパラメータ名を?します?
166 * 引数が?null の場合?、何もしません?
167 *
168 * @og.rev 5.6.0.3 (2012/01/24) JSONのパラメータ名を?します?
169 * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?を行います?
170 *
171 * @param listParam HybsEntryリス?
172 */
173 @Override
174 public void setParam( final List<HybsEntry> listParam ) {
175 if( listParam != null && ! listParam.isEmpty() ) {
176 for( HybsEntry entry : listParam ) {
177 String key = entry.getKey() ; // 5.6.6.1 (2013/07/12) keys の整合?チェ?
178 checkParam( key , keysMap );
179
180 String val = entry.getValue() ; // 5.6.6.1 (2013/07/12) val を?に取?
181 if( val != null && val.length() > 0 ) {
182 // JSON形式で??列をオブジェクトとしてまとめるパラメータを指定する?合に使??
183 if( "JsonName".equalsIgnoreCase( key ) ) {
184 jsonName = val ;
185 }
186 // カラ?(=パラメータ?を小文字にする場合?true にセ?します?初期値はfalse:大??まま?
187 else if( "LowerCase".equalsIgnoreCase( key ) ) {
188 toLowerCase = Boolean.parseBoolean( val );
189 }
190 }
191
192 // // JSON形式で??列をオブジェクトとしてまとめるパラメータを指定する?合に使??
193 // if( "JsonName".equalsIgnoreCase( entry.getKey() ) ) {
194 // jsonName = entry.getValue();
195 // }
196 // // カラ?(=パラメータ?を小文字にする場合?true にセ?します?初期値は大??まま?
197 // if( "LowerCase".equalsIgnoreCase( entry.getKey() ) ) {
198 // toLowerCase = true;
199 // }
200 }
201 }
202 }
203 }