Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 87517 Details for
Bug 214816
[prov] Local caching of remote metadata repositories
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Metadata Caching WIP
patch-metadataCaching_v01.txt (text/plain), 15.69 KB, created by
Tim Mok
on 2008-01-22 10:19:34 EST
(
hide
)
Description:
Metadata Caching WIP
Filename:
MIME Type:
Creator:
Tim Mok
Created:
2008-01-22 10:19:34 EST
Size:
15.69 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.equinox.p2.metadata.repository >Index: src/org/eclipse/equinox/internal/p2/metadata/repository/SimpleMetadataRepositoryFactory.java >=================================================================== >RCS file: /cvsroot/eclipse/equinox-incubator/provisioning/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/SimpleMetadataRepositoryFactory.java,v >retrieving revision 1.16 >diff -u -r1.16 SimpleMetadataRepositoryFactory.java >--- src/org/eclipse/equinox/internal/p2/metadata/repository/SimpleMetadataRepositoryFactory.java 11 Jan 2008 21:10:16 -0000 1.16 >+++ src/org/eclipse/equinox/internal/p2/metadata/repository/SimpleMetadataRepositoryFactory.java 22 Jan 2008 13:53:58 -0000 >@@ -12,19 +12,21 @@ > > import java.io.*; > import java.net.URL; >+import java.util.Date; > import java.util.jar.JarEntry; > import java.util.jar.JarInputStream; > import org.eclipse.core.runtime.*; >-import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; >-import org.eclipse.equinox.internal.p2.core.helpers.Tracing; >+import org.eclipse.equinox.internal.p2.core.helpers.*; > import org.eclipse.equinox.p2.core.ProvisionException; >+import org.eclipse.equinox.p2.core.location.AgentLocation; > import org.eclipse.equinox.p2.metadata.repository.IMetadataRepository; > import org.eclipse.equinox.spi.p2.metadata.repository.IMetadataRepositoryFactory; > > public class SimpleMetadataRepositoryFactory implements IMetadataRepositoryFactory { > > private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$ >- private static final String XML_EXTENSION = ".xml"; >+ private static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$ >+ private static final String CONTENT_FILENAME = "content"; //$NON-NLS-1$ > > public IMetadataRepository create(URL location, String name, String type) { > if (location.getProtocol().equals("file")) //$NON-NLS-1$ >@@ -33,54 +35,88 @@ > } > > public IMetadataRepository load(URL location, IProgressMonitor monitor) throws ProvisionException { >- if (monitor == null) >- monitor = new NullProgressMonitor(); >- // load the jar >- IMetadataRepository result = load(location, JAR_EXTENSION, monitor); >- // compressed file is not available, load the xml >- if (result == null) { >- result = load(location, XML_EXTENSION, monitor); >- } >- return result; >- } >- >- private IMetadataRepository load(URL location, String extension, IProgressMonitor monitor) throws ProvisionException { > long time = 0; >+ boolean compress = true; > final String debugMsg = "Restoring metadata repository "; //$NON-NLS-1$ >+ AgentLocation agentLocation = (AgentLocation) ServiceHelper.getService(Activator.getContext(), AgentLocation.class.getName()); >+ Date timestamp, cacheTimestamp; >+ URL actualFile, dataArea; > if (Tracing.DEBUG_METADATA_PARSING) { > Tracing.debug(debugMsg + location); > time = -System.currentTimeMillis(); > } > try { >- URL actualFile = URLMetadataRepository.getActualLocation(location); >- InputStream inStream = URLMetadataRepository.getActualLocation(location, extension).openStream(); >- if (JAR_EXTENSION.equalsIgnoreCase(extension)) { >- JarInputStream jInStream = new JarInputStream(inStream); >- JarEntry jarEntry = jInStream.getNextJarEntry(); >- String entryName = new Path(actualFile.getPath()).lastSegment(); >- while (jarEntry != null && (!entryName.equals(jarEntry.getName()))) { >- jarEntry = jInStream.getNextJarEntry(); >- } >- if (jarEntry == null) { >- throw new FileNotFoundException("Repository not found in " + actualFile.getPath() + extension); //$NON-NLS-1$ >+ IStatus status; >+ OutputStream metadata; >+ SubMonitor sub = SubMonitor.convert(monitor, 300); >+ String fileLocation = URLMetadataRepository.getActualLocation(location, JAR_EXTENSION).toExternalForm(); >+ int hashCode = location.hashCode(); >+ timestamp = getTransport().getLastModified(fileLocation); >+ cacheTimestamp = null; >+ actualFile = URLMetadataRepository.getActualLocation(location); >+ dataArea = agentLocation.getDataArea(Activator.ID + "/cache/"); //$NON-NLS-1$ >+ String cachePath = dataArea.getPath(); >+ File cacheFile = null; >+ if (timestamp != null) { >+ cacheFile = new File(cachePath + CONTENT_FILENAME + hashCode + JAR_EXTENSION); >+ cacheTimestamp = new Date(cacheFile.lastModified()); >+ } else { >+ fileLocation = URLMetadataRepository.getActualLocation(location, XML_EXTENSION).toExternalForm(); >+ timestamp = getTransport().getLastModified(fileLocation); >+ if (timestamp != null) { >+ compress = false; >+ cacheFile = new File(cachePath, CONTENT_FILENAME + hashCode + XML_EXTENSION); >+ cacheTimestamp = new Date(cacheFile.lastModified()); >+ } else >+ return null; >+ } >+ if (timestamp.after(cacheTimestamp)) { >+ // retrieve the newer index file >+ File parentFile = cacheFile.getParentFile(); >+ if (!parentFile.exists()) { >+ parentFile.mkdirs(); > } >- inStream = jInStream; >+ cacheFile.createNewFile(); >+ metadata = new BufferedOutputStream(new FileOutputStream(cacheFile)); >+ status = getTransport().download(fileLocation, metadata, sub); >+ } else { >+ // use the cached file >+ status = Status.OK_STATUS; >+ metadata = null; > } >- InputStream descriptorStream = new BufferedInputStream(inStream); >- try { >- IMetadataRepository result = new MetadataRepositoryIO().read(actualFile, descriptorStream, monitor); >- if (result instanceof LocalMetadataRepository) >- ((LocalMetadataRepository) result).initializeAfterLoad(location); >- if (result instanceof URLMetadataRepository) >- ((URLMetadataRepository) result).initializeAfterLoad(location); >- if (Tracing.DEBUG_METADATA_PARSING) { >- time += System.currentTimeMillis(); >- Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ >+ if (status.isOK()) { >+ if (metadata != null) { >+ metadata.close(); >+ } >+ InputStream inStream = new BufferedInputStream(new FileInputStream(cacheFile)); >+ if (compress) { >+ JarInputStream jInStream = new JarInputStream(inStream); >+ JarEntry jarEntry = jInStream.getNextJarEntry(); >+ String entryName = new Path(actualFile.getPath()).lastSegment(); >+ while (jarEntry != null && (!entryName.equals(jarEntry.getName()))) { >+ jarEntry = jInStream.getNextJarEntry(); >+ } >+ if (jarEntry == null) { >+ throw new FileNotFoundException("Repository not found in compressed file."); //$NON-NLS-1$ >+ } >+ inStream = jInStream; >+ } >+ InputStream descriptorStream = new BufferedInputStream(inStream); >+ try { >+ IMetadataRepository result = new MetadataRepositoryIO().read(cacheFile.toURL(), descriptorStream, sub.newChild(100)); >+ if (result instanceof LocalMetadataRepository) >+ ((LocalMetadataRepository) result).initializeAfterLoad(location); >+ if (result instanceof URLMetadataRepository) >+ ((URLMetadataRepository) result).initializeAfterLoad(location); >+ if (Tracing.DEBUG_METADATA_PARSING) { >+ time += System.currentTimeMillis(); >+ Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ >+ } >+ return result; >+ } finally { >+ if (descriptorStream != null) >+ descriptorStream.close(); > } >- return result; >- } finally { >- if (descriptorStream != null) >- descriptorStream.close(); > } > } catch (FileNotFoundException e) { > //if the repository doesn't exist, then it's fine to return null >@@ -90,6 +126,10 @@ > return null; > } > >+ private ECFMetadataTransport getTransport() { >+ return ECFMetadataTransport.getInstance(); >+ } >+ > private void log(String message, Exception e) { > LogHelper.log(new Status(IStatus.ERROR, Activator.PI_METADATA_REPOSITORY, message, e)); > } >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/equinox-incubator/provisioning/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF,v >retrieving revision 1.9 >diff -u -r1.9 MANIFEST.MF >--- META-INF/MANIFEST.MF 2 Jan 2008 21:17:55 -0000 1.9 >+++ META-INF/MANIFEST.MF 22 Jan 2008 13:53:58 -0000 >@@ -32,5 +32,8 @@ > Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1, > J2SE-1.4 > Require-Bundle: org.eclipse.equinox.common, >- org.eclipse.equinox.registry >+ org.eclipse.equinox.registry, >+ org.eclipse.osgi;bundle-version="3.4.0", >+ org.eclipse.ecf;bundle-version="1.2.0", >+ org.eclipse.ecf.filetransfer;bundle-version="2.0.0" > Eclipse-BuddyPolicy: registered >Index: src/org/eclipse/equinox/internal/p2/metadata/repository/ECFMetadataTransport.java >=================================================================== >RCS file: src/org/eclipse/equinox/internal/p2/metadata/repository/ECFMetadataTransport.java >diff -N src/org/eclipse/equinox/internal/p2/metadata/repository/ECFMetadataTransport.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/equinox/internal/p2/metadata/repository/ECFMetadataTransport.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,180 @@ >+/******************************************************************************* >+ * Copyright (c) 2007, 2008 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.equinox.internal.p2.metadata.repository; >+ >+import java.io.IOException; >+import java.io.OutputStream; >+import java.util.Date; >+import org.eclipse.core.runtime.*; >+import org.eclipse.ecf.core.*; >+import org.eclipse.ecf.filetransfer.*; >+import org.eclipse.ecf.filetransfer.events.*; >+import org.eclipse.ecf.filetransfer.identity.FileCreateException; >+import org.eclipse.ecf.filetransfer.identity.FileIDFactory; >+import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory; >+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; >+import org.osgi.util.tracker.ServiceTracker; >+ >+public class ECFMetadataTransport { >+ >+ /** >+ * The singleton transport instance. >+ */ >+ private static ECFMetadataTransport instance; >+ >+ private final ServiceTracker retrievalFactoryTracker; >+ >+ public static synchronized ECFMetadataTransport getInstance() { >+ if (instance == null) { >+ instance = new ECFMetadataTransport(); >+ } >+ return instance; >+ } >+ >+ private ECFMetadataTransport() { >+ retrievalFactoryTracker = new ServiceTracker(Activator.getContext(), IRetrieveFileTransferFactory.class.getName(), null); >+ retrievalFactoryTracker.open(); >+ } >+ >+ public IStatus download(String toDownload, OutputStream target, IProgressMonitor monitor) { >+ IRetrieveFileTransferFactory factory = (IRetrieveFileTransferFactory) retrievalFactoryTracker.getService(); >+ if (factory == null) >+ return null; >+ >+ return transfer(factory.newInstance(), toDownload, target, monitor); >+ } >+ >+ /** >+ * Gets the last modified date for the specified file. >+ * @param location - The URL location of the file. >+ * @return The <code>Date</code> of the file's last modified date, <code>null</code> if operation was not successful. >+ */ >+ public Date getLastModified(String location) { >+ IContainer container; >+ try { >+ container = ContainerFactory.getDefault().createContainer(); >+ } catch (ContainerCreateException e) { >+ return null; >+ } >+ IRemoteFileSystemBrowserContainerAdapter adapter = (IRemoteFileSystemBrowserContainerAdapter) container.getAdapter(IRemoteFileSystemBrowserContainerAdapter.class); >+ if (adapter == null) { >+ return null; >+ } >+ IRemoteFile remoteFile = checkFile(adapter, location); >+ if (remoteFile == null) { >+ return null; >+ } >+ return new Date(remoteFile.getInfo().getLastModified()); >+ } >+ >+ private IRemoteFile checkFile(final IRemoteFileSystemBrowserContainerAdapter retrievalContainer, final String location) { >+ final Object[] result = new Object[1]; >+ IRemoteFileSystemListener listener = new IRemoteFileSystemListener() { >+ public void handleRemoteFileEvent(IRemoteFileSystemEvent event) { >+ if (event instanceof IRemoteFileSystemBrowseEvent) { >+ IRemoteFileSystemBrowseEvent fsbe = (IRemoteFileSystemBrowseEvent) event; >+ IRemoteFile[] remoteFiles = fsbe.getRemoteFiles(); >+ if (remoteFiles != null && remoteFiles.length > 0) { >+ synchronized (result) { >+ result[0] = remoteFiles[0]; >+ result.notify(); >+ } >+ } >+ } >+ } >+ }; >+ try { >+ retrievalContainer.sendBrowseRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getBrowseNamespace(), location), listener); >+ } catch (RemoteFileSystemException e) { >+ return null; >+ } catch (FileCreateException e) { >+ return null; >+ } >+ synchronized (result) { >+ while (result[0] == null) { >+ boolean logged = false; >+ try { >+ result.wait(); >+ } catch (InterruptedException e) { >+ if (!logged) >+ LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF browse", e)); //$NON-NLS-1$ >+ } >+ } >+ } >+ return (IRemoteFile) result[0]; >+ } >+ >+ private IStatus transfer(final IRetrieveFileTransferContainerAdapter retrievalContainer, final String toDownload, final OutputStream target, final IProgressMonitor monitor) { >+ final IStatus[] result = new IStatus[1]; >+ IFileTransferListener listener = new IFileTransferListener() { >+ >+ public void handleTransferEvent(IFileTransferEvent event) { >+ if (event instanceof IIncomingFileTransferReceiveStartEvent) { >+ IIncomingFileTransferReceiveStartEvent rse = (IIncomingFileTransferReceiveStartEvent) event; >+ if (target != null) { >+ try { >+ rse.receive(target); >+ } catch (IOException e) { >+ IStatus status = convertToStatus(e); >+ synchronized (result) { >+ result[0] = status; >+ result.notify(); >+ } >+ } >+ } >+ } >+ if (event instanceof IIncomingFileTransferReceiveDataEvent) { >+ IIncomingFileTransfer source = ((IIncomingFileTransferReceiveDataEvent) event).getSource(); >+ if (monitor != null) { >+ if (monitor.isCanceled()) >+ source.cancel(); >+ } >+ } >+ if (event instanceof IIncomingFileTransferReceiveDoneEvent) { >+ IStatus status = convertToStatus(((IIncomingFileTransferReceiveDoneEvent) event).getException()); >+ synchronized (result) { >+ result[0] = status; >+ result.notify(); >+ } >+ } >+ } >+ }; >+ >+ try { >+ retrievalContainer.sendRetrieveRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getRetrieveNamespace(), toDownload), listener, null); >+ } catch (IncomingFileTransferException e) { >+ return new Status(IStatus.ERROR, Activator.ID, "error during transfer", e); >+ } catch (FileCreateException e) { >+ return new Status(IStatus.ERROR, Activator.ID, "error during transfer - could not create file", e); >+ } >+ synchronized (result) { >+ while (result[0] == null) { >+ boolean logged = false; >+ try { >+ result.wait(); >+ } catch (InterruptedException e) { >+ if (!logged) >+ LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF transfer", e)); //$NON-NLS-1$ >+ } >+ } >+ } >+ >+ return result[0]; >+ } >+ >+ protected IStatus convertToStatus(Exception e) { >+ if (e == null) >+ return Status.OK_STATUS; >+ if (e instanceof UserCancelledException) >+ return new Status(IStatus.CANCEL, Activator.ID, e.getMessage(), e); >+ return new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e); >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 214816
:
87517
|
87772
|
88147
|
88162