Insert metadata into ditamap using SDK

Post here questions and problems related to oXygen frameworks/document types.
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Insert metadata into ditamap using SDK

Post by msambasiva »

Hi,

XML Editor 21.0

We have a requirement to capture the user input and insert into ditamap.

I've taken the sample of workspace access extension plugin as base and created a menu option(i.e Metadata Form) to open a Swing window form. Able to capture the userinput data some thing as below.

Code: Select all

public class CustomWorkspaceAccessPluginExtension implements WorkspaceAccessPluginExtension {

	@SuppressWarnings("serial")
	private AbstractAction createShowOpenMetadataformAction(
			final StandalonePluginWorkspace pluginWorkspaceAccess) {
		return new AbstractAction("Metadata Form") {
			  public void actionPerformed(ActionEvent actionevent) {
				  //Get the current opened XML document
//				  pluginWorkspaceAccess.showInformationMessage("Iam in Metadata form");
				  MetadataForm.display();
				  String category = MetadataForm.getCategory();
			  }
		  };
	}
Below is the swing class to open a form,

Code: Select all

public class MetadataForm extends JFrame{
    
    public MetadataForm(){
        JPanel mainPanel = new JPanel(new GridBagLayout());
        HashMap<String,String> categoryMap = extractSSOT("2003");
    }
}
 
Please suggest the best way to insert the user input data into ditamap as some thing as below

Code: Select all

<keydef>
	<topicmeta>
		<keywords>
			<keyword>
				categrogy: Category
			<keyword>
		</keywords>
	</topicmeta>
</keydef>
Please correct me if I am wrong.

Thanks,
Samba.
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hello,

Is the ditamap opened inside Oxygen? If it is, then you can use our API to change it. Something like this:

Code: Select all

WSEditor editorAccess = pluginWorkspaceAccess.getEditorAccess(ditamapURL, PluginWorkspace.DITA_MAPS_EDITING_AREA);
if (editorAccess == null) {
  // Perhaps it's opened in the main editing area.
  editorAccess = pluginWorkspaceAccess.getEditorAccess(ditamapURL, PluginWorkspace.MAIN_EDITING_AREA);
}

if (editorAccess != null) {
  String fragment = "<keydef>\n" + 
		  "	<topicmeta>\n" + 
		  "		<keywords>\n" + 
		  "			<keyword>\n" + 
		  "				categrogy: Category\n" + 
		  "			<keyword>\n" + 
		  "		</keywords>\n" + 
		  "	</topicmeta>\n" + 
		  "</keydef>";
  // The ditamap is opened.
  if (EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())) {
	  // Open in main editing area, author page.
	  WSAuthorEditorPage authorPage = (WSAuthorEditorPage) editorAccess.getCurrentPage();

	  AuthorDocumentController documentController = authorPage.getDocumentController();
	  AuthorElement mapElement = documentController.getAuthorDocumentNode().getRootElement();


	  documentController.insertXMLFragment(fragment, mapElement.getStartOffset() + 1);

  } else if (EditorPageConstants.PAGE_DITA_MAP.equals(editorAccess.getCurrentPageID())) {
	  // Open in dita maps manager.
	  WSDITAMapEditorPage authorPage = (WSDITAMapEditorPage) editorAccess.getCurrentPage();

	  AuthorDocumentController documentController = authorPage.getDocumentController();
	  // TODO Same as above.

  } else if (EditorPageConstants.PAGE_TEXT.equals(editorAccess.getCurrentPageID())) {
	  // Open in main editing area, text page.
	  WSXMLTextEditorPage textPage = (WSXMLTextEditorPage) editorAccess.getCurrentPage();
	  textPage.getDocumentController().insertXMLFragment(fragment, "/map", RelativeInsertPosition.INSERT_LOCATION_AS_FIRST_CHILD);
  }
}
Is the ditamap is not opened inside Oxygen, You can use other methods, using plain Java mechanisms, like for example:
- read the ditamap content as plain text
- search for an insertion location, perhaps using regexp
- build the fragment and insert it
- write the content back into the ditamap file

Another possibility, if the ditamap is not opened inside Oxygen is to open it yourself in an editor, make the insertion using Oxygen's API and select it for the user to see it. You can either save or let the user save it.

Please let me know i you need more details in a specific direction.

Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Thanks Alex!
I am using eclipse as IDE Version: 2020-03 (4.15.0). Could you suggest any pointer to help in debugging the java code in Oxygen Editor?
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hi,

I can think of 2 possibilities. Asa prerequisite, in case you have already deployed the plugin, remove it. You are using one of our Maven startup projects? If you do, these projects have a structure that facilitates the following procedures. If you don't, you can tailor the procedures according to the setup of your project.

