Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit aef7b72

Browse files
committed
Added classpath
Signed-off-by: jpinkney <[email protected]>
1 parent 70c7ee9 commit aef7b72

25 files changed

+1605
-14
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2012-2018 Red Hat, Inc.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which is available at http://www.eclipse.org/legal/epl-2.0.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
13+
import { inject, injectable } from "inversify";
14+
import { ClasspathContainer, ClasspathEntry, ClasspathEntryKind } from "../classpath/classpath-container";
15+
import { CommandContribution, MenuContribution, SelectionService, CommandRegistry, MenuModelRegistry, Command } from "@theia/core";
16+
import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler";
17+
import URI from "@theia/core/lib/common/uri";
18+
import { NAVIGATOR_CONTEXT_MENU } from "@theia/navigator/lib/browser/navigator-contribution";
19+
import { CompositeTreeNode, WidgetManager } from "@theia/core/lib/browser";
20+
import { WorkspaceService } from "@theia/workspace/lib/browser";
21+
import { FileNavigatorWidget, FILE_NAVIGATOR_ID } from "@theia/navigator/lib/browser/navigator-widget";
22+
import { JavaUtils } from "../java-utils";
23+
import { SourceView } from "../classpath/pages/source/source-view";
24+
25+
26+
export const MARKSOURCEDIR = [...NAVIGATOR_CONTEXT_MENU, '7_sourcedir'];
27+
28+
29+
export namespace JavaCommands {
30+
export const MARKSOURCEDIR: Command = {
31+
id: 'java:mark-source-dir',
32+
label: 'Mark Dir as Source'
33+
};
34+
}
35+
36+
@injectable()
37+
export class MarkDirAsSourceAction implements CommandContribution, MenuContribution {
38+
39+
constructor(@inject(ClasspathContainer) protected readonly classpathContainer: ClasspathContainer,
40+
@inject(SelectionService) protected readonly selectionService: SelectionService,
41+
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
42+
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService,
43+
@inject(SourceView) protected readonly sourceView: SourceView) {
44+
}
45+
46+
async performAction(projectURI: string, treeNodeID: string) {
47+
const classpathItems = await this.classpathContainer.getClassPathEntries(projectURI);
48+
const newClasspathItem = {
49+
children: [],
50+
entryKind: ClasspathEntryKind.SOURCE,
51+
path: JavaUtils.getIDFromMultiRootID(treeNodeID)
52+
} as ClasspathEntry
53+
classpathItems.push(newClasspathItem);
54+
this.classpathContainer.resolveClasspathEntries(classpathItems);
55+
this.classpathContainer.updateClasspath(projectURI);
56+
this.sourceView.classpathModel.addClasspathNodes(newClasspathItem);
57+
}
58+
59+
registerCommands(commands: CommandRegistry): void {
60+
commands.registerCommand(JavaCommands.MARKSOURCEDIR, this.newUriAwareCommandHandler({
61+
execute: async fileUri => {
62+
const fileWidget = await this.widgetManager.tryGetWidget(FILE_NAVIGATOR_ID) as FileNavigatorWidget;
63+
if (fileWidget) {
64+
65+
const roots = await this.workspaceService.roots;
66+
const root = JavaUtils.getRootProjectURI(roots, fileUri.toString());
67+
if (roots && root) {
68+
const multiRootURI = JavaUtils.getMultiRootReadyURI(root, fileUri.toString());
69+
const treeNode = fileWidget.model.getNode(multiRootURI);
70+
if (treeNode && CompositeTreeNode.is(treeNode)) {
71+
this.performAction(root, treeNode.id);
72+
}
73+
}
74+
}
75+
76+
}
77+
}));
78+
}
79+
80+
registerMenus(menus: MenuModelRegistry): void {
81+
menus.registerMenuAction(MARKSOURCEDIR, {
82+
commandId: JavaCommands.MARKSOURCEDIR.id
83+
});
84+
}
85+
86+
protected newUriAwareCommandHandler(handler: UriCommandHandler<URI>): UriAwareCommandHandler<URI> {
87+
return new UriAwareCommandHandler(this.selectionService, handler);
88+
}
89+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2012-2018 Red Hat, Inc.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which is available at http://www.eclipse.org/legal/epl-2.0.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
13+
import { inject, injectable } from "inversify";
14+
import { ClasspathContainer } from "../classpath/classpath-container";
15+
import { CommandContribution, MenuContribution, SelectionService, CommandRegistry, MenuModelRegistry, Command } from "@theia/core";
16+
import { UriAwareCommandHandler, UriCommandHandler } from "@theia/core/lib/common/uri-command-handler";
17+
import URI from "@theia/core/lib/common/uri";
18+
import { CompositeTreeNode, WidgetManager } from "@theia/core/lib/browser";
19+
import { WorkspaceService } from "@theia/workspace/lib/browser";
20+
import { FileNavigatorWidget, FILE_NAVIGATOR_ID } from "@theia/navigator/lib/browser/navigator-widget";
21+
import { JavaUtils } from "../java-utils";
22+
import { MARKSOURCEDIR } from "./mark-dir-as-source";
23+
import { SourceView } from "../classpath/pages/source/source-view";
24+
25+
export const UNMARKSOURCEDIR: Command = {
26+
id: 'java:unmark-source-dir',
27+
label: 'Unmark Dir as Source'
28+
};
29+
30+
@injectable()
31+
export class UnmarkDirAsSourceAction implements CommandContribution, MenuContribution {
32+
33+
constructor(@inject(ClasspathContainer) protected readonly classpathContainer: ClasspathContainer,
34+
@inject(SelectionService) protected readonly selectionService: SelectionService,
35+
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
36+
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService,
37+
@inject(SourceView) protected readonly sourceView: SourceView
38+
) {
39+
}
40+
41+
async performAction(projectURI: string, treeNodeID: string) {
42+
const classpathItems = await this.classpathContainer.getClassPathEntries(projectURI);
43+
this.classpathContainer.clearClasspathEntries();
44+
const realID = JavaUtils.getIDFromMultiRootID(treeNodeID);
45+
const filteredClasspathItems = classpathItems.filter(item => item.path !== realID);
46+
this.classpathContainer.resolveClasspathEntries(filteredClasspathItems);
47+
this.classpathContainer.updateClasspath(projectURI);
48+
this.sourceView.classpathModel.removeClasspathNode(realID);
49+
}
50+
51+
registerCommands(commands: CommandRegistry): void {
52+
commands.registerCommand(UNMARKSOURCEDIR, this.newUriAwareCommandHandler({
53+
execute: async fileUri => {
54+
const fileWidget = await this.widgetManager.tryGetWidget(FILE_NAVIGATOR_ID) as FileNavigatorWidget;
55+
if (fileWidget) {
56+
57+
const roots = await this.workspaceService.roots;
58+
const root = JavaUtils.getRootProjectURI(roots, fileUri.toString());
59+
if (roots && root) {
60+
const multiRootURI = JavaUtils.getMultiRootReadyURI(root, fileUri.toString());
61+
const treeNode = fileWidget.model.getNode(multiRootURI);
62+
if (treeNode && CompositeTreeNode.is(treeNode)) {
63+
this.performAction(root, treeNode.id);
64+
}
65+
}
66+
}
67+
68+
}
69+
}));
70+
}
71+
72+
registerMenus(menus: MenuModelRegistry): void {
73+
menus.registerMenuAction(MARKSOURCEDIR, {
74+
commandId: UNMARKSOURCEDIR.id
75+
});
76+
}
77+
78+
protected newUriAwareCommandHandler(handler: UriCommandHandler<URI>): UriAwareCommandHandler<URI> {
79+
return new UriAwareCommandHandler(this.selectionService, handler);
80+
}
81+
}

che-theia-java-extension/src/browser/che-theia-java-contribution.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,42 @@
1010
* Red Hat, Inc. - initial API and implementation
1111
*/
1212

13-
import { injectable } from 'inversify';
14-
import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry } from '@theia/core/lib/common';
15-
import { KeybindingContribution, KeybindingRegistry } from '@theia/core/lib/browser';
13+
import { injectable, inject } from "inversify";
14+
import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry, MAIN_MENU_BAR, Command } from "@theia/core/lib/common";
15+
import { KeybindingContribution, KeybindingRegistry, WidgetManager } from "@theia/core/lib/browser";
16+
import { ClassPathDialog } from "./classpath/classpath-dialog";
17+
import { WorkspaceService } from "@theia/workspace/lib/browser";
18+
19+
export const HELP = [...MAIN_MENU_BAR, '5_classpath'];
20+
21+
export const CONFIGURE_CLASSPATH_COMMAND: Command = {
22+
id: 'java.configure.classpath',
23+
label: 'Configure Classpath'
24+
};
1625

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

