Edit online

Modify the XML Content on Open

Use Case

You want to convert fixed paths in an attribute value to relative paths.

Solution

The Plugins SDK contains a sample plugin type called WorkspaceAccess. Such a plugin is notified when the application starts and it can do what you want in a couple of ways:

  1. Add a listener that notifies you when the user opens an XML document. Then if the XML document is opened in the Author visual editing mode you can use the Author API to change attributes:
       pluginWorkspaceAccess.addEditorChangeListener(new  WSEditorChangeListener() {
          /**
           * @see WSEditorChangeListener#editorOpened(java.net.URL) 
           */
          @Override
          public void editorOpened(URL editorLocation) {
            WSEditor openedEditor = pluginWorkspaceAccess.getCurrentEditorAccess
    (StandalonePluginWorkspace.MAIN_EDITING_AREA); 
            if(openedEditor.getCurrentPage() instanceof WSAuthorEditorPage) {     
            WSAuthorEditorPage authPage = (WSAuthorEditorPage)  
    openedEditor.getCurrentPage();
            AuthorDocumentController docController = 
    authPage.getDocumentController();
            try {
             //All changes will be undone by pressing Undo once.            
             docController.beginCompoundEdit();
             fixupImageRefs(docController,
              docController.getAuthorDocumentNode());
            } finally {       
               docController.endCompoundEdit();
              }
            }   
          }
    
          private void fixupImageRefs
    (AuthorDocumentController docController, AuthorNode authorNode) {
              if(authorNode instanceof AuthorParentNode) {
                //Recurse
                List<AuthorNode> contentNodes = 
    ((AuthorParentNode)authorNode).getContentNodes();   
                if(contentNodes != null) {
                   for (int i = 0; i < contentNodes.size(); i++) {
                     fixupImageRefs(docController, contentNodes.get(i));
                   }
                 }       
              }
              if(authorNode.getType() == AuthorNode.NODE_TYPE_ELEMENT) {   
                AuthorElement elem = (AuthorElement) authorNode;         
                if("image".equals(elem.getLocalName())) {           
                   if(elem.getAttribute("href") != null) {
                     String originalHref = elem.getAttribute("href").getValue();
        URL currentLocation = docController.getAuthorDocumentNode().getXMLBaseURL();
                    //TODO here you compute the new href.
                    String newHref = null;   
                  docController.setAttribute("href", new AttrValue(newHref), elem); 
                 }
              }
            }
          }
        },
      StandalonePluginWorkspace.MAIN_EDITING_AREA);
  2. An API to open XML documents in the application:
    ro.sync.exml.workspace.api.Workspace.open(URL)
    So you can create a plugin that automatically opens XML documents one at a time from a certain folder in the application, makes modifications to them, and saves the content by calling:
    ro.sync.exml.workspace.api.editor.WSEditorBase.save()
    then closes the editor by calling:
    ro.sync.exml.workspace.api.Workspace.close(URL)