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.table;
017
018 import java.io.File;
019 import java.io.PrintWriter;
020 import java.util.Map;
021
022 import org.opengion.fukurou.db.DBUtil;
023 import org.opengion.fukurou.db.Transaction;
024 import org.opengion.fukurou.util.ErrorMessage;
025 import org.opengion.fukurou.util.FileUtil;
026 import org.opengion.fukurou.util.FixLengthData;
027 import org.opengion.fukurou.util.StringUtil;
028
029 import org.opengion.hayabusa.common.HybsSystem;
030 import org.opengion.hayabusa.common.HybsSystemException;
031 import org.opengion.hayabusa.db.AbstractTableFilter;
032 import org.opengion.hayabusa.db.DBTableModel;
033
034 /**
035 * TableFilter_DBSRC_OUT は、TableFilter インターフェースを継承した、DBTableModel 処?の
036 * 実?ラスです?
037 *
038 * ここでは、オブジェクト?(GF82)の検索結果より、オブジェクト?細??ブル(GF83)から
039 * ?な??を取得し、各種オブジェクトソースを抜き?します?
040 * 出力ファイルは、オブジェクト名??.sql" と?命名規則で作?します?
041 *
042 * ここで、PACKAGE と、PACKAGE BODY が同じオブジェクト名の場合?同じファイルに追?append=true)されます?
043 * 本来は、??ォル?先に削除しておかな?、上書きされてしま?す?
044 * ここでは、フォル?除ではなく?できる?ローカル処?るよ?、PACKAGE の場合だけ?
045 * 先に、ファイルを削除する処?実行します?
046 *
047 * また?オブジェクトタイプによって、?力フォル?変える?合?、???してください?
048 * 以下?コメント?参?です?で、詳細は、jsp 側の抜?プログラ??仕様をご確認く???
049 *
050 * view 04_VIEW
051 * function 05_SRC
052 * package 05_SRC
053 * package body 05_SRC
054 * procedure 05_SRC
055 * trigger 06_TRG
056 *
057 * オブジェクト?(GF82)の検索では?SYSTEM_ID,TBLSYU,OBJ_TYPE,OBJ_NAME,NAME_JA)
058 * の?を取得する?があります?
059 *
060 * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
061 * 【パラメータ?
062 * {
063 * DIR : {@BASE_DIR}/sql/install/05_SRC ; 出力ファイルの基準フォル???)
064 * XML : false ; XML出力を行うかど?[true/false]を指定しま?初期値:false)?
065 * }
066 *
067 * @og.formSample
068 * ●形式?
069 * select SYSTEM_ID,TBLSYU,OBJ_TYPE,OBJ_NAME,NAME_JA from GF82
070 * ?<og:tableFilter classId="DBSRC_OUT" keys="DIR" vals="{@BASE_DIR}/sql/install/05_SRC" />
071 *
072 * ② <og:tableFilter classId="DBSRC_OUT" >
073 * {
074 * DIR : {@BASE_DIR}/sql/install/05_SRC ;
075 * XML : false ;
076 * }
077 * </og:tableFilter>
078 *
079 * @og.rev 5.6.7.0 (2013/07/27) 新規作?
080 *
081 * @version 0.9.0 2000/10/17
082 * @author Kazuhiko Hasegawa
083 * @since JDK1.1,
084 */
085 public class TableFilter_DBSRC_OUT extends AbstractTableFilter {
086 //* こ?プログラ??VERSION??を設定します? {@value} */
087 private static final String VERSION = "5.7.2.0 (2014/01/10)" ;
088
089 /**
090 * keys の整合?チェ?を行うための初期設定を行います?
091 *
092 * @param keysMap keys の整合?チェ?を行うための Map
093 */
094 @Override
095 protected void init( final Map<String,String> keysMap ) {
096 keysMap.put( "DIR" , "出力ファイルの基準フォル???)" );
097 keysMap.put( "XML" , "XML出力を行うかど?[true/false]を指?初期値:false)" );
098 }
099
100 private static final String[] KEYS = new String[] { "SYSTEM_ID","TBLSYU","OBJ_TYPE","OBJ_NAME","NAME_JA" };
101
102 private static final int SYSTEM_ID = 0;
103 private static final int TBLSYU = 1;
104 private static final int OBJ_TYPE = 2;
105 private static final int OBJ_NAME = 3;
106 // private static final int NAME_JA = 4;
107
108 private static final String ENCODE = "UTF-8" ;
109
110 // オブジェクト?細??ブル(GF83) の検索SQL
111 private static final String GF83_SEL = "select NOLINE,SRC_TEXT"
112 + " from GF83"
113 + " where SYSTEM_ID=? and TBLSYU=? and OBJ_TYPE=? and OBJ_NAME=?"
114 + " and FGJ='1'"
115 + " order by NOLINE" ;
116
117 // 5.6.6.0 (2013/07/05) ヘッ??部作?用
118 private static final String CMNT = "************************************************************************" ;
119
120 private static final int X = FixLengthData.X ; // type 定数
121 private static final int K = FixLengthData.K ; // type 定数
122
123 /** 5.6.7.0 (2013/07/27) ?定数 */
124 protected static final String XML_START_TAG = "<?xml version='1.0' encoding='UTF-8'?>" + CR + "<ROWSET tableName='xxx'>";
125 protected static final String XML_END_TAG = "</ROWSET>";
126 protected static final String EXEC_START_TAG= "<EXEC_SQL>";
127 protected static final String EXEC_END_TAG = "</EXEC_SQL>";
128
129 /** XML形式かど? */
130 protected boolean isXml = false; // 5.6.7.0 (2013/07/27)
131
132 /**
133 * DBTableModel処?実行します?
134 *
135 * @og.rev 5.8.2.2 (2014/12/19) XML時エスケープなど
136 *
137 * @return 処?果のDBTableModel
138 */
139 public DBTableModel execute() {
140 DBTableModel table = getDBTableModel();
141
142 isXml = StringUtil.nval( getValue( "XML" ), false );
143
144 int[] clmNo = getTableColumnNo( KEYS );
145 int rowCnt = table.getRowCount();
146
147 File dir = new File( getValue( "DIR" ) );
148 if( ! dir.exists() && !dir.mkdirs() ) {
149 String errMsg = "??フォル?作?できませんでした?" + dir + "]" ;
150 throw new HybsSystemException( errMsg );
151 }
152
153 String[] data = null;
154 PrintWriter writer = null;
155 Transaction tran = getTransaction();
156
157 for( int row=0; row<rowCnt; row++ ) {
158 String objType = null;
159 String objName = null;
160 String fileName = null; // 5.8.2.2. (2014/12/19)
161 try {
162 data = table.getValues( row );
163 String systemId = data[clmNo[SYSTEM_ID]];
164 String tblsyu = data[clmNo[TBLSYU]];
165 objType = data[clmNo[OBJ_TYPE]];
166 objName = data[clmNo[OBJ_NAME]];
167 fileName = objName; // 5.8.2.2. (2014/12/19)
168
169
170 // 5.8.2.2. (2014/12/19) BODYの場合?追記?タグ制御難しいのでファイルを?ける
171 if( "PACKAGE BODY".equalsIgnoreCase( objType ) ){ fileName = fileName + "_BODY"; }
172
173 // パッケージの場合?、既存?ファイルを削除します?(PACKAGE BODY がappendされるた?
174 // File objFile = new File( dir,objName + ( isXml ? ".xml" : ".sql" ) );
175 File objFile = new File( dir,fileName + ( isXml ? ".xml" : ".sql" ) );
176 // 6.0.0.1 (2014/04/25) These nested if statements could be combined
177 if( "PACKAGE".equalsIgnoreCase( objType ) && objFile.exists() && !objFile.delete() ) {
178 // こ?Exceptionは、catchでErrorMessageにセ?されます?
179 String errMsg = "??ファイルが削除できませんでした?" + objFile + "]" ;
180 throw new HybsSystemException( errMsg );
181 }
182
183
184 // // 出力ファイル名?、オブジェクト名と同じ
185 // // PACKAGE と、PACKAGE BODY が同じオブジェクト名の場合?同じファイルに追?append=true)されます?
186 //出力ファイルは原則オブジェクト名と同じ?、PachageBodyのみ後ろに?BODYを付けて?
187 writer = FileUtil.getPrintWriter( objFile,ENCODE,true );
188
189 if( isXml ) { writer.println( XML_START_TAG ); }
190 writer.println( makeHeadLine( clmNo,data ) );
191
192 // オブジェクト?細??ブル(GF83) の検索
193 String[] vals = new String[] { systemId,tblsyu,objType,objName };
194 String[][] gf83 = DBUtil.dbExecute( GF83_SEL,vals,tran );
195 if( gf83.length == 0 ) {
196 System.out.println( "OBJ_TYPE=[" + objType + "], OBJ_NAME=[" + objName + "] is Not Found!" );
197 continue;
198 }
199
200 // ソースの出?
201 StringBuilder buf = new StringBuilder() ;
202 for( int j=0; j<gf83.length; j++ ) {
203 if( isXml ){ buf.append(StringUtil.xmlFilter( gf83[j][1] )).append( CR );; } // 5.8.8.2 (2014/12/19) XML時??エスケープす?
204 else{ buf.append( gf83[j][1] ).append( CR ); }
205 }
206
207 writer.print( buf.toString() );
208 writer.println( makeEndLine() );
209 if( isXml ) { writer.println( XML_END_TAG ); }
210 if( writer != null ) { writer.close(); }
211 }
212 catch( RuntimeException ex ) {
213 ErrorMessage errMessage = makeErrorMessage( "TableFilter_DBSRC_OUT Error",ErrorMessage.NG );
214 errMessage.addMessage( row+1,ErrorMessage.NG,"SRC",ex.getMessage() );
215 errMessage.addMessage( row+1,ErrorMessage.NG,"SRC",StringUtil.array2csv( data ) );
216 errMessage.addMessage( row+1,ErrorMessage.NG,"SRC","OBJ_TYPE=[" + objType + "], OBJ_NAME=[" + objName + "]" );
217 }
218 finally {
219 if( writer != null ) { writer.close(); }
220 }
221 }
222
223 return table;
224 }
225
226 /**
227 * ヘッ??として使用する??を作?します?
228 *
229 * @og.rev 5.7.2.0 (2014/01/10) 構文の見直?
230 * @og.rev 5.8.8.2 (2014/12/19) View以外?場合に不正Create?なる?で修正
231 *
232 * @param clmNo カラ?号配?
233 * @param data ?行?の??タ配?
234 *
235 * @return ヘッ??として使用する??
236 */
237 protected String makeHeadLine( final int[] clmNo,final String[] data ) {
238 // 5.7.2.0 (2014/01/10) objType,objName の再利用と、VIEWの場合?、AS を追?ます?
239 String objType = data[clmNo[OBJ_TYPE]];
240 String objName = data[clmNo[OBJ_NAME]];
241 String as = "VIEW".equalsIgnoreCase( objType ) ? " AS " : " " ;
242
243 String LINE1 = "SYSTEM_ID : " + data[clmNo[SYSTEM_ID]] ;
244 String LINE2 = objName + " ( " + objType + " )" ; // 5.7.2.0 (2014/01/10)
245 String LINE3 = "Created : " + HybsSystem.getDate() ;
246
247 int[] addLen = new int[] { 0,0,0 }; // ?ータ間?スペ?ス
248 int[] type = new int[] { X,K,X }; // ?ータの種別 X:半?S:空白前埋?K:全角混在
249 FixLengthData fixData = new FixLengthData( addLen,type );
250
251 String[][] outData = new String[][] {
252 { "/**", CMNT , "**/" },
253 { "/* ", LINE1, " */" },
254 { "/* ", LINE2, " */" },
255 { "/* ", LINE3, " */" },
256 { "/**", CMNT , "**/" },
257 };
258
259 // 5.6.6.0 (2013/07/05) 簡易メソ?を利用
260 fixData.addAllListData( outData );
261
262 StringBuilder buf = new StringBuilder();
263 fixData.getAllFixData( buf );
264
265 // 5.8.2.2 (2014/12/19)
266 objType = "VIEW".equalsIgnoreCase( objType ) ? objType : " " ;
267 objName = "VIEW".equalsIgnoreCase( objType ) ? objName : " " ;
268
269 if( isXml ) { buf.append( EXEC_START_TAG ).append( CR ); }
270 buf.append( "CREATE " ).append( objType ).append( " " ).append( objName ).append( as ); // 5.7.2.0 (2014/01/10)
271
272 return buf.toString() ;
273 }
274
275 /**
276 * ??行に相当する文字?を作?します?
277 *
278 * @return ??行に相当する文字?
279 */
280 private String makeEndLine() {
281
282 StringBuilder buf = new StringBuilder();
283
284 if( isXml ) { buf.append( CR ).append( EXEC_END_TAG ); }
285 else { buf.append( "/" ); }
286
287 return buf.toString() ;
288 }
289 }