Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support exporting jar #271

Merged
merged 48 commits into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
6a92859
add getmainmethod command
CsCherrYY Jun 23, 2020
3d85cf2
Update ProjectCommand.java
CsCherrYY Jun 23, 2020
1e0333c
Update params
CsCherrYY Jun 23, 2020
afea0b1
Update ProjectCommand.java
CsCherrYY Jun 24, 2020
86b2454
Update ProjectCommand.java
CsCherrYY Jun 24, 2020
d461fb2
Update ProjectCommand.java
CsCherrYY Jun 24, 2020
e3884b5
Update ProjectCommand.java
CsCherrYY Jun 24, 2020
c1a4446
Merge pull request #1 from microsoft/master
CsCherrYY Jul 16, 2020
9f819ca
Export jar
CsCherrYY Jul 16, 2020
7c844e1
Update pom.xml
CsCherrYY Jul 16, 2020
9b8a612
Update ProjectCommand.java
CsCherrYY Jul 16, 2020
317c840
Apply changes
CsCherrYY Jul 17, 2020
67ea013
Merge branch 'master' into master
jdneo Jul 20, 2020
c9bdc4f
Fix tslint error
CsCherrYY Jul 20, 2020
c4e2ee2
Merge branch 'master' of https://github.com/CsCherrYY/vscode-java-dep…
CsCherrYY Jul 20, 2020
9eda159
Merge branch 'master' of https://github.com/CsCherrYY/vscode-java-dep…
CsCherrYY Jul 20, 2020
f353796
Apply changes
CsCherrYY Jul 20, 2020
b9c673a
Error handing
CsCherrYY Jul 20, 2020
e502fb9
Apply changes
CsCherrYY Jul 21, 2020
a27b683
Apply changes
CsCherrYY Jul 21, 2020
de2c5f7
Apply resolved changes
CsCherrYY Jul 22, 2020
ec9bd67
Apply changes
CsCherrYY Jul 23, 2020
753ae9c
Merge branch 'master' into master
CsCherrYY Jul 23, 2020
1666c3a
Update exportJarFileCommand.ts
CsCherrYY Jul 23, 2020
2fbcf79
Apply changes and modify view group
CsCherrYY Jul 23, 2020
e79a752
Template version remains more debugging
CsCherrYY Jul 23, 2020
57a8fd0
Update ProjectCommand.java
CsCherrYY Jul 23, 2020
69277f4
Update progress message
CsCherrYY Jul 24, 2020
e74c441
Apply changes
CsCherrYY Jul 27, 2020
9ddf4f8
Update exportJarFileCommand.ts
CsCherrYY Jul 27, 2020
e5d3fcd
Apply changes
CsCherrYY Jul 27, 2020
0e8ec92
Apply changes
CsCherrYY Jul 27, 2020
12af080
Update exportJarFileCommand.ts
CsCherrYY Jul 27, 2020
b696b10
Fix classpath bug
CsCherrYY Jul 27, 2020
636f917
Rename Variables
CsCherrYY Jul 28, 2020
b145363
Update exportJarFileCommand.ts
CsCherrYY Jul 28, 2020
add8555
Update exportJarFileCommand.ts
CsCherrYY Jul 28, 2020
6da5127
Update exportJarFileCommand.ts
CsCherrYY Jul 28, 2020
3513237
Change back button type
CsCherrYY Jul 28, 2020
2744de0
Update Placeholder message
CsCherrYY Jul 29, 2020
22e57a7
Rename command
CsCherrYY Jul 29, 2020
f3fbd4d
Divide into steps (debug version)
CsCherrYY Jul 29, 2020
10f3590
Divide process into steps
CsCherrYY Jul 29, 2020
3bfc6dd
Using a map to record steps
CsCherrYY Jul 30, 2020
c31e7c1
Apply changes
CsCherrYY Jul 30, 2020
720103a
Delete unnecessary code
CsCherrYY Jul 30, 2020
8a91a97
Delete unnecessary code
CsCherrYY Jul 30, 2020
1381e33
Delete unnecessary code fix
CsCherrYY Jul 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<command id="java.project.list"/>
<command id="java.getPackageData"/>
<command id="java.resolvePath" />
<command id="java.project.getMainMethod" />
<command id="java.project.generateJar" />
</delegateCommandHandler>
</extension>
<extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
return PackageCommand.getChildren(arguments, monitor);
case "java.resolvePath":
return PackageCommand.resolvePath(arguments, monitor);
case "java.project.getMainMethod":
return ProjectCommand.getMainMethod(arguments, monitor);
case "java.project.generateJar":
return ProjectCommand.exportJar(arguments, monitor);
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ private static Object[] findJarDirectoryChildren(JarEntryDirectory directory, St
return null;
}