1. If you want to skip building the jar. This helps if you add log inside your classes and you want to quickly start Oxygen to see that log.
  • Go to {OxygenInstallDir}/plugins and create a directory myPlugin (this name is not important). In it create a file named plugin.redirect. In it put the absolute path to the plugin project, the one that is being developed inside Eclipse. For example:

    Code: Select all

    C:\Users\alex_jitianu\Documents\Git-workspace\oxygen-git-plugin
  • Modify the plugin.xml file from your project root directory. Again, this file is there if you've used one of our Maven sample projects. You need to add a library reference to the directory where Eclipse copies the compiled output. For Maven projects this is target/classes. If you don't have a Maven project, to find out where this directory is located, invoke the contextual menu of the project (in the Project view), and go to Build Path > Configure Build Path. Then inspect the value of the Default output folder text box.
    Example: If the compiled output folder is classes, then in the plugin.xml, you need to add the following library reference:

    <library name=".target/classes"/>
  • Start Oxygen
2. If you want to also add breakpoints, and do a debugging session with Eclipse, the procedure is a bit different: https://www.oxygenxml.com/doc/versions/ ... lugin.html

Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Thanks Alex for quick response!

I am looking for adding breakpoints in the eclipse java project code. I've taken ShowSelection plugin as a maven startup project.

I've followed instructions given in https://www.oxygenxml.com/doc/versions/ ... lugin.html

1) I've created eclipse project in [OXYGEN_INSTALL_DIR]/plugins i.e C:\Program Files\Oxygen XML Editor 21\plugins\MySDKProject.
2) Imported the maven project from D:\Oxygen
3) By default it's getting plugin.xml

So I don't find the value of myPlugin folder and plugin.xml in it as per the step #4 in https://www.oxygenxml.com/doc/versions/ ... lugin.html

I've put break point in createShowSelectionAction method.

private AbstractAction createShowSelectionAction(
final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Show Selection") {
public void actionPerformed(ActionEvent actionevent) {
//Get the current opened XML document
WSEditor editorAccess = pluginWorkspaceAccess.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);

Finally started oxygen. Selected a text from dita file and 'Show Selection' menu option. I don't see the debugging stopped as expected in the java code.

Iam missing some thing. Please correct me if I am wrong.
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hi,
1) I've created eclipse project in [OXYGEN_INSTALL_DIR]/plugins i.e C:\Program Files\Oxygen XML Editor 21\plugins\MySDKProject.
I don't think the procedure tells you to do this, at least I don't see where. Which step from the procedure is this?
https://www.oxygenxml.com/doc/versions/ ... lugin.html

The idea of this porcedure is to make your project root directory simulate the {oxygenInstallDir}/plugins directory. That's why at Step 5. you copy a plugin.dtd in it. That's why you create a myPlugin directory in it, with a plugin.xml in it.
So I don't find the value of myPlugin folder and plugin.xml in it as per the step #4
You have to create this myPlugin folder? You need to create it and copy in it the plugin.xml present in the root project directory. Afterwards, you need to modify this copy as described in Step 4.
Finally started oxygen.
Did you start Oxygen from within Eclipse, as described in Step 9, after doing the required setup (Step 6 and 7)?

Please note that at Step 7, the value of com.oxygenxml.editor.plugins.dir should be set to the absolute path of your root project:

Code: Select all

-Dcom.oxygenxml.app.descriptor=ro.sync.exml.EditorFrameDescriptor -Xmx1024m 
-XX:MaxPermSize=384m -Dcom.oxygenxml.editor.plugins.dir=D:\projects\MyPluginProject
Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Thanks a lot Alex!
Finally able to debug my code.
I missed to start oxygen from eclipse. Its my bad!
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Hi,

Able to open a swing form from CustomWorkspaceAccessPluginExtension.java using below logic,

@SuppressWarnings("serial")
private AbstractAction createShowOpenMetadataformAction(
final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Open Metadata Form") {
public void actionPerformed(ActionEvent actionevent) {
MetadataForm mForm = new MetadataForm();
mForm.display();
}
};
}

I can select category from a dropdown list in the form and then submit the form. How can i get the control back to CustomWorkspaceAccessPluginExtension.java with the selected form data on submit? The form should close on submit.

Once we got the form data, we can use below logic to insert it into ditamap as per Alex,

