Edit online

OXY-URL: File URLs in Oxygen XML Web Author

Oxygen XML Web Author works with files such as DITA documents, images referenced from documents, and DITA maps used as a context for editing. Oxygen XML Web Author can be instructed to load or save a particular file using an OXY-URL that identifies that file.

An OXY-URL is a URL from a technical point of view, but it is not a normal HTTP URL like the ones that browsers use. It should have several characteristics:
  1. It must have a unique scheme according to the file storage system the file comes from.
  2. It should behave like an identifier for the file that it references.
  3. It is usually different from other URLs identifying the file, such as one that would open it in a CMS web interface (herein called CMS-URL) or the one that is used to access the raw content of the file (herein called RAW-URL).

    Example: OXY-URL for a File in Oxygen's User Manual

    Suppose that the OXY-URL for the DITA/topics/introduction.dita topic from the Oxygen User Manual (hosted on GitHub) is the following:
    gitgh://https%3A%2F%2Fgithub.com%2Foxygenxml%2Fug/master/DITA/topics/introduction.dita
    Notice that:
    1. The URL scheme is gitgh.
    2. It uniquely identifies the file DITA/topics/introduction.dita on branch master in the repository oxygenxml/ug on GitHub.
    3. It is different from the URL used to access the file in the GitHub web interface (CMS-URL) https://github.com/oxygenxml/ug/blob/master/DITA/topics/introduction.dita and from the URL used to access the file's raw content (RAW-URL) https://raw.githubusercontent.com/oxygenxml/ug/master/DITA/topics/introduction.dita.

Unique URL Scheme

GitHub
The URLs have the following format:
gitgh://REPOSITORY_URI/BRANCH/PATH_TO_FILE
where:
  • gitgh = The URL scheme. Note that the GitHub plugin must be configured for this URL scheme to work.
  • REPOSITORY_URI = The URI of the GitHub repository (URI-encoded).
  • BRANCH = The name of the branch where the file is located (URI-encoded).
    Note: Git connectors support a Commit ID instead of a Branch name. When specifying a commit ID, the file is always open in read-only mode.
  • PATH_TO_FILE = The path to the file. Each entry in the path should be URI-encoded.

Example: gitgh://https%3A%2F%2Fgithub.com%2Fuser%2Frepo/master/DITA/topics/intro%20topic.dita

GitLab
The URLs have the following format:
gitgl://REPOSITORY_URI/BRANCH/PATH_TO_FILE
where:
  • gitgl = The URL scheme. Note that the GitLab plugin must be configured for this URL scheme to work.
  • REPOSITORY_URI = The URI of the GitLab repository (URI-encoded).
  • BRANCH = The name of the branch where the file is located (URI-encoded).
    Note: Git connectors support a Commit ID instead of a Branch name. When specifying a commit ID, the file is always open in read-only mode.
  • PATH_TO_FILE = The path to the file. Each entry in the path should be URI-encoded.

Example: gitgl://https%3A%2F%2Fgithub.com%2Fuser%2Frepo/master/DITA/topics/intro%20topic.dita

GitLab On-Premise
The URLs have the following format:
gitgle://REPOSITORY_URI/BRANCH/PATH_TO_FILE
where:
  • gitgle = The URL scheme. Note that the GitLab On-Premise plugin must be configured for this URL scheme to work.
  • REPOSITORY_URI = The URI of the GitLab On-Premise repository (URI-encoded).
  • BRANCH = The name of the branch where the file is located (URI-encoded).
    Note: Git connectors support a Commit ID instead of a Branch name. When specifying a commit ID, the file is always open in read-only mode.
  • PATH_TO_FILE = The path to the file. Each entry in the path should be URI-encoded.

Example: gitgle://https%3A%2F%2Fgitlab-example.com%2Fuser%2Frepo/master/DITA/topics/intro%20topic.dita

Bitbucket
The URLs have the following format:
gitbb://REPOSITORY_URI/BRANCH/PATH_TO_FILE
where:
  • gitbb = The URL scheme. Note that the Bitbucket plugin must be configured for this URL scheme to work.
  • REPOSITORY_URI = The URI of the Bitbucket repository (URI-encoded).
  • BRANCH = The name of the branch where the file is located (URI-encoded).
    Note: Git connectors support a Commit ID instead of a Branch name. When specifying a commit ID, the file is always open in read-only mode.
  • PATH_TO_FILE = The path to the file. Each entry in the path should be URI-encoded.

Example: gitbb://https%3A%2F%2Fbitbucket.com%2Fuser%2Frepo/master/DITA/topics/intro%20topic.dita

Git
The URLs have the following format:
git://REPOSITORY_URI/BRANCH/PATH_TO_FILE
where:
  • git = The URL scheme.
  • REPOSITORY_URI = The URI of the Git repository (URI-encoded).
  • BRANCH = The name of the branch where the file is located (URI-encoded).
    Note: Git connectors support a Commit ID instead of a Branch name. When specifying a commit ID, the file is always open in read-only mode.
  • PATH_TO_FILE = The path to the file. Each entry in the path should be URI-encoded.

Example: git://https%3A%2F%2Fgithub.com%2Fuser%2Frepo/master/DITA/topics/intro%20topic.dita

WebDAV
The URLs have the following format:
webdav-https://dav.box.com/dav/path/to/file.dita

where the WebDAV URL of the file is: https://dav.box.com/dav/path/to/file.dita.

