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.Map ;
021    import java.util.LinkedHashMap ;
022    
023    import org.opengion.fukurou.util.HybsEntry;
024    import org.opengion.fukurou.util.StringUtil;
025    import org.opengion.hayabusa.common.HybsSystem;
026    import org.opengion.hayabusa.db.DBTableModel;
027    
028    /**
029     * TableWriter をXML形式で出力する為の実?ラスです?
030     * DefaultTableWriter を継承して?す?で?ラベル?名前,データの出力部のみ
031     * オーバ?ライドして?XML形式ファイルの出力機?を実現して?す?
032     *
033     * 出力?XML形式?、拡張オラクル ???形式????ファイルです?
034     * オラクル???形式????とは、下記?ような ROWSET をト??とする ROW の
035     * ?りで?レコードを表し?各ROWには、カラ?をキーとするXMLになって?す?
036     *
037     *   <ROWSET>
038     *       <ROW num="1">
039     *           <カラ?>値1</カラ?>
040     *             ???
041     *           <カラ?>値n</カラ?>
042     *       </ROW>
043     *        ???
044     *       <ROW num="n">
045     *          ???
046     *       </ROW>
047     *   <ROWSET>
048     *
049     * こ?形式であれば、XDK(Oracle XML Developer's Kit)を利用すれば?常に簡単に
050     * ??タベ?スとXMLファイルとの交換が可能です?
051     * <a href="http://otn.oracle.co.jp/software/tech/xml/xdk/index.html" target="_blank" >
052     * XDK(Oracle XML Developer's Kit)</a>
053     *
054     * 拡張???形式とは、ROW 以外に、SQL処?タグ(EXEC_SQL)を持つ XML ファイルです?
055     * これは、オラクルXDKで処?る?合?無視されます?で、同様に扱?とが?来ます?
056     * こ?、EXEC_SQL は、それそれ? XML??タをデータベ?スに登録する際に?
057     * SQL処?自動的に流す為の、SQL?記載します?
058     * こ?処??、イベント毎に実行される為、その配置??重要です?
059     * こ?タグは、?記述することも?来ますが、BODY部には?つのSQL??み記述します?
060     *
061     *   &lt;ROWSET tablename="GEXX" &gt;
062     *       &lt;EXEC_SQL&gt;                    ??に記載して、?期????タクリア?を実行させる?
063     *           delete from GEXX where YYYYY
064     *       &lt;/EXEC_SQL&gt;
065     *       &lt;MERGE_SQL&gt;                   こ?SQL? UPDATEして、結果が0件ならINSERTを行います?
066     *           update GEXX set AA=[AA] , BB=[BB] where CC=[CC]
067     *       &lt;/MERGE_SQL&gt;
068     *       &lt;ROW num="1"&gt;
069     *           &lt;カラ?&gt;値1&lt;/カラ?&gt;
070     *             ???
071     *           &lt;カラ?&gt;値n&lt;/カラ?&gt;
072     *       &lt;/ROW&gt;
073     *        ???
074     *       &lt;ROW num="n"&gt;
075     *          ???
076     *       &lt;/ROW&gt;
077     *       &lt;EXEC_SQL&gt;                    ?に記載して??目の設?整合?登録)を行う?
078     *           update GEXX set AA='XX' , BB='XX' where YYYYY
079     *       &lt;/EXEC_SQL&gt;
080     *   &lt;ROWSET&gt;
081     *
082     * @og.group ファイル出?
083     *
084     * @version  4.0
085     * @author   Kazuhiko Hasegawa
086     * @since    JDK5.0,
087     */
088    public class TableWriter_XML extends TableWriter_Default {
089            //* こ?プログラ??VERSION??を設定します?       {@value} */
090            private static final String VERSION = "5.6.7.0 (2013/07/27)" ;
091    
092            // 5.6.6.1 (2013/07/12) keys の整合?チェ?を行います?
093            private static final Map<String,String> keysMap = new LinkedHashMap<String,String>();
094    
095            static {
096                    keysMap.put( "TABLENAME"        , "処?実施する??ブル名を??                                                                                             );
097                    keysMap.put( "FIRST"            , "??に記載して、?期????タクリア?を実行させる、EXEC_SQLを指?            );
098                    keysMap.put( "LAST"                     , "?に記載して??目の設?整合?登録)を行う、EXEC_SQLを指?                         );
099                    keysMap.put( "MERGESQL"         , "こ?SQL? UPDATEして、結果が0件ならINSERTを行う、MERGE_SQLを指?                  );
100            }
101    
102            private String  tableName               = "" ;          // 4.0.0 (2005/01/31)
103            private String  firstExecSql    = "" ;          // 4.0.0 (2005/01/31)
104            private String  lastExecSql             = "" ;          // 4.0.0 (2005/01/31)
105    
106            private String  mergeSql                = "" ;          // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
107    
108    //      /**
109    //       * ?ォルトコンストラクター
110    //       *
111    //       */
112    //      public TableWriter_XML() {
113    //              super();
114    //      }
115    
116            /**
117             * DBTableModel から ??タを作?して,PrintWriter に書き?します?
118             *
119             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
120             * @og.rev 3.5.4.3 (2004/01/05) 引数に PrintWriter を受け取るよ?変更します?
121             *
122             * @param       writer PrintWriterオブジェク?
123             */
124            @Override
125            public void writeDBTable( final PrintWriter writer )  {
126                    super.setHeaderSequence( "D" );
127                    super.writeDBTable( writer );
128            }
129    
130            /**
131             * PrintWriter に DBTableModelのヘッ????を書き込みます?
132             * XML のヘッ??は?lt;?xml version='1.0' encoding='encode値'?&gt; になります?
133             * encoding属?には、encode値をセ?します?
134             * encoding属?に設定できる値は?UTF-8","UTF-16","Shift_JIS" です?
135             *
136             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
137             * @og.rev 4.0.0.0 (2005/01/31) XML宣?のencoding属?を?encode値をセ?する?
138             *
139             * @param       writer PrintWriterオブジェク?
140             */
141            @Override
142            protected void writeHeader( final PrintWriter writer ) {
143                    String encoding = getEncode();
144                    writer.println( "<?xml version='1.0' encoding='" + encoding + "'?>" ) ;
145            }
146    
147            /**
148             * PrintWriter に DBTableModelの??ブル??を書き込みます?
149             *
150             * 出力?XML形式?、ORACLE XDK での出力ファイルと同じ形式です?で、直接??タベ?スに
151             * 登録することができます?
152             *
153             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
154             * @og.rev 3.8.0.1 (2005/06/17) DBType?NVAR の場合?、?のUnicodeに戻します?
155             * @og.rev 4.0.0.0 (2005/01/31) EXEC_SQL タグ機?の追?
156             * @og.rev 5.1.6.0 (2010/05/01) DbType の初期値(dbType)を利用する?
157             * @og.rev 5.2.1.0 (2010/10/01) useRenderer 対?
158             * @og.rev 5.6.6.1 (2013/07/12) MERGE_SQL 対?
159             * @og.rev 5.6.7.0 (2013/07/27) 改行???見直?
160             *
161             * @param       table  DBTableModelオブジェク?
162             * @param       writer PrintWriterオブジェク?
163             */
164            @Override
165            protected void writeData( final DBTableModel table,final PrintWriter writer ) {
166                    int numberOfRows =  table.getRowCount();
167                    boolean useRenderer = isUseRenderer();  // 5.2.1.0 (2010/10/01)
168    
169                    writer.print( "<ROWSET" );
170                    writer.print( tableName );
171                    writer.println( ">" );
172    
173                    // 4.0.0 (2005/01/31)
174    //              writer.println( firstExecSql );
175                    writer.print( firstExecSql );                           // 5.6.7.0 (2013/07/27) 改行???見直?
176    
177                    // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
178    //              writer.println( mergeSql );
179                    writer.print( mergeSql );                                       // 5.6.7.0 (2013/07/27) 改行???見直?
180    
181                    for( int row=0; row<numberOfRows; row++ ) {
182                            writer.print( "<ROW num=\"" );
183                            writer.print( row+1 );
184                            writer.println( "\">" );
185                            for( int i=0; i<numberOfColumns; i++ ) {
186                                    int clm = clmNo[i];
187                                    String val = table.getValue(row,clm);
188    //                              if( "NVAR".equals( dbColumn[clm].getDbType()) ) {
189                                    if( dbType[i] == NVAR ) {
190                                            val = StringUtil.getReplaceEscape( val );
191                                    }
192                                    // 5.2.1.0 (2010/10/01) useRenderer 対?
193                                    else if( useRenderer ) {
194                                            val = StringUtil.spanCut( dbColumn[clm].getRendererValue( val ) );
195                                    }
196    
197                                    writer.print( "<" );
198                                    writer.print( table.getColumnName(clm) );
199                                    writer.print( ">" );
200                                    writer.print( StringUtil.htmlFilter( val ) );
201                                    writer.print( "</" );
202                                    writer.print( table.getColumnName(clm) );
203                                    writer.println( ">" );
204                            }
205                            writer.println( "</ROW>" );
206                    }
207    
208                    // 4.0.0 (2005/01/31)
209    //              writer.println( lastExecSql );
210                    writer.print( lastExecSql );                            // 5.6.7.0 (2013/07/27) 改行???見直?
211                    writer.println( "</ROWSET>" );
212            }
213    
214            /**
215             * パラメーターリストをセ?します?
216             * ?は、HybsEntry クラスを持って?す?
217             * 引数が?null の場合?、何もしません?
218             *
219             * @og.rev 4.0.0.0 (2005/01/31) 新規追?
220             * @og.rev 5.6.6.1 (2013/07/12) MERGE_SQL 対?
221             * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?を行います?
222             *
223             * @param       listParam       HybsEntryリス?
224             */
225            @Override
226            public void setParam( final List<HybsEntry> listParam ) {
227                    if( listParam != null && ! listParam.isEmpty() ) {
228                            StringBuilder first = new StringBuilder() ;
229                            StringBuilder last  = new StringBuilder() ;
230                            StringBuilder merge = new StringBuilder() ;             // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
231    
232                            for( HybsEntry entry : listParam ) {
233                                    String key = entry.getKey() ;           // 5.6.6.1 (2013/07/12) keys の整合?チェ?
234                                    checkParam( key , keysMap );
235    
236                                    String val = entry.getValue() ;         // 5.6.6.1 (2013/07/12) val を?に取?
237                                    if( val != null && val.length() > 0 ) {
238                                            // 処?実施する??ブル名を??
239                                            // ?の key="TableName" があれ?、最後?みが有効?
240                                            if( "TableName".equalsIgnoreCase( key ) ) {
241                                                    tableName = " tableName=\"" + val + "\"" ;
242                                            }
243                                            // ??に記載して、?期????タクリア?を実行させる、EXEC_SQLを指?
244                                            else if( "First".equalsIgnoreCase( key ) ) {
245                                                    first.append( "<EXEC_SQL>" );
246                                                    first.append( StringUtil.htmlFilter( val ) );
247                                                    first.append( "</EXEC_SQL>" );
248                                                    first.append( HybsSystem.CR );
249                                            }
250                                            // ?に記載して??目の設?整合?登録)を行う、EXEC_SQLを指?
251                                            else if( "Last".equalsIgnoreCase( key ) ) {
252                                                    last.append( "<EXEC_SQL>" );
253                                                    last.append( StringUtil.htmlFilter( val ) );
254                                                    last.append( "</EXEC_SQL>" );
255                                                    last.append( HybsSystem.CR );
256                                            }
257                                            // こ?SQL? UPDATEして、結果が0件ならINSERTを行う、MERGE_SQLを指?
258                                            else if( "MergeSql".equalsIgnoreCase( key ) ) {
259                                                    merge.append( "<MERGE_SQL>" );
260                                                    merge.append( StringUtil.htmlFilter( val ) );
261                                                    merge.append( "</MERGE_SQL>" );
262                                                    merge.append( HybsSystem.CR );
263                                            }
264                                    }
265                            }
266                            firstExecSql = first.toString();
267                            lastExecSql  = last.toString();
268                            mergeSql     = merge.toString();                // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
269                    }
270    
271    //                      HybsEntry[] entries = listParam.toArray( new HybsEntry[listParam.size()] );
272    //                      for( int i=0; i<entries.length; i++ ) {
273    //                              String key = entries[i].getKey();
274    //                              String val = entries[i].getValue();
275    //                              if( "First".equalsIgnoreCase( key ) ) {
276    //                                      first.append( "<EXEC_SQL>" );
277    //                                      first.append( StringUtil.htmlFilter( val ) );
278    //                                      first.append( "</EXEC_SQL>" );
279    //                                      first.append( HybsSystem.CR );
280    //                              }
281    //                              else if( "Last".equalsIgnoreCase( key ) ) {
282    //                                      last.append( "<EXEC_SQL>" );
283    //                                      last.append( StringUtil.htmlFilter( val ) );
284    //                                      last.append( "</EXEC_SQL>" );
285    //                                      last.append( HybsSystem.CR );
286    //                              }
287    //                              // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
288    //                              else if( "MergeSql".equalsIgnoreCase( key ) ) {
289    //                                      merge.append( "<MERGE_SQL>" );
290    //                                      merge.append( StringUtil.htmlFilter( val ) );
291    //                                      merge.append( "</MERGE_SQL>" );
292    //                                      merge.append( HybsSystem.CR );
293    //                              }
294    //                              // ?の TableName があれ?、最後?みが有効?チェ?な?
295    //                              else if( "TableName".equalsIgnoreCase( key )
296    //                                                      && val != null && val.length() > 0 ) {
297    //                                      tableName = " tableName=\"" + val + "\"" ;
298    //                              }
299    //                      }
300    //                      firstExecSql = first.toString();
301    //                      lastExecSql  = last.toString();
302    //                      mergeSql     = merge.toString();                // 5.6.6.1 (2013/07/12) MERGE_SQL 対?
303    //              }
304            }
305    }