<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "http://docs.oasis-open.org/dita/v1.1/OS/dtd/topic.dtd">
<topic id="howto-cms-plugin">
  <title>How to Write a CMS Integration Plugin</title>
  <prolog>
    <metadata>
      <keywords>
        <indexterm>Oxygen SDK<indexterm>CMS integration</indexterm></indexterm>
        <indexterm>Plugins<indexterm>CMS integration</indexterm></indexterm>
      </keywords>
    </metadata>
  </prolog>
  <body>
    <p>To have a complete integration between <ph keyref="product"/> and a CMS, you usually have to
      write a <xref keyref="glossentry_plugin"><term>plugin</term></xref> that combines the
      following two available <term>plugin</term> extensions:<ul id="ol_gnu_jbt_z">
        <li><xref href="workspace-access-plugin.dita#workspace-access-plugin" format="dita"
            >Workspace Access</xref></li>
        <li><xref href="howto-custom-protocol-plugin.dita#howto-custom-protocol-plugin"
            format="dita">Custom protocol</xref></li>
      </ul>The usual set of requirements for an integration between <ph keyref="product"/> and the
      CMS are as follows:</p>
    <ol id="procedure-custom-protocol">
      <li>Contribute to the <ph keyref="product"/> toolbars and main menu with your custom <b>Check
          Out</b> and <b>Check In</b> actions:<ul>
          <li><b>Check Out</b> triggers your custom dialog boxes that allow you to browse the remote
            CMS and choose the resources you want to open.</li>
          <li>
            <p><b>Check In</b> allows you to send the modified content back to the server.</p>
            <p>You can use the <b>Workspace Access</b>
              <term>plugin extension</term> (and provided sample Java code) for all these
              operations.</p>
          </li>
        </ul></li>
      <li>
        <p>When <b>Check Out</b> is called, use the <ph keyref="product"/> API to open your custom
          URLs (URLs created using your custom protocol). It is important to implement and use a
            <b>Custom Protocol</b> extension to be notified when the files are opened and saved and
          to be able to provide the content for the relative references the files may contain to <ph
            keyref="product"/>. Your custom <i>java.net.URLStreamHandler</i> implementation checks
          out the resource content from the server, stores it locally and provides its content.
          Sample <b>Check Out</b>
          implementation:<codeblock outputclass="language-java">  /**
   * Sample implementation for the "Check Out" method.
   *
   * @param pluginWorkspaceAccess (Workspace Access plugin).
   * @throws MalformedURLException 
   */
    private void checkOut(StandalonePluginWorkspace pluginWorkspaceAccess) 
throws MalformedURLException {
    //TODO Show the user a custom dialog box for browsing the CMS
    //TODO after user selected the resource create a URL with a custom protocol 
    //which will uniquely map to the resource on the CMS using the URLHandler
    //something like:
    URL customURL = new URL("mycms://host/path/to/file.xml");
    //Ask Oxygen to open the URL
    pluginWorkspaceAccess.open(customURL);
    //Oxygen will then your custom protocol handler to provide the contents for 
    //the resource "mycms://host/path/to/file.xml"
    //Your custom protocol handler will check out the file in a temporary
    //directory, for example, and provide the content from it.
    //Oxygen will also pass through your URLHandler if you have any relative 
    //references which need to be opened/obtained.
  } </codeblock></p>
        <p>
          <fig>
            <title>Check Out Process Diagram</title>
            <image href="../img/cmscheckout.png" id="image_yvg_bmg_ab"/>
          </fig>
        </p>
        <p>The phases are:<ul id="ol_svs_qxm_hb">
            <li>1 - Browse CMS repository</li>
            <li>2 - User chooses a resource</li>
            <li>3 - Use API to open custom URL: <filepath>mycms://path/to/file.xml</filepath></li>
            <li>4 - Get content of URL: <filepath>mycms://path/to/file.xml</filepath></li>
            <li>5 - Get content of resource</li>
            <li>6 - Store on disk for faster access</li>
            <li>7 - Retrieve content from disk if already checked out</li>
            <li>8 - Retrieved content</li>
          </ul></p>
      </li>
      <li>
        <p>Contribute a special <b>Browse CMS</b> action to every dialog box in <ph keyref="product"
          /> where a URL can be chosen to perform a special action (such as the <b>Reuse Content</b>
          or <b>Insert Image</b> action). Sample
          code:<codeblock outputclass="language-java">      //Add an additional browse action to all dialog boxes/places 
      //where Oxygen allows selecting a URL.
      pluginWorkspaceAccess.addInputURLChooserCustomizer
