Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
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
89 changes: 89 additions & 0 deletions che-theia-java-extension/src/browser/action/mark-dir-as-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which is available at http://www.eclipse.org/legal/epl-2.0.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/

import { inject, injectable } from "inversify";
import { ClasspathContainer, ClasspathEntry, ClasspathEntryKind } from "../classpath/classpath-container";
import { CommandContribution, MenuContribution, SelectionService, CommandRegistry, MenuModelRegistry, Command } from "@theia/core";
import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler";
import URI from "@theia/core/lib/common/uri";
import { NAVIGATOR_CONTEXT_MENU } from "@theia/navigator/lib/browser/navigator-contribution";
import { CompositeTreeNode, WidgetManager } from "@theia/core/lib/browser";
import { WorkspaceService } from "@theia/workspace/lib/browser";
import { FileNavigatorWidget, FILE_NAVIGATOR_ID } from "@theia/navigator/lib/browser/navigator-widget";
import { JavaUtils } from "../java-utils";
import { SourceView } from "../classpath/pages/source/source-view";


export const MARKSOURCEDIR = [...NAVIGATOR_CONTEXT_MENU, '7_sourcedir'];


export namespace JavaCommands {
export const MARKSOURCEDIR: Command = {
id: 'java:mark-source-dir',
label: 'Mark Dir as Source'
};
}

@injectable()
export class MarkDirAsSourceAction implements CommandContribution, MenuContribution {

constructor(@inject(ClasspathContainer) protected readonly classpathContainer: ClasspathContainer,
@inject(SelectionService) protected readonly selectionService: SelectionService,
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService,
@inject(SourceView) protected readonly sourceView: SourceView) {
}

async performAction(projectURI: string, treeNodeID: string) {
const classpathItems = await this.classpathContainer.getClassPathEntries(projectURI);
const newClasspathItem = {
children: [],
entryKind: ClasspathEntryKind.SOURCE,
path: JavaUtils.getIDFromMultiRootID(treeNodeID)
} as ClasspathEntry
classpathItems.push(newClasspathItem);
this.classpathContainer.resolveClasspathEntries(classpathItems);
this.classpathContainer.updateClasspath(projectURI);
this.sourceView.classpathModel.addClasspathNodes(newClasspathItem);
}

registerCommands(commands: CommandRegistry): void {
commands.registerCommand(JavaCommands.MARKSOURCEDIR, this.newUriAwareCommandHandler({
execute: async fileUri => {
const fileWidget = await this.widgetManager.tryGetWidget(FILE_NAVIGATOR_ID) as FileNavigatorWidget;
if (fileWidget) {

const roots = await this.workspaceService.roots;
const root = JavaUtils.getRootProjectURI(roots, fileUri.toString());
if (roots && root) {
const multiRootURI = JavaUtils.getMultiRootReadyURI(root, fileUri.toString());
const treeNode = fileWidget.model.getNode(multiRootURI);
if (treeNode && CompositeTreeNode.is(treeNode)) {
this.performAction(root, treeNode.id);
}
}
}

}
}));
}

registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(MARKSOURCEDIR, {
commandId: JavaCommands.MARKSOURCEDIR.id
});
}

