Package org.apache.wicket.util.resource

Source Code of org.apache.wicket.util.resource.UrlResourceStream

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wicket.util.resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;

import org.apache.wicket.Application;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* UrlResourceStream implements IResource for URLs.
*
* @see org.apache.wicket.util.resource.IResourceStream
* @see org.apache.wicket.util.watch.IModifiable
* @author Jonathan Locke
*/
public class UrlResourceStream extends AbstractResourceStream
  implements
    IFixedLocationResourceStream
{
  private static final long serialVersionUID = 1L;

  /** Logging. */
  private static final Logger log = LoggerFactory.getLogger(UrlResourceStream.class);

  /** Resource stream. */
  private transient InputStream inputStream;

  /** The URL to this resource. */
  private final URL url;

  /** the handle to the file if it is a file resource */
  private File file;

  /** Length of stream. */
  private int contentLength;

  /** Content type for stream. */
  private String contentType;

  /** Last known time the stream was last modified. */
  private long lastModified;

  /**
   * Construct.
   *
   * @param url
   *            URL of resource
   */
  public UrlResourceStream(final URL url)
  {
    // Save URL
    this.url = url;
    URLConnection connection = null;
    try
    {
      connection = url.openConnection();
      contentLength = connection.getContentLength();
      contentType = connection.getContentType();
      lastModified = connection.getLastModified();
      try
      {
        file = new File(new URI(url.toExternalForm()));
      }
      catch (Exception ex)
      {
        log.debug("cannot convert url: " + url + " to file (" + ex.getMessage() +
          "), falling back to the inputstream for polling");
      }
      if (file != null && !file.exists())
      {
        file = null;
      }
    }
    catch (IOException ex)
    {
      // It should be impossible to get here or the original URL
      // couldn't have been constructed. But we re-throw with details
      // anyway.
      final IllegalArgumentException illegalArgumentException = new IllegalArgumentException(
        "Invalid URL parameter " + url);
      illegalArgumentException.initCause(ex);
      throw illegalArgumentException;
    }
    finally
    {
      // if applicable, disconnect
      if (connection != null)
      {
        if (connection instanceof HttpURLConnection)
        {
          ((HttpURLConnection)connection).disconnect();
        }
        else
        {
          try
          {
            connection.getInputStream().close();
          }
          catch (Exception ex)
          {
            // ignore
          }
        }
      }
    }
  }

  /**
   * Closes this resource.
   *
   * @throws IOException
   */
  public void close() throws IOException
  {
    if (inputStream != null)
    {
      inputStream.close();
      inputStream = null;
    }
  }

  /**
   * @return The content type of this resource, such as "image/jpeg" or "text/html"
   */
  @Override
  public String getContentType()
  {
    testContentType();
    return contentType;
  }

  /**
   * Method to test the content type on null or unknown. if this is the case the content type is
   * tried to be resolved throw the servlet context
   */
  private void testContentType()
  {
    if (contentType == null || contentType.indexOf("unknown") != -1)
    {
      Application application = Application.get();
      if (application instanceof WebApplication)
      {
        // TODO Post 1.2: General: For non webapplication another method
        // should be implemented (getMimeType on application?)
        contentType = ((WebApplication)application).getServletContext().getMimeType(
          url.getFile());
        if (contentType == null)
        {
          contentType = URLConnection.getFileNameMap().getContentTypeFor(url.getFile());
        }
      }
      else
      {
        contentType = URLConnection.getFileNameMap().getContentTypeFor(url.getFile());
      }
    }
  }

  /**
   * @return A readable input stream for this resource.
   * @throws ResourceStreamNotFoundException
   */
  public InputStream getInputStream() throws ResourceStreamNotFoundException
  {
    if (inputStream == null)
    {
      try
      {
        inputStream = url.openStream();
      }
      catch (IOException e)
      {
        throw new ResourceStreamNotFoundException("Resource " + url +
          " could not be opened", e);
      }
    }

    return inputStream;
  }

  /**
   * @return The URL to this resource (if any)
   */
  public URL getURL()
  {
    return url;
  }

  /**
   * @see org.apache.wicket.util.watch.IModifiable#lastModifiedTime()
   * @return The last time this resource was modified
   */
  @Override
  public Time lastModifiedTime()
  {
    if (file != null)
    {
      // In case the file has been removed by now
      if (file.exists() == false)
      {
        return null;
      }

      long lastModified = file.lastModified();
      if (lastModified != this.lastModified)
      {
        this.lastModified = lastModified;
        contentLength = (int)file.length();
      }
    }
    else
    {
      URLConnection urlConnection = null;
      boolean close = false;
      try
      {
        urlConnection = url.openConnection();
        long lastModified = this.lastModified;
        if (urlConnection instanceof JarURLConnection)
        {
          JarURLConnection jarUrlConnection = (JarURLConnection)urlConnection;
          URL jarFileUrl = jarUrlConnection.getJarFileURL();
          URLConnection jarFileConnection = jarFileUrl.openConnection();
          try
          {
            lastModified = jarFileConnection.getLastModified();
          }
          finally
          {
            jarFileConnection.getInputStream().close();
          }
        }
        else
        {
          close = true;
          lastModified = urlConnection.getLastModified();
        }

        // update the last modified time.
        if (lastModified != this.lastModified)
        {
          this.lastModified = lastModified;
          close = true;
          contentLength = urlConnection.getContentLength();
        }
      }
      catch (IOException e)
      {
        if (url.toString().indexOf(".jar!") >= 0)
        {
          if (log.isDebugEnabled())
          {
            log.debug("getLastModified for " + url + " failed: " + e.getMessage());
          }
        }
        else
        {
          log.warn("getLastModified for " + url + " failed: " + e.getMessage());
        }

        // Allow modification watcher to detect the problem
        return null;
      }
      finally
      {
        // if applicable, disconnect
        if (urlConnection != null)
        {
          if (urlConnection instanceof HttpURLConnection)
          {
            ((HttpURLConnection)urlConnection).disconnect();
          }
          else if (close)
          {
            try
            {
              urlConnection.getInputStream().close();
            }
            catch (Exception ex)
            {
              // ignore
            }
          }
        }
      }
    }
    return Time.milliseconds(lastModified);
  }

  /**
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString()
  {
    return url.toString();
  }

  /**
   * @see org.apache.wicket.util.resource.IResourceStream#length()
   */
  @Override
  public long length()
  {
    return contentLength;
  }

  /**
   * @see org.apache.wicket.util.resource.IFixedLocationResourceStream#locationAsString()
   */
  public String locationAsString()
  {
    return url.toExternalForm();
  }
}
TOP

Related Classes of org.apache.wicket.util.resource.UrlResourceStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.