blob: 632e409f2d46ed2eed594c8817987c1319e9bfd6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 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
* @deprecated The org.eclipse.update component has been replaced by Equinox p2.
* This API will be deleted in a future release. See bug 311590 for details.
*/
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;
}
}