Page 1 of 1

Rendering include content in DocBook

Posted: Sat Nov 28, 2020 2:22 am
by manojdcoder
I had posted about rendering xref and conref in DITA earlier [1], implementing RelativeReferenceResolver and URIResolver solved everything.

I have similar issues with DocBook (include) now. I have something like below in my document

Code: Select all

<xi:include xpointer="elementid" href="filename.xml"/>
I get a hit in URIResolver with href as filename.xml#elementid, the right url is returned by resolve method but while rendering in editor it reads Error while parsing external reference

The logs read

Code: Select all

199977 WARN [ http-nio-8080-exec-10 ] ro.sync.servlet.RESTDocumentManager - Error while loading document:  System ID: https://localhost:25608/Editor?ComponentId=id&Token=authtoken
Severity: warning
Description: An 'include' failed, and no 'fallback' element was found.
 
Not sure exactly where it's failing, any pointers?

[1] topic22151.html

Re: Rendering include content in DocBook

Posted: Mon Nov 30, 2020 10:11 pm
by manojdcoder
@cristi_talau You had been helpful so far, I really appreciate that.

Can you show some light on this one please?

Re: Rendering include content in DocBook

Posted: Wed Dec 02, 2020 7:49 pm
by cristi_talau
Hello,

I managed to reproduce your problem in a test case. It seems that the XML parser that we use handles xi:include resolution and it does not invoke the URIResolver. The URIResolver hit that you got was to generate the target for the link icon rendered near the xi:include element. I registered an issue to use the URIResolver also in this case, but is not yet scheduled.

I think that a more robust solution would be to follow the approach described here [1].

If you want a simplified version, you can try to encode the auth token in the "userInfo" part of the URL.
For example, instead of "https://localhost:25608/Editor?Componen ... =authtoken" use an URL like "custom-https://authtoken@localhost:25608/Editor?ComponentId=id". Now, if you implement an URLStreamHandler for "custom-https", you should be able to make the same requests as before, but you do not depend on URIResolver to be invoked for every URL used by the application.

Another possible path would be to use "ro.sync.exml.workspace.api.util.XMLUtilAccess.addPriorityEntityResolver(EntityResolver)" to register an EntityResolver. This EntityResolver is called after the xi:include target is resolved (without using the URIResolver). If you use an URL like: "https://authtoken@localhost:25608/Edito ... =authtoken", the EntityResolver will receive ""https://authtoken@localhost:25608/included.xml" and now you should have all the data required to construct the final URL.

[1] https://www.oxygenxml.com/doc/versions/ ... _auth.html

Re: Rendering include content in DocBook

Posted: Wed Dec 02, 2020 8:33 pm
by manojdcoder
Thank you Cristi, I'm going to try EntityResolver as we transform the URLs into filenames while inserting them into the document in order to support our legacy editor.

https://localhost:25608/Editor?Componen ... =authtoken is transformed to filename.xml

Re: Rendering include content in DocBook

Posted: Thu Dec 03, 2020 7:48 pm
by manojdcoder
I added an EntityResolver, when it hits resolveEntity method, the systemId is like https://authtoken@localhost:25608/included.xml but the publicId is null, how may I get the editor url from which I can construct the final url?

Re: Rendering include content in DocBook

Posted: Thu Dec 03, 2020 10:59 pm
by manojdcoder
I tried getting current editor url using code below.

Code: Select all

pluginWorkspaceAccess.getAllEditorLocations(PluginWorkspace.MAIN_EDITING_AREA)
and returned InputSource, no matter what I do it still fails with same error.

Code: Select all

com.oxygenxml.webauthor.SecurityManager - [OUTGOING CONNECTION] <localhost:25608> - The application tried to connect to https://localhost:25608/Editor?ComponentId=id&Token=authtoken.

27482 WARN [ http-nio-8080-exec-2 ] ro.sync.servlet.RESTDocumentManager - Error while loading document:  System ID: https://localhost:25608/Editor?ComponentId=id&Token=authtoken.
Severity: warning
Description: An 'include' failed, and no 'fallback' element was found.
By the looks of it, SecurityManager logs the correct url constructed by InputSource but still says An 'include' failed, and no 'fallback' element was found.

Re: Rendering include content in DocBook

Posted: Fri Dec 04, 2020 1:13 pm
by cristi_talau
Hello,

In my test, I tried to use inputSource.setCharacterStream() to give the content of the included file. The xi:include was resolved in this case.

Also, I think a better way to get the current editor URL is to use ro.sync.exml.workspace.api.PluginWorkspace.getCurrentEditorAccess(int) .

Best,
Cristian

Re: Rendering include content in DocBook

Posted: Sun Dec 06, 2020 9:29 am
by manojdcoder
Sorry still same issue with inputSource.setCharacterStream(), below is pseudocode