SharePoint
The URL of the file is the SharePoint file URL, prefixed with spo-, as in the following example:
spo-https://mycompany.sharepoint.com/myfolder/Shared%20Documents/myfile.dita
REST
The URLs have the following format:
rest://<server-id>/path/to/file.dita

The format can be further specified by the implementer of the REST API.

CMIS
The URLs have the following format:
cmis://SERVER-URL/repository/path/to/file.dita

where the SERVER-URL is the URL of the CMIS service document (URI-encoded). For examples of such server URLs, see the CMIS connector configuration instructions.

Perforce
The URLs have the following format:
p4java://<server-address>:<server-port>//<depot>/path/to/file.xml
where:
  • server-address = The domain name or IP of the server.
  • server-port = The server port, usually 1666.
  • depot = The name of the depot that contains the file.

Opening and Saving Files

For Oxygen XML Web Author to be able to open and save files identified by an OXY-URL, you need to provide a ro.sync.ecss.extensions.api.webapp.plugin.URLStreamHandlerWithContext class and associate it with the scheme of your OXY-URL.

User Authentication

The URLStreamHandlerWithContext receives a contextId for each open and save. This contextId is the session ID of the user that will open or save the file.

Resolving References to Other Files

The XML content edited in Oxygen XML Web Author may contain references to other files. To access a referenced file, Oxygen XML Web Author needs to compute its OXY-URL based on the OXY-URL of the edited file and the value of the reference to it.

For example, the value of the reference of the following image:
<img src="../image/iris.jpg" />
is
../image/iris.jpg

Relative References

Oxygen XML Web Author tries to resolve relative references against the OXY-URL of the currently open file. Also, when inserting references to other files (for example, images), Oxygen XML Web Author tries to insert relative URLs.

Absolute References (Usually CMS-URL)

For this case, you need to provide a URIResolver that will receive the OXY-URL of the currently open file and the CMS-URL of the referenced file.
Note: This resolver will need to make sure that any userinfo from the OXY-URL of the current file is transferred to the result.

For example, suppose an image is referenced in a DITA topic and the OXY-URL of the topic (from a GitHub repository) is:

gitgh://ff33bba498@https%3A%2F%2Fgithub.com%2Foxygenxml%2Fug/master/DITA/topics/intro.dita

and the CMS-URL of the referenced image is:

https://github.com/oxygenxml/ug/blob/master/DITA/img/login.png

then the resolved OXY-URL of the image should be:

gitgh://ff33bba498@https%3A%2F%2Fgithub.com%2Foxygenxml%2Fug/master/DITA/img/login.png

WebDAV Example

If the main document is loaded over WebDAV, the following URIResolver rewrites references to HTTP URLs to use WebDAV and inherit the credentials:
URIResolver uriResolver = new URIResolver() {
    @Override
    public Source resolve(String href, String base) throws TransformerException {
      if (base != null && base.indexOf("webdav-") == 0) {
        if (href.indexOf("http://") == 0 || href.indexOf("https://") == 0) {
          try {
            URL hrefUrl = new URL(href);
            URL baseUrl = new URL(base);
            final URL hrefWithUserInfo = 
                URLUtil.attachUserInfo(hrefUrl, baseUrl.getUserInfo(), null);
            return new Source() {
              
              @Override
              public void setSystemId(String systemId) {
              }
              
              @Override
              public String getSystemId() {
                return "webdav-" + hrefWithUserInfo.toExternalForm();
              }
            };
          } catch (MalformedURLException e) {
          }
        }
      }
      return null;
    }
  };
It can be registered like this:
public class SampleWorkspaceAccess implements WorkspaceAccessPluginExtension {
  public void applicationStarted(StandalonePluginWorkspace pluginWorkspaceAccess) {
    pluginWorkspaceAccess.getXMLUtilAccess().addPriorityURIResolver(uriResolver);
  }
  public boolean applicationClosing() {
    return true;
  }
}

To make Oxygen XML Web Author insert an absolute CMS-URL in content, you should also provide a RelativeReferencesResolver to be used in the Java server-side code and a ReferencesResolver to be used by the JavaScript client-side code.

Anchors

The URLs of the files opened in Oxygen XML Web Author can contain a #fragment anchor that can be used to select or highlight a specific content fragment.

  • If the anchor has the comment(author=...,timestamp=...) form, it points to the first review comment encountered in the document that has the author and the creation time indicated by the anchor. For example, if the following OXY-URL is used to open the intro.dita document:
    gitgh://https%3A%2F%2Fgithub.com%2Foxygenxml%2Fug/master/DITA/topics/intro.dita#comment(author=John%20Doe,timestamp=20220309T151955+0200)
    then the comment created by John at the specified time will be selected in the Review pane and the content associated with this comment will be highlighted in the document.
    Note: The timestamp from the comment anchor can be the timestamp serialized in the XML document or the UNIX timestamp.
  • If the anchor has the line=...,column=... form, it points to the element located at the given line and column in the source of the XML document.
  • If the anchor has a different syntax, then it will be interpreted by the ro.sync.ecss.extensions.api.link.ElementLocatorProvider that is provided by the framework.

    For DITA documents (for example), the anchor can point to a specific element that will be highlighted when the document is opened. For example, the #topic_1/image_1 anchor points to the element with the image_1 id, located inside the topic element with the topic_1 id.