All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.util.io.HTTPRemoteFile Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.util.io;

import java.io.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.hfg.util.StringUtil;


//------------------------------------------------------------------------------
/**
 * Implementation of RemoteFile for HTTP files
 *
 * @author J. Alex Taylor, hairyfatguy.com
 */
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------


public class HTTPRemoteFile extends AbstractRemoteFile
{

   //###########################################################################
   // PRIVATE FIELDS
   //###########################################################################

   private String mURL;
   private Long   mSize;
   private Calendar mTimestamp;
   private int    mNumRedirects;
   private String mUserAgentString = sDefaultUserAgentString;
   private String mRequestedPath;

   private static String sDefaultUserAgentString;

   private static final int MAX_REDIRECTS = 10;

   // Some places don't like to talk to or don't recognize Java. Pretend we're IE
   private static final String USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";

   private final static Logger LOGGER = Logger.getLogger(HTTPRemoteFile.class.getName());

   //###########################################################################
   // CONSTRUCTORS
   //###########################################################################


   //---------------------------------------------------------------------------
   public HTTPRemoteFile(String inURL)
   {
      mURL = inURL;
   }



   //###########################################################################
   // PUBLIC METHODS
   //###########################################################################

   //---------------------------------------------------------------------------
   public static void setDefaultUserAgentString(String inValue)
   {
      sDefaultUserAgentString = inValue;
   }

   //---------------------------------------------------------------------------
   public static String getDefaultUserAgentString()
   {
      return sDefaultUserAgentString;
   }


   //---------------------------------------------------------------------------
   public HTTPRemoteFile setUserAgentString(String inValue)
   {
      mUserAgentString = inValue;
      return this;
   }

   //---------------------------------------------------------------------------
   public String geUserAgentString()
   {
      return mUserAgentString;
   }

   //---------------------------------------------------------------------------
   public static Logger getLogger()
   {
      return LOGGER;
   }

   //---------------------------------------------------------------------------
   @Override
   public String getURL()
   {
      return mURL;
   }

   //---------------------------------------------------------------------------
   @Override
   public String getName()
   {
      String name;

      int index = mURL.lastIndexOf('/');
      if (index > 0)
      {
         name = mURL.substring(index + 1);
      }
      else
      {
         name = mURL;
      }

      // Don't include arguments in the name
      index = name.indexOf('?');
      if (index > 0)
      {
         name = name.substring(0, index);
      }

      return name;
   }

   //---------------------------------------------------------------------------
   @Override
   public String getPath()
   {
      String path;

      // Remove http://
      int index = mURL.indexOf("//");
      if (index > 0)
      {
         path = mURL.substring(index + 2);
      }
      else
      {
         path = mURL;
      }

      // Remove the server or server:port
      index = path.indexOf("/");
      if (index > 0)
      {
         path = path.substring(index + 1);
      }

      // Don't include arguments in the path
      index = path.indexOf('?');
      if (index > 0)
      {
         path = path.substring(0, index);
      }



      return path;
   }

   //---------------------------------------------------------------------------
   public HTTPRemoteFile setRequestedPath(String inValue)
   {
      mRequestedPath = inValue;
      return this;
   }

   //---------------------------------------------------------------------------
   @Override
   public String getRequestedPath()
   {
      return mRequestedPath != null ? mRequestedPath : getPath();
   }

   //---------------------------------------------------------------------------
   @Override
   public long getSize()
   {
      if (null == mSize)
      {
         getFileInfo();
      }

      return mSize != null ? mSize.longValue() : -1;
   }

   //---------------------------------------------------------------------------
   @Override
   public Calendar getTimestamp()
   {
      if (null == mTimestamp)
      {
         getFileInfo();
      }

      return mTimestamp;
   }

   //---------------------------------------------------------------------------
   @Override
   public InputStream getInputStream()
   throws IOException
   {
      HttpURLConnection conn = (HttpURLConnection) new URL(mURL).openConnection();
      conn.setRequestProperty("User-Agent", USER_AGENT);
      conn.connect();

      return new BufferedInputStream(conn.getInputStream());
   }


