Source code: com/yaftp/ftp/MVSftp.java
1 /**
2 *
3 * CopyRights Jean-Yves MENGANT 1999,2000,2001,2002
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 package com.yaftp.ftp;
21
22 import java.util.* ;
23
24 /**
25 implements MVS idiosynchrasy based on abstract methods
26 defined in parent FtpOs class
27
28 @Author Jean-Yves MENGANT
29 @version : 0.0.1
30
31
32 */
33 public class MVSftp extends FtpOs {
34
35 private final static String _WKDIR_MESSAGE_ = "working directory" ;
36 private final static String _PARTITIONNED_DS_MESSAGE_ = "partitioned" ;
37 private final static char _DOUBLE_QUOTE_ = '"' ;
38
39 private final int _DIRECTORY_COUNT_ = 10 ;
40 private final String _EMPTY_ = "" ;
41 /** this is what we get when the queue is empty */
42 private final String _NO_JOB_FOUNDS_ = "No jobs found" ;
43 /** the standard JES columns */
44 private final static String[] _JES_COLUMNS_ = {
45 "JobName" , "JOBID" , "Input/Output" , "nb files"
46 } ;
47
48 private String[] _DETAILED_COLUMNS_ ;
49
50 /**
51 a UNIXFtp object instance is allocated if HFS mode is switched
52 during session
53 */
54 private UNIXftp _hfs = null ;
55
56 /** true whenever the LIST is turned on to view JES2 OUT files */
57 private boolean _jesMode = false ;
58
59 // TO DO : following variables should be set and unset through the
60 // checkCurDirectory method depending on FTP received message.
61 private boolean _isPds = false ;
62 private String _filePrefix = "" ;
63
64
65 private void build_DETAILED_COLUMNS_( String colList )
66 {
67 StringTokenizer tokenList = new StringTokenizer( colList ) ;
68 _DETAILED_COLUMNS_ = new String[ tokenList.countTokens() ] ;
69
70 for ( int ii = 1 ; ii <= _DETAILED_COLUMNS_.length ; ii++ )
71 _DETAILED_COLUMNS_[ii-1] = tokenList.nextToken() ;
72
73 }
74
75 /**
76 if jes mode is toggle just build the standard JES job column list
77 */
78 private void build_DETAILED_JES_COLUMNS()
79 {
80 _DETAILED_COLUMNS_ = _JES_COLUMNS_ ;
81 }
82
83 public void set_jesMode( boolean jesMode )
84 {
85 _jesMode = jesMode ;
86 }
87
88 public MVSftp()
89 { super() ; }
90
91 public void reset_COLTITLE()
92 { _DETAILED_COLUMNS_ = null ; }
93
94 public String[] get_Column_Names()
95 { return _DETAILED_COLUMNS_ ; }
96
97 public String toString()
98 { return("MVS") ; }
99
100 /**
101 this entry point called after a changed directory with
102 the CD FTP returned message , this gives the capacity to determine
103 on which file system we're positionned
104 */
105 public final String checkCurDirectory( String message )
106 {
107 // extract the working directory first
108 if ( message == null )
109 return message ;
110
111 int quotePos = message.indexOf(_DOUBLE_QUOTE_) ;
112 if ( quotePos != -1 )
113 {
114 int lastQuotePos = message.lastIndexOf(_DOUBLE_QUOTE_) ;
115 _filePrefix = message.substring(quotePos+1,lastQuotePos) ;
116 }
117 if ( message.indexOf(_PARTITIONNED_DS_MESSAGE_) != -1 )
118 {
119 message = "MVS PDS " + _filePrefix + " is current directory" ;
120 _isPds = true ;
121 }
122 else
123 message = "Name Space " + _filePrefix + " is current directory" ;
124 return message ;
125 }
126
127 // Convert InDIr String into MVS style directory
128 public void convertDirectory( String inDir )
129 {
130 // if inDir starts with a UNX path symbol
131 // we assume user wants to jump to HFS mode
132 // and we do not do any changes
133 if ( inDir.startsWith( Ftp.ABSOLUTE_UNX ) &&
134 ( _hfs == null )
135 )
136 _hfs = new UNIXftp() ;
137 if ( _hfs != null )
138 {
139 _hfs.convertDirectory(inDir) ;
140 _newDirectory = _hfs.getCurDirectory() ;
141 return ;
142 }
143
144 // Here we're supposed to deal with TSO PDS stuff
145
146 // consume any incomming ./ directory reference
147 if ( inDir.startsWith( Ftp.RELATIVE_UNX ) )
148 inDir = inDir.substring( Ftp.RELATIVE_UNX.length() ) ;
149
150 StringBuffer curDirectory = new StringBuffer("") ;
151 int ii = 0 ;
152 boolean firstSlash = true ;
153
154 while ( ii < inDir.length() )
155 {
156 switch ( inDir.charAt(ii) )
157 {
158 case '/' :
159 case '\\' :
160 if ( firstSlash )
161 firstSlash = false ;
162 else
163 curDirectory.append('.') ;
164 break ;
165
166 default :
167 curDirectory.append(Character.toUpperCase(inDir.charAt(ii) ) ) ;
168 break ;
169 }
170 ii++ ;
171 }
172 // curDirectory.append('\"');
173 _newDirectory = new String(curDirectory) ;
174 }
175
176 // Convert InDIr String into MVS style FileName
177 public void convertFileName( String inFile )
178 {
179 if ( _hfs != null )
180 {
181 _hfs.convertFileName(inFile);
182 _curFile = _hfs.getCurFile() ;
183 return ;
184 }
185
186 if ( _isPds )
187 {
188 StringBuffer curFile = new StringBuffer() ;
189 // remove any FTYPE suffix only if we are in an MVS PDS
190 // file
191 int ii = 0 ;
192 while ( ( ii < inFile.length() ) && ( inFile.charAt(ii) != '.' ) )
193 curFile.append( Character.toUpperCase(inFile.charAt(ii++)) ) ;
194 _curFile = new String(curFile) ; // Stop each Dir or file name with "
195 }
196 else
197 _curFile = inFile ; // looks like a standard MVS QSAM dataset
198 }
199
200 private void dealWithToken( StringTokenizer parser ,
201 String detailled[] ,
202 int detailledInd
203 )
204 {
205 if ( parser.hasMoreTokens() )
206 detailled[detailledInd] = parser.nextToken() ;
207 else
208 detailled[detailledInd] = _EMPTY_ ;
209 }
210
211 // set up a JES
212 public FtpOsFile convertJESLISTElement( String inString )
213 throws ClientFtpError
214 {
215 // System.out.println(inString) ;
216 if ( _DETAILED_COLUMNS_ == null ) // First MVS ftp lines contains COL NAMES
217 {
218 build_DETAILED_JES_COLUMNS() ;
219 }
220
221 if ( inString.startsWith(_NO_JOB_FOUNDS_) )
222 return null ;
223
224 String detailled[] = new String[_DETAILED_COLUMNS_.length] ;
225 int detailledInd = 0 ;
226
227 boolean directory = false ;
228 String fName = null ;
229 StringTokenizer tokenList = new StringTokenizer( inString ) ;
230
231 // Standard JES QUEUE list
232 // JOBNAME
233 dealWithToken( tokenList , detailled , detailledInd++ ) ;
234 // JOBID
235 dealWithToken( tokenList , detailled , detailledInd ) ;
236 fName = detailled[detailledInd++] ;
237 // INPUT | OUTPUT
238 dealWithToken( tokenList , detailled , detailledInd++ ) ;
239 // number of spool files
240 dealWithToken( tokenList , detailled , detailledInd++ ) ;
241
242 return new FtpOsFile( fName , directory , -1 , detailled ) ;
243 }
244
245 // Convert LIST command result into File r name to dest dir format
246 public FtpOsFile convertLISTelement( String inString )
247 throws ClientFtpError
248 {
249 if ( _jesMode )
250 return convertJESLISTElement(inString) ;
251
252 if ( _hfs != null )
253 {
254 FtpOsFile returned = _hfs.convertLISTelement(inString) ;
255 _DETAILED_COLUMNS_ = _hfs.get_Column_Names() ;
256 return returned ;
257 }
258
259 // System.out.println(inString) ;
260 if ( _DETAILED_COLUMNS_ == null ) // First MVS ftp lines contains COL NAMES
261 {
262 build_DETAILED_COLUMNS_(inString) ;
263 return null ;
264 }
265
266 String detailled[] = new String[_DETAILED_COLUMNS_.length] ;
267 int detailledInd = 0 ;
268
269 boolean directory = false ;
270 String fName = null ;
271 StringTokenizer tokenList = new StringTokenizer( inString ) ;
272 FtpOsFile returned = null ;
273
274 // on initial connection
275 if ( tokenList.countTokens() == _DIRECTORY_COUNT_ )
276 {
277 dealWithToken( tokenList , detailled , detailledInd++ ) ;
278 dealWithToken( tokenList , detailled , detailledInd++ ) ;
279 dealWithToken( tokenList , detailled , detailledInd++ ) ;
280 dealWithToken( tokenList , detailled , detailledInd++ ) ;
281 dealWithToken( tokenList , detailled , detailledInd++ ) ;
282 dealWithToken( tokenList , detailled , detailledInd++ ) ;
283 dealWithToken( tokenList , detailled , detailledInd++ ) ;
284 dealWithToken( tokenList , detailled , detailledInd++ ) ;
285
286 dealWithToken( tokenList , detailled , detailledInd ) ;
287 String fileType = detailled[detailledInd++] ;
288
289 dealWithToken( tokenList , detailled , detailledInd ) ;
290 fName = detailled[detailledInd] ;
291
292 if ( fileType.equals("PO") ) // PARTITIONNED DATASET ORG
293 {
294 directory = true ;
295 int dotPos = fName.indexOf('.') ;
296 // assume that when PDS the dot is a directory separator
297 if ( dotPos != -1 )
298 fName = fName.substring(0,dotPos) ;
299 returned = new FtpOsFile( fName , directory , -1 , detailled ) ;
300 returned.set_mvsPds(true);
301 }
302 else
303 returned = new FtpOsFile( fName , false , -1 , detailled ) ;
304 }
305 // Standard PDS MEMBER list
306 else
307 {
308 dealWithToken( tokenList , detailled , detailledInd ) ;
309 fName = detailled[detailledInd++] ;
310
311 dealWithToken( tokenList , detailled , detailledInd++ ) ;
312 dealWithToken( tokenList , detailled , detailledInd++ ) ;
313 dealWithToken( tokenList , detailled , detailledInd++ ) ;
314 dealWithToken( tokenList , detailled , detailledInd++ ) ;
315 dealWithToken( tokenList , detailled , detailledInd++ ) ;
316 dealWithToken( tokenList , detailled , detailledInd++ ) ;
317 dealWithToken( tokenList , detailled , detailledInd ) ;
318 returned = new FtpOsFile( fName , directory , -1 , detailled ) ;
319 returned.set_mvsPdsMember(true);
320 }
321 return returned ;
322 }
323
324 // parse FTP file / dir List in Os Context
325 public Vector ftpList( FtpClientSession curSess )
326 throws ClientFtpError
327 {
328 FtpVectorListener filesListener = new FtpVectorListener() ;
329
330 _fileList = new Vector() ;
331
332 curSess.list( filesListener ) ;
333
334 Hashtable mvsDirFilter = new Hashtable() ;
335 for ( int ii = 0 ; ii < filesListener.get_dataList().size() ; ii++ )
336 {
337 FtpOsFile curFile = convertLISTelement(
338 ( (String)( filesListener.get_dataList().elementAt(ii) ) )
339 ) ;
340 if ( curFile != null )
341 {
342 if ( curFile.is_directory() )
343 {
344 if ( mvsDirFilter.get( curFile.get_name() ) == null ) // not yet in
345 {
346 _fileList.addElement(curFile) ;
347 mvsDirFilter.put( curFile.get_name() , curFile ) ;
348 }
349 }
350 else
351 _fileList.addElement(curFile) ;
352 }
353 }
354
355 return ( _fileList ) ;
356 }
357
358 /**
359 @return true since it's MVS
360 */
361 public boolean isMVS()
362 {
363 return true ;
364 }
365
366 }
367
368
369