/**
* Copyright (c) 2009 Farata Systems http://www.faratasystems.com
*
* Licensed under The MIT License
* Re-distributions of files must retain the above copyright notice.
*
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/
package com.farata.cleardatabuilder.extjs.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.Bundle;
/**
* Set of utilities solving common tasks of different aspects of plug-ins
* development.
*
*
*/
public final class Commons {
private static final IProgressMonitor DEFAULT_MONITOR = new IProgressMonitor() {
public void beginTask(final String name, final int totalWork) {
}
public void done() {
}
public void internalWorked(final double work) {
}
public boolean isCanceled() {
return false;
}
public void setCanceled(final boolean value) {
}
public void setTaskName(final String name) {
}
public void subTask(final String name) {
}
public void worked(final int work) {
}
};
private Commons() {
}
/**
* Returns always nonnull instance of {@link IProgressMonitor}. If specified
* <tt>progressMonitor</tt> is <tt>null</tt> then default instance will be
* returned, otherwise the specified argument will be returned.
*
* @param progressMonitor
* the monitor to check.
* @return nonnull instance of {@link IProgressMonitor}.
*/
public static IProgressMonitor prepareMonitor(
final IProgressMonitor progressMonitor) {
final IProgressMonitor result;
if (progressMonitor != null) {
result = progressMonitor;
} else {
result = Commons.DEFAULT_MONITOR;
}
return result;
}
/**
* Returns a File representing the specified entry in the given plug-in. The
* classloader is not used here, only the contents of the plug-in is
* searched for the specified entry. A specified path of "/" indicates the
* root of the plug-in.
*
*
* @param bundle
* Bundle which contents to search for the entry.
* @param entry
* The name of the entry. See java.lang.ClassLoader.getResource
* for a description of the format of a resource name.
* @return a File representing the specified entry in the given plug-in, or
* <tt>null</tt> if no entry could be found or if the caller does
* not have the appropriate permission.
* @throws CoreException
* When failed to convert the URL of the entry to the URL using
* the file protocol.
* @throws IllegalStateException
* If this plug-in has been uninstalled.
* @throws NullPointerException
* When specified arguments are <tt>null</tt>.
*/
public static File getBundleEntry(final Bundle bundle,
final String entryName) throws Exception {
final File result;
final URL entry = bundle.getEntry(entryName);
if (entry != null) {
final URL fileUrl = FileLocator.toFileURL(entry);
result = urlToFile(fileUrl);
} else {
result = null;
}
return result;
}
/**
* See {@link #getBundleEntry(Bundle, String)} and
* {@link Bundle#findEntries(String, String, boolean)}.
*/
public static List<File> getBundleEntries(final Bundle bundle,
final String path, final String filePattern, final boolean recurse)
throws Exception {
final Enumeration<?> entries = bundle.findEntries(path, filePattern,
recurse);
final List<File> result = new ArrayList<File>();
while (entries.hasMoreElements()) {
final URL entry = (URL) entries.nextElement();
final URL fileUrl = FileLocator.toFileURL(entry);
result.add(urlToFile(fileUrl));
}
return result;
}
/**
* Returns a File representing the specified entry in the given plug-in. The
* classloader is not used here, only the contents of the plug-in is
* searched for the specified entry. A specified path of "/" indicates the
* root of the plug-in.
*
*
* @param plugin
* Plug-in which contents to search for the entry.
* @param entry
* The name of the entry. See java.lang.ClassLoader.getResource
* for a description of the format of a resource name.
* @return a File representing the specified entry in the given plug-in, or
* <tt>null</tt> if no entry could be found or if the caller does
* not have the appropriate permission.
* @throws CoreException
* When failed to convert the URL of the entry to the URL using
* the file protocol.
* @throws IllegalStateException
* If this plug-in has been uninstalled.
* @throws NullPointerException
* When specified arguments are <tt>null</tt>.
*/
public static File getPluginEntry(final Plugin plugin,
final String entryName) throws Exception {
return getBundleEntry(plugin.getBundle(), entryName);
}
/**
* Converts {@link URL} to {@link File}.
* <p>
* <b>Developers Note:</b><br>
* The correct way to do it is:
*
* <pre>
* File file = new File(url.toURI());
* </pre>
*
* There is no other solution. If this method fails, then only because the
* URL was broken. This method tries to repair the URL assuming that path
* component contains unencoded unsafe characters (e.g. whitespaces) and
* thus constructing new URI by component.
* <p>
* Example of correct url: <tt>file:///c:/Program%20Files/</tt><br>
*
* Example of incorrect but possible for convertation url:
* <tt>file:///c:/Program Files/</tt>
*
* @param url
* The url to be converted.
* @return The instance of {@link File} corresponding to the given url.
* @throws CoreException
* When the specified url is broken beyond automatic repair and
* cannot be converted to URI (RFC2396).
*/
public static File urlToFile(final URL url) throws Exception {
URI uri;
try {
// this is the step that can fail, and so
// it should be this step that should be fixed
uri = url.toURI();
} catch (final URISyntaxException e) {
// OK if we are here, then obviously the URL did
// not comply with RFC 2396. This can only
// happen if we have illegal unescaped characters.
// If we have one unescaped character, then
// the only automated fix we can apply, is to assume
// all characters are unescaped.
// If we want to construct a URI from unescaped
// characters, then we have to use the component
// constructors:
uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
url.getPort(), url.getPath(), url.getQuery(), url.getRef());
}
return new File(uri);
}
public static void close(final InputStream stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void close(final OutputStream stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
/** Reads first line of file with buffered reader using UTF-8 encoding. */
public static String readFirstLine(final IFile file) throws IOException,
CoreException {
InputStream contents = null;
try {
contents = file.getContents();
return new BufferedReader(new InputStreamReader(contents, "UTF8"))
.readLine();
} finally {
close(contents);
}
}
/** Reads all lines of file with buffered reader using UTF-8 encoding. */
public static List<String> readToStringsList(final InputStream stream)
throws IOException {
final List<String> result = new ArrayList<String>();
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(stream, "UTF8"));
String line;
while ((line = reader.readLine()) != null) {
final String trimmed = line.trim();
if (trimmed.length() > 0)
result.add(trimmed);
}
} finally {
close(stream);
}
return result;
}
public static List<IPath> toPaths(final List<String> strings) {
final List<IPath> result = new ArrayList<IPath>(strings.size());
for (final String string : strings) {
result.add(new Path(string));
}
return result;
}
}