Code: Select all

public class MyEntityResolver implements EntityResolver {
    ....

	@Override
	public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
		if (systemId != null) {
			URL url = new URL(...); // based on systemId and editorLocation

            logger.info(systemId + " ==== " + url); // url is logged as expected

			InputStreamReader in = new InputStreamReader(url.openStream());
			BufferedReader reader = new BufferedReader(in);
			InputSource inputSource = new InputSource();
			inputSource.setCharacterStream(reader);
			return inputSource;
		}
		return null;
	}

}


Also tried using getCurrentEditorAccess(int).getEditorLocation() to get editor url instead of getAllEditorLocations(int) but it throws UnsupportedOperationException

Code: Select all

URL baseUrl = pluginWorkspaceAccess.getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA)
					.getEditorLocation();
Error log:

Code: Select all

java.lang.UnsupportedOperationException: Method unavailable on webapp
        at ro.sync.ecss.webapp.access.g.o(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.access.g.getCurrentEditorAccess(Unknown Source) ~[oxygen.jar:?]
        at com.package.plugin.MyEntityResolver.resolveEntity(MyEntityResolver.java:30) ~[?:?]
        at ro.sync.xml.catalogresolver.m.d(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.xml.catalogresolver.m.c(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.xml.i.d(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.xml.i.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.m.s.c(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_bb.z(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_r.z(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_s.r(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_s.g(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_s.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_r.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_db.ab(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_bb.q(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_s.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_db.ab(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_bb.q(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_s.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_db.ab(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e$_k.b(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.ecss.webapp.e.render(Unknown Source) ~[oxygen.jar:?]
        at ro.sync.servlet.RESTDocumentManager.buildDocumentInfo(RESTDocumentManager.java:1022) ~[classes/:?]
        at ro.sync.servlet.RESTDocumentManager.retrieveDocument(RESTDocumentManager.java:599) ~[classes/:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]

Re: Rendering include content in DocBook

Posted: Mon Dec 07, 2020 5:05 pm
by cristi_talau
Hello,

Can you try to first read the content of the reference in a String to make sure that the content is fetched correctly?

Here is how I implemented the entity resolver:

Code: Select all

  xmlUtilAccess.addPriorityEntityResolver(new EntityResolver() {
      
      @Override
      public InputSource resolveEntity(String publicId, String systemId)
          throws SAXException, IOException {
        InputSource inputSource = new InputSource(systemId);
        inputSource.setCharacterStream(new StringReader(includedFile));
        return inputSource;
      }
    });
Best,
Cristian

Re: Rendering include content in DocBook

Posted: Tue Dec 08, 2020 5:47 am
by manojdcoder
Let me try that, thanks!

Any thoughts on getCurrentEditorAccess(int).getEditorLocation() exception?

Re: Rendering include content in DocBook

Posted: Tue Dec 08, 2020 6:37 am
by manojdcoder
I'm sorry but once again it failed. Below is my DocBook Chapter, has an include of DocBook Section.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<chapter xml:id="chapter_1b53cca2-6337-40a0-aeec-409c92f8a2c2" xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
	<title xml:id="title_e13e7246-70ef-406f-ae0b-a5bd9e1e5430">a002_Chapter</title>
	<para>Test chapter</para>
	<para/>
	<xi:include xpointer="title_0125766b-9997-4275-9eee-8d902abb28ef" href="a3_Section_4ef81e80-6242-4bb2-8aa2-2d417d38417e.xml"/>
</chapter>
Here is how my input source look like now,

Code: Select all

        @Override
	public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
		if (systemId != null && systemId.startsWith(Config.SCHEME) && systemId.indexOf(Config.HREF) == -1) {
			URL[] urls = pluginWorkspaceAccess.getAllEditorLocations(PluginWorkspace.MAIN_EDITING_AREA);
			if (urls.length > 0) {
				URL baseUrl = urls[0];

				URL url = new URL("url for given system id");
				
				// getText(url) returns the content / string form the url
				logger.info(systemId + " = " + getText(url));

				InputSource inputSource = new InputSource(systemId);
				inputSource.setCharacterStream(new StringReader(getText(url)));
				return inputSource;
			}
		}
		return null;
	}
The content is logged as expected but still there is same exception,

Code: Select all

 https://localhost:25608/a3_Section_4ef81e80-6242-4bb2-8aa2-2d417d38417e.xml = <?xml version="1.0" encoding="utf-8"?><section xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="section_afc810d8-6beb-4757-896f-5637bb155a2b">
        <title xml:id="title_0125766b-9997-4275-9eee-8d902abb28ef">a3_Section</title>
        <para>Hello, this is a section in A3 section document.</para>
</section>

74265 WARN [ http-nio-8080-exec-10 ] ro.sync.servlet.RESTDocumentManager - Error while loading document:  System ID: https://localhost:25608/Editor?ComponentId=229&EditorType=OxygenWeb&Token=authtoken
Severity: warning
Description: An 'include' failed, and no 'fallback' element was found.

Re: Rendering include content in DocBook

Posted: Tue Dec 08, 2020 7:10 pm
by mihaela
Hi,

Can you please give us some details about the place were you have added the priority EntityResolver? We are thinking that maybe you placed the code after the document content is resolved.

Best Regards,
Mihaela

Re: Rendering include content in DocBook

Posted: Wed Dec 09, 2020 5:40 am
by manojdcoder
Sure, here is the content of my workspace plugin. Please let me know what am I doing wrong

Code: Select all

public class MyWorkspaceAccess implements WorkspaceAccessPluginExtension {

	private MyRelativeReferenceResolver referenceResolver;
	private MyURIResolver uriResolver;
	private MyEntityResolver entityResolver;

	public void applicationStarted(StandalonePluginWorkspace pluginWorkspaceAccess) {
	        // Resolves actual url into simple filename while inserting it into document
		referenceResolver = new MyRelativeReferenceResolver();
		pluginWorkspaceAccess.addRelativeReferencesResolver(Config.SCHEME, referenceResolver);

                // Handles requests for DITA
		uriResolver = new MyURIResolver();
		pluginWorkspaceAccess.getXMLUtilAccess().addPriorityURIResolver(uriResolver);

                // For DocBook?
		entityResolver = new MyEntityResolver(pluginWorkspaceAccess);
		pluginWorkspaceAccess.getXMLUtilAccess().addPriorityEntityResolver(entityResolver);
	}

	public boolean applicationClosing() {
		return true;
	}
}

Re: Rendering include content in DocBook

Posted: Wed Dec 09, 2020 4:17 pm
by mihaela
Hello,
manojdcoder wrote: Tue Dec 08, 2020 5:47 am Any thoughts on getCurrentEditorAccess(int).getEditorLocation() exception?
We haven't added support for this API in Web Author doe to some limitations that we hade in the past in our code. Now the limitation is gone so I have added an issue in our internal issue tracker to implement it. We will update this thread when it will be available.

Best Regards,
Mihaela

Re: Rendering include content in DocBook

Posted: Wed Dec 09, 2020 4:34 pm
by mihaela
Hi,

The EntityResolver is registered correctly in your code, on applicationStarted.

We did not managed to reproduce the problem, so we need your help to debug this.
The first step is to check if the reference is resolved if you keep only the EntityResolver (please comment the addition of referenceResolver and uriResolver).
Then, if the reference is still not resolved please try to also to change the code from your resolveEntity method to return an InputSource that provides a simple xml (in other words please try to eliminate the code that retrieves the content of the reference file from your server).
Please let us know if the reference is resolved as expected in this case.

Best Regards,
Mihaela

Re: Rendering include content in DocBook

Posted: Wed Dec 09, 2020 6:07 pm
by manojdcoder
I tried removing both URIResolver and ReferenceResolver, hardcoded the XML in the input source but still the same exception.

Code: Select all

InputSource inputSource = new InputSource(systemId);
						inputSource.setCharacterStream(new StringReader(
								"<?xml version=\"1.0\" encoding=\"utf-8\"?><section xmlns=\"http://docbook.org/ns/docbook\" xmlns:xi=\"http://www.w3.org/2001/XInclude\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"5.0\" xml:id=\"section_afc810d8-6beb-4757-896f-5637bb155a2b\">\r\n"
										+ "        <title xml:id=\"title_0125766b-9997-4275-9eee-8d902abb28ef\">a3_Section</title>\r\n"
										+ "        <para>Hello, this is a section in A3 section document.</para>\r\n"
										+ "</section>"));
Is there anything else I could provide to help you debug? I'm on Oxygen 22.1.0.0 if it matters.

Re: Rendering include content in DocBook

Posted: Thu Dec 10, 2020 4:46 pm
by mihaela
Hello,

In 22.1.0.0 version the EntityManager should work. Next thing to try: please include a stacktrace in your resolveEntity implementation and send us the logs to see were it is called from. If you want you can send us the logs on our support email address (support@oxygenxml.com). Thank you.

Best regards,
Mihaela

Re: Rendering include content in DocBook

Posted: Thu Dec 10, 2020 10:53 pm
by manojdcoder
We have just upgraded to v23, we get a hit on resolveEntity still but getAllEditorLocations(PluginWorkspace.MAIN_EDITING_AREA) no longer returns editor url like it used to in v22.1.

Irrespective of that I have emailed you the stack trace. Please let me know if you need any further details.