protected newUriAwareCommandHandler(handler: UriCommandHandler<URI>): UriAwareCommandHandler<URI> {
return new UriAwareCommandHandler(this.selectionService, handler);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which is available at http://www.eclipse.org/legal/epl-2.0.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/

import { inject, injectable } from "inversify";
import { ClasspathContainer } from "../classpath/classpath-container";
import { CommandContribution, MenuContribution, SelectionService, CommandRegistry, MenuModelRegistry, Command } from "@theia/core";
import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler";
import URI from "@theia/core/lib/common/uri";
import { CompositeTreeNode, WidgetManager } from "@theia/core/lib/browser";
import { WorkspaceService } from "@theia/workspace/lib/browser";
import { FileNavigatorWidget, FILE_NAVIGATOR_ID } from "@theia/navigator/lib/browser/navigator-widget";
import { JavaUtils } from "../java-utils";
import { MARKSOURCEDIR } from "./mark-dir-as-source";
import { SourceView } from "../classpath/pages/source/source-view";

export const UNMARKSOURCEDIR: Command = {
id: 'java:unmark-source-dir',
label: 'Unmark Dir as Source'
};

@injectable()
export class UnmarkDirAsSourceAction implements CommandContribution, MenuContribution {

constructor(@inject(ClasspathContainer) protected readonly classpathContainer: ClasspathContainer,
@inject(SelectionService) protected readonly selectionService: SelectionService,
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService,
@inject(SourceView) protected readonly sourceView: SourceView
) {
}

async performAction(projectURI: string, treeNodeID: string) {
const classpathItems = await this.classpathContainer.getClassPathEntries(projectURI);
this.classpathContainer.clearClasspathEntries();
const realID = JavaUtils.getIDFromMultiRootID(treeNodeID);
const filteredClasspathItems = classpathItems.filter(item => item.path !== realID);
this.classpathContainer.resolveClasspathEntries(filteredClasspathItems);
this.classpathContainer.updateClasspath(projectURI);
this.sourceView.classpathModel.removeClasspathNode(realID);
}

registerCommands(commands: CommandRegistry): void {
commands.registerCommand(UNMARKSOURCEDIR, this.newUriAwareCommandHandler({
execute: async fileUri => {
const fileWidget = await this.widgetManager.tryGetWidget(FILE_NAVIGATOR_ID) as FileNavigatorWidget;
if (fileWidget) {
const roots = await this.workspaceService.roots;
const root = JavaUtils.getRootProjectURI(roots, fileUri.toString());
if (roots && root) {
const multiRootURI = JavaUtils.getMultiRootReadyURI(root, fileUri.toString());
const treeNode = fileWidget.model.getNode(multiRootURI);
if (treeNode && CompositeTreeNode.is(treeNode)) {
this.performAction(root, treeNode.id);
}
}
}
}
}));
}

registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(MARKSOURCEDIR, {
commandId: UNMARKSOURCEDIR.id
});
}

protected newUriAwareCommandHandler(handler: UriCommandHandler<URI>): UriAwareCommandHandler<URI> {
return new UriAwareCommandHandler(this.selectionService, handler);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,42 @@
* Red Hat, Inc. - initial API and implementation
*/

import { injectable } from 'inversify';
import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry } from '@theia/core/lib/common';
import { KeybindingContribution, KeybindingRegistry } from '@theia/core/lib/browser';
import { injectable, inject } from "inversify";
import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry, MAIN_MENU_BAR, Command } from "@theia/core/lib/common";
import { KeybindingContribution, KeybindingRegistry, WidgetManager } from "@theia/core/lib/browser";
import { ClassPathDialog } from "./classpath/classpath-dialog";
import { WorkspaceService } from "@theia/workspace/lib/browser";

export const HELP = [...MAIN_MENU_BAR, '5_classpath'];

export const CONFIGURE_CLASSPATH_COMMAND: Command = {
id: 'java.configure.classpath',
label: 'Configure Classpath'
};

@injectable()
export class JavaExtensionContribution implements CommandContribution, MenuContribution, KeybindingContribution {

constructor(
@inject(ClassPathDialog) protected readonly aboutDialog: ClassPathDialog,
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService) {
}

registerCommands(registry: CommandRegistry): void {
registry.registerCommand(CONFIGURE_CLASSPATH_COMMAND, {
execute: e => {
this.aboutDialog.open();
}
});
}

registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(HELP, {
commandId: CONFIGURE_CLASSPATH_COMMAND.id,
label: CONFIGURE_CLASSPATH_COMMAND.label,
order: '10'
});
}

registerKeybindings(keybindings: KeybindingRegistry): void {
Expand Down
146 changes: 143 additions & 3 deletions che-theia-java-extension/src/browser/che-theia-java-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,28 @@ import {
ResourceResolver
} from "@theia/core/lib/common";

import { ContainerModule } from 'inversify';
import { KeybindingContribution, KeybindingContext, WidgetFactory} from '@theia/core/lib/browser';
import { ContainerModule, Container, interfaces } from "inversify";
import { KeybindingContribution, KeybindingContext, WidgetFactory, TreeProps, createTreeContainer,
defaultTreeProps, TreeWidget, TreeModelImpl, TreeModel } from '@theia/core/lib/browser';

import '../../src/browser/styles/icons.css';
import "../../src/browser/styles/icons.css";
import "../../src/browser/styles/classpath.css";
import { FileStructure } from './navigation/file-structure';
import { JavaEditorTextFocusContext } from './java-keybinding-contexts';
import { BuildPathTreeWidget, BuildPathTreeWidgetID } from './classpath/build-path-widget';
import { ClassPathDialog, DialogProps } from './classpath/classpath-dialog';
import { ClasspathContainer } from './classpath/classpath-container';
import { SourceModel } from './classpath/pages/source/source-model';
import { LibraryModel } from './classpath/pages/library/library-model';
import { ClasspathDecorator } from './classpath/classpath-tree-decorator';
import { MarkDirAsSourceAction } from './action/mark-dir-as-source';
import { UnmarkDirAsSourceAction } from './action/unmark-dir-as-source';
import { NavigatorTreeDecorator } from '@theia/navigator/lib/browser/navigator-decorator-service';
import { LibraryView, LibraryViewID } from './classpath/pages/library/library-view';
import { SourceView, SourceViewID } from './classpath/pages/source/source-view';
import { IClasspathNode } from './classpath/nodes/classpath-node';
import { LibraryNode } from './classpath/nodes/library-node';
import { SourceNode } from './classpath/nodes/source-node';

import { ExternalLibrariesWidget, EXTERNAL_LIBRARIES_ID } from './libraries/external-libraries-widget';
import { createExternalLibrariesWidget } from './libraries/external-libraries-container';
Expand Down Expand Up @@ -64,4 +80,128 @@ export default new ContainerModule((bind, unbind, isBound) => {
id: EXTERNAL_LIBRARIES_ID,
createWidget: () => context.container.get<ExternalLibrariesWidget>(ExternalLibrariesWidget)
}));

