Source for gnu.java.net.protocol.ftp.FTPURLConnection

   1: /* FTPURLConnection.java --
   2:    Copyright (C) 2003, 2004, 2006  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.java.net.protocol.ftp;
  40: 
  41: import gnu.classpath.SystemProperties;
  42: import gnu.java.net.GetLocalHostAction;
  43: 
  44: import java.io.FilterInputStream;
  45: import java.io.FilterOutputStream;
  46: import java.io.IOException;
  47: import java.io.InputStream;
  48: import java.io.OutputStream;
  49: import java.net.InetAddress;
  50: import java.net.URL;
  51: import java.net.URLConnection;
  52: import java.security.AccessController;
  53: import java.util.HashMap;
  54: import java.util.Map;
  55: 
  56: /**
  57:  * An FTP URL connection.
  58:  *
  59:  * @author Chris Burdess (dog@gnu.org)
  60:  */
  61: public class FTPURLConnection
  62:   extends URLConnection
  63: {
  64: 
  65:   /**
  66:    * The connection managing the protocol exchange.
  67:    */
  68:   protected FTPConnection connection;
  69: 
  70:   protected boolean passive;
  71:   protected int representationType;
  72:   protected int fileStructure;
  73:   protected int transferMode;
  74: 
  75:   /**
  76:    * Constructs an FTP connection to the specified URL.
  77:    * @param url the URL
  78:    */
  79:   public FTPURLConnection(URL url)
  80:   {
  81:     super(url);
  82:     passive = true;
  83:     representationType = FTPConnection.TYPE_BINARY;
  84:     fileStructure = -1;
  85:     transferMode = -1;
  86:   }
  87: 
  88:   /**
  89:    * Establishes the connection.
  90:    */
  91:   public void connect()
  92:     throws IOException
  93:   {
  94:     if (connected)
  95:       {
  96:         return;
  97:       }
  98:     String host = url.getHost();
  99:     int port = url.getPort();
 100:     String username = url.getUserInfo();
 101:     String password = null;
 102:     if (username != null)
 103:       {
 104:         int ci = username.indexOf(':');
 105:         if (ci != -1)
 106:           {
 107:             password = username.substring(ci + 1);
 108:             username = username.substring(0, ci);
 109:           }
 110:       }
 111:     else
 112:       {
 113:         username = "anonymous";
 114:         GetLocalHostAction a = new GetLocalHostAction();
 115:         InetAddress localhost =(InetAddress) AccessController.doPrivileged(a);
 116:         password = SystemProperties.getProperty("user.name") + "@" +
 117:           ((localhost == null) ? "localhost" : localhost.getHostName());
 118:       }
 119:     connection = new FTPConnection(host, port);
 120:     if (!connection.authenticate(username, password))
 121:       {
 122:         throw new SecurityException("Authentication failed");
 123:       }
 124:     connection.setPassive(passive);
 125:     if (representationType != -1)
 126:       {
 127:         connection.setRepresentationType(representationType);
 128:       }
 129:     if (fileStructure != -1)
 130:       {
 131:         connection.setFileStructure(fileStructure);
 132:       }
 133:     if (transferMode != -1)
 134:       {
 135:         connection.setTransferMode(transferMode);
 136:       }
 137:   }
 138:   
 139:   /**
 140:    * This connection supports doInput.
 141:    */
 142:   public void setDoInput(boolean doinput)
 143:   {
 144:     doInput = doinput;
 145:   }
 146: 
 147:   /**
 148:    * This connection supports doOutput.
 149:    */
 150:   public void setDoOutput(boolean dooutput)
 151:   {
 152:     doOutput = dooutput;
 153:   }
 154:   
 155:   /**
 156:    * Returns an input stream that reads from this open connection.
 157:    */
 158:   public InputStream getInputStream()
 159:     throws IOException
 160:   {
 161:     if (!connected)
 162:       {
 163:         connect();
 164:       }
 165:     String path = url.getPath();
 166:     if (connection.changeWorkingDirectory(path))
 167:       {
 168:         return this.new ClosingInputStream(connection.list(null));
 169:       }
 170:     else
 171:       {
 172:         return this.new ClosingInputStream(connection.retrieve(path));
 173:       }
 174:   }
 175:   
 176:   /**
 177:    * Returns an output stream that writes to this connection.
 178:    */
 179:   public OutputStream getOutputStream()
 180:     throws IOException
 181:   {
 182:     if (!connected)
 183:       {
 184:         connect();
 185:       }
 186:     String path = url.getPath();
 187:     return this.new ClosingOutputStream(connection.store(path));
 188:   }
 189: 
 190:   public String getRequestProperty(String key)
 191:   {
 192:     if ("passive".equals(key))
 193:       {
 194:         return Boolean.toString(passive);
 195:       }
 196:     else if ("representationType".equals(key))
 197:       {
 198:         switch (representationType)
 199:           {
 200:           case FTPConnection.TYPE_ASCII:
 201:             return "ASCII";
 202:           case FTPConnection.TYPE_EBCDIC:
 203:             return "EBCDIC";
 204:           case FTPConnection.TYPE_BINARY:
 205:             return "BINARY";
 206:           }
 207:       }
 208:     else if ("fileStructure".equals(key))
 209:       {
 210:         switch (fileStructure)
 211:           {
 212:           case FTPConnection.STRUCTURE_FILE:
 213:             return "FILE";
 214:           case FTPConnection.STRUCTURE_RECORD:
 215:             return "RECORD";
 216:           case FTPConnection.STRUCTURE_PAGE:
 217:             return "PAGE";
 218:           }
 219:       }
 220:     else if ("transferMode".equals(key))
 221:       {
 222:         switch (transferMode)
 223:           {
 224:           case FTPConnection.MODE_STREAM:
 225:             return "STREAM";
 226:           case FTPConnection.MODE_BLOCK:
 227:             return "BLOCK";
 228:           case FTPConnection.MODE_COMPRESSED:
 229:             return "COMPRESSED";
 230:           }
 231:       }
 232:     return null;
 233:   }
 234: 
 235:   public Map getRequestProperties()
 236:   {
 237:     Map map = new HashMap();
 238:     addRequestPropertyValue(map, "passive");
 239:     addRequestPropertyValue(map, "representationType");
 240:     addRequestPropertyValue(map, "fileStructure");
 241:     addRequestPropertyValue(map, "transferMode");
 242:     return map;
 243:   }
 244: 
 245:   private void addRequestPropertyValue(Map map, String key)
 246:   {
 247:     String value = getRequestProperty(key);
 248:     map.put(key, value);
 249:   }
 250:   
 251:   public void setRequestProperty(String key, String value)
 252:   {
 253:     if (connected)
 254:       {
 255:         throw new IllegalStateException();
 256:       }
 257:     if ("passive".equals(key))
 258:       {
 259:         passive = Boolean.valueOf(value).booleanValue();
 260:       }
 261:     else if ("representationType".equals(key))
 262:       {
 263:         if ("A".equalsIgnoreCase(value) ||
 264:             "ASCII".equalsIgnoreCase(value))
 265:           {
 266:             representationType = FTPConnection.TYPE_ASCII;
 267:           }
 268:         else if ("E".equalsIgnoreCase(value) ||
 269:                  "EBCDIC".equalsIgnoreCase(value))
 270:           {
 271:             representationType = FTPConnection.TYPE_EBCDIC;
 272:           }
 273:         else if ("I".equalsIgnoreCase(value) ||
 274:                  "BINARY".equalsIgnoreCase(value))
 275:           {
 276:             representationType = FTPConnection.TYPE_BINARY;
 277:           }
 278:         else
 279:           {
 280:             throw new IllegalArgumentException(value);
 281:           }
 282:       }
 283:     else if ("fileStructure".equals(key))
 284:       {
 285:         if ("F".equalsIgnoreCase(value) ||
 286:             "FILE".equalsIgnoreCase(value))
 287:           {
 288:             fileStructure = FTPConnection.STRUCTURE_FILE;
 289:           }
 290:         else if ("R".equalsIgnoreCase(value) ||
 291:                  "RECORD".equalsIgnoreCase(value))
 292:           {
 293:             fileStructure = FTPConnection.STRUCTURE_RECORD;
 294:           }
 295:         else if ("P".equalsIgnoreCase(value) ||
 296:                  "PAGE".equalsIgnoreCase(value))
 297:           {
 298:             fileStructure = FTPConnection.STRUCTURE_PAGE;
 299:           }
 300:         else
 301:           {
 302:             throw new IllegalArgumentException(value);
 303:           }
 304:       }
 305:     else if ("transferMode".equals(key))
 306:       {
 307:         if ("S".equalsIgnoreCase(value) ||
 308:             "STREAM".equalsIgnoreCase(value))
 309:           {
 310:             transferMode = FTPConnection.MODE_STREAM;
 311:           }
 312:         else if ("B".equalsIgnoreCase(value) ||
 313:                  "BLOCK".equalsIgnoreCase(value))
 314:           {
 315:             transferMode = FTPConnection.MODE_BLOCK;
 316:           }
 317:         else if ("C".equalsIgnoreCase(value) ||
 318:                  "COMPRESSED".equalsIgnoreCase(value))
 319:           {
 320:             transferMode = FTPConnection.MODE_COMPRESSED;
 321:           }
 322:         else
 323:           {
 324:             throw new IllegalArgumentException(value);
 325:           }
 326:       }
 327:   }
 328: 
 329:   public void addRequestProperty(String key, String value)
 330:   {
 331:     setRequestProperty(key, value);
 332:   }
 333: 
 334:   class ClosingInputStream
 335:     extends FilterInputStream
 336:   {
 337: 
 338:     ClosingInputStream(InputStream in)
 339:     {
 340:       super(in);
 341:     }
 342: 
 343:     public void close()
 344:       throws IOException
 345:     {
 346:       super.close();
 347:       connection.logout();
 348:     }
 349:     
 350:   }
 351: 
 352:   class ClosingOutputStream
 353:     extends FilterOutputStream
 354:   {
 355: 
 356:     ClosingOutputStream(OutputStream out)
 357:     {
 358:       super(out);
 359:     }
 360: 
 361:     public void close()
 362:       throws IOException
 363:     {
 364:       super.close();
 365:       connection.logout();
 366:     }
 367:     
 368:   }
 369: 
 370: }