Skip to content

Commit b5c6359

Browse files
authored
Merge pull request #167 from oracle/sqldev-worksheet-action
New SQL Developer Extension Example: WorksheetActions
2 parents 5619125 + ff70067 commit b5c6359

17 files changed

+852
-2
lines changed

sqldeveloper/extension/.classpath

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
33
<classpathentry kind="src" output="java/DependencyExample/built/classes" path="java/DependencyExample/built/gen-src"/>
4+
<classpathentry kind="src" path="java/WorksheetAction/src"/>
5+
<classpathentry kind="src" path="java/WorksheetAction/built/gen-src"/>
46
<classpathentry kind="src" path="java/ConnectionHelper/built/gen-src"/>
57
<classpathentry kind="src" path="java/InsertTemplateAction/built/gen-src"/>
68
<classpathentry kind="src" path="java/InsertTemplateAction/src"/>

sqldeveloper/extension/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Depending on requirements, this can be done in either XML or java and deployed b
66

77
### New
88

9+
* [WorksheetAction](java/WorksheetAction)
10+
How to add actions to the worksheet context menu and / or toolbar; execute the action directly or in a background task; and present advanced / detailed information in a result panel.
11+
912
* [Managing Extensions](./ManagingExtensions.md) - ([Issue 113](https://github.com/oracle/oracle-db-examples/issues/113)) How to add, disable, and remove extensions.
1013

1114
* [ConnectionHelper](java/ConnectionHelper)
@@ -14,8 +17,6 @@ Optionally accept connection info from the command line and/or on a [SocketServe
1417
* [ConnectionHelperClient](java/ConnectionHelperClient)
1518
A simple command line client for the ConnectionHelper socket server.
1619

17-
* Added resource reference for Philipp Salvisberg's [Example-based tutorials](https://github.com/PhilippSalvisberg/sqldev) to extend SQL Developer functionality. (external)
18-
1920

2021
### Contents
2122

sqldeveloper/extension/buildtools/ant/classpaths.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ limitations under the License.
119119
<pathelement location="${sqldev.extensions}/oracle.sqldeveloper.utils.jar" />
120120
</path>
121121

122+
<!-- osgi.bundle.worksheet -->
123+
<property name="osgi.bundle.worksheet" value="oracle.sqldeveloper.worksheet" />
124+
<path id="oracle.sqldeveloper.worksheet">
125+
<pathelement location="${sqldev.extensions}/oracle.sqldeveloper.worksheet.jar" />
126+
</path>
127+
122128
<!-- osgi.bundle.jfxrt -->
123129
<property name="osgi.bundle.jfxrt" value="oracle.external.jfxrt" />
124130
<path id="javafx.runtime" description="Java FX runtime library">

sqldeveloper/extension/java/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ Optionally accept connection info from the command line and/or on a [SocketServe
2525

2626
* [ConnectionHelperClient](ConnectionHelperClient)
2727
A simple command line client for the ConnectionHelper socket server.
28+
29+
* [WorksheetAction](WorksheetAction)
30+
How to add actions to the worksheet context menu and / or toolbar; execute the action directly or in a background task; and present advanced / detailed information in a result panel.

sqldeveloper/extension/java/SQLDeveloper.userlibraries

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/extensions/oracle.sqldeveloper.jar"/>
2828
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/extensions/oracle.sqldeveloper.extras.jar"/>
2929
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/extensions/oracle.sqldeveloper.utils.jar"/>
30+
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/extensions/oracle.sqldeveloper.worksheet.jar"/>
3031
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/lib/dbtools-common.jar"/>
3132
<archive path="/Users/bjeffrie/eclipse-workspace-20.1/sql-developer/ide/sqldeveloper/lib/oracle.sqldeveloper.jfx-nodeps.jar"/>
3233
</library>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# SQL Developer Examples
2+
## Worksheet Action
3+
4+
Example extension showing how to add actions to the worksheet context menu and / or toolbar; execute the action directly or in a background task; and present information in a result panel.
5+
6+
7+
### Build it
8+
[Set up your environment](../../setup.md). If using the eclipse project, also modify paths in *SQLDeveloper.userlibraries* and import into eclipse. (This example was built using the "SQLDeveloper 20.1" Library)
9+
* Build and install using those instructions
10+
11+
### Try it
12+
13+
![WorksheetActionEnable image](images/WorksheetActionEnable.png)
14+
#### First time (Use the trigger to fully load the extension)
15+
* Open a worksheet
16+
* Select "Trigger/Load WorksheetAction Extension" from the context menu
17+
* Close the worksheet
18+
* Only have to do that the 1st time as extension.xml says to reload once loaded
19+
* Typically this would be part of a larger extension with natural triggers IMHO & not need this hack.
20+
21+
![WorksheetActionWorking image](images/WorksheetActionWorking.png)
22+
23+
#### Then (Extension loaded, now what?)
24+
* Open a worksheet
25+
* Positioning
26+
* * Toolbar: Has entries for BOTH (blue bug) and TOOLBAR_ONLY (yellow bug)
27+
* * Context menu: Has entries for BOTH (blue bug) and CONTEXT_MENU_ONLY (purple bug)
28+
* Enabling:
29+
* * BOTH - Enabled unless the worksheet connection is disconnected
30+
* * CONTEXT_MENU_ONLY - Always enabled
31+
* * TOOLBAR_ONLY - Enabled only when there is text in the editor
32+
* Running (*Open the task progress viewer* (View->Task Progress) *to see the task messages which do not show on the toolbar task viwer.*)
33+
* * The [ExampleActionTask](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleActionTask.java) sets up a ten second loop to demonstrate setting progress / status as well as checking for cancel/pause
34+
* * Try pause / resume / cancel
35+
* * Try running twice without closing result window - note the 2nd one 'replaces' the original. Try pinning the result & running again - a second result window should be used.
36+
* * try running multiple ones at the same time. You should see them stacked in the task viewer waiting on each other running one at a time.
37+
38+
### Change it
39+
* Read the section on How it works & play.
40+
* * How does it work if one of them has a different "connectionName"? (not blocked from running by others with a different name)
41+
* * How about sending null for callback & id? (no result panel, worksheet not locked when the task runs)
42+
* * How about adding your own listener to do something?
43+
* * . . .
44+
45+
46+
### How it works
47+
[extension.xml](etc/extension.xml)
48+
* In the trigger-hooks/triggers section, declares a dummy trigger action (*WorksheetAction.DUMMY*), with [DummyActionController](src/oracle/db/example/sqldeveloper/extension/worksheetAction/DummyActionController.java) as controller, always enabled on the context menu of any editor to load the extension.
49+
* In the hooks/jdeveloper-hook section, declares the actions (*WorksheetAction.BOTH*, *WorksheetAction.CONTEXT_MENU_ONLY*, *WorksheetAction.TOOLBAR_ONLY*) we will be adding with this extension.
50+
* and finally, hooks/sqldev-worksheet-hook declares the [ExampleActionProvider](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleActionProvider.java) that defines the processing for and integrates those actions with the worksheet.
51+
52+
[DummyActionController](src/oracle/db/example/sqldeveloper/extension/worksheetAction/DummyActionController.java)
53+
* As its name implies, this is a controller that does nothing. It and the associated action exist in this extension only to provide a mechanism to demand load the extension in the absence of any natural trigger(s).
54+
55+
[ExampleActionProvider](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleActionProvider.java)
56+
This is the brains of the outfit, it
57+
* Declares contants for the actions ids (matching the ids declared in extension.xml)
58+
* ```getActionAt``` Creates a worksheet action for each id specifying menu(s), section, and weight for each
59+
* ```doAction``` Executes the processing for each id with the context passed in. In this case, all three use an [ExampleActionTask](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleActionTask.java)
60+
* * NOTE: *If the action is quick* (think e.g., format text) *and isn't something that requires a task in its own right* (e.g., anything that talks to the database), you can do / invokeLater the action here and return null.
61+
* * For tasks, wraps that up for the worksheet along with any listeners and / or viewers desired. For a viewer, we are getting the one from the worksheet context (which is the toolbar task viewer), For listeners, this example adds
62+
* * * ```getTaskListenerList``` - Log task listener events (INFO/SEVERE for exceptions) controlled by LOG_TASK_EVENTS
63+
* * * ```getTaskUIListenerList``` - Log task UI listener events (INFO) controlled by LOG_TASK_UI_EVENTS
64+
* * * (*Uncomment* oracle.level = INFO *in logging.conf to have them show in the log window*)
65+
* ```checkActionEnabled``` is set up with different criteria for each action
66+
* * *WorksheetAction.BOTH* - return (we have a connection)
67+
* * *WorksheetAction.CONTEXT_MENU_ONLY* - return true (always enabled)
68+
* * *WorksheetAction.TOOLBAR_ONLY* - return (editor has text)
69+
70+
[ExampleActionTask](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleActionTask.java) - a dummy task to show the basic mechanics plus how to attach a result panel to the worksheet. Sets up a ten second loop to demonstrate setting progress / status as well as checking for cancel/pause
71+
* Why DatabaseQueryTask or derivative?
72+
* * It serializes executions against a string (connectionName).
73+
* * If you are going to access the worksheet's (or any shared) connection, you MUST use a task to do so.
74+
* * This can also be used to serialize executions of your actions.
75+
* How to set up a result panel
76+
* How to lock the worksheet while processing
77+
* How to support pause / cancel
78+
79+
[ExampleResultPanel](src/oracle/db/example/sqldeveloper/extension/worksheetAction/ExampleResultPanel.java)- a really simple result panel just allowing text to be appended.
80+
81+
82+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
extension.id=oracle.db.example.sqldeveloper.extension.worksheetAction
2+
extension.name=Worksheet Action Example
3+
extension.descr=Example showing how to add actions to the worksheet context menu and/or toolbar
4+
extension.version=20.1.1
5+
extension.resources=oracle.db.example.sqldeveloper.extension.worksheetAction.ExtensionResources
6+
7+
extension.lib=external:$oracle.fcp.home$/sqldeveloper/extensions/${extension.id}/lib
8+
osgi.bundle.classpath=.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="windows-1252" ?>
2+
<project name="WorksheetAction" default="_deploy">
3+
<!-- imports -->
4+
<import file="../../buildtools/ant/build.xml" />
5+
6+
<!-- bundle dependencies -->
7+
<property name="osgi.required.bundles"
8+
value="${osgi.bundle.default.dependencies},${osgi.bundle.sqldev},${osgi.bundle.utils-nodeps},${osgi.bundle.utils},${osgi.bundle.worksheet}" />
9+
10+
<!-- classpath declarations -->
11+
<path id="local.classpath">
12+
<path refid="oracle.sqldeveloper.utils-nodeps"/>
13+
<path refid="oracle.sqldeveloper.utils"/>
14+
<path refid="oracle.sqldeveloper" />
15+
<path refid="oracle.sqldeveloper.worksheet" />
16+
</path>
17+
18+
<!-- local targets -->
19+
20+
<!-- target overrides -->
21+
<!-- Build structure from ../../buildtools/ant/build.xml < targets.xml -->
22+
23+
</project>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
<extension xmlns="http://jcp.org/jsr/198/extension-manifest"
19+
id="@@extension.id@@"
20+
version="@@extension.version@@.@@extension.build@@"
21+
esdk-version="1.0" rsbundle-class="@@extension.resources@@">
22+
23+
<name>@@extension.name@@</name>
24+
<owner>@@extension.owner@@ @@extension.owner.url@@</owner>
25+
26+
<feature id="@@extension.id@@"
27+
xmlns="http://xmlns.oracle.com/ide/extension">
28+
<name>@@extension.name@@</name>
29+
<description>@@extension.descr@@</description>
30+
<type>
31+
<service can-user-disable="true"
32+
reload-if-used="true" />
33+
</type>
34+
</feature>
35+
36+
<trigger-hooks
37+
xmlns="http://xmlns.oracle.com/ide/extension">
38+
<triggers
39+
xmlns:c="http://xmlns.oracle.com/ide/customization">
40+
<!-- Hack to add action to fully load the extension.
41+
Typically (IMHO) worksheet actions would be part of a larger extension
42+
with more natural triggers
43+
-->
44+
<actions
45+
xmlns="http://xmlns.oracle.com/jdeveloper/1013/extension">
46+
<action id="WorksheetAction.DUMMY">
47+
<properties>
48+
<property name="Name">${WORKSHEET_ACTION_DUMMY}
49+
</property>
50+
<!-- You could also use your own by putting path in rsbundle
51+
e.g., MY_ICON = /oracle/db/example/sqldeveloper/extension/dependency/icons/my_icon.png
52+
and referencing its key as res:${MY_ICON} -->
53+
<!-- <property name="SmallIcon">${OracleIcons.DUKE}</property> -->
54+
</properties>
55+
</action>
56+
</actions>
57+
<controllers
58+
xmlns="http://xmlns.oracle.com/ide/extension">
59+
<controller
60+
class="oracle.db.example.sqldeveloper.extension.worksheetAction.DummyActionController">
61+
<update-rules>
62+
<update-rule rule="always-enabled">
63+
<action id="WorksheetAction.DUMMY" />
64+
</update-rule>
65+
</update-rules>
66+
</controller>
67+
</controllers>
68+
<context-menu-hook rule="always-enabled">
69+
<site idref="editor" /> <!-- can do multiple e.g.;, "db_nav;editor" -->
70+
<menu>
71+
<section
72+
xmlns="http://jcp.org/jsr/198/extension-manifest"
73+
id="SECTION_WINDOW_CTXT_MENU" weight="1.0">
74+
<item action-ref="WorksheetAction.DUMMY"
75+
weight="1.0" />
76+
</section>
77+
</menu>
78+
</context-menu-hook>
79+
<!-- end of force load extension hack -->
80+
</triggers>
81+
</trigger-hooks>
82+
83+
<hooks>
84+
<jdeveloper-hook
85+
xmlns="http://xmlns.oracle.com/jdeveloper/1013/extension">
86+
<actions>
87+
<action id="WorksheetAction.BOTH">
88+
<properties>
89+
<property name="Name">${WORKSHEET_ACTION_BOTH}
90+
</property>
91+
<!-- You could also use your own by putting path in rsbundle
92+
e.g., MY_ICON = /oracle/db/example/sqldeveloper/extension/dependency/icons/my_icon.png
93+
and referencing its key as res:${MY_ICON} -->
94+
<property name="SmallIcon">${OracleIcons.DEBUG_BLUE}
95+
</property>
96+
</properties>
97+
</action>
98+
<action id="WorksheetAction.CONTEXT_MENU_ONLY">
99+
<properties>
100+
<property name="Name">${WORKSHEET_ACTION_CONTEXT_MENU_ONLY}
101+
</property>
102+
<!-- You could also use your own by putting path in rsbundle
103+
e.g., MY_ICON = /oracle/db/example/sqldeveloper/extension/dependency/icons/my_icon.png
104+
and referencing its key as res:${MY_ICON} -->
105+
<property name="SmallIcon">${OracleIcons.DEBUG_PURPLE}
106+
</property>
107+
</properties>
108+
</action>
109+
<action id="WorksheetAction.TOOLBAR_ONLY">
110+
<properties>
111+
<property name="Name">${WORKSHEET_ACTION_TOOLBAR_ONLY}
112+
</property>
113+
<!-- You could also use your own by putting path in rsbundle
114+
e.g., MY_ICON = /oracle/db/example/sqldeveloper/extension/dependency/icons/my_icon.png
115+
and referencing its key as res:${MY_ICON} -->
116+
<property name="SmallIcon">${OracleIcons.DEBUG_YELLOW}
117+
</property>
118+
</properties>
119+
</action>
120+
</actions>
121+
</jdeveloper-hook>
122+
123+
<sqldev-worksheet-hook
124+
xmlns="http://xmlns.oracle.com/sqldeveloper/sqldev-worksheet">
125+
<provider>oracle.db.example.sqldeveloper.extension.worksheetAction.ExampleActionProvider
126+
</provider>
127+
</sqldev-worksheet-hook>
128+
</hooks>
129+
130+
</extension>
Loading
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
oracle.db.example.sqldeveloper.extension.worksheetAction.ExtensionResources
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9+
* KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10+
*/
11+
12+
package oracle.db.example.sqldeveloper.extension.worksheetAction;
13+
14+
import oracle.ide.Context;
15+
import oracle.ide.controller.Controller;
16+
import oracle.ide.controller.IdeAction;
17+
18+
/**
19+
* DummyActionController - deploy as editor trigger action to force load the extension which has no natural trigger.
20+
*
21+
* @author <a href="mailto:brian.jeffries@oracle.com?subject=oracle.db.example.sqldeveloper.extension.worksheetAction.DummyActionController">Brian Jeffries</a>
22+
* @since SQL Developer 20.1
23+
*/
24+
public class DummyActionController implements Controller {
25+
26+
@Override
27+
public boolean handleEvent(IdeAction action, Context ctx) {
28+
// Just for the side effect - no real action needed
29+
return true;
30+
}
31+
32+
@Override
33+
public boolean update(IdeAction action, Context ctx) {
34+
// Trigger-hook - return true so deferred loading works
35+
}
36+
37+
}

0 commit comments

Comments
 (0)