Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
import java.util.zip.ZipFile;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IFile;
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.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
Expand Down Expand Up @@ -67,6 +70,8 @@

public final class ProjectCommand {

private static String COMMAND_EXPORT_JAR_REPORT = "java.view.package.exportJarReport";

private static class MainClassInfo {
public String name;
public String path;
Expand All @@ -83,23 +88,6 @@ private static class Classpath {
public boolean isArtifact;
}

private static class ExportResult {
public boolean result;
public String message;
public String log;

ExportResult(boolean result) {
this.result = result;
this.log = "";
}

ExportResult(boolean result, String message) {
this.result = result;
this.message = message;
this.log = "";
}
}

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

Expand Down Expand Up @@ -151,16 +139,14 @@ private static IWorkspaceRoot getWorkspaceRoot() {
return ResourcesPlugin.getWorkspace().getRoot();
}

public static ExportResult exportJar(List<Object> arguments, IProgressMonitor monitor) {
if (arguments.size() < 3) {
return new ExportResult(false, "Invalid export Arguments");
}
if (monitor.isCanceled()) {
return new ExportResult(false, "User cancelled");
public static boolean exportJar(List<Object> arguments, IProgressMonitor monitor) {
if (arguments.size() < 4) {
return false;
}
String mainClass = gson.fromJson(gson.toJson(arguments.get(0)), String.class);
Classpath[] classpaths = gson.fromJson(gson.toJson(arguments.get(1)), Classpath[].class);
String destination = gson.fromJson(gson.toJson(arguments.get(2)), String.class);
String taskLabel = gson.fromJson(gson.toJson(arguments.get(3)), String.class);
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
if (mainClass.length() > 0) {
Expand All @@ -170,24 +156,39 @@ public static ExportResult exportJar(List<Object> arguments, IProgressMonitor mo
Set<String> directories = new HashSet<>();
for (Classpath classpath : classpaths) {
if (monitor.isCanceled()) {
return new ExportResult(false, "User cancelled");
return false;
}
if (classpath.isArtifact) {
writeArchive(new ZipFile(classpath.source), /* areDirectoryEntriesIncluded = */true,
/* isCompressed = */true, target, directories, monitor);
MultiStatus resultStatus = writeArchive(new ZipFile(classpath.source),
/* areDirectoryEntriesIncluded = */true, /* isCompressed = */true, target, directories, monitor);
int severity = resultStatus.getSeverity();
if (severity == IStatus.OK) {
java.nio.file.Path path = java.nio.file.Paths.get(classpath.source);
reportExportJarMessage(taskLabel, IStatus.OK, "successfully export " + path.getFileName().toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message is not accurate.

Successfully added the file to the exported jar: path.getFileName().toString()

continue;
}
if (resultStatus.isMultiStatus()) {
for (IStatus childStatus : resultStatus.getChildren()) {
reportExportJarMessage(taskLabel, severity, childStatus.getMessage());
}
} else {
reportExportJarMessage(taskLabel, severity, resultStatus.getMessage());
}
} else {
try {
writeFile(new File(classpath.source), new Path(classpath.destination), /* areDirectoryEntriesIncluded = */true,
/* isCompressed = */true, target, directories);
reportExportJarMessage(taskLabel, IStatus.OK, "successfully export " + classpath.destination);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully added the file to the exported jar: classpath.destination

} catch (CoreException e) {
// TODO: Collect reports
reportExportJarMessage(taskLabel, IStatus.ERROR, e.getMessage());
}
}
}
} catch (IOException e) {
return new ExportResult(false, e.getMessage());
reportExportJarMessage(taskLabel, IStatus.ERROR, e.getMessage());
return false;
}
return new ExportResult(true);
return true;
}

public static List<MainClassInfo> getMainClasses(List<Object> arguments, IProgressMonitor monitor) throws Exception {
Expand Down Expand Up @@ -253,4 +254,28 @@ public static String getModuleName(IJavaProject project) {
}
}

private static void reportExportJarMessage(String taskLabel, int severity, String message) {
if (StringUtils.isNotBlank(message) && StringUtils.isNotBlank(taskLabel)) {
String readableSeverity = getSeverityString(severity);
JavaLanguageServerPlugin.getInstance().getClientConnection().executeClientCommand(COMMAND_EXPORT_JAR_REPORT,
taskLabel, readableSeverity + ": " + message);
}
}

private static String getSeverityString(int severity) {
switch (severity) {
case IStatus.INFO:
return "INFO";
case IStatus.WARNING:
return "WARNING";
case IStatus.ERROR:
return "ERROR";
case IStatus.CANCEL:
return "CANCEL";
case IStatus.OK:
return "OK";
default:
return "UNKNOWN STATUS";
}
}
}
2 changes: 2 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export namespace Commands {

export const VIEW_PACKAGE_EXPORT_JAR = "java.view.package.exportJar";

export const EXPORT_JAR_REPORT = "java.view.package.exportJarReport";

export const VIEW_PACKAGE_NEW_JAVA_CLASS = "java.view.package.newJavaClass";

export const VIEW_PACKAGE_NEW_JAVA_PACKAGE = "java.view.package.newPackage";
Expand Down
22 changes: 15 additions & 7 deletions src/exportJarSteps/ExportJarTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { lstat } from "fs-extra";
import * as globby from "globby";
import * as _ from "lodash";
import { platform } from "os";
import { EOL, platform } from "os";
import { dirname, extname, isAbsolute, join, relative } from "path";
import {
CustomExecution, Event, EventEmitter, Pseudoterminal, Task, TaskDefinition,
Expand Down Expand Up @@ -44,6 +44,7 @@ export async function executeExportJarTask(node?: INodeData): Promise<void> {
isExportingJar = true;
const stepMetadata: IStepMetadata = {
entry: node,
taskLabel: "exportjar:default",
steps: [],
projectList: [],
elements: [],
Expand All @@ -55,7 +56,7 @@ export async function executeExportJarTask(node?: INodeData): Promise<void> {
throw new Error(ExportJarMessages.stepErrorMessage(ExportJarMessages.StepAction.FINDEXECUTOR, ExportJarStep.ResolveJavaProject));
}
await resolveJavaProjectExecutor.execute(stepMetadata);
tasks.executeTask(ExportJarTaskProvider.getTask(stepMetadata));
tasks.executeTask(ExportJarTaskProvider.getDefaultTask(stepMetadata));
} catch (err) {
if (err) {
failMessage(`${err}`);
Expand All @@ -68,13 +69,13 @@ export class ExportJarTaskProvider implements TaskProvider {

public static exportJarType: string = "java";

public static getTask(stepMetadata: IStepMetadata): Task {
public static getDefaultTask(stepMetadata: IStepMetadata): Task {
if (!stepMetadata.workspaceFolder) {
throw new Error(ExportJarMessages.fieldUndefinedMessage(ExportJarMessages.Field.WORKSPACEFOLDER, ExportJarStep.ResolveTask));
}
const defaultDefinition: IExportJarTaskDefinition = {
type: ExportJarTaskProvider.exportJarType,
label: `${ExportJarTaskProvider.exportJarType}: exportjar:default`,
label: "exportjar:default",
targetPath: Settings.getExportJarTargetPath(),
elements: [],
mainClass: undefined,
Expand All @@ -93,9 +94,10 @@ export class ExportJarTaskProvider implements TaskProvider {
const definition: IExportJarTaskDefinition = <IExportJarTaskDefinition>task.definition;
const folder: WorkspaceFolder = <WorkspaceFolder>task.scope;
const resolvedTask: Task = new Task(definition, folder, task.name, ExportJarTaskProvider.exportJarType,
new CustomExecution(async (resolvedDefinition: TaskDefinition): Promise<Pseudoterminal> => {
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
const stepMetadata: IStepMetadata = {
entry: undefined,
taskLabel: resolvedDefinition.label || `${ExportJarTaskProvider.exportJarType}: exportjar:${folder.name}`,
workspaceFolder: folder,
projectList: await Jdtls.getProjects(folder.uri.toString()),
steps: [],
Expand Down Expand Up @@ -139,10 +141,11 @@ export class ExportJarTaskProvider implements TaskProvider {
targetPath: Settings.getExportJarTargetPath(),
elements: elementList,
};
const defaultTask: Task = new Task(defaultDefinition, folder, `exportjar:${folder.name}`,
ExportJarTaskProvider.exportJarType, new CustomExecution(async (resolvedDefinition: TaskDefinition): Promise<Pseudoterminal> => {
const defaultTask: Task = new Task(defaultDefinition, folder, `exportjar:${folder.name}`, ExportJarTaskProvider.exportJarType,
new CustomExecution(async (resolvedDefinition: IExportJarTaskDefinition): Promise<Pseudoterminal> => {
const stepMetadata: IStepMetadata = {
entry: undefined,
taskLabel: resolvedDefinition.label || `${ExportJarTaskProvider.exportJarType}: exportjar:${folder.name}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to append ${ExportJarTaskProvider.exportJarType}: before the task label.

workspaceFolder: folder,
projectList: await Jdtls.getProjects(folder.uri.toString()),
steps: [],
Expand Down Expand Up @@ -170,11 +173,16 @@ class ExportJarTaskTerminal implements Pseudoterminal {

constructor(exportJarTaskDefinition: IExportJarTaskDefinition, stepMetadata: IStepMetadata) {
this.stepMetadata = stepMetadata;
this.stepMetadata.taskLabel = exportJarTaskDefinition.label || "";
this.stepMetadata.mainClass = exportJarTaskDefinition.mainClass;
this.stepMetadata.outputPath = exportJarTaskDefinition.targetPath;
this.stepMetadata.elements = exportJarTaskDefinition.elements || [];
}

public handleInput(data: string): void {
this.writeEmitter.fire(data + EOL);
}

public async open(_initialDimensions: TerminalDimensions | undefined): Promise<void> {
let exportResult: boolean | undefined;
try {
Expand Down
16 changes: 6 additions & 10 deletions src/exportJarSteps/GenerateJarExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Jdtls } from "../java/jdtls";
import { INodeData } from "../java/nodeData";
import { IExportJarStepExecutor } from "./IExportJarStepExecutor";
import { IClasspath, IStepMetadata } from "./IStepMetadata";
import { createPickBox, ExportJarMessages, ExportJarStep, ExportJarTargets, getExtensionApi, toPosixPath } from "./utility";
import { createPickBox, ExportJarMessages, ExportJarStep, ExportJarTargets, getExtensionApi, revealTerminal, toPosixPath } from "./utility";

export class GenerateJarExecutor implements IExportJarStepExecutor {

Expand Down Expand Up @@ -82,12 +82,14 @@ export class GenerateJarExecutor implements IExportJarStepExecutor {
if (_.isEmpty(classpaths)) {
return reject(new Error(ExportJarMessages.CLASSPATHS_EMPTY));
}
const exportResult: IExportResult | undefined = await Jdtls.exportJar(basename(mainClass), classpaths, destPath, token);
if (exportResult?.result === true) {
revealTerminal(stepMetadata.taskLabel);
const exportResult: boolean | undefined = await Jdtls.exportJar(basename(mainClass),
classpaths, destPath, stepMetadata.taskLabel, token);
if (exportResult === true) {
stepMetadata.outputPath = destPath;
return resolve(true);
} else {
return reject(new Error("Export jar failed." + exportResult?.message));
return reject(new Error("Export jar failed."));
}
});
});
Expand Down Expand Up @@ -249,9 +251,3 @@ interface IJarQuickPickItem extends QuickPickItem {
path: string;
type: string;
}

export interface IExportResult {
result: boolean;
message: string;
log?: string;
}
1 change: 1 addition & 0 deletions src/exportJarSteps/IStepMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ExportJarStep } from "./utility";

export interface IStepMetadata {
entry?: INodeData;
taskLabel: string;
workspaceFolder?: WorkspaceFolder;
mainClass?: string;
outputPath?: string;
Expand Down
16 changes: 16 additions & 0 deletions src/exportJarSteps/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,19 @@ export async function getExtensionApi(): Promise<any> {
}
return extensionApi;
}

export function showExportJarReport(taskLabel: string, message: string) {
const terminals = window.terminals;
const presenterTerminals = terminals.filter((terminal) => terminal.name.indexOf(taskLabel) >= 0);
if (presenterTerminals.length > 0) {
presenterTerminals[presenterTerminals.length - 1].sendText(message);
}
}

export function revealTerminal(terminalName: string) {
const terminals = window.terminals;
const presenterTerminals = terminals.filter((terminal) => terminal.name.indexOf(terminalName) >= 0);
if (presenterTerminals.length > 0) {
presenterTerminals[presenterTerminals.length - 1].show();
}
}
7 changes: 3 additions & 4 deletions src/java/jdtls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { CancellationToken, commands } from "vscode";
import { Commands, executeJavaLanguageServerCommand } from "../commands";
import { IExportResult } from "../exportJarSteps/GenerateJarExecutor";
import { IClasspath } from "../exportJarSteps/IStepMetadata";
import { IMainClassInfo } from "../exportJarSteps/ResolveMainClassExecutor";
import { INodeData } from "./nodeData";
Expand All @@ -17,7 +16,7 @@ export namespace Jdtls {
return commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_REFRESH_LIB_SERVER, params);
}

export async function getPackageData(params: {[key: string]: any}): Promise<INodeData[]> {
export async function getPackageData(params: { [key: string]: any }): Promise<INodeData[]> {
return await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_GETPACKAGEDATA, params) || [];
}

Expand All @@ -30,9 +29,9 @@ export namespace Jdtls {
}

export async function exportJar(mainClass: string, classpaths: IClasspath[],
destination: string, token: CancellationToken): Promise<IExportResult | undefined> {
destination: string, taskLabel: string, token: CancellationToken): Promise<boolean | undefined> {
return commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_GENERATEJAR,
mainClass, classpaths, destination, token);
mainClass, classpaths, destination, taskLabel, token);
}

export enum CompileWorkspaceStatus {
Expand Down
4 changes: 4 additions & 0 deletions src/views/dependencyDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { contextManager } from "../../extension.bundle";
import { Commands } from "../commands";
import { Context } from "../constants";
import { executeExportJarTask } from "../exportJarSteps/ExportJarTaskProvider";
import { showExportJarReport } from "../exportJarSteps/utility";
import { Jdtls } from "../java/jdtls";
import { INodeData, NodeKind } from "../java/nodeData";
import { languageServerApiManager } from "../languageServerApi/languageServerApiManager";
Expand All @@ -35,6 +36,9 @@ export class DependencyDataProvider implements TreeDataProvider<ExplorerNode> {
constructor(public readonly context: ExtensionContext) {
context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_REFRESH, (debounce?: boolean, element?: ExplorerNode) =>
this.refreshWithLog(debounce, element)));
context.subscriptions.push(commands.registerCommand(Commands.EXPORT_JAR_REPORT, (taskLabel: string, message: string) => {
showExportJarReport(taskLabel, message);
}));
context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_EXPORT_JAR, async (node: INodeData) => {
executeExportJarTask(node);
}));
Expand Down