WSEditor editorAccess = pluginWorkspaceAccess.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
if (editorAccess != null) {
String fragment = "<keydef>\n" +
" <topicmeta>\n" +
" <keywords>\n" +
" <keyword>\n" +
" categrogy: Category\n" +
" <keyword>\n" +
" </keywords>\n" +
" </topicmeta>\n" +
"</keydef>";
// The ditamap is opened.
if (EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())) {
// Open in main editing area, author page.
WSAuthorEditorPage authorPage = (WSAuthorEditorPage) editorAccess.getCurrentPage();
AuthorDocumentController documentController = authorPage.getDocumentController();
AuthorElement mapElement = documentController.getAuthorDocumentNode().getRootElement();
try {
documentController.insertXMLFragment(fragment, mapElement.getStartOffset() + 1);
} catch (AuthorOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
else {
System.out.println("The map has not been opened!!");
}


Thanks,
Samba.
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hi,

If MetadataForm is a modal dialog, it can be something like this:

Code: Select all

MetadataForm mForm = new MetadataForm();
mForm.display();
MyFormData data = mForm.getData();
insertInDitamap(data);
A modal dialog blocks the current thread until the dialog closes.

Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Hi Alex,

Here is the logic,

MetadataForm mForm = new MetadataForm();
mForm.display();

Opens the Form with display() method call. Then user can fill the form and submit it.So there is no data with getData() method call.

MyFormData data = mForm.getData();
insertInDitamap(data);

I hope, there should be a way to callback on form submit to get the data and insert the data into map.

Please correct me if I am wrong.

Thanks,
Samba.
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hi Samba,

MetadataForm extends a javax.swing.JDialog ? This display() method invokes setVisible(true)? If the answer is yes to both of these questions, then what happens next depends on whether MetadataForm is modal dialog or not:
1. A Modal dialog, once setVisible(true) has been called, will block the current thread until the user closes the dialog. At that point() the program will exit the display() method and you can get from the MetadataForm the data received from the user (from the widgets - textfields, combox etc).
2. A Modeless dialog will not block the current thread. Calling display() willl present the dialog, and the program will imediatly exit the display() method will continue running the subsequent lines of codes. In this case, MetadataForm can receive all it needs to update the document itself, when the user closes it (it can call insertInDitamap(data) itself). Please not that if MetadataForm extends javax.swing.JFrame it falls in this case as well.
So there is no data with getData() method call.
So this line of code , that calls getData() , gets executed. This makes me believe that you are on the second case from above. Either a Modeless dialog or a JFrame. The easiest fix would be to just use a Modal JDialog. Ceck the constructors of JDialog to see the one with a boolean named "modal".

It is recommended to give your dialog a parent. Use {{(JFrame) PluginWorkspaceProvider.getPluginWorkspace().getParentFrame()}} for that. If you have a reference to {{PluginWorkspace}}, then you can use that directly instead of calling the provider.

Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Thanks Alex!
It helped me a lot. Able to fix the issue.
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Hi Alex,

When I run the application in debug mode (using plugin.redirect) , its working as expected by Swing form opening perfectly. But when I run by deploying the jar into plugs folder or added as an add-on, then unable to open the form on menu button click. I've used model form by extending JDialog.

Please correct me, if I am wrong with form invocation from CustomWorkspaceAccessPluginExtension.java.

Below is the code ,

CustomWorkspaceAccessPluginExtension.java:
private AbstractAction createShowOpenMetadataformAction(
final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Open Metadata Form") {
public void actionPerformed(ActionEvent actionevent) {
System.out.println("Start createShowOpenMetadataformAction");
MetadataForm mForm = new MetadataForm();
mForm.setSize(750, 750);
mForm.setModalityType(ModalityType.APPLICATION_MODAL);
mForm.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
mForm.setVisible(true);
// String category = String.valueOf(mForm.getSelectedCategory());
System.out.println("End createShowOpenMetadataformAction");
// updateMap(pluginWorkspaceAccess,category);
}
};
}

MetadataForm.java:

public class MetadataForm extends JDialog{
//public class MetadataForm extends JFrame{
public MetadataForm(){
System.out.println("MetadataForm");
JTextField path = new JTextField(16);
JPanel mainPanel = new JPanel(new GridBagLayout());
HashMap<String,String> categoryMap = this.extractSSOT("2003");
// HashMap<String,String> categoryMap = new HashMap<String,String>();
JComboBox catList = new JComboBox(categoryMap.entrySet().toArray());
catList.insertItemAt("Category", 0);
catList.setSelectedIndex(0);
GridBagConstraints gbc = new GridBagConstraints();

----
add(mainPanel);
}


btw, some how I don't find any log (oxygen.log or output.log) with print messages when we deploy plugin as jar. Please suggest to enable logging for my plugin.

Thanks,
Samba.
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Hi Alex,
Apologize for inconvenience. Please ignore my previous issue. The root cause of issue is missing of REST API jar in [OXYGEN]\lib folder.
Thanks,
Samba.
alex_jitianu
Posts: 1008
Joined: Wed Nov 16, 2005 11:11 am

Re: Insert metadata into ditamap using SDK

Post by alex_jitianu »

Hi Samba,

I'm glad that you found a solution. But that jar should be inside [PLUGIN_DIR]\lib, isn't that right? The plugin should be self contained. When you build the deliverable in your project, this jar should be present inside the deliverable.

Best regards,
Alex
msambasiva
Posts: 87
Joined: Tue Jul 17, 2018 6:57 am

Re: Insert metadata into ditamap using SDK

Post by msambasiva »

Got it! Thanks Alex!!
Post Reply