| /******************************************************************************* |
| * Copyright (c) 2000, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.update.core; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.update.internal.core.FatalIOException; |
| import org.eclipse.update.internal.core.Messages; |
| import org.eclipse.update.internal.core.URLEncoder; |
| import org.eclipse.update.internal.core.UpdateManagerUtils; |
| import org.eclipse.update.internal.core.connection.ConnectionFactory; |
| import org.eclipse.update.internal.core.connection.HttpResponse; |
| import org.eclipse.update.internal.core.connection.IResponse; |
| |
| /** |
| * Content reference implements a general access wrapper |
| * to feature and site content. The reference specifies |
| * a "symbolic" path identifier for the content, and the actual |
| * reference as a file, or a URL. |
| * <p> |
| * This class may be instantiated or subclassed by clients. |
| * </p> |
| * <p> |
| * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to |
| * change significantly before reaching stability. It is being made available at this early stage to solicit feedback |
| * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken |
| * (repeatedly) as the API evolves. |
| * </p> |
| * @see org.eclipse.update.core.JarContentReference |
| * @see org.eclipse.update.core.JarEntryContentReference |
| * @since 2.0 |
| */ |
| public class ContentReference { |
| |
| /** |
| * Unknown size indication |
| * @since 2.0 |
| */ |
| public static final long UNKNOWN_SIZE = -1; |
| |
| /** |
| * Default executable permission when installing a content reference |
| * Will add executable bit if necessary |
| * |
| * @since 2.0.1 |
| */ |
| public static final int DEFAULT_EXECUTABLE_PERMISSION = -1; |
| |
| private static final String FILE_URL_PROTOCOL = "file"; //$NON-NLS-1$ |
| |
| private String id; |
| private URL url; // reference is either URL reference *OR* |
| private File file; // local file reference |
| private IResponse response; |
| private int permission; |
| private long length; |
| |
| // <true> if a copy of a Contentreferenec in a temp local directory |
| private boolean tempLocal = false; |
| |
| private long lastModified; |
| |
| /** |
| * Create content reference from URL. |
| * |
| * @param id "symbolic" path identifier |
| * @param url actual referenced URL |
| * @since 2.0 |
| */ |
| public ContentReference(String id, URL url) { |
| this.id = (id == null ? "" : id); //$NON-NLS-1$ |
| this.url = url; // can be null |
| this.file = null; |
| } |
| |
| /** |
| * Create content reference from file. |
| * |
| * @param id "symbolic" path identifier |
| * @param file actual referenced file |
| * @since 2.0 |
| */ |
| public ContentReference(String id, File file) { |
| this.id = (id == null ? "" : id); //$NON-NLS-1$ |
| this.file = file; // can be null |
| this.url = null; |
| } |
| |
| /** |
| * A factory method to create a content reference of |
| * the same type. |
| * |
| * @param id "symbolic" path identifier |
| * @param file actual referenced file |
| * @return content reference of the same type |
| * @since 2.0 |
| */ |
| public ContentReference createContentReference(String id, File file) { |
| return new ContentReference(id, file,true); |
| } |
| /** |
| * |
| */ |
| private ContentReference(String id, File file, boolean b) { |
| this(id,file); |
| setTempLocal(b); |
| } |
| |
| /** |
| * Retrieves the "symbolic" path identifier for the reference. |
| * |
| * @return "symbolic" path identifier |
| * @since 2.0 |
| */ |
| public String getIdentifier() { |
| return id; |
| } |
| |
| /** |
| * Creates an input stream for the reference. |
| * |
| * @return input stream |
| * @exception IOException unable to create stream |
| * @since 2.0 |
| */ |
| public InputStream getInputStream() throws IOException { |
| if (file != null) |
| return new FileInputStream(file); |
| else if (url != null) { |
| if (response == null) { |
| URL resolvedURL = URLEncoder.encode(url); |
| response = ConnectionFactory.get(resolvedURL); |
| UpdateManagerUtils.checkConnectionResult(response,resolvedURL); |
| } |
| InputStream is=response.getInputStream(); |
| length=response.getContentLength(); |
| return is; |
| } else |
| throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToCreateInputStream, (new String[] { this.toString() }))); |
| } |
| /** |
| * Creates an input stream for the reference. |
| * |
| * @return input stream |
| * @exception IOException unable to create stream |
| * @since 2.0 |
| */ |
| InputStream getPartialInputStream(long offset) throws IOException { |
| if (url != null && "http".equals(url.getProtocol())) { //$NON-NLS-1$ |
| URL resolvedURL = URLEncoder.encode(url); |
| response = ConnectionFactory.get(resolvedURL); |
| if(response instanceof HttpResponse) |
| ((HttpResponse)response).setOffset(offset); |
| UpdateManagerUtils.checkConnectionResult(response,resolvedURL); |
| InputStream is = response.getInputStream(); |
| length=offset + response.getContentLength(); |
| return is; |
| } else |
| throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToCreateInputStream, (new String[] { this.toString() }))); |
| } |
| |
| /** |
| * Returns the size of the referenced input, if it can be determined. |
| * |
| * @return input size, or @see #UNKNOWN_SIZE if size cannot be determined. |
| * @since 2.0 |
| */ |
| public long getInputSize() throws IOException { |
| if (length>0) |
| return length; |
| if (file != null) |
| return file.length(); |
| else if (url != null) { |
| if (response == null) { |
| URL resolvedURL = null; |
| try { |
| resolvedURL = URLEncoder.encode(url); |
| response = ConnectionFactory.get(resolvedURL); |
| } catch (IOException e) { |
| return ContentReference.UNKNOWN_SIZE; |
| } |
| UpdateManagerUtils.checkConnectionResult(response,resolvedURL); |
| } |
| long size = response.getContentLength(); |
| return size == -1 ? ContentReference.UNKNOWN_SIZE : size; |
| } else |
| return ContentReference.UNKNOWN_SIZE; |
| } |
| |
| /** |
| * Indicates whether the reference is a local file reference. |
| * |
| * @return <code>true</code> if the reference is local, |
| * otherwise <code>false</code> |
| * @since 2.0 |
| */ |
| public boolean isLocalReference() { |
| /*if (file != null) |
| return true; |
| else if (url != null) |
| return FILE_URL_PROTOCOL.equals(url.getProtocol()); |
| else |
| return false;*/ |
| // only temp files are considered local |
| return tempLocal; |
| } |
| |
| /** |
| * Returns the content reference as a file. Note, that this method |
| * <b>does not</b> cause the file to be downloaded if it |
| * is not already local. |
| * |
| * @return reference as file |
| * @exception IOException reference cannot be returned as file |
| * @since 2.0 |
| */ |
| public File asFile() throws IOException { |
| if (file != null) |
| return file; |
| |
| if (url != null && FILE_URL_PROTOCOL.equals(url.getProtocol())) { |
| File result = new File(url.getFile()); |
| if (result.exists()) |
| return result; |
| else |
| throw new IOException(NLS.bind(Messages.ContentReference_FileDoesNotExist, (new String[] { this.toString() }))); |
| } |
| |
| throw new IOException(NLS.bind(Messages.ContentReference_UnableToReturnReferenceAsFile, (new String[] { this.toString() }))); |
| } |
| |
| /** |
| * Returns the content reference as a URL. |
| * |
| * @return reference as URL |
| * @exception IOException reference cannot be returned as URL |
| * @since 2.0 |
| */ |
| public URL asURL() throws IOException { |
| if (url != null) |
| return url; |
| |
| if (file != null) |
| return file.toURL(); |
| |
| throw new FatalIOException(NLS.bind(Messages.ContentReference_UnableToReturnReferenceAsURL, (new String[] { this.toString() }))); |
| } |
| |
| /** |
| * Return string representation of this reference. |
| * |
| * @return string representation |
| * @since 2.0 |
| */ |
| public String toString() { |
| if (file != null) |
| return file.getAbsolutePath(); |
| else |
| return url.toExternalForm(); |
| } |
| /** |
| * Returns the permission for this file. |
| * |
| * @return the content reference permission |
| * @see #DEFAULT_EXECUTABLE_PERMISSION |
| * @since 2.0.1 |
| */ |
| public int getPermission() { |
| return permission; |
| } |
| |
| /** |
| * Sets the permission of this content reference. |
| * |
| * @param permission The permission to set |
| */ |
| public void setPermission(int permission) { |
| this.permission = permission; |
| } |
| |
| /** |
| * Sets if a content reference is considered local |
| * |
| * @param tempLocal <code>true</code> if the file is considered local |
| */ |
| protected void setTempLocal(boolean tempLocal) { |
| this.tempLocal = tempLocal; |
| } |
| |
| /** |
| * Sets the timestamp the content was last modified. |
| * @param timestamp |
| * @since 3.0 |
| */ |
| public void setLastModified(long timestamp) { |
| this.lastModified = timestamp; |
| } |
| |
| /** |
| * Returns the timestamp when the content was last modified |
| * @return the timestamp |
| * @since 3.0 |
| */ |
| public long getLastModified() { |
| if (lastModified == 0) { |
| if (file != null) |
| lastModified = file.lastModified(); |
| else if (url != null) { |
| if (response == null) { |
| try { |
| URL resolvedURL = URLEncoder.encode(url); |
| response = ConnectionFactory.get(resolvedURL); |
| } catch (MalformedURLException e) { |
| // return 0 |
| } catch (IOException e) { |
| // return 0 |
| } |
| } |
| lastModified = response.getLastModified(); |
| } |
| } |
| return lastModified; |
| } |
| } |