UKLUG 2009 - Extending Domino Designer on Eclipse

Preview:

DESCRIPTION

These slides have been shown at UKLUG 2009 in Edinburgh and are an introduction to extending Domino Designer (formerly known as DDE).

Citation preview

Presenter: René Winkelmeyer Company: Partner Dialog

The new “R” in Rapid Application Development ?!

Extending Domino Designer on Eclipse

•  All the code is based on Notes 8.5.1 Managed Beta Refresh 2 (Code Drop 8).

•  Every code is subject to change, there is no commitment when it ships or what functionality will ship.

Beta information

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

with live demos and sample code

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  René Winkelmeyer

•  (still) 31 years old

•  Married, two dogs, two cats

•  Consultant for Business Process Optimization and Domino Development at Partner Dialog Unternehmensberatung GmbH

•  IBM Business Partner

•  Using Notes/Domino since 4.57 (OS/2!)

•  Member of IBMs Domino NEXT Design Partner program

•  http://blog.winkelmeyer.com (really not well maintained)

About me

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Anybody here with strong Java experience?

•  Anybody here with strong Eclipse know-how?

•  And what about strong Notes/Domino experience? ;-)

•  That’s what I expected…

•  At least you need a litte bit of everything. But don’t be afraid, it’s quite easy.

About you

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  No hard-core dive into every corner of Eclipse

•  No basic coding course for Java

•  No coaching for using LotusScript related classes in Domino Java

•  To see some samples about extending your favourite Application Development Tool

•  To learn some do’s and don’ts

What’s to expect from this session

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Domino Designer on Eclipse

•  With Domino Designer 8.5 a new, powerful application was given to our hands.

•  Yes – it was slow (some people said).

•  But – the new features reimbursed everything.

•  With Domino Designer 8.5.1 (don’t forget, GA date is 12.10.2009!) we even get more power

•  A new LotusScript editor

•  More XPages features

•  … (just to name a few)

Ingedrients to make you more productive (I)

•  Java

•  Language basics (data types, loops, if’s, casting…)

•  Domino Java

•  Just as you use them from within Domino

•  Eclipse (currently Ganymede=3.4)

•  Using the UI extension model (for menu items or key bindings)

•  Most things would work through “copy&paste”

•  SWT / JFace

•  If you would like to make interactive interfaces

Ingredients to make you more productive (II)

•  Lotus Expeditor (6.2.1 for Notes 8.5.1)

•  see the Resources section for download and install information

Ingredients to make you more productive (III)

•  Ideas

•  Get information about the current Notes session

•  Run an agent from within the agent editor

•  Remove the “Prohibit design refresh” flag from all design notes of a selected database

•  Set all or single design element aliases automatically

•  Set the design template name for a database - with a visually chosen source database

•  Archive a selected design element – or restore it

•  Push design elements to other databases

•  Create a form based on your own wizard

•  …

Ingredients to make you more productive (III) w

ith li

ve d

emos

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Contributions to the ui are made through the plugin.xml

•  The most known – and chosen – extension points of Eclipse are located in the package

Understanding how to extend the UI (I)

org.eclipse.ui.*

menus actionsets … (key) bindings

•  UI menus are nice – but when they don’t call anything… nearly useless

•  So we need “commands” and “handlers”

•  “commands” are the second part of a plugin.xml definition

•  they are called by a handler

Understanding how to extend the UI (II)

„myCommand“

„myUIMenu“ „myHandler“

„myBinding“

•  Create your menu modifications with the standard editor.

•  You can edit the plugin.xml directly (I prefer that because not every setting is available through the user interface).

Understanding how to extend the UI (III)

Understanding how to extend the UI (IV)

<command category=„uklugCategory" categoryId="com.winkelmeyer.uklug.dde.commandCategory" id="com.winkelmeyer.uklug.dde.sessioninformation" name="1. Session information"> </command>

One command – you can build up multiple of them within one plugin.xml

Name of the command

A unique identifier – please no existing names…

The main category id

The main category

Understanding how to extend the UI (V)

That‘s a menu command.

Push the entry… ;-)

That‘s how the user will see the menu entry

Provide your own icon to enhance the ui

ID of the related command