/**
* Classpath configuration
*/
bind(MarkDirAsSourceAction).toSelf().inSingletonScope();
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(MarkDirAsSourceAction));
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(MarkDirAsSourceAction));

bind(UnmarkDirAsSourceAction).toSelf().inSingletonScope();
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(UnmarkDirAsSourceAction));
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(UnmarkDirAsSourceAction));

bind(ClassPathDialog).toSelf().inSingletonScope();
bind(DialogProps).toConstantValue({ title: 'Configure Classpath' });

bind(ClasspathContainer).toSelf().inSingletonScope();

bind(IClasspathNode).to(LibraryNode).inSingletonScope();
bind(IClasspathNode).to(SourceNode).inSingletonScope();

/**
* Build path tree widget
*/
bind(BuildPathTreeWidget).toDynamicValue(ctx =>
createBuildPathTreeWidget(ctx.container)
).inSingletonScope();

bind(WidgetFactory).toDynamicValue(context => ({
id: BuildPathTreeWidgetID,
createWidget: () => context.container.get<BuildPathTreeWidget>(BuildPathTreeWidget)
}));

/**
* Library View widget
*/
bind(LibraryView).toDynamicValue(ctx =>
createLibraryViewTreeWidget(ctx.container)
).inSingletonScope();

bind(WidgetFactory).toDynamicValue(context => ({
id: LibraryViewID,
createWidget: () => context.container.get<LibraryView>(LibraryView)
}));

/**
* Source View widget
*/
bind(SourceView).toDynamicValue(ctx =>
createSourceViewTreeWidget(ctx.container)
).inSingletonScope();

bind(WidgetFactory).toDynamicValue(context => ({
id: SourceViewID,
createWidget: () => context.container.get<SourceView>(SourceView)
}));

bind(ClasspathDecorator).toSelf().inSingletonScope();
bind(NavigatorTreeDecorator).toService(ClasspathDecorator);

});

export const PROPS_PROPS = <TreeProps>{
...defaultTreeProps,
contextMenuPath: ["NAVIGATOR_CONTEXT_MENU"],
multiSelect: false
};

export function createBuildPathTreeWidgetContainer(parent: interfaces.Container): Container {
const child = createTreeContainer(parent);

child.rebind(TreeProps).toConstantValue(PROPS_PROPS);

child.unbind(TreeWidget);
child.bind(BuildPathTreeWidget).toSelf();

return child;
}

export function createBuildPathTreeWidget(parent: interfaces.Container): BuildPathTreeWidget {
return createBuildPathTreeWidgetContainer(parent).get(BuildPathTreeWidget);
}

/**
* Library view
*/
export function createLibraryViewTreeWidgetContainer(parent: interfaces.Container): Container {
const child = createTreeContainer(parent);

child.rebind(TreeProps).toConstantValue(PROPS_PROPS);

child.unbind(TreeModelImpl);
child.bind(LibraryModel).toSelf();
child.rebind(TreeModel).toDynamicValue(ctx => ctx.container.get(LibraryModel));

child.unbind(TreeWidget);
child.bind(LibraryView).toSelf();

return child;
}

export function createLibraryViewTreeWidget(parent: interfaces.Container): LibraryView {
return createLibraryViewTreeWidgetContainer(parent).get(LibraryView);
}

/**
* Source view
*/
export function createSourceViewTreeWidgetContainer(parent: interfaces.Container): Container {
const child = createTreeContainer(parent);

child.rebind(TreeProps).toConstantValue(PROPS_PROPS);

child.unbind(TreeModelImpl);
child.bind(SourceModel).toSelf();
child.rebind(TreeModel).toDynamicValue(ctx => ctx.container.get(SourceModel));

child.unbind(TreeWidget);
child.bind(SourceView).toSelf();

return child;
}

export function createSourceViewTreeWidget(parent: interfaces.Container): SourceView {
return createSourceViewTreeWidgetContainer(parent).get(SourceView);
}
Loading