29+
constructor(
30+
@inject(ClassPathDialog) protected readonly aboutDialog: ClassPathDialog,
31+
@inject(WidgetManager) protected readonly widgetManager: WidgetManager,
32+
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService) {
33+
}
34+
2035
registerCommands(registry: CommandRegistry): void {
36+
registry.registerCommand(CONFIGURE_CLASSPATH_COMMAND, {
37+
execute: e => {
38+
this.aboutDialog.open();
39+
}
40+
});
2141
}
2242

2343
registerMenus(menus: MenuModelRegistry): void {
44+
menus.registerMenuAction(HELP, {
45+
commandId: CONFIGURE_CLASSPATH_COMMAND.id,
46+
label: CONFIGURE_CLASSPATH_COMMAND.label,
47+
order: '10'
48+
});
2449
}
2550

2651
registerKeybindings(keybindings: KeybindingRegistry): void {

che-theia-java-extension/src/browser/che-theia-java-frontend-module.ts

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,28 @@ import {
1616
MenuContribution
1717
} from "@theia/core/lib/common";
1818

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

22-
import '../../src/browser/styles/icons.css';
22+
import "../../src/browser/styles/icons.css";
23+
import "../../src/browser/styles/classpath.css";
2324
import { FileStructure } from './navigation/file-structure';
2425
import { FindImplementers } from './navigation/find-implementers';
2526
import { JavaEditorTextFocusContext } from './java-keybinding-contexts';
27+
import { BuildPathTreeWidget, BuildPathTreeWidgetID } from './classpath/build-path-widget';
28+
import { ClassPathDialog, DialogProps } from './classpath/classpath-dialog';
29+
import { ClasspathContainer } from './classpath/classpath-container';
30+
import { SourceModel } from './classpath/pages/source/source-model';
31+
import { LibraryModel } from './classpath/pages/library/library-model';
32+
import { ClasspathDecorator } from './classpath/classpath-tree-decorator';
33+
import { MarkDirAsSourceAction } from './action/mark-dir-as-source';
34+
import { UnmarkDirAsSourceAction } from './action/unmark-dir-as-source';
35+
import { NavigatorTreeDecorator } from '@theia/navigator/lib/browser/navigator-decorator-service';
36+
import { LibraryView, LibraryViewID } from './classpath/pages/library/library-view';
37+
import { SourceView, SourceViewID } from './classpath/pages/source/source-view';
38+
import { IClasspathNode } from './classpath/nodes/classpath-node';
39+
import { LibraryNode } from './classpath/nodes/library-node';
40+
import { SourceNode } from './classpath/nodes/source-node';
2641

2742
export default new ContainerModule((bind) => {
2843

@@ -42,4 +57,127 @@ export default new ContainerModule((bind) => {
4257

4358
bind(KeybindingContext).to(JavaEditorTextFocusContext).inSingletonScope();
4459

60+
/**
61+
* Classpath configuration
62+
*/
63+
bind(MarkDirAsSourceAction).toSelf().inSingletonScope();
64+
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(MarkDirAsSourceAction));
65+
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(MarkDirAsSourceAction));
66+
67+
bind(UnmarkDirAsSourceAction).toSelf().inSingletonScope();
68+
bind(CommandContribution).toDynamicValue(ctx => ctx.container.get(UnmarkDirAsSourceAction));
69+
bind(MenuContribution).toDynamicValue(ctx => ctx.container.get(UnmarkDirAsSourceAction));
70+
71+
bind(ClassPathDialog).toSelf().inSingletonScope();
72+
bind(DialogProps).toConstantValue({ title: 'Configure Classpath' });
73+
74+
bind(ClasspathContainer).toSelf().inSingletonScope();
75+
76+
bind(IClasspathNode).to(LibraryNode).inSingletonScope();
77+
bind(IClasspathNode).to(SourceNode).inSingletonScope();
78+
79+
/**
80+
* Build path tree widget
81+
*/
82+
bind(BuildPathTreeWidget).toDynamicValue(ctx =>
83+
createBuildPathTreeWidget(ctx.container)
84+
).inSingletonScope();
85+
86+
bind(WidgetFactory).toDynamicValue(context => ({
87+
id: BuildPathTreeWidgetID,
88+
createWidget: () => context.container.get<BuildPathTreeWidget>(BuildPathTreeWidget)
89+
}));
90+
91+
/**
92+
* Library View widget
93+
*/
94+
bind(LibraryView).toDynamicValue(ctx =>
95+
createLibraryViewTreeWidget(ctx.container)
96+
).inSingletonScope();
97+
98+
bind(WidgetFactory).toDynamicValue(context => ({
99+
id: LibraryViewID,
100+
createWidget: () => context.container.get<LibraryView>(LibraryView)
101+
}));
102+
103+
/**
104+
* Source View widget
105+
*/
106+
bind(SourceView).toDynamicValue(ctx =>
107+
createSourceViewTreeWidget(ctx.container)
108+
).inSingletonScope();
109+
110+
bind(WidgetFactory).toDynamicValue(context => ({
111+
id: SourceViewID,
112+
createWidget: () => context.container.get<SourceView>(SourceView)
113+
}));
114+
115+
bind(ClasspathDecorator).toSelf().inSingletonScope();
116+
bind(NavigatorTreeDecorator).toService(ClasspathDecorator);
117+
45118
});
119+
120+
export const PROPS_PROPS = <TreeProps>{
121+
...defaultTreeProps,
122+
contextMenuPath: ["NAVIGATOR_CONTEXT_MENU"],
123+
multiSelect: false
124+
};
125+
126+
export function createBuildPathTreeWidgetContainer(parent: interfaces.Container): Container {
127+
const child = createTreeContainer(parent);
128+
129+
child.rebind(TreeProps).toConstantValue(PROPS_PROPS);
130+
131+
child.unbind(TreeWidget);
132+
child.bind(BuildPathTreeWidget).toSelf();
133+
134+
return child;
135+
}
136+
137+
export function createBuildPathTreeWidget(parent: interfaces.Container): BuildPathTreeWidget {
138+
return createBuildPathTreeWidgetContainer(parent).get(BuildPathTreeWidget);
139+
}
140+
141+
/**
142+
* Library view
143+
*/
144+
export function createLibraryViewTreeWidgetContainer(parent: interfaces.Container): Container {
145+
const child = createTreeContainer(parent);
146+
147+
child.rebind(TreeProps).toConstantValue(PROPS_PROPS);
148+
149+
child.unbind(TreeModelImpl);
150+
child.bind(LibraryModel).toSelf();
151+
child.rebind(TreeModel).toDynamicValue(ctx => ctx.container.get(LibraryModel));
152+
153+
child.unbind(TreeWidget);
154+
child.bind(LibraryView).toSelf();
155+
156+
return child;
157+
}
158+
159+
export function createLibraryViewTreeWidget(parent: interfaces.Container): LibraryView {
160+
return createLibraryViewTreeWidgetContainer(parent).get(LibraryView);
161+
}
162+
163+
/**
164+
* Source view
165+
*/
166+
export function createSourceViewTreeWidgetContainer(parent: interfaces.Container): Container {
167+
const child = createTreeContainer(parent);
168+
169+
child.rebind(TreeProps).toConstantValue(PROPS_PROPS);
170+
171+
child.unbind(TreeModelImpl);
172+
child.bind(SourceModel).toSelf();
173+
child.rebind(TreeModel).toDynamicValue(ctx => ctx.container.get(SourceModel));
174+
175+
child.unbind(TreeWidget);
176+
child.bind(SourceView).toSelf();
177+
178+
return child;
179+
}
180+
181+
export function createSourceViewTreeWidget(parent: interfaces.Container): SourceView {
182+
return createSourceViewTreeWidgetContainer(parent).get(SourceView);
183+
}

0 commit comments

Comments
 (0)