Unique ID of this ui element

<command commandId="com.winkelmeyer.uklug.dde.sessioninformation" icon="icons/wizard.gif" id="SessionInformation" label="1. Session information" style="push"> </command>

Understanding how to extend the UI (VI)

A simple handler

ID of the command

The Java class name

<handler class="com.winkelmeyer.uklug.dde.SessionInformation" commandId="com.winkelmeyer.uklug.dde.sessioninformation"> </handler>

Understanding how to extend the UI (VII)

A litte bit more complex handler.

In this case the menu item is only available, when one form is selected.

<handler class="com.winkelmeyer.uklug.dde.CreateView" commandId="com.winkelmeyer.uklug.dde.createview"> <enabledWhen> <with variable="selection"> <test property=_

"com.ibm.designer.domino.ui.commons.extensions.numAndType" value="1,forms" forcePluginActivation="true"> </test> </with> </enabledWhen> </handler>

•  Excursion: Domino Designer specifics for design element selection.

•  You can find all properties in the file “com.ibm.designer.domino.ui.commons_8.5.0.20090810-1007.jar” which is located directly in <NOTES>\framework\shared\eclipse\plugins.

•  In example you can choose this properties:

•  elementType: Specify the needed design element

•  elementCount: Specifiy just the needed number of selected design elements

•  numAndType: Specify number and type of the design elements •  Or enable the menu items when any design element is selected, disregarding the count or type.

Understanding how to extend the UI (VIII)

</enabledWhen> <reference definitionId="com.ibm.designer.domino.ui.commons.extensions.designElementSelected" /> </enabledWhen>

Understanding how to extend the UI (IX) <?eclipse version="3.2"?> <plugin> <extension point="org.eclipse.ui.commands"> <category id="com.winkelmeyer.uklug.dde.commandCategory" name="UKLUG Examples"> </category> <command category=„uklugCategory" categoryId="com.winkelmeyer.uklug.dde.commandCategory" id="com.winkelmeyer.uklug.dde.sessioninformation" name="1. Session information"> </command> </extension> <extension point="org.eclipse.ui.handlers"> <handler class="com.winkelmeyer.uklug.dde.SessionInformation" commandId="com.winkelmeyer.uklug.dde.sessioninformation"> </handler> </extension>

Understanding how to extend the UI (X) <extension point="org.eclipse.ui.menus"> <menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=additions"> <menu id="com.winkelmeyer.uklug.dde.testselection" label="UKLUG Examples"> <command commandId="com.winkelmeyer.uklug.dde.sessioninformation" icon="icons/wizard.gif" id="SessionInformation" label="1. Session information" style="push"> </command> </menu> </menuContribution> </extension> </plugin>

Understanding how to extend the UI (XI)

Make your own key bindings!

That means „SHIFT+A“ for any operating system.

•  Extra bonus: key bindings

<extension point="org.eclipse.ui.bindings"> <key commandId="com.winkelmeyer.uklug.dde.runagent" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M2+A"> </key> </extension>

•  Now you know everything to make your own menus.

•  There are uncountable sites on the internet for more information, i. e. to make context-menus, toolbars and so on. More on that in the resources section.

Understanding how to extend the UI (XII)

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Using the Domino Java API from within DDE is the same as developing an Domino Java agent.

•  This is not related to using the Designer Extensibility API. It’s just Domino Java development.

Using Domino Java within DDE (I)

DEMO 1 – Session information

Using Domino Java within DDE (II)

Standard Domino Java code

A java dialog box

You always need a shell for GUI interaction

public Object execute(ExecutionEvent event) throws ExecutionException { Shell shell=HandlerUtil.getActiveShell(event); try { NotesThread.sinitThread(); try { Session session = NotesFactory.createSession(); String sessionInformation = null; sessionInformation = "User: " + session.getCommonUserName() + NL +_ "Version: " + session.getNotesVersion() + NL + "Platform: " + _ session.getPlatform(); MessageDialog.openInformation(shell, "Session information", _ sessionInformation); } catch (Exception e) { throw e; } finally { NotesThread.stermThread(); } } catch (Exception e) { e.printStackTrace(); } return null; }

