Conrefs are not pulled in the Author component sometimes

Having trouble installing Oxygen? Got a bug to report? Post it all here.
yury.eroshenkov
Posts: 34
Joined: Mon Jun 03, 2013 2:17 pm

Conrefs are not pulled in the Author component sometimes

Post by yury.eroshenkov »

Hi, Oxygen team.
We are using Oxygen Author web component and have a next problem:
after insert the conref from some topic inside current topic, which are opened in the Author component, the referenced content is not visible, just like the referenced element hasn't an ID, but, actually it has.
Looks like the reference resolver takes an old XML from the referenced topic from some cache, where the ID was not present yet.
Two interesting facts:
1. This happens only on the tomcat server, on which our web app is deployed(including an oxygen applet) with the non-"localhost" address, but never happens on the local dev environment on the localhost.
2. The issue occures only when the referenced element didn't has an ID before conref insering operation, but while creation of a conref this ID is generated, and the Oxygen resolver starting to resolve a reference only when the ID is already exists in the referenced XML. This two operations are working together in the one part of the code synchronously (first operation - genereting an ID in the referenced topic, second - past the reference to the Oxygen resolver). Feeling, like while resolving the content is taken not from the actual topic, but from some cache, and this cache has not enough time to update between this two operations. Because, when we go to the referenced topc and make an ID manually and after that create the content reference - everything is ok.

Best regards, Yury.
Radu
Posts: 9449
Joined: Fri Jul 09, 2004 5:18 pm

Re: Conrefs are not pulled in the Author component sometimes

Post by Radu »

Hi Yury,

I think the problem might be the fact that the default Java SUN HTTP connection implementation has such a connection caching enabled by default. You can look at the java.net.URLConnection.defaultUseCaches flag and at the java.net.URLConnection.setUseCaches(boolean), java.net.URLConnection.setDefaultUseCaches(boolean) method. So if you open an HTTP URL connection over the same URL and read the content twice from it you will obtain by default the same older content although the content has been modified between the two reads.

If you look at the Java sources (available in the Author SDK) for "ro.sync.ecss.extensions.dita.conref.DITAConRefResolver.resolveReference" Oxygen creates an input source over the reference URL:

Code: Select all

inputSource = new InputSource(conRef.getUri());
and then the created sax source will be delegated to the Xerces parser to read. The parser will create HTTP connections over the source but because of the caching the same content will be obtained by it.

So you might want to consider calling the static method java.net.URLConnection.setDefaultUseCaches(boolean) sometime before the AuthorComponentFactory is initialized and see if this works for you.

Or possibly try this workaround:

http://www.oxygenxml.com/doc/ug-oxygen/ ... ching.html

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
yury.eroshenkov
Posts: 34
Joined: Mon Jun 03, 2013 2:17 pm

Re: Conrefs are not pulled in the Author component sometimes

Post by yury.eroshenkov »

Hi Radu.
Thanks for the solution. There is no static method setDefaultUseCaches() in the URLConnection class, but we've reorganized the referenceResolve() method in the way when we past an InpurSource based on the already asked InputStream to SAXReader, because the URLConnection creation logic was incapsulated deep inside SAX code.

Thank you.
Radu
Posts: 9449
Joined: Fri Jul 09, 2004 5:18 pm

Re: Conrefs are not pulled in the Author component sometimes

Post by Radu »

Hi Yuri,

Indeed that method is not static, sorry for not looking better at it. One alternative would have been to modify the field java.net.URLConnection.defaultUseCaches using Java reflection.

Anyway your approach is also a good one, as you are the one opening the input stream you should also be the one closing it, for example you could do something like:

Code: Select all

              inputSource = new InputSource(conRef.getUri());
URL conrefURL = new URL(conRef.getUri());
//Connect without caching.
URLConnection connection = conrefURL.openConnection();
connection.setUseCaches(false);
connection.connect();
//Read entire bytes content from input stream.
InputStream is = connection.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = -1;
while((len = is.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
//Close input stream:
is.close();
//Disconnect
if(connection instanceof java.net.HttpURLConnection) {
((java.net.HttpURLConnection)connection).disconnect();
}
inputSource.setByteStream(new ByteArrayInputStream(bos.toByteArray()));
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply