Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 214816 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/equinox/internal/p2/metadata/repository/SimpleMetadataRepositoryFactory.java (-41 / +81 lines)
Lines 12-30 Link Here
12
12
13
import java.io.*;
13
import java.io.*;
14
import java.net.URL;
14
import java.net.URL;
15
import java.util.Date;
15
import java.util.jar.JarEntry;
16
import java.util.jar.JarEntry;
16
import java.util.jar.JarInputStream;
17
import java.util.jar.JarInputStream;
17
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.*;
18
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
19
import org.eclipse.equinox.internal.p2.core.helpers.*;
19
import org.eclipse.equinox.internal.p2.core.helpers.Tracing;
20
import org.eclipse.equinox.p2.core.ProvisionException;
20
import org.eclipse.equinox.p2.core.ProvisionException;
21
import org.eclipse.equinox.p2.core.location.AgentLocation;
21
import org.eclipse.equinox.p2.metadata.repository.IMetadataRepository;
22
import org.eclipse.equinox.p2.metadata.repository.IMetadataRepository;
22
import org.eclipse.equinox.spi.p2.metadata.repository.IMetadataRepositoryFactory;
23
import org.eclipse.equinox.spi.p2.metadata.repository.IMetadataRepositoryFactory;
23
24
24
public class SimpleMetadataRepositoryFactory implements IMetadataRepositoryFactory {
25
public class SimpleMetadataRepositoryFactory implements IMetadataRepositoryFactory {
25
26
26
	private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
27
	private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
27
	private static final String XML_EXTENSION = ".xml";
28
	private static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$
29
	private static final String CONTENT_FILENAME = "content"; //$NON-NLS-1$
28
30
29
	public IMetadataRepository create(URL location, String name, String type) {
31
	public IMetadataRepository create(URL location, String name, String type) {
30
		if (location.getProtocol().equals("file")) //$NON-NLS-1$
32
		if (location.getProtocol().equals("file")) //$NON-NLS-1$
Lines 33-86 Link Here
33
	}
35
	}
34
36
35
	public IMetadataRepository load(URL location, IProgressMonitor monitor) throws ProvisionException {
37
	public IMetadataRepository load(URL location, IProgressMonitor monitor) throws ProvisionException {
36
		if (monitor == null)
37
			monitor = new NullProgressMonitor();
38
		// load the jar
39
		IMetadataRepository result = load(location, JAR_EXTENSION, monitor);
40
		// compressed file is not available, load the xml
41
		if (result == null) {
42
			result = load(location, XML_EXTENSION, monitor);
43
		}
44
		return result;
45
	}
46
47
	private IMetadataRepository load(URL location, String extension, IProgressMonitor monitor) throws ProvisionException {
48
		long time = 0;
38
		long time = 0;
39
		boolean compress = true;
49
		final String debugMsg = "Restoring metadata repository "; //$NON-NLS-1$
40
		final String debugMsg = "Restoring metadata repository "; //$NON-NLS-1$
41
		AgentLocation agentLocation = (AgentLocation) ServiceHelper.getService(Activator.getContext(), AgentLocation.class.getName());
42
		Date timestamp, cacheTimestamp;
43
		URL actualFile, dataArea;
50
		if (Tracing.DEBUG_METADATA_PARSING) {
44
		if (Tracing.DEBUG_METADATA_PARSING) {
51
			Tracing.debug(debugMsg + location);
45
			Tracing.debug(debugMsg + location);
52
			time = -System.currentTimeMillis();
46
			time = -System.currentTimeMillis();
53
		}
47
		}
54
		try {
48
		try {
55
			URL actualFile = URLMetadataRepository.getActualLocation(location);
49
			IStatus status;
56
			InputStream inStream = URLMetadataRepository.getActualLocation(location, extension).openStream();
50
			OutputStream metadata;
57
			if (JAR_EXTENSION.equalsIgnoreCase(extension)) {
51
			SubMonitor sub = SubMonitor.convert(monitor, 300);
58
				JarInputStream jInStream = new JarInputStream(inStream);
52
			String fileLocation = URLMetadataRepository.getActualLocation(location, JAR_EXTENSION).toExternalForm();
59
				JarEntry jarEntry = jInStream.getNextJarEntry();
53
			int hashCode = location.hashCode();
60
				String entryName = new Path(actualFile.getPath()).lastSegment();
54
			timestamp = getTransport().getLastModified(fileLocation);
61
				while (jarEntry != null && (!entryName.equals(jarEntry.getName()))) {
55
			cacheTimestamp = null;
62
					jarEntry = jInStream.getNextJarEntry();
56
			actualFile = URLMetadataRepository.getActualLocation(location);
63
				}
57
			dataArea = agentLocation.getDataArea(Activator.ID + "/cache/"); //$NON-NLS-1$
64
				if (jarEntry == null) {
58
			String cachePath = dataArea.getPath();
65
					throw new FileNotFoundException("Repository not found in " + actualFile.getPath() + extension); //$NON-NLS-1$
59
			File cacheFile = null;
60
			if (timestamp != null) {
61
				cacheFile = new File(cachePath + CONTENT_FILENAME + hashCode + JAR_EXTENSION);
62
				cacheTimestamp = new Date(cacheFile.lastModified());
63
			} else {
64
				fileLocation = URLMetadataRepository.getActualLocation(location, XML_EXTENSION).toExternalForm();
65
				timestamp = getTransport().getLastModified(fileLocation);
66
				if (timestamp != null) {
67
					compress = false;
68
					cacheFile = new File(cachePath, CONTENT_FILENAME + hashCode + XML_EXTENSION);
69
					cacheTimestamp = new Date(cacheFile.lastModified());
70
				} else
71
					return null;
72
			}
73
			if (timestamp.after(cacheTimestamp)) {
74
				// retrieve the newer index file
75
				File parentFile = cacheFile.getParentFile();
76
				if (!parentFile.exists()) {
77
					parentFile.mkdirs();
66
				}
78
				}
67
				inStream = jInStream;
79
				cacheFile.createNewFile();
80
				metadata = new BufferedOutputStream(new FileOutputStream(cacheFile));
81
				status = getTransport().download(fileLocation, metadata, sub);
82
			} else {
83
				// use the cached file
84
				status = Status.OK_STATUS;
85
				metadata = null;
68
			}
86
			}
69
			InputStream descriptorStream = new BufferedInputStream(inStream);
87
			if (status.isOK()) {
70
			try {
88
				if (metadata != null) {
71
				IMetadataRepository result = new MetadataRepositoryIO().read(actualFile, descriptorStream, monitor);
89
					metadata.close();
72
				if (result instanceof LocalMetadataRepository)
90
				}
73
					((LocalMetadataRepository) result).initializeAfterLoad(location);
91
				InputStream inStream = new BufferedInputStream(new FileInputStream(cacheFile));
74
				if (result instanceof URLMetadataRepository)
92
				if (compress) {
75
					((URLMetadataRepository) result).initializeAfterLoad(location);
93
					JarInputStream jInStream = new JarInputStream(inStream);
76
				if (Tracing.DEBUG_METADATA_PARSING) {
94
					JarEntry jarEntry = jInStream.getNextJarEntry();
77
					time += System.currentTimeMillis();
95
					String entryName = new Path(actualFile.getPath()).lastSegment();
78
					Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ 
96
					while (jarEntry != null && (!entryName.equals(jarEntry.getName()))) {
97
						jarEntry = jInStream.getNextJarEntry();
98
					}
99
					if (jarEntry == null) {
100
						throw new FileNotFoundException("Repository not found in compressed file."); //$NON-NLS-1$
101
					}
102
					inStream = jInStream;
103
				}
104
				InputStream descriptorStream = new BufferedInputStream(inStream);
105
				try {
106
					IMetadataRepository result = new MetadataRepositoryIO().read(cacheFile.toURL(), descriptorStream, sub.newChild(100));
107
					if (result instanceof LocalMetadataRepository)
108
						((LocalMetadataRepository) result).initializeAfterLoad(location);
109
					if (result instanceof URLMetadataRepository)
110
						((URLMetadataRepository) result).initializeAfterLoad(location);
111
					if (Tracing.DEBUG_METADATA_PARSING) {
112
						time += System.currentTimeMillis();
113
						Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ 
114
					}
115
					return result;
116
				} finally {
117
					if (descriptorStream != null)
118
						descriptorStream.close();
79
				}
119
				}
80
				return result;
81
			} finally {
82
				if (descriptorStream != null)
83
					descriptorStream.close();
84
			}
120
			}
85
		} catch (FileNotFoundException e) {
121
		} catch (FileNotFoundException e) {
86
			//if the repository doesn't exist, then it's fine to return null
122
			//if the repository doesn't exist, then it's fine to return null
Lines 90-95 Link Here
90
		return null;
126
		return null;
91
	}
127
	}
92
128
129
	private ECFMetadataTransport getTransport() {
130
		return ECFMetadataTransport.getInstance();
131
	}
132
93
	private void log(String message, Exception e) {
133
	private void log(String message, Exception e) {
94
		LogHelper.log(new Status(IStatus.ERROR, Activator.PI_METADATA_REPOSITORY, message, e));
134
		LogHelper.log(new Status(IStatus.ERROR, Activator.PI_METADATA_REPOSITORY, message, e));
95
	}
135
	}
(-)META-INF/MANIFEST.MF (-1 / +4 lines)
Lines 32-36 Link Here
32
Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1,
32
Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1,
33
 J2SE-1.4
33
 J2SE-1.4
34
Require-Bundle: org.eclipse.equinox.common,
34
Require-Bundle: org.eclipse.equinox.common,
35
 org.eclipse.equinox.registry
35
 org.eclipse.equinox.registry,
36
 org.eclipse.osgi;bundle-version="3.4.0",
37
 org.eclipse.ecf;bundle-version="1.2.0",
38
 org.eclipse.ecf.filetransfer;bundle-version="2.0.0"
36
Eclipse-BuddyPolicy: registered
39
Eclipse-BuddyPolicy: registered
(-)src/org/eclipse/equinox/internal/p2/metadata/repository/ECFMetadataTransport.java (+180 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.equinox.internal.p2.metadata.repository;
12
13
import java.io.IOException;
14
import java.io.OutputStream;
15
import java.util.Date;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.ecf.core.*;
18
import org.eclipse.ecf.filetransfer.*;
19
import org.eclipse.ecf.filetransfer.events.*;
20
import org.eclipse.ecf.filetransfer.identity.FileCreateException;
21
import org.eclipse.ecf.filetransfer.identity.FileIDFactory;
22
import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory;
23
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
24
import org.osgi.util.tracker.ServiceTracker;
25
26
public class ECFMetadataTransport {
27
28
	/**
29
	 * The singleton transport instance.
30
	 */
31
	private static ECFMetadataTransport instance;
32
33
	private final ServiceTracker retrievalFactoryTracker;
34
35
	public static synchronized ECFMetadataTransport getInstance() {
36
		if (instance == null) {
37
			instance = new ECFMetadataTransport();
38
		}
39
		return instance;
40
	}
41
42
	private ECFMetadataTransport() {
43
		retrievalFactoryTracker = new ServiceTracker(Activator.getContext(), IRetrieveFileTransferFactory.class.getName(), null);
44
		retrievalFactoryTracker.open();
45
	}
46
47
	public IStatus download(String toDownload, OutputStream target, IProgressMonitor monitor) {
48
		IRetrieveFileTransferFactory factory = (IRetrieveFileTransferFactory) retrievalFactoryTracker.getService();
49
		if (factory == null)
50
			return null;
51
52
		return transfer(factory.newInstance(), toDownload, target, monitor);
53
	}
54
55
	/**
56
	 * Gets the last modified date for the specified file.
57
	 * @param location - The URL location of the file.
58
	 * @return The <code>Date</code> of the file's last modified date, <code>null</code> if operation was not successful.
59
	 */
60
	public Date getLastModified(String location) {
61
		IContainer container;
62
		try {
63
			container = ContainerFactory.getDefault().createContainer();
64
		} catch (ContainerCreateException e) {
65
			return null;
66
		}
67
		IRemoteFileSystemBrowserContainerAdapter adapter = (IRemoteFileSystemBrowserContainerAdapter) container.getAdapter(IRemoteFileSystemBrowserContainerAdapter.class);
68
		if (adapter == null) {
69
			return null;
70
		}
71
		IRemoteFile remoteFile = checkFile(adapter, location);
72
		if (remoteFile == null) {
73
			return null;
74
		}
75
		return new Date(remoteFile.getInfo().getLastModified());
76
	}
77
78
	private IRemoteFile checkFile(final IRemoteFileSystemBrowserContainerAdapter retrievalContainer, final String location) {
79
		final Object[] result = new Object[1];
80
		IRemoteFileSystemListener listener = new IRemoteFileSystemListener() {
81
			public void handleRemoteFileEvent(IRemoteFileSystemEvent event) {
82
				if (event instanceof IRemoteFileSystemBrowseEvent) {
83
					IRemoteFileSystemBrowseEvent fsbe = (IRemoteFileSystemBrowseEvent) event;
84
					IRemoteFile[] remoteFiles = fsbe.getRemoteFiles();
85
					if (remoteFiles != null && remoteFiles.length > 0) {
86
						synchronized (result) {
87
							result[0] = remoteFiles[0];
88
							result.notify();
89
						}
90
					}
91
				}
92
			}
93
		};
94
		try {
95
			retrievalContainer.sendBrowseRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getBrowseNamespace(), location), listener);
96
		} catch (RemoteFileSystemException e) {
97
			return null;
98
		} catch (FileCreateException e) {
99
			return null;
100
		}
101
		synchronized (result) {
102
			while (result[0] == null) {
103
				boolean logged = false;
104
				try {
105
					result.wait();
106
				} catch (InterruptedException e) {
107
					if (!logged)
108
						LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF browse", e)); //$NON-NLS-1$
109
				}
110
			}
111
		}
112
		return (IRemoteFile) result[0];
113
	}
114
115
	private IStatus transfer(final IRetrieveFileTransferContainerAdapter retrievalContainer, final String toDownload, final OutputStream target, final IProgressMonitor monitor) {
116
		final IStatus[] result = new IStatus[1];
117
		IFileTransferListener listener = new IFileTransferListener() {
118
119
			public void handleTransferEvent(IFileTransferEvent event) {
120
				if (event instanceof IIncomingFileTransferReceiveStartEvent) {
121
					IIncomingFileTransferReceiveStartEvent rse = (IIncomingFileTransferReceiveStartEvent) event;
122
					if (target != null) {
123
						try {
124
							rse.receive(target);
125
						} catch (IOException e) {
126
							IStatus status = convertToStatus(e);
127
							synchronized (result) {
128
								result[0] = status;
129
								result.notify();
130
							}
131
						}
132
					}
133
				}
134
				if (event instanceof IIncomingFileTransferReceiveDataEvent) {
135
					IIncomingFileTransfer source = ((IIncomingFileTransferReceiveDataEvent) event).getSource();
136
					if (monitor != null) {
137
						if (monitor.isCanceled())
138
							source.cancel();
139
					}
140
				}
141
				if (event instanceof IIncomingFileTransferReceiveDoneEvent) {
142
					IStatus status = convertToStatus(((IIncomingFileTransferReceiveDoneEvent) event).getException());
143
					synchronized (result) {
144
						result[0] = status;
145
						result.notify();
146
					}
147
				}
148
			}
149
		};
150
151
		try {
152
			retrievalContainer.sendRetrieveRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getRetrieveNamespace(), toDownload), listener, null);
153
		} catch (IncomingFileTransferException e) {
154
			return new Status(IStatus.ERROR, Activator.ID, "error during transfer", e);
155
		} catch (FileCreateException e) {
156
			return new Status(IStatus.ERROR, Activator.ID, "error during transfer - could not create file", e);
157
		}
158
		synchronized (result) {
159
			while (result[0] == null) {
160
				boolean logged = false;
161
				try {
162
					result.wait();
163
				} catch (InterruptedException e) {
164
					if (!logged)
165
						LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF transfer", e)); //$NON-NLS-1$
166
				}
167
			}
168
		}
169
170
		return result[0];
171
	}
172
173
	protected IStatus convertToStatus(Exception e) {
174
		if (e == null)
175
			return Status.OK_STATUS;
176
		if (e instanceof UserCancelledException)
177
			return new Status(IStatus.CANCEL, Activator.ID, e.getMessage(), e);
178
		return new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e);
179
	}
180
}

Return to bug 214816