blob: 51ec35e6ca864e7f69febb524b961be1674b30f3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2014 Christian Pontesegger 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:
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.ui.views.imagebrowser.repositories;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.views.imagebrowser.IImageTarget;
import org.eclipse.pde.internal.ui.views.imagebrowser.ImageElement;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.ImageData;
public abstract class AbstractRepository extends Job {
protected List<ImageElement> mElementsCache = new LinkedList<>();
private IImageTarget mTarget;
public AbstractRepository(IImageTarget target) {
super(PDEUIMessages.AbstractRepository_ScanForUI);
mTarget = target;
}
private static final String[] KNOWN_EXTENSIONS = new String[] {".gif", ".png"}; //$NON-NLS-1$ //$NON-NLS-2$
@Override
protected synchronized IStatus run(IProgressMonitor monitor) {
while ((mTarget.needsMore()) && (!monitor.isCanceled())) {
if (mElementsCache.isEmpty()) {
// need more images in cache
if (!populateCache(monitor)) {
// could not populate cache, giving up
return Status.OK_STATUS;
}
} else {
// return 1 image from cache
mTarget.notifyImage(mElementsCache.remove(0));
}
}
return Status.OK_STATUS;
}
public synchronized void clearCache() {
mElementsCache.clear();
}
protected abstract boolean populateCache(IProgressMonitor monitor);
protected ImageData createImageData(final IFile file) throws CoreException {
return new ImageData(new BufferedInputStream(file.getContents()));
}
protected boolean isImage(final File resource) {
if (resource.isFile())
return isImageName(resource.getName());
return false;
}
protected boolean isImageName(final String fileName) {
for (String extension : KNOWN_EXTENSIONS) {
if (fileName.regionMatches(true, fileName.length() - extension.length(), extension, 0, extension.length()))
return true;
}
return false;
}
protected boolean isJar(final File file) {
return file.getName().toLowerCase().endsWith(".jar"); //$NON-NLS-1$
}
protected void searchJarFile(final File jarFile, final IProgressMonitor monitor) {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(jarFile);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while ((entries.hasMoreElements()) && (!monitor.isCanceled())) {
ZipEntry entry = entries.nextElement();
if (isImageName(entry.getName())) {
InputStream inputStream = null;
try {
inputStream = zipFile.getInputStream(entry);
ImageData imageData = new ImageData(inputStream);
addImageElement(new ImageElement(imageData, jarFile.getName(), entry.getName()));
} catch (IOException e) {
PDEPlugin.log(e);
} catch (SWTException e) {
// invalid image format
PDEPlugin.log(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), NLS.bind(PDEUIMessages.AbstractRepository_ErrorLoadingImageFromJar, jarFile.getAbsolutePath(), entry.getName()), e));
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
}
}
}
}
}
} catch (ZipException e) {
PDEPlugin.log(e);
} catch (IOException e) {
PDEPlugin.log(e);
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
}
}
}
}
protected void searchDirectory(File directory, final IProgressMonitor monitor) {
File manifest = new File(directory, "META-INF/MANIFEST.MF"); //$NON-NLS-1$
if (manifest.exists()) {
try {
String pluginName = getPluginName(new FileInputStream(manifest));
int directoryPathLength = directory.getAbsolutePath().length();
Collection<File> locations = new HashSet<>();
locations.add(directory);
do {
File next = locations.iterator().next();
locations.remove(next);
for (File resource : next.listFiles()) {
if (monitor.isCanceled())
return;
if (resource.isDirectory()) {
locations.add(resource);
} else {
try {
if (isImage(resource)) {
addImageElement(new ImageElement(createImageData((IFile) resource), pluginName, resource.getAbsolutePath().substring(directoryPathLength)));
}
} catch (Exception e) {
// could not create image for location
}
}
}
} while ((!locations.isEmpty()) && (!monitor.isCanceled()));
} catch (IOException e) {
// could not read manifest
PDEPlugin.log(e);
}
}
}
protected String getPluginName(final InputStream manifest) throws IOException {
Properties properties = new Properties();
BufferedInputStream stream = new BufferedInputStream(manifest);
properties.load(stream);
stream.close();
String property = properties.getProperty("Bundle-SymbolicName"); //$NON-NLS-1$
if (property.contains(";")) //$NON-NLS-1$
return property.substring(0, property.indexOf(';')).trim();
return property.trim();
}
protected void addImageElement(ImageElement element) {
mElementsCache.add(element);
}
}