   //---------------------------------------------------------------------------
   @Override
   public boolean writeToLocalDir(File inLocalDir)
         throws IOException
   {
      boolean result = super.writeToLocalDir(inLocalDir);
      if (null ==  mSize
          || mSize < 0)
      {
         mSize = new File(inLocalDir, getName()).length();
      }

      return result;
   }

   //---------------------------------------------------------------------------
   @Override
   public boolean copyLocallyPreservingPath(File inLocalDir)
   throws IOException
   {
      boolean result = super.copyLocallyPreservingPath(inLocalDir);
      if (null ==  mSize
          || mSize < 0)
      {
         mSize = new File(inLocalDir, getPath()).length();
      }

      return result;
   }

   //---------------------------------------------------------------------------
   @Override
   public long writeToStream(OutputStream stream)
   throws IOException
   {
      long fileSize = super.writeToStream(stream);
      if (null ==  mSize
          || mSize < 0)
      {
         mSize = fileSize;
      }

      return fileSize;
   }

   //---------------------------------------------------------------------------
   @Override
   public boolean writeToLocalFile(File inLocalFile)
         throws IOException
   {
      boolean result = super.writeToLocalFile(inLocalFile);
      if (null ==  mSize
          || mSize < 0)
      {
         mSize = inLocalFile.length();
      }

      return result;
   }

   //###########################################################################
   // PRIVATE METHODS
   //###########################################################################

   //---------------------------------------------------------------------------
   private void getFileInfo()
   {
      HttpURLConnection conn = null;
      try
      {
         conn = (HttpURLConnection) new URL(mURL).openConnection();
         conn.setRequestMethod("HEAD");
         conn.setUseCaches(false);
         conn.setInstanceFollowRedirects(false);
         if (StringUtil.isSet(geUserAgentString()))
         {
            conn.setRequestProperty("User-Agent", geUserAgentString());
         }
         conn.connect();

         if (getLogger().isLoggable(Level.FINE))
         {
            LOGGER.log(Level.FINE, "RESPONSE CODE: " + conn.getResponseCode());
            LOGGER.log(Level.FINE, "RESPONSE MSG: " + conn.getResponseMessage());
            LOGGER.log(Level.FINE, "CONTENT LENGTH: " + conn.getContentLength());
            LOGGER.log(Level.FINE, "LAST MODIFIED: " + conn.getLastModified());
         }

         final int responseCode = conn.getResponseCode();
         if (   responseCode == HttpURLConnection.HTTP_MOVED_PERM
             || responseCode == HttpURLConnection.HTTP_MOVED_TEMP
             || responseCode == HttpURLConnection.HTTP_SEE_OTHER)
         {
            final String newLocation = conn.getHeaderField("Location");

            final String msg = getURL() + (responseCode == HttpURLConnection.HTTP_MOVED_PERM ? " permanently" : "") + " moved to " + newLocation;
            LOGGER.log(Level.INFO, msg);

            mNumRedirects++;
            if (mNumRedirects > MAX_REDIRECTS)
            {
               throw new IOException("More than " + MAX_REDIRECTS + " redirects!");
            }

            final URL newURL = new URL(new URL(getURL()), newLocation);

            conn.disconnect();

            mURL = newURL.toString();

            getFileInfo(); // Recurse
         }
         else if (responseCode == HttpURLConnection.HTTP_OK)
         {
            mSize = new Long(conn.getContentLength());

            long lastModifiedMilliseconds = conn.getLastModified();
            if (lastModifiedMilliseconds > 0)
            {
               mTimestamp = new GregorianCalendar();
               mTimestamp.setTime(new Date(conn.getLastModified()));
            }
         }
      }
      catch (IOException e)
      {
         throw new RuntimeException(e.toString());
      }
      finally
      {
         if (conn != null) conn.disconnect();
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy