LPEX
4.4.0

Package com.ibm.lpex.alef

This package provides advanced line-oriented editing functions for Eclipse technology plug-ins.

See:
          Description

Interface Summary
LineNumberColumn.ICompatibilityForwarder Forwarder for preference checks and ruler creation.
LpexLanguageHelp Interface LpexLanguageHelp defines a language-sensitive help (LSH) provider for LpexSourceViewer, or an editor using it.
LpexLanguageHelpExtension Interface LpexLanguageHelpExtension is to be used with a language-sensitive help (LSH) provider LpexLanguageHelp for LpexSourceViewer, or an editor using it.
LpexPreload Interface LpexPreload defines an extension point for a plug-in to extend LPEX.
 

Class Summary
AnnotationColumn The annotation ruler contribution.
LineNumberColumn The line number ruler contribution.
LpexAbstractDecoratedTextEditor A line oriented, LPEX-based abstract base implementation of an extended text editor.
LpexAbstractTextEditor A line oriented, LPEX-based abstract base implementation of a text editor.
LpexAbstractTextEditor.ColumnSupport Implements the ruler column support for the given LPEX text editor.
LpexAbstractTextEditor.IdMapEntry Maps an Eclipse action definition name to an LPEX action.
LpexAbstractTextEditor.TextEditorSavable This text editor's savable.
LpexAnnotationBarHoverManager LPEX implementation of AnnotationBarHoverManager.
LpexAnnotationRulerColumn A vertical ruler column connected to an LpexCompositeRuler.
LpexCompositeRuler A composite vertical ruler which is connected to an LpexTextViewer.
LpexContextContributor Basic LPEX contributions to the Eclipse context.
LpexDefaultHyperlinkPresenter The default hyperlink presenter shows one hyperlink in one window of an LPEX source viewer.
LpexHyperlinkManager Default implementation of a hyperlink manager for an LPEX text viewer.
LpexLineChangeHover Quick diff hover for LPEX.
LpexLineChangeInformationControl Quick diff information control for LPEX.
LpexLineNumberChangeRulerColumn A vertical ruler column for quick diff and revisions.
LpexOverviewRuler A vertical ruler displayed next to an LpexSourceViewer showing all annotations of the viewer's annotation model in a compact format.
LpexPlugin LPEX Editor plug-in runtime class.
LpexRevisionPainter A strategy for painting the live annotate colors onto the vertical ruler column.
LpexSourceViewer A line-oriented, LPEX-based partial implementation of org.eclipse.jface.text.source.ISourceViewer.
LpexSourceViewerConfiguration This class extends the configuration space defined by TextSourceViewerConfiguration, with LPEX's content assist and hyperlink support for use with an LpexSourceViewer.
LpexStatusTextEditor A line-oriented, LPEX-based version of StatusTextEditor.
LpexStickyHoverManager Implements a sticky hover control, i.e.
LpexTextEditor A line-oriented, LPEX-based version of TextEditor.
LpexTextViewer A line-oriented, LPEX-based partial implementation of org.eclipse.jface.text.ITextViewer.
LpexTextViewer.TextHoverKey Value object used as a key in the text hover configuration table.
LpexViewPreferenceNode PreferenceNode for a view-scoped preference page.
Utilities Various preferences utilities for SWT LPEX, which must also take into account the case when running inside a plug-in inside the Eclipse workbench.
 

Package com.ibm.lpex.alef Description

This package provides advanced line-oriented editing functions for Eclipse technology plug-ins.

The organization of the LPEX Editor plug-in classes mirrors Eclipse text editing framework's:

 
                                      Viewer
                                         ^
                                         |
          EditorPart               LpexTextViewer:  new LpexView,
              ^                          ^          new LpexMultiWindow 
              |                          |
     LpexAbstractTextEditor:  new LpexSourceViewer
              ^
              |
      LpexStatusTextEditor
              ^
              |
 LpexAbstractDecoratedTextEditor
              ^
              |
        LpexTextEditor

Several functions, however, are not supported.  This is mainly functionality which is already implemented in the LPEX widget.  The main differences from the corresponding Eclipse classes are documented in each class.