•  Just do any Notes backend action you want – without any strong Java experience.

•  Another example could be to run an agent.

•  But wait – which agent do you want to run?

•  I think you have to wait a little bit…

Using Domino Java within DDE (III)

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Domino Designer on Eclipse 8.5 has shipped with the new Designer Extensibility API. It maps between the Eclipse resources and the Notes design elements.

•  With the Extensibility API you are allowed to gain the actual selected design element(s). And it doesn’t matter where you select it (in the app navigator or in the design element list).

•  Now you can easily access i. e. the noteid of a selected design element.

•  The API consists of these interfaces and classes:

•  DesignerDesignElement – representing a single design element

•  DesignerDesignElementSelection – representing a design element selection

•  DesignerException – I think you know the word exception

•  DesignerProject – every Notes app represents a single DesignerProject

•  DesignerResource – the counter-part of an Eclipse IResource

Leveraging DDE with the Extensibility API (I)

Leveraging DDE with the Extensibility API (II)

•  Step-by-step

•  Think about an idea

•  Add the required plug-ins to your plug-in project

•  Prepare the UI stuff (remember the first chapters)

•  Code your plug-in

•  Have fun !!

Leveraging DDE with the Extensibility API (III)

•  The problem: running an agent from within Designer was always a little bit “tricky”

•  Switch between Designer tabs was necessary (1-click)

•  search the agent from the agent list

•  select the agent context-menu (1-click)

•  select “Run…” from the context-menu (1-click)

•  click “OK” in the dialog (1-click)

•  going back to the agent (1-click)

•  The idea: running an agent via a custom menu item

Leveraging DDE with the Extensibility API (IV)

•  Add the required plug-ins to your plug-in project

•  You need “com.ibm.designer.domino.ui.commons” and “com.ibm.designer.domino.ide.resources. Both are provided with the DDE installation.

•  And other plug-ins, like com.ibm.notes.java.api for Domino Java.

Leveraging DDE with the Extensibility API (V)

•  Create the appropriate plugin.xml

•  Watch out for the handler!

Leveraging DDE with the Extensibility API (VI)

Testing for count and type of the selected design element

It should be only available, when one agent is selected.

<handler class="com.winkelmeyer.uklug.dde.RunAgent" commandId="com.winkelmeyer.uklug.dde.runagent"> <enabledWhen> <with variable="selection"> <test property="com.ibm.designer.domino.ui.commons.extensions.numAndType" value="1,agents" forcePluginActivation="true"> </test> </with> </enabledWhen> </handler>

•  The Java class – Part one: creating the class

Leveraging DDE with the Extensibility API (VII)

As we are working with handlers we have to implement an IHandler. Eclipse will then add the unimplemented methods automatically.

