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.fukurou.util;
017
018 import java.io.FileInputStream;
019 import java.io.FileOutputStream;
020 import java.io.InputStream;
021 import java.io.OutputStream;
022 import java.io.BufferedInputStream;
023 import java.io.BufferedOutputStream;
024 import java.io.IOException;
025 import java.util.Map;
026 import java.util.LinkedHashMap ;
027 import java.net.MalformedURLException ;
028
029 import jcifs.smb.SmbFile;
030
031 /**
032 * SMBConnect.java は、å?通的に使用されã‚?Smb関連の基本機è?を実è£?�—たã?クラスですã?
033 *
034 * これは、jcifs.smb パッケージをã?ースに開発されてã�?�¾すã?
035 * こã?クラスの実行には、jcifs-1.3.14.jar がå¿?¦�ですã?
036 *
037 * 接続å?のURL schemeは、以下ã?形式をしてã�?�¾すã?
038 * smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
039 * こã?URLは、å?部çš?�«自動作æ?しますã?/[[share/[dir/]file]] 部åˆ?�Œ、remoteFile としてæŒ?®šする部åˆ?�«なりますã? *
040 *
041 * -host=Smbサーバã? -user=ユーザー -passwd=パスワーãƒ?-remoteFile=Smb先ã?ファイルå�?をå¿??設定しますã?
042 * -localFile=ローカルのファイル名ã?、å¿??ではありませんがã?-command=DEL の場合にのみ不要でありã€?
043 * それ以外ã? command の場合ã?、å¿?¦�ですã?
044 *
045 * -command=[GET/PUT/DEL/GETDIR/PUTDIR/DELDIR] は、SFTPサーバã?に対しての処ç�??方法をæŒ?®šしますã?
046 * GET:Smbサーバã?からローカルにファイル転送しまã�?初期値)
047 * PUT:ローカルファイルをSmbサーバã?に PUT(STORE、SAVE、UPLOAD、などと同意èª?しますã?
048 * DEL:Smbサーバã?のæŒ?®šã?ファイルを削除しますã?こã?場合ã?みã€?localFile 属æ?のæŒ?®šã?不要ですã?
049 * GETDIR,PUTDIR,DELDIR:æŒ?®šã?フォルãƒ?»¥下ã?ファイルをå?ç�?�—ますã?
050 *
051 * -mkdirs=[true/false] は、受けå?のファイル(GETæ™?LOCAL、PUTæ™?Smbサーバã?)に取り込ã‚?ƒ•ァイルのãƒ?‚£レクトリã�?
052 * 存在しなã�??合に、作æ?するかどã�?�‹を指定しまã�?初期値:true)ã€?
053 * 通常、Smbサーバã?に、フォルãƒ?šŽ層を作æ?してPUTする場合ã?動的にフォルãƒ?šŽ層を作æ?したã�?‚±ースで便利ですã?
054 * é€?�«、フォルãƒ??確定しており、指定フォルãƒ?»¥外に PUT するのはバグってã�?‚‹と事がåˆ?�‹ってã�?‚‹場合には
055 * false に設定して、存在しなã�?ƒ•ォルãƒ?�«PUT しよã�?�¨すると、エラーになるよã�?�«しますã?
056 *
057 * 引数æ–?—å?中に空白を含ã‚??合ã?、ダブルコーãƒ??ション("") で括って下さã�??
058 * 引数æ–?—å?の ã€?』ã?前後には、空白は挟めません。å¿?�šã€?key=value の様に
059 * 繋げてくださいã€?
060 *
061 * @og.formSample
062 * SMBConnect -host=Smbサーバã? -user=ユーザー -passwd=パスワーãƒ?-remoteFile=Smb先ã?ファイルå�?[-localFile=ローカルのファイル名]
063 * [-command=[GET/PUT/DEL/GETDIR/PUTDIR/DELDIR] ] ]
064 *
065 * -host=Smbサーバã? ?š接続å?のSmbサーバã?のアドレスまたã?、サーバã?å�?
066 * -user=ユーザー ?š接続するユーザーå�?
067 * -passwd=パスワーãƒ? ?š接続するユーザーのパスワーãƒ?
068 * -remoteFile=Smb先ã?ファイルå�? ?š接続å?のSmbサーバã?側のファイル名ã?PUT,GET 関係なくSmb側としてæŒ?®šしますã?
069 * [-localFile=ローカルのファイル名] ?šローカルのファイル名ã?PUT,GET 関係なくローカルファイルを指定しますã?
070 * [-domain=ドメイン ] ?š接続するサーバã?のドメインを指定しますã?
071 * [-port=ポã?ãƒ?] ?š接続するサーバã?のポã?トをæŒ?®šしますã?
072 * [-command=[GET/PUT/DEL] ] ?šSmbサーバã?側での処ç�??方法をæŒ?®šしますã?
073 * [GETDIR/PUTDIR/DELDIR]] GET:Smb⇒LOCAL、PUT:LOCAL⇒Smb への転送でã�?初期値:GET)
074 * DEL:Smbファイルを削除しますã?
075 * GETDIR,PUTDIR,DELDIR æŒ?®šã?フォルãƒ?»¥下ã?ファイルをå?ç�?�—ますã?
076 * [-mkdirs=[true/false] ] ?š受けå?ファイル(GETæ™?LOCAL、PUTæ™?Smbサーバã?)にãƒ?‚£レクトリを作æ?するかどã�?�‹(初期値:true)
077 * (false:ãƒ?‚£レクトリが無ければ、エラーにしますã?)
078 * [-display=[false/true] ] ?štrueは、検索状況を表示しまã�?初期値:false)
079 * [-debug=[false|true] ] ?šデバッグæƒ??を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
080 *
081 * @og.rev 5.1.6.0 (2010/05/01) 新規追åŠ?
082 *
083 * @version 5.0
084 * @author Kazuhiko Hasegawa
085 * @since JDK5.0,
086 */
087 public final class SMBConnect extends AbstractConnect {
088 private String domain = null; // ドメイン
089 private String connURI = null; // Smb接続するå?合ã?URIæ–?—å?(の先é?)
090
091 /**
092 * ãƒ?ƒ•ォルトコンストラクター
093 */
094 // public SMBConnect() {
095 // }
096
097 /**
098 * Smbサーバã?への接続ã?ログインを行いますã?
099 *
100 * こã?メソãƒ?ƒ‰は、å?期化メソãƒ?ƒ‰ですã?
101 * Smbサーバã?への接続ã?ログインを行いますã?で、è¤?•°ファイルを転送すã‚?
102 * ケースでは、最初に?‘度ã�?�‘呼び出すだけですã?
103 * 接続å?を変更する場合ã?、もã�?¸?º¦こã?メソãƒ?ƒ‰をコールするå¿?¦�がありますã?
104 * (そã?ような場合ã?ã€??常、オブジェクトを構築しなおす方がよã�?�¨思いますã?)
105 * 接続時のアドレスは、下記ã?形式になりますが、ファイル名ã?ç®?‰€は、action 時にæŒ?®šするためã?
106 * ここでは、å?頭部åˆ?‚’先に用意しておきますã?
107 * smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
108 *
109 */
110 @Override
111 public void connect() {
112 if( isDisplay ) { System.out.println( "CONNECT: HOST=" + host + ",USER=" + user + ",PORT=" + port ); }
113
114 if( host == null ) {
115 errAppend( "host は、å¿??ですã?" );
116 throw new RuntimeException( getErrMsg() );
117 }
118
119 // smb://[[[domain;]username[:password]@]server[:port] ここまで作æ?
120 connURI = "smb://"
121 + ((domain == null) ? "" : domain + ";" )
122 + ((user == null) ? "" : user )
123 + ((passwd == null) ? "" : ":" + passwd )
124 + ((user == null) ? "" : "@" )
125 + host
126 + ((port == null) ? "" : ":" + port ) ;
127
128 if( isDebug ) { System.out.println( "connURI=" + connURI ); }
129 }
130
131 /**
132 * Smbサーバã?との接続をクローズしますã?
133 *
134 * ここでは、何も処ç�?‚’行いませんã€?
135 *
136 */
137 @Override
138 public void disconnect() {
139 if( isDisplay ) { System.out.println( "DISCONNECT:" ); }
140 }
141
142 /**
143 * command="GET" が指定されたときã?処ç�?‚’行いますã?
144 *
145 * 接続å?のSmbサーバã?側のファイル名をローカルにãƒ?‚¦ンロードしますã?
146 *
147 * @param localFile ローカルのファイルå�?
148 * @param remoteFile Smb先ã?ファイルå�?
149 * @throws IOException 入出力エラーが発生したとã�?
150 */
151 @Override
152 protected void actionGET( final String localFile, final String remoteFile ) throws IOException {
153 if( isDebug ) { System.out.println( "GET: " + remoteFile + " => " + localFile ); }
154
155 SmbFile rmtFile = makeSmbURI( remoteFile );
156
157 // GET(DOWNLOAD)取得時は、ローカルファイルのãƒ?‚£レクトリを作æ?するå¿?¦�があるã€?
158 if( isMkdirs ) {
159 makeLocalDir( localFile );
160 }
161
162 InputStream input = null;
163 OutputStream output = null;
164 try {
165 // input = new BufferedInputStream( new SmbFileInputStream( remoteFile ) );
166 input = new BufferedInputStream( rmtFile.getInputStream() );
167 output = new FileOutputStream( localFile );
168 FileUtil.copy( input,output );
169 }
170 finally {
171 Closer.ioClose( input );
172 Closer.ioClose( output );
173 }
174 }
175
176 /**
177 * command="GETDIR" が指定されたときã?処ç�?‚’行いますã?
178 *
179 * 接続å?のSmbサーバã?側のãƒ?‚£レクトリ以下をローカルãƒ?‚£レクトリに階層構é?のままãƒ?‚¦ンロードしますã?
180 *
181 * @param localDir ローカルのãƒ?‚£レクトリå�?
182 * @param remoteDir Smb先ã?ãƒ?‚£レクトリå�?
183 * @throws IOException 入出力エラーが発生したとã�?
184 */
185 @Override
186 protected void actionGETdir( final String localDir, final String remoteDir ) throws IOException {
187 SmbFile rmtFile = makeSmbURI( remoteDir );
188
189 SmbFile[] rmtFiles = rmtFile.listFiles();
190 for( int i=0; i<rmtFiles.length; i++ ) {
191 String rmt = rmtFiles[i].getName();
192 if( rmtFiles[i].isDirectory() ) {
193 actionGETdir( addFile( localDir,rmt ),addFile( remoteDir,rmt ) );
194 }
195 else {
196 actionGET( addFile( localDir,rmt ),addFile( remoteDir,rmt ) );
197 }
198 }
199 }
200
201 /**
202 * command="PUT" が指定されたときã?処ç�?‚’行いますã?
203 *
204 * ローカルファイルをã?接続å?のSmbサーバã?側にアãƒ??ロードしますã?
205 *
206 * @param localFile ローカルのファイルå�?
207 * @param remoteFile Smb先ã?ファイルå�?
208 * @throws IOException 入出力エラーが発生したとã�?
209 */
210 @Override
211 protected void actionPUT( final String localFile, final String remoteFile ) throws IOException {
212 if( isDebug ) { System.out.println( "PUT: " + localFile + " => " + remoteFile ); }
213
214 SmbFile rmtFile = makeSmbURI( remoteFile );
215
216 // 存在チェãƒ?‚¯?šすでに存在してã�?‚‹場合ã?、å?に削除しますã?
217 if( rmtFile.exists() ) { rmtFile.delete() ; }
218 else {
219 // PUT(UPLOAD)登録時ã?、リモートファイルのãƒ?‚£レクトリを作æ?するå¿?¦�があるã€?
220 if( isMkdirs ) {
221 String tmp = rmtFile.getParent();
222 SmbFile dir = new SmbFile( tmp );
223 if( !dir.exists() ) { dir.mkdirs() ; }
224 }
225 }
226
227 InputStream input = null;
228 OutputStream output = null;
229 try {
230 input = new FileInputStream( localFile );
231 // output = new BufferedOutputStream( new SmbFileOutputStream( remoteFile ) );
232 output = new BufferedOutputStream( rmtFile.getOutputStream() );
233
234 FileUtil.copy( input,output );
235 }
236 finally {
237 Closer.ioClose( input );
238 Closer.ioClose( output );
239 }
240 }
241
242 /**
243 * command="DEL" が指定されたときã?処ç�?‚’行いますã?
244 *
245 * 接続å?のSmbサーバã?側のファイル名を削除しますã?
246 *
247 * @param remoteFile Smb先ã?ファイルå�?
248 * @throws IOException 入出力エラーが発生したとã�?
249 */
250 @Override
251 protected void actionDEL( final String remoteFile ) throws IOException {
252 if( isDebug ) { System.out.println( "DEL: " + remoteFile ); }
253
254 SmbFile rmtFile = makeSmbURI( remoteFile );
255 rmtFile.delete() ;
256 }
257
258 /**
259 * command="DELDIR" が指定されたときã?処ç�?‚’行いますã?
260 *
261 * 接続å?のSmbサーバã?側のãƒ?‚£レクトリ以下をローカルãƒ?‚£レクトリに階層構é?のままãƒ?‚¦ンロードしますã?
262 *
263 * @param remoteDir Smb先ã?ãƒ?‚£レクトリå�?
264 * @throws IOException 入出力エラーが発生したとã�?
265 */
266 @Override
267 protected void actionDELdir( final String remoteDir ) throws IOException {
268 SmbFile rmtFile = makeSmbURI( remoteDir );
269 SmbFile[] rmtFiles = rmtFile.listFiles();
270 for( int i=0; i<rmtFiles.length; i++ ) {
271 String rmt = addFile( remoteDir,rmtFiles[i].getName() );
272 if( rmtFiles[i].isDirectory() ) {
273 actionDELdir( rmt );
274 }
275 else {
276 actionDEL( rmt );
277 // rmtFiles[i].delete();
278 }
279 }
280 rmtFile.delete();
281 }
282
283 /**
284 * SMB形式ã?URLを作æ?しますã?
285 *
286 * 処ç�?š„には、å?部で先に作æ?済みの connURI と、引数のファイルパスを文字å?連結しますã?
287 * connURI のæœ?¾Œにはã€?/" を付加してã�?�¾せんので、引数のファイルパスにã€?
288 * "/" を含まなã�??合ã?ã€?/" を付加しますã?
289 *
290 * smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]]
291 *
292 * @param remoteFile Smb先ã?ファイルå�?
293 *
294 * @return SMB形式ã?URL
295 */
296 private SmbFile makeSmbURI( final String remoteFile ) throws MalformedURLException {
297 final String smbFile ;
298
299 if( remoteFile.startsWith( "smb://" ) ) {
300 smbFile = remoteFile;
301 }
302 else if( remoteFile.startsWith( "/" ) ) {
303 smbFile = connURI + remoteFile ;
304 }
305 else {
306 smbFile = connURI + "/" + remoteFile ;
307 }
308
309 // SmbFile rmtFile = new SmbFile( smbFile );
310 // return rmtFile;
311 return new SmbFile( smbFile );
312 }
313
314 /**
315 * 接続å?にログインするドメインを設定しますã?
316 *
317 * @param domain 接続å?にログインするドメイン
318 */
319 public void setDomain( final String domain ) {
320 this.domain = domain ;
321 }
322
323 // ******************************************************************************************************* //
324 // 以下ã?単独で使用する場合ã? main処ç�?
325 // ******************************************************************************************************* //
326
327 private static final Map<String,String> mustProparty ; // ?»プロパティ?½å¿??チェãƒ?‚¯用 Map
328 private static final Map<String,String> usableProparty ; // ?»プロパティ?½整合æ?チェãƒ?‚¯ Map
329
330 static {
331 mustProparty = new LinkedHashMap<String,String>();
332 mustProparty.put( "host", "接続å?のSmbサーバã?のアドレスまたã?、サーバã?å�?å¿??)" );
333 mustProparty.put( "user", "接続するユーザーå�?å¿??)" );
334 mustProparty.put( "passwd", "接続するユーザーのパスワーãƒ?å¿??)" );
335 mustProparty.put( "command", "Smbサーバã?側での処ç�??方æ³?GET/PUT/DEL/GETDIR/PUTDIR/DELDIR)を指定しますã?(å¿??)" );
336 mustProparty.put( "remoteFile", "接続å?のSmbサーバã?側のファイルå�?å¿??)" );
337
338 usableProparty = new LinkedHashMap<String,String>();
339 usableProparty.put( "localFile", "ローカルのファイルå�? );
340 usableProparty.put( "domain", "接続å?にログインするドメインを指定しますã?" );
341 usableProparty.put( "port", "接続に利用するポã?ト番号を設定しますã?" );
342 usableProparty.put( "mkdirs", "受け側ファイル(GETæ™?LOCAL、PUTæ™?Smbサーバã?)にãƒ?‚£レクトリを作æ?するかどã�?�‹(初期値:true)" );
343 usableProparty.put( "display", "[false/true]:trueは、検索状況を表示しまã�?初期値:false)" );
344 usableProparty.put( "debug", "ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�? +
345 CR + "(初期値:false:表示しなã�?" );
346 }
347
348 private static final String[] CMD_LST = new String[] { "GET","PUT","DEL","GETDIR","PUTDIR","DELDIR" };
349
350 /**
351 * こã?クラスの動作確認用の、main メソãƒ?ƒ‰ですã?
352 *
353 * @param args コマンド引数配å?
354 */
355 public static void main( final String[] args ) {
356 Argument arg = new Argument( "org.opengion.fukurou.util.SMBConnect" );
357 arg.setMustProparty( mustProparty );
358 arg.setUsableProparty( usableProparty );
359 arg.setArgument( args );
360
361 SMBConnect smb = new SMBConnect();
362
363 String host = arg.getProparty( "host"); // Smbサーバã?
364 String user = arg.getProparty( "user" ); // ユーザー
365 String passwd = arg.getProparty( "passwd" ); // パスワーãƒ?
366
367 smb.setHostUserPass( host,user,passwd );
368
369 smb.setDomain( arg.getProparty( "domain" ) ); // 接続å?にログインするドメインを指定しますã?
370 smb.setPort( arg.getProparty( "port" ) ); // 接続に利用するポã?ト番号を設定しますã?
371 smb.setMkdirs( arg.getProparty( "mkdirs" ,true ) ); // 受け側ファイルにãƒ?‚£レクトリを作æ?するかどã�?�‹
372 smb.setDisplay( arg.getProparty( "display" ,false ) ); // trueは、検索状況を表示しまã�?初期値:false)
373 smb.setDebug( arg.getProparty( "debug" ,false ) ); // ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�?
374
375 try {
376 // コネクトしますã?
377 smb.connect();
378
379 String command = arg.getProparty( "command" ,"GET" ,CMD_LST ); // Smb処ç�??方法をæŒ?®šしますã?
380 String localFile = arg.getProparty( "localFile" ); // ローカルのファイルå�?
381 String remoteFile = arg.getProparty( "remoteFile" ); // Smb先ã?ファイルå�?
382
383 // command , localFile , remoteFile をå?に、SFTP処ç�?‚’行いますã?
384 smb.action( command,localFile,remoteFile );
385 }
386 catch( RuntimeException ex ) {
387 System.err.println( smb.getErrMsg() );
388 }
389 finally {
390 // ホストとの接続を終äº?�—ますã?
391 smb.disconnect();
392 }
393 }
394 }