private static IJavaProject getJavaProject(String projectUri) {
public static IJavaProject getJavaProject(String projectUri) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IContainer[] containers = root.findContainersForLocationURI(JDTUtils.toURI(projectUri));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,45 @@

package com.microsoft.jdtls.ext.core;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipFile;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
Expand All @@ -30,9 +58,31 @@

import com.microsoft.jdtls.ext.core.model.NodeKind;
import com.microsoft.jdtls.ext.core.model.PackageNode;
import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.json.adapters.EnumTypeAdapter;

import static org.eclipse.jdt.internal.jarpackager.JarPackageUtil.writeFile;
import static org.eclipse.jdt.internal.jarpackager.JarPackageUtil.writeArchive;

CsCherrYY marked this conversation as resolved.
Show resolved Hide resolved
public final class ProjectCommand {

public static class MainClassInfo {

public String name;

public String path;

public MainClassInfo(String name, String path) {
this.name = name;
this.path = path;
}
}

private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new CollectionTypeAdapter.Factory())
.registerTypeAdapterFactory(new EnumTypeAdapter.Factory())
.create();

public static List<PackageNode> listProjects(List<Object> arguments, IProgressMonitor monitor) {
String workspaceUri = (String) arguments.get(0);
IPath workspacePath = ResourceUtils.canonicalFilePathFromURI(workspaceUri);
Expand Down Expand Up @@ -79,4 +129,116 @@ private static String getWorkspaceInvisibleProjectName(IPath workspacePath) {
String fileName = workspacePath.toFile().getName();
return fileName + "_" + Integer.toHexString(workspacePath.toPortableString().hashCode());
}

public static boolean exportJar(List<Object> arguments, IProgressMonitor monitor) {
if (arguments.size() < 3) {
return false;
}
String mainMethod = gson.fromJson(gson.toJson(arguments.get(0)), String.class);
String[] classpaths = gson.fromJson(gson.toJson(arguments.get(1)), String[].class);
String destination = gson.fromJson(gson.toJson(arguments.get(2)), String.class);
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
if (mainMethod.length() > 0) {
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS,mainMethod);
}
try (JarOutputStream target = new JarOutputStream(new FileOutputStream(destination), manifest)) {
Set<String> fDirectories = new HashSet<>();
for (String classpath : classpaths) {
if (classpath != null) {
if(classpath.endsWith(".jar")) {
ZipFile zip = new ZipFile(classpath);
writeArchive(zip, true, true, target, fDirectories, monitor);
}
else {
File folder = new File(classpath);
writeFileRecursively(folder, target, fDirectories, folder.getAbsolutePath().length() + 1);
}
}
}
} catch (Exception e) {
return false;
}
return true;
}

private static void writeFileRecursively(File folder, JarOutputStream fJarOutputStream, Set<String> fDirectories, int len) {
File[] files = folder.listFiles();
for (File file : files) {
if (file.isDirectory()) {
writeFileRecursively(file, fJarOutputStream, fDirectories, len);
} else if (file.isFile()) {
try {
writeFile(file, new Path(file.getAbsolutePath().substring(len)), true, true, fJarOutputStream, fDirectories);
}
catch (Exception e) {
// do nothing
}
}
}
}

public static List<MainClassInfo> getMainMethod(List<Object> arguments, IProgressMonitor monitor) throws Exception {
List<PackageNode> projectList = listProjects(arguments, monitor);
final List<MainClassInfo> res = new ArrayList<>();
List<IJavaElement> searchRoots = new ArrayList<>();
if (projectList.size() == 0) {
return res;
}
for (PackageNode project : projectList) {
IJavaProject javaProject = PackageCommand.getJavaProject(project.getUri());
for (IPackageFragmentRoot packageFragmentRoot : javaProject.getAllPackageFragmentRoots()) {
if (!packageFragmentRoot.isExternal()) {
searchRoots.add(packageFragmentRoot);
}
}
}
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(searchRoots.toArray(IJavaElement[]::new));
SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD,
IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
SearchRequestor requestor = new SearchRequestor() {
@Override
public void acceptSearchMatch(SearchMatch match) {
Object element = match.getElement();
if (!(element instanceof IMethod)) {
return;
}
IMethod method = (IMethod) element;
try {
if (!method.isMainMethod() || method.getResource() == null || method.getJavaProject() == null) {
return;
}
String mainClass = method.getDeclaringType().getFullyQualifiedName();
String filePath = "";
if (match.getResource() instanceof IFile) {
filePath = match.getResource().getLocation().toOSString();
}
res.add(new MainClassInfo(mainClass, filePath));
} catch (JavaModelException e) {
// ignore
}
}
};
SearchEngine searchEngine = new SearchEngine();
try {
searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
scope, requestor, new NullProgressMonitor());
} catch (CoreException e) {
// ignore
}
return res;
}

public static String getModuleName(IJavaProject project) {
if (project == null || !JavaRuntime.isModularProject(project)) {
return null;
}
try {
IModuleDescription module = project.getModuleDescription();
return module == null ? null : module.getElementName();
} catch (CoreException e) {
return null;
}
}

}
Loading