Tutorial: Retrieving Information About the Current Document by Invoking Java Operations from JavaScript Code

Retrieving Information About the Current Document by Invoking Java Operations from JavaScript Code

Suppose that you want to retrieve the names of the allowed elements that a user can insert at the current cursor position.

First, you have to implement a Java class to extend the ro.sync.ecss.extensions.api.webapp.AuthorOperationWithResult class which will be invoked to return a result to the JavaScript code.

package com.example.plugin;

import java.util.ArrayList;
import java.util.List;

import javax.swing.text.BadLocationException;

import org.apache.log4j.Logger;

import ro.sync.contentcompletion.xml.CIElement;
import ro.sync.contentcompletion.xml.WhatElementsCanGoHereContext;
import ro.sync.ecss.extensions.api.ArgumentsMap;
import ro.sync.ecss.extensions.api.AuthorAccess;
import ro.sync.ecss.extensions.api.AuthorOperationException;
import ro.sync.ecss.extensions.api.AuthorSchemaManager;
import ro.sync.ecss.extensions.api.webapp.AuthorDocumentModel;
import ro.sync.ecss.extensions.api.webapp.AuthorOperationWithResult;
import ro.sync.ecss.extensions.api.webapp.WebappRestSafe;

@WebappRestSafe
public class GetElementsAtCaretOperation extends AuthorOperationWithResult {
  /**
   * Logger for logging. 
   */
  private static Logger logger = Logger.getLogger(GetElementsAtCaretOperation.class.getName());

  @Override
  public String doOperation(AuthorDocumentModel model, ArgumentsMap args) throws AuthorOperationException {
    List<String> elementNames = new ArrayList<>();
    try {
      AuthorAccess authorAccess = model.getAuthorAccess();

      AuthorSchemaManager authorSchemaManager =
          authorAccess.getDocumentController().getAuthorSchemaManager();

      int caretOffset = authorAccess.getEditorAccess().getCaretOffset();
      WhatElementsCanGoHereContext context =
          authorSchemaManager.createWhatElementsCanGoHereContext(caretOffset);

      if (context != null) {
        List<CIElement> childrenElements = authorSchemaManager.whatElementsCanGoHere(context);
        if (childrenElements != null) {
          for (int i = 0; i < childrenElements.size(); i++) {
            CIElement currentElement = childrenElements.get(i);
            elementNames.add(currentElement.getQName());
          }
        }
      }
    } catch (BadLocationException e) {
      logger.error(e, e);
      throw new AuthorOperationException("An exception occured when trying to determine "
          + "the elements that can be inserted at caret offset: " + e.getMessage());
    }

    return String.join(",", elementNames);
  }
}

To invoke the Author Operation asynchronously from the JavaScript code, you have to call sync.api.ActionsManager#invokeOperation. The following code will iterate the list of all element names that can be inserted at the cursor position:

var actionsManager = editor.getActionsManager();
actionsManager.invokeOperation('com.example.plugin.GetElementsAtCaretOperation', {}, 
    function(e, result) {
        result.split(',').forEach(function (elementName) {
            // ......
        });
    });