(new InputURLChooserCustomizer() {
        public void customizeBrowseActions
(List&lt;Action> existingBrowseActions, final InputURLChooser chooser) {
          //IMPORTANT, you also need to set a custom icon on the action 
          //for situations when its text is not used for display.
          Action browseCMS = new AbstractAction("CMS") {
            public void actionPerformed(ActionEvent e) {
              URL chosenResource = browseCMSAndChooseResource();
              if (chosenResource != null) {
                try {
                  //Set the chosen resource in the combo box chooser.
                  chooser.urlChosen(chosenResource);
                } catch (MalformedURLException e1) {
                  //
                }
              }
            }
          };
          existingBrowseActions.add(browseCMS);
        }
      });
...</codeblock></p>
        <p>When inserting references to other resources using the actions already implemented in <ph
            keyref="product"/>, the reference to the resource is made by default relative to the
          absolute location of the edited XML file. You can gain control over the way that the
          reference is made relative for a specific protocol like
          this:<codeblock outputclass="language-java">      //Add a custom relative reference resolver for your custom protocol.
      //Usually when inserting references from one URL to another Oxygen 
      //makes the inserted path relative.
      //If your custom protocol needs special relativization techniques then 
      //it should set up a custom relative
      //references resolver to be notified when resolving needs to be done.
      pluginWorkspaceAccess.addRelativeReferencesResolver(
          //Your custom URL protocol that you already have a 
          //custom URLStreamHandlerPluginExtension set up.
          "mycms", 
          //The relative references resolver
          new RelativeReferenceResolver() {
        public String makeRelative(URL baseURL, URL childURL) {
          //Return the referenced path as absolute for example.
          //return childURL.toString();
          //Or return null for the default behavior.
          return null;
        }
      });
...</codeblock></p>
      </li>
      <li>Write the <filepath>plugin.xml</filepath> descriptor file. Your <term>plugin</term>
        combines the two extensions using a single set of libraries. The descriptor would look like
        this:<codeblock outputclass="language-xml">&lt;!DOCTYPE plugin SYSTEM "../plugin.dtd">
&lt;plugin
 name="CustomCMSAccess"
 description="Test"
 version="1.0.0"
 vendor="ACME"
 class="custom.cms.CMSAccessPlugin">
 &lt;runtime>
  &lt;library name="lib/cmsaccess.jar"/>
 &lt;/runtime>
 &lt;!--Access to add actions to the main menu and toolbars or to add custom views.-->
 &lt;!--See the "CustomWorkspaceAccessPluginExtension" Java sample for more details-->
 &lt;extension type="WorkspaceAccess" 
  class="custom.cms.CustomWorkspaceAccessPluginExtension"/>
 &lt;!--The custom URL handler that will communicate with the CMS implementation-->
 &lt;!--See the "CustomProtocolURLHandlerExtension" Java sample for more details-->
 &lt;extension type="URLHandler" 
  class="custom.cms.CustomProtocolURLHandlerExtension"/>
&lt;/plugin></codeblock></li>
      <li>Create a <filepath>cmsaccess.jar</filepath>
        <xref keyref="glossentry_jar"><term>JAR</term></xref> archive containing your implementation
        classes.</li>
      <li>Copy your new <term>plugin</term> directory in the <filepath>plugins</filepath> subfolder of the <ph keyref="product"/> install folder (for example, <filepath><term conkeyref="reusables-user-guide/oxy-install-dir"/>/plugins/myPlugin</filepath>) and start <ph keyref="product"/>.</li>
    </ol>
  </body>
  <related-links>
    <linklist>
      <title>Related Information:</title>
      <link href="https://github.com/oxygenxml/oxygen-cmis-plugin" format="html" scope="external"/>
      <link href="https://github.com/axxepta/project-argon" format="html" scope="external"/>
    </linklist>
  </related-links>
</topic>