public class RunAgent implements IHandler {

•  The Java class – Part two: getting the active selection

Leveraging DDE with the Extensibility API (VIII)

This selection represents the current selected Eclipse resource.

The current Eclipse workbench

public Object execute(ExecutionEvent event) throws ExecutionException { IWorkbenchWindow window= HandlerUtil.getActiveWorkbenchWindow(event); ISelection selection = window.getSelectionService().getSelection(); // do your stuff here return null; }

•  The Java class – Part three: moving the active Eclipse selection to the Extensibility API

Leveraging DDE with the Extensibility API (IX)

First time usage of the Extensibility API: Retrieve the ISelection element from Eclipse. Now we have the selection. But not the project or the elements…

Just some variables

String serverName = null; String dbPath = null; DesignerDesignElementSelection ddes = DesignerResource.getDesignerSelection(selection);

•  The Java class – Part four: getting the project and some project properties

Leveraging DDE with the Extensibility API (X)

Assigning the server name and the database path to the string vars.

Being sure, that there is a Domino project

Get the DesignerProject from the selected design element.

Hints: - The method „getDatabaseName“ returns the file path. There is no method „getFilePath“. - The method „getServerName“ returns null if the database is local.

if (ddes.isDominoProjectSelected()) { try { DesignerProject dp = ddes.getSelectedDesignerProject(); serverName = dp.getServerName(); dbPath = dp.getDatabaseName();

•  The Java class – Part five: get the selected design element

Leveraging DDE with the Extensibility API (XI)

Put all selected design elements into a DesignElement list.

Just a double-check, as the menu-item is only enabled when one design element is selected.

Get the DesignerProject from the selected design element.

Getting the first selected design element.

if (ddes.getDesignElementCount() == 1) { DesignerDesignElement elem; List<DesignerDesignElement> elems = ddes.getSelectedDesignElements(); elem = elems.get(0);

•  The Java class – Part six: use some Domino Java code

Leveraging DDE with the Extensibility API (XII)

Get the element name, so we can choose the agent by name.

The database is not local, so we use runOnServer.

try { NotesThread.sinitThread(); try { Session sess = NotesFactory.createSession(); Database db = sess.getDatabase(serverName,dbPath); Agent ag = db.getAgent(elem.getName()); if (serverName!=null) { if (ag.runOnServer() == 0) { MessageDialog.openInformation(shell, title, messageSuccess); } else { MessageDialog.openError(shell, title, messageError); } } else { ag.run(); MessageDialog.openInformation(shell, title, messageSuccess); }

Leveraging DDE with the Extensibility API (XIII)

DEMO 2 – Run agent

•  The problem: sometimes you forgot to remove the “ProhibitDesign” flag from design elements

•  switch through all design elements (n-clicks)

•  switch to the property view (n-clicks)

•  disable the flag (n-clicks)

•  The idea: remove that flag automatically from all design elements

Leveraging DDE with the Extensibility API (XIV)

•  The Java class – Part one: basic implementation

Leveraging DDE with the Extensibility API (XV)

public Object execute(ExecutionEvent event) { IWorkbenchWindow window= HandlerUtil.getActiveWorkbenchWindow(event); ISelection selection = window.getSelectionService().getSelection(); DesignerDesignElementSelection uisel=DesignerResource.getDesignerSelection(selection); DesignerProject designerProject = uisel.getSelectedDesignerProject();

You already know this stuff from the previous example.

•  The Java class – Part two: retrieving the resource folder

Leveraging DDE with the Extensibility API (XVI)

Assigning the Designer project to a standard Eclipse project.

Now all design elements of the DesignerProject are assigned to the IResource array.

IProject eclipseProject = designerProject.getProject(); IResource resMembers[]=null; try { resMembers=eclipseProject.members(); } catch (CoreException e) { e.printStackTrace(); }

•  The Java class – Part three: retrieving the design element resources

Leveraging DDE with the Extensibility API (XVII)

All design elements are in their specific „folders“.

This are the „real“ design element resources

IResource resChilds[]=null; DesignerDesignElement dele=null; for(int i=0;i<resMembers.length;i++){ if(resMembers[i]instanceof IFolder){ IFolder folder = (IFolder)resMembers[i]; try { resChilds=null; resChilds=folder.members();

•  The Java class – Part three: iterating through the design elements

Leveraging DDE with the Extensibility API (XVIII)

And just remove the flag.

Getting every single design element from the IResource array.

Hint: - You can do that with Domino Java, too. But I don‘t want a Notes thread for this.

for(int m=0;m<resChilds.length;m++){ if(resChilds[m]!=null) { dele = DesignerResource.getDesignElement(resChilds[m]); if (dele.isProhibitRefresh()) { dele.setProhibitRefresh(false); } } }

•  The problem: I don’t want to set the alias manually

•  You always have to think about your corporate standards

•  sometimes you write something wrong

•  The idea: just set the alias automatically for all design elements

Leveraging DDE with the Extensibility API (XIX)

•  The Java class – Part one: set the design element alias

Leveraging DDE with the Extensibility API (XX)

Use some custom classes

for(int m=0;m<resChilds.length;m++){ if(resChilds[m]!=null) { dele = DesignerResource.getDesignElement(resChilds[m]); if (isUsableDesignElement(dele)) { dele.setAlias(buildAliasName(dele)); } } }

•  The Java class – Part two: creating custom classes

Leveraging DDE with the Extensibility API (XXI)

Watch out the „metamodel“, use DesignerResource constants, i. e. TYPE_AGENTS

Specific: - If you don‘t have a specific design element in your database, you‘ll get a null value for that element type. - Every DesignElementType starts with „metamodel.type“. Care about that!

You MUST check null !

private boolean isUsableDesignElement(DesignerDesignElement deleUsable) { boolean retVal=false; if (deleUsable.getDesignElementType()!=null) { String delType = deleUsable.getDesignElementType(); if (delType.equals("metamodel.forms") || delType.equals("metamodel.views") || _ delType.equals("metamodel.outlines") || delType.equals("metamodel.framesets") || _ delType.equals("metamodel.agents")) { retVal=true; } } return retVal; }

Leveraging DDE with the Extensibility API (XXII) Element name Element type($AgentContexts) metamodel.viewsAbout Document metamodel.aboutdocumentactions nullAgentContext metamodel.formsAgentContexts metamodel.viewsAgents nullApplets nullApplications nullColumns nullComponents nullDatabase Script metamodel.databasescriptDataConnections nullDB2AccessViews nulldbprops metamodel.applicationpropertiesFields nullFiles nullIcon metamodel.iconImages nullMasterView metamodel.viewsNavigators nullOutlines nullplugin nullScriptLibraries nullStyleSheets nullSubforms nullThemes nullUsing Document metamodel.usingdocumentWEB-INF metamodel.webcontentWebServiceConsumer nullWebServices nullWiringProperties null

no design element

no design element

Leveraging DDE with the Extensibility API (XXIII)

DEMO 3 – Set alias automatically

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  As you build user-friendly apps – there should be user friendly plug-ins in DDE, too!

•  For that you should use SWT/JFace, as it’s the favourite GUI programming language for DDE.

•  The best way to use a GUI is to use separate classes.

Reaching the top – using GUI interaction (I)

•  The problem: changing the design template property always needs to leave the current app

•  The idea: build a user interface for choosing the design template name

Reaching the top – using GUI interaction (II)

DEMO 4 – Set design template name (visually)

•  The problem: sometimes you change a design element – and want to undo that later

•  Where to put the “old” design element?

•  Not a real version tracking – just an archiving solution.

•  And how to get it back?

•  Always copy and paste?

•  The idea: build a plug-in that archives and restores from and to another database

Reaching the top – using GUI interaction (III)

•  The archiving workflow

•  get selected design element

•  get the noteid of the design element

•  get the design document by noteid

•  copy the document – with some manipulated fields – to another database

Reaching the top – using GUI interaction (IV)

•  The restoring workflow

•  get selected design element

•  get the name of the design element

•  search the name in the archiving database

•  get the noteid of the archived design document

•  copy the design document to the original database

Reaching the top – using GUI interaction (V)

•  Watch out when using DesignerDesignElement.getNoteId() !!

•  elem.getNoteId() returns an int value!

•  So you need to cast it into a hex string: Integer.toHexString(elem.getNoteId());

•  And this string must not have the needed length of 8! Please use a helper method.

Reaching the top – using GUI interaction (VI)

public String updateNoteID(String noteID) { for (int i=8-noteID.length();i<=8;i++) { noteID = "0"+noteID; } return noteID; }

Reaching the top – using GUI interaction (VII)

DEMO 5 – Archive and restore design elements

•  About me

•  About you

•  What’s to expect from this session

•  Ingredients to make you more productive

•  Understanding how to extend the UI

•  Using Domino Java within DDE

•  Leveraging DDE with the Extensibility API

•  Reaching the top – using GUI interaction

•  Resources

Agenda

•  Books

•  The Java Developer’s Guide to Eclipse, Addison Wesley

•  Professional Java Native Interfaces with SWT/JFace, Wiley & Sons

•  Internet

•  http://lekkimworld.com, a very real good and well known Notes/Java blog

•  http://www.vogella.de, everything you could find about RCP development – in English

•  Code

•  The JavaDoc of the Designer Extensibility API

•  The source code of this session

Resources

•  Tutorials

•  Setting up Eclipse with the Expeditor Toolkit http://www-10.lotus.com/ldd/compappwiki.nsf/dx/setting-up-eclipse-and-the-expeditor-toolkit

Resources

Thank you!

Thank you very much for attending my session !

René Winkelmeyer

Questions and – hopefully good – answers can now be placed !

Recommended