Skip to content

Commit

Permalink
Merge pull request #365 from demonfiddler/master
Browse files Browse the repository at this point in the history
[Enhancement][REDO] ternModuleInstalls to support folders within a plug-in JAR per Issue #332
  • Loading branch information
angelozerr committed Nov 10, 2015
2 parents d73d2c8 + 57a774c commit 9af16f8
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
5 changes: 3 additions & 2 deletions core/tern.core/src/tern/repository/TernRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import tern.server.ITernPlugin;
import tern.server.ModuleType;
import tern.utils.ExtensionUtils;
import tern.utils.IOUtils;
import tern.utils.TernModuleHelper;
import tern.utils.ZipUtils;

Expand Down Expand Up @@ -226,7 +227,7 @@ public ITernPlugin[] getLinters() {
public void install(File moduleFile) throws IOException, TernException {
if (!moduleFile.exists()) {
throw new TernException(
"Cannot install module file <" + TernModuleHelper.getPath(moduleFile) + ">. It doesn't exists.");
"Cannot install module file <" + TernModuleHelper.getPath(moduleFile) + ">. It doesn't exist.");
}
File baseDir = getNodeModulesDir();
if (!baseDir.exists()) {
Expand All @@ -238,7 +239,7 @@ public void install(File moduleFile) throws IOException, TernException {
ZipUtils.extract(moduleFile, baseDir);
} else if (moduleFile.isDirectory()) {
// Folder, copy this folder to the tern repository
throw new TernException("TODO!");
IOUtils.copy(moduleFile, new File(baseDir, moduleFile.getName()), false);
} else {
throw new TernException("Cannot install module file <" + TernModuleHelper.getPath(moduleFile)
+ ">. It must be a folder or a zip/jar file.");
Expand Down
87 changes: 87 additions & 0 deletions core/tern.core/src/tern/utils/IOUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -1415,6 +1417,40 @@ public static void writeLines(Collection<?> lines, String lineEnding,
}
}

// copy from File
//-----------------------------------------------------------------------
/**
* Copy bytes from one <code>File</code> to another <code>File</code>.
* Directory files are copied recursively.
* <p>
* Large files (over 2GB) will return a bytes copied value of
* <code>-1</code> after the copy has completed since the correct number of
* bytes cannot be returned as an int. For large files use the
* <code>copyLarge(InputStream, OutputStream)</code> method.
*
* @param input
* the <code>File</code> to read from
* @param output
* the <code>File</code> to write to
* @param forceOverwrite
* pass <code>true</code> to force existing files to be
* overwritten regardless; otherwise, a file will only be
* overwritten if it is older than the file being copied.
* @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
* @since 1.1
*/
public static int copy(File input, File output, boolean forceOverwrite) throws IOException {
long count = copyLarge(input, output, forceOverwrite);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}

// copy from InputStream
//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -1444,6 +1480,57 @@ public static int copy(InputStream input, OutputStream output) throws IOExceptio
return (int) count;
}

/**
* Copy bytes from one large (over 2GB) <code>File</code> to another
* <code>File</code>. Directory files are copied recursively.
* <p>
* This method buffers the input internally, so there is no need to use a
* <code>BufferedInputStream</code>.
* <p>
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
* @param input
* the <code>File</code> to read from
* @param output
* the <code>File</code> to write to
* @param forceOverwrite
* pass <code>true</code> to force existing files to be
* overwritten regardless; otherwise, a file will only be
* overwritten if it is older than the file being copied.
* @return the number of bytes copied
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
* @since 1.3
*/
public static long copyLarge(File input, File output, boolean forceOverwrite) throws IOException {
if (input.isDirectory()) {
if (!output.exists())
output.mkdirs();
else if (!output.isDirectory())
throw new IOException(output.getCanonicalPath() + " already exists but is not a directory");
long count = 0L;
for (File child : input.listFiles()) {
count += copyLarge(child, new File(output, child.getName()), forceOverwrite);
}
return count;
} else if (input.lastModified() > output.lastModified() || forceOverwrite) {
if (!output.getParentFile().exists())
output.getParentFile().mkdirs();
FileInputStream inStream = new FileInputStream(input);
FileOutputStream outStream = new FileOutputStream(output);
try {
return copyLarge(inStream, outStream);
} finally {
closeQuietly(inStream);
closeQuietly(outStream);
}
} else {
return input.length();
}
}

/**
* Copy bytes from a large (over 2GB) <code>InputStream</code> to an
* <code>OutputStream</code>.
Expand Down
4 changes: 2 additions & 2 deletions core/tern.core/src/tern/utils/ZipUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class ZipUtils {
* @return true if the given file is a zip file and false otherwise.
*/
public static boolean isZipFile(File file) {
return file.isFile() && file.getName().endsWith(ZIP_EXTENSION);
return file.isFile() && file.getName().toLowerCase().endsWith(ZIP_EXTENSION);
}

/**
Expand All @@ -45,7 +45,7 @@ public static boolean isZipFile(File file) {
* @return true if the given file is a jar file and false otherwise.
*/
public static boolean isJarFile(File file) {
return file.isFile() && file.getName().endsWith(JAR_EXTENSION);
return file.isFile() && file.getName().toLowerCase().endsWith(JAR_EXTENSION);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@

import java.io.File;
import java.io.IOException;
import java.net.URL;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;

import tern.TernException;
import tern.eclipse.ide.core.utils.FileUtils;
Expand Down Expand Up @@ -48,8 +54,13 @@ public TernModuleInstall(IConfigurationElement element) throws IOException {
}

private File getFile(String src, String pluginId) throws IOException {
File baseDir = FileLocator.getBundleFile(Platform.getBundle(pluginId));
return new File(baseDir, src);
// Obtain a file: URL for the bundle entry containing the Tern module contributions.
Bundle bundle = Platform.getBundle(pluginId);
URL moduleUrl = FileLocator.toFileURL(bundle.getEntry(src));
if (moduleUrl == null || !"file".equals(moduleUrl.getProtocol())) {
throw new IOException(NLS.bind("Unable to obtain a file URL for {0} in plug-in {1}", src, pluginId));
}
return new File(moduleUrl.getPath()).getCanonicalFile();
}

public String getId() {
Expand Down

0 comments on commit 9af16f8

Please sign in to comment.