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.ArrayList;
  54: import java.util.HashMap;
  55: import java.util.List;
  56: import java.util.Map;
  57: 
  58: /**
  59:  * An FTP URL connection.
  60:  *
  61:  * @author Chris Burdess (dog@gnu.org)
  62:  */
  63: public class FTPURLConnection
  64:   extends URLConnection
  65: {
  66: 
  67:   /**
  68:    * The connection managing the protocol exchange.
  69:    */
  70:   protected FTPConnection connection;
  71: 
  72:   protected boolean passive;
  73:   protected int representationType;
  74:   protected int fileStructure;
  75:   protected int transferMode;
  76: 
  77:   /**
  78:    * Constructs an FTP connection to the specified URL.
  79:    * @param url the URL
  80:    */
  81:   public FTPURLConnection(URL url)
  82:   {
  83:     super(url);
  84:     passive = true;
  85:     representationType = FTPConnection.TYPE_BINARY;
  86:     fileStructure = -1;
  87:     transferMode = -1;
  88:   }
  89: 
  90:   /**
  91:    * Establishes the connection.
  92:    */
  93:   public void connect()
  94:     throws IOException
  95:   {
  96:     if (connected)
  97:       {
  98:         return;
  99:       }
 100:     String host = url.getHost();
 101:     int port = url.getPort();
 102:     String username = url.getUserInfo();
 103:     String password = null;
 104:     if (username != null)
 105:       {
 106:         int ci = username.indexOf(':');
 107:         if (ci != -1)
 108:           {
 109:             password = username.substring(ci + 1);
 110:             username = username.substring(0, ci);
 111:           }
 112:       }
 113:     else
 114:       {
 115:         username = "anonymous";
 116:         GetLocalHostAction a = new GetLocalHostAction();
 117:         InetAddress localhost = AccessController.doPrivileged(a);
 118:         password = SystemProperties.getProperty("user.name") + "@" +
 119:           ((localhost == null) ? "localhost" : localhost.getHostName());
 120:       }
 121:     connection = new FTPConnection(host, port);
 122:     if (!connection.authenticate(username, password))
 123:       {
 124:         throw new SecurityException("Authentication failed");
 125:       }
 126:     connection.setPassive(passive);
 127:     if (representationType != -1)
 128:       {
 129:         connection.setRepresentationType(representationType);
 130:       }
 131:     if (fileStructure != -1)
 132:       {
 133:         connection.setFileStructure(fileStructure);
 134:       }
 135:     if (transferMode != -1)
 136:       {
 137:         connection.setTransferMode(transferMode);
 138:       }
 139:   }
 140: 
 141:   /**
 142:    * This connection supports doInput.
 143:    */
 144:   public void setDoInput(boolean doinput)
 145:   {
 146:     doInput = doinput;
 147:   }
 148: 
 149:   /**
 150:    * This connection supports doOutput.
 151:    */
 152:   public void setDoOutput(boolean dooutput)
 153:   {
 154:     doOutput = dooutput;
 155:   }
 156: 
 157:   /**
 158:    * Returns an input stream that reads from this open connection.
 159:    */
 160:   public InputStream getInputStream()
 161:     throws IOException
 162:   {
 163:     if (!connected)
 164:       {
 165:         connect();
 166:       }
 167:     String path = url.getPath();
 168:     if (connection.changeWorkingDirectory(path))
 169:       {
 170:         return this.new ClosingInputStream(connection.list(null));
 171:       }
 172:     else
 173:       {
 174:         return this.new ClosingInputStream(connection.retrieve(path));
 175:       }
 176:   }
 177: 
 178:   /**
 179:    * Returns an output stream that writes to this connection.
 180:    */
 181:   public OutputStream getOutputStream()
 182:     throws IOException
 183:   {
 184:     if (!connected)
 185:       {
 186:         connect();
 187:       }
 188:     String path = url.getPath();
 189:     return this.new ClosingOutputStream(connection.store(path));
 190:   }
 191: 
 192:   public String getRequestProperty(String key)
 193:   {
 194:     if ("passive".equals(key))
 195:       {
 196:         return Boolean.toString(passive);
 197:       }
 198:     else if ("representationType".equals(key))
 199:       {
 200:         switch (representationType)
 201:           {
 202:           case FTPConnection.TYPE_ASCII:
 203:             return "ASCII";
 204:           case FTPConnection.TYPE_EBCDIC:
 205:             return "EBCDIC";
 206:           case FTPConnection.TYPE_BINARY:
 207:             return "BINARY";
 208:           }
 209:       }
 210:     else if ("fileStructure".equals(key))
 211:       {
 212:         switch (fileStructure)
 213:           {
 214:           case FTPConnection.STRUCTURE_FILE:
 215:             return "FILE";
 216:           case FTPConnection.STRUCTURE_RECORD:
 217:             return "RECORD";
 218:           case FTPConnection.STRUCTURE_PAGE:
 219:             return "PAGE";
 220:           }
 221:       }
 222:     else if ("transferMode".equals(key))
 223:       {
 224:         switch (transferMode)
 225:           {
 226:           case FTPConnection.MODE_STREAM:
 227:             return "STREAM";
 228:           case FTPConnection.MODE_BLOCK:
 229:             return "BLOCK";
 230:           case FTPConnection.MODE_COMPRESSED:
 231:             return "COMPRESSED";
 232:           }
 233:       }
 234:     return null;
 235:   }
 236: 
 237:   public Map<String, List<String>> getRequestProperties()
 238:   {
 239:     Map<String, List<String>> map = new HashMap<String, List<String>>();
 240:     addRequestPropertyValue(map, "passive");
 241:     addRequestPropertyValue(map, "representationType");
 242:     addRequestPropertyValue(map, "fileStructure");
 243:     addRequestPropertyValue(map, "transferMode");
 244:     return map;
 245:   }
 246: 
 247:   private void addRequestPropertyValue(Map<String, List<String>> map,
 248:                                        String key)
 249:   {
 250:     String value = getRequestProperty(key);
 251:     ArrayList<String> l = new ArrayList<String>();
 252:     l.add(value);
 253:     map.put(key, l);
 254:   }
 255: 
 256:   public void setRequestProperty(String key, String value)
 257:   {
 258:     if (connected)
 259:       {
 260:         throw new IllegalStateException();
 261:       }
 262:     if ("passive".equals(key))
 263:       {
 264:         passive = Boolean.valueOf(value).booleanValue();
 265:       }
 266:     else if ("representationType".equals(key))
 267:       {
 268:         if ("A".equalsIgnoreCase(value) ||
 269:             "ASCII".equalsIgnoreCase(value))
 270:           {
 271:             representationType = FTPConnection.TYPE_ASCII;
 272:           }
 273:         else if ("E".equalsIgnoreCase(value) ||
 274:                  "EBCDIC".equalsIgnoreCase(value))
 275:           {
 276:             representationType = FTPConnection.TYPE_EBCDIC;
 277:           }
 278:         else if ("I".equalsIgnoreCase(value) ||
 279:                  "BINARY".equalsIgnoreCase(value))
 280:           {
 281:             representationType = FTPConnection.TYPE_BINARY;
 282:           }
 283:         else
 284:           {
 285:             throw new IllegalArgumentException(value);
 286:           }
 287:       }
 288:     else if ("fileStructure".equals(key))
 289:       {
 290:         if ("F".equalsIgnoreCase(value) ||
 291:             "FILE".equalsIgnoreCase(value))
 292:           {
 293:             fileStructure = FTPConnection.STRUCTURE_FILE;
 294:           }
 295:         else if ("R".equalsIgnoreCase(value) ||
 296:                  "RECORD".equalsIgnoreCase(value))
 297:           {
 298:             fileStructure = FTPConnection.STRUCTURE_RECORD;
 299:           }
 300:         else if ("P".equalsIgnoreCase(value) ||
 301:                  "PAGE".equalsIgnoreCase(value))
 302:           {
 303:             fileStructure = FTPConnection.STRUCTURE_PAGE;
 304:           }
 305:         else
 306:           {
 307:             throw new IllegalArgumentException(value);
 308:           }
 309:       }
 310:     else if ("transferMode".equals(key))
 311:       {
 312:         if ("S".equalsIgnoreCase(value) ||
 313:             "STREAM".equalsIgnoreCase(value))
 314:           {
 315:             transferMode = FTPConnection.MODE_STREAM;
 316:           }
 317:         else if ("B".equalsIgnoreCase(value) ||
 318:                  "BLOCK".equalsIgnoreCase(value))
 319:           {
 320:             transferMode = FTPConnection.MODE_BLOCK;
 321:           }
 322:         else if ("C".equalsIgnoreCase(value) ||
 323:                  "COMPRESSED".equalsIgnoreCase(value))
 324:           {
 325:             transferMode = FTPConnection.MODE_COMPRESSED;
 326:           }
 327:         else
 328:           {
 329:             throw new IllegalArgumentException(value);
 330:           }
 331:       }
 332:   }
 333: 
 334:   public void addRequestProperty(String key, String value)
 335:   {
 336:     setRequestProperty(key, value);
 337:   }
 338: 
 339:   class ClosingInputStream
 340:     extends FilterInputStream
 341:   {
 342: 
 343:     ClosingInputStream(InputStream in)
 344:     {
 345:       super(in);
 346:     }
 347: 
 348:     public void close()
 349:       throws IOException
 350:     {
 351:       super.close();
 352:       connection.logout();
 353:     }
 354: 
 355:   }
 356: 
 357:   class ClosingOutputStream
 358:     extends FilterOutputStream
 359:   {
 360: 
 361:     ClosingOutputStream(OutputStream out)
 362:     {
 363:       super(out);
 364:     }
 365: 
 366:     public void close()
 367:       throws IOException
 368:     {
 369:       super.close();
 370:       connection.logout();
 371:     }
 372: 
 373:   }
 374: 
 375: }