Such low-level integration results in a strong dependency on the Eclipse implementation of these classes and its definition of the related interfaces.  This in turn causes significant rewrites when new Eclipse drivers (traditionally heavily-modified) are released.

All text changes should be applied to LPEX (rather than to Eclipse's IDocument), using the LPEX API.  This is imperative, given LPEX's unique text support of sequence numbers, record length, editing fields, DBCS support (SO/SI emulation, calculation of EBCDIC bytes on the remote), bidirectional support (logical / smart logical / syntax-smart logical, ligatures in EBCDIC on the remote, bidirectional marks), etc.

LPEX-based solution editors should subclass LpexAbstractDecoratedTextEditor, or a class lower in the hierarchy.

Example LPEX-based editor plug-in

A minimal implementation of an LPEX-based editor plug-in could consist of one file, for example, eclipse/plugins/com.mycompany.simplelpexeditor_1.0/plugin.xml:

 
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
 <!-- ========================================= -->
 <!-- Simple LPEX-based editor plug-in example. -->
 <!-- ========================================= -->
 <plugin
  id="com.mycompany.simplelpexeditor"
  name="Simple LPEX Editor"
  version="1.0.0"
  provider-name="My Company">

  <requires>
   <import plugin="com.ibm.lpex"/>
  </requires>

  <extension point="org.eclipse.ui.editors">
   <editor
    id="com.mycompany.SimpleLpexEditor"
    name="Simple LPEX Editor"
    icon="./icons/SimpleLpexEditor.gif"
    class="com.ibm.lpex.alef.examples.BasicLpexEditor"
    extensions="app,asm,c,c++,cbl,cc,ccs,cicsc,cmd,cob,cpp,cpy,cxx,epf,f,f90,f95,for,h,h++,hh,hla,hpp,htm,html,hxx,inc,inl,j,jav,java,jcl,jj,lx,lxl,lxu,mac,mf,pli,prefs,pro,properties,rc,readme,rex,rexx,rpg,sqc,sql,sqlc,sqlj,txt,xml,xsl" 
    contributorClass="com.ibm.lpex.alef.examples.BasicLpexEditorActionContributor"
    default="false">
   </editor>
  </extension>
 </plugin>

Editor actions and commands

LpexAbstractTextEditor defines several new editor actions and commands, available in all the LPEX-based solution editors.

Context contributions

To add its contributions to the Eclipse global actions, menus, toolbar, and status line, your LPEX-based solution should extend LpexContextContributor, rather than BasicTextEditorActionContributor.  This gives LPEX the opportunity to add its own basic editor contributions to Eclipse.

An LPEX-based editor plug-in that has no contributions of its own must still use this class (or a class extending it) as the contributorClass in its plugin.xml declaration of the "org.eclipse.ui.editors" extension point, in order to have the LPEX contributions appear in the workbench, and link the editor actions to the global workbench actions.

 
 BasicTextEditorActionContributor 
                ^
                |
     LpexContextContributor
                ^
                |
  MyTextEditorActionContributor

Here is the relevant section of a solution plug-in's plugin.xml file:

 
 <extension point="org.eclipse.ui.editors">
  <editor
   . . .
   contributorClass="com.mycompany.MyTextEditorActionContributor"> 
  </editor>
 </extension>

Editor extensions

LPEX extensions (document parsers, actions, commands, and user profiles) are defined by name (for example, "detab" command).  AWT LPEX and SWT LPEX running outside the Eclipse workbench can load and run such user-defined classes which are located in the Java CLASSPATH.  Inside the Eclipse workbench, however, each plug-in has its own class loader, restricted to the class path defined in its plugin.xml or bundle (usually one or more specific jar files, and the prerequisite plug-ins).

Extending the class path

When the LPEX Editor plug-in cannot load a class defined for an extension (action, command, user profile, document parser), it will attempt to load it via alternative class loaders.  An LPEX-based solution editor plug-in's class loader is by default registered as an alternative class loader.  Therefore, such a plug-in doesn't need to do anything in order to have its own editor extensions work.  In other cases, as discussed below, the scope of the class loader must be explicitly extended.

In order to allow the user of the editor to add their own custom classes that extend LPEX:

The com.ibm.lpex.preload extension point

Any plug-in that provides document parsers, actions, commands, or user profiles (either exclusively, or for its own LPEX-based editor), can make them available to any other LPEX-based editor plug-in installed in the workbench.  This can be accomplished through the com.ibm.lpex.preload extension point defined in the LPEX Editor plug-in:

 
 <!-- ======================================================================= --> 
 <!-- Extension Point: preload.                                               -->
 <!-- Define an extension point for a plug-in to extend LPEX with user        -->
 <!-- profiles, commands, actions, and document parsers.                      -->
 <!--                                                                         -->
 <!--   <!ELEMENT preload>                                                    -->
 <!--     <!ATTLIST preload                                                   -->
 <!--      class    CDATA #REQUIRED                                           -->
 <!--     >                                                                   -->
 <!-- where                                                                   -->
 <!--   class - the class that registers LPEX parsers, etc.  The class must   -->
 <!--           be a public implementation of com.ibm.lpex.alef.LpexPreload,  -->
 <!--           with a public 0-argument constructor.                         -->
 <!--                                                                         -->
 <!-- Example of a plug-in hooking into the "preload" extension point:        -->
 <!--   <extension point="com.ibm.lpex.preload">                              -->
 <!--     <preload class="com.example.LpexRegistration"/>                     -->
 <!--   </extension>                                                          -->
 <!-- ======================================================================= -->
 <extension-point id="preload" name="preload" schema="schema/preload.exsd"/>

This extension point allows the LPEX Editor plug-in to record, upon initialization, the class loaders of all declaring client plug-ins, and use them when attempting to load extension classes that had been defined in LPEX.

The client plug-in's preload() method in the preload class specified is called.  This method can be empty, or the client plug-in may set default editor settings (for example, add its command contributions to the existing default.updateProfile.userCommands), or choose to extend the LPEX install settings, by providing the new parsers and parser associations that it contributes.  These settings will show in the LPEX Editor preference pages the first time these are displayed, even when the client plug-in has not been explicitly activated yet.

Multiple document views

LPEX supports multiple views on the same document.  In order to allow opening multiple document views and have the view-management actions added to pop-up (context) menu, you must explicitly enable this feature in one of the hooks that your editor application uses during initialization, for example:

 
 public void initializeLpexView(LpexView lpexView)
 {
  // . . .

  // enable multiple document views
  lpexView.doDefaultCommand("set multipleViews on"); 

  // . . .
 }

Contributions to the pop-up menu, the actions and commands defined, and in general the functions available may be different in each view of the document, depending on how you want to configure your editor application.

Each view runs its own document parser instance.  For information on special parser considerations when multiple document views are open, see LpexCommonParser.

Related editor parameters: documentId, documentViews, multipleViews, splitWindow, splitWindow.orientation, viewId.

Split window

Multiple document views may be displayed in a split window inside one workbench editor part, and/or in different editor parts inside the workbench.  Each document view is associated with an LpexView and, usually, an LpexWindow.

The current implementation of multiple views in package com.ibm.lpex.alef defines the first view created for the document inside a workbench editor part as a primary view.  When the primary view is closed, that editor part is closed.  That is, regardless of the other (secondary) views being opened and closed, the first view created in the editor part is available until that part is closed:

 
 // is the view primary in this editor part?
 boolean isPartPrimaryView = lpexView == getFirstLpexView(); 

A view with an id of 1 will always be a primary view of the document in some workbench editor part:

 
 // is the view a primary view of the document?
 boolean isCurrentDocPrimaryView = lpexView.queryInt("viewId") == 1

See also: getLpexView(), getFirstLpexView(), getActiveLpexView(), getLpexWindow(), getFirstLpexWindow(), getActiveLpexWindow().

External views

When window splitting is disabled (the current.splitWindow parameter is off), "Open new view" requests will optionally open external Lpex windows.  These views are opened outside the workbench, therefore you may need to delegate some of their actions (such as save) so they are run in the context of your application, by extending handleDelegate().

Language sensitive help (LSH)

LPEX provides the basic services in support of a solution editor to implement language-sensitive help:

Here is a sample implementation of LSH support for C/C++ documents in an editor that subclasses LpexAbstractDecoratedTextEditor.  The editor registers one instance of its LshSupport class, which implements the LpexLanguageHelp interface to look up help in a C/C++ documentation plug-in.

 
 private LshSupport _lshSupport;
 public void updateProfile(LpexView lpexView)
 {
  // . . .

  // register LSH for C/C++ instances of this LPEX-based editor
  LpexParser parser = lpexView.parser();
  if (parser != null && parser instanceof CppParser)
   {
    // singleton LshSupport for all C/C++ LpexAbstractDecoratedTextEditor instances 
    if (_lshSupport == null)
     {
      _lshSupport = new LshSupport();
     }

    // register it with our LpexAbstractTextEditor
    setLanguageHelp(_lshSupport);
   }

  // . . .
 }

Class LshSupport may be implemented as follows:

 
 /**
  * One instance of this class is being registered to provide LSH support for
  * all the instances of LpexEditor that use an LPEX C/C++ document parser
  * (CppParser, or one of its extending parsers).  The getHelpPage() call-back
  * determines the help panel to be displayed for the current editing context.
  *
  * The map of keywords to help panels (file CppLsh.properties) is packaged in
  * this plug-in.  In other implementations it may be part of the language
  * documentation plug-in itself, and loaded using that plug-in's class loader.
  * We assume here that the C/C++ documentation plug-in is installed in the
  * workbench.
  *
  * LshSupport can be modified to handle LSH for several document parsers.
  */
 public class LshSupport implements LpexLanguageHelp
 {
  // information for the current instance of this LSH provider
  private String     _languagePluginId;
  private String     _languageHelpMapId;
  private Properties _languageHelpMap;

  /**
   * Constructs an instance of this provider for C/C++ LSH.
   */
  LshSupport()
  {
   // initialize for C/C++ LSH: C/C++ documentation plug-in, help map file name
   _languagePluginId  = "com.ibm.etools.iseries.cpp.doc";
   _languageHelpMapId = "CppLsh.properties";
  }

  /**
   * Returns the fully-qualified help panel name for the current token in the
   * given editor view, for example:
   *   "/com.ibm.etools.iseries.cpp.doc/help/helpitem55.html".
   */
  public String getHelpPage(LpexView lpexView)
  {
   LpexParser parser = lpexView.parser();
   if (parser == null || !(parser instanceof LpexCommonParser))
    {
     return null;
    }

   // let parser determine the current token for LSH,
   // which will serve as the key into the help map
   lpexView.doCommand("parse");
   lpexView.doCommand("screenShow view");
   String token = ((LpexCommonParser)parser).getLshToken();

   // keys are defined in lower case in the help map: helpful for case-sensitive
   // languages, so that the help may guide user to correct case syntax on errors
   token = (token == null)? "default_help" : token.toLowerCase();

   // ensure the help map is loaded
   loadLanguageHelpMap();

   // retrieve help page for the keyword, or default help page if none defined
   String helpPage = _languageHelpMap.getProperty(token);
   if (helpPage == null)
    {
     helpPage = _languageHelpMap.getProperty("default_help");
    }

   // fully-qualify the documentation plug-in help page
   return (helpPage == null)? null : '/' + _languagePluginId + '/' + helpPage;
  }

  /**
   * On the first LSH request (F1), load the map of language
   * keywords to help panels, which is in this package in our plug-in's jar.
   */
  private void loadLanguageHelpMap()
  {
   if (_languageHelpMap == null)
    {
     _languageHelpMap = new Properties();

     try
      {
       _languageHelpMap.load(LshSupport.class.getResourceAsStream(_languageHelpMapId)); 
      }
     catch (Exception x) {} // cannot load help map
    }
  }
 }


LPEX
4.4.0

Copyright � 2016 IBM Corp. All Rights Reserved.

Note: This documentation is for part of an interim API that is still under development and expected to change significantly before reaching stability. It is being made available at this early stage to solicit feedback from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken (repeatedly) as the API evolves.