Specifying a root map for key references resolving programma
-
- Posts: 34
- Joined: Mon Jun 03, 2013 2:17 pm
Specifying a root map for key references resolving programma
Post by yury.eroshenkov »
We are using integrated Oxygen Web Component for our web application and using Oxygen only like a topic editor. To resolving a key referencing we need to specify a root map. But we would like do not present a root map directly as a map, but as a context and switching the context in the background, so, is there any way to specify a root map programmatically using Author Component API?
Thank you, Yury E.
Head of DITAworks development department, *instinctools Gmbh
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Specifying a root map for key references resolving progr
One possibility would be this API:
ro.sync.ecss.extensions.api.component.AuthorComponentFactory.setDITAKeyDefinitionManager(KeyDefinitionManager)
which would allow you to provide the map of keys to be used by our code when computing conkeyrefs, keyrefs, clicking keyref links and so on.
The API would be implemented something like this:
Code: Select all
AuthorComponentFactory.getInstance().setDITAKeyDefinitionManager(new KeyDefinitionManager() {
@Override
public List<KeyDefinitionInfo> getContextKeyDefinitions() {
List<KeyDefinitionInfo> kds = new ArrayList<KeyDefinitionInfo>();
KeyDefinitionInfo kdInfo = new KeyDefinitionInfo();
kdInfo.setProperty(KeyDefinitionInfo.NAME, "test");
kdInfo.setProperty(KeyDefinitionInfo.HREF, "topic2.dita");
try {
kdInfo.setProperty(KeyDefinitionInfo.DEFINITION_LOCATION, URLUtil.correct(new File("test/EXM-26565/test.ditamap")));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
kds.add(kdInfo);
return kds;
}
});
and load in it the DITA Map content. This provider can also be added to a swing JPanel and presents the DITA Map in a tree-like fashion. But even if you just create it and load in it the DITA Map, it should be used as a default for the component to load the keys from.
Regards,
Radu
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I tried to use your suggestion(create a DITAMapTreeComponentProvider using AuthorComponentFactory.createDITAMapTreeComponentProvider()) and I have some questions.
I have some contextMap for example
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<map id="contextMap" xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:oasis:names:tc:dita:xsd:map.xsd">
<title />
<keydef keys="keyFirst">
<topicmeta>
<keywords>
<keyword>This is first key</keyword>
</keywords>
</topicmeta>
</keydef>
<keydef keys="keySecond">
<topicmeta>
<keywords>
<keyword>This is second key</keyword>
</keywords>
</topicmeta>
</keydef>
<keydef keys="reuseTopic" href="reuseTopic.dita" format="dita"/>
</map>
Also I have reuseTopic.xml file for example
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<topic xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="library" xsi:noNamespaceSchemaLocation="urn:oasis:names:tc:dita:xsd:topic.xsd">
<title/>
<body>
<p id="keyP">This is test p.</p>
</body>
</topic>
When I created DITAMapTreeComponentProvider and loaded this contextMap as root context, I opened new topic and insert into some element as
Code: Select all
<keyword keyref="keyFirst"/>
Then I tried insert some element as
Code: Select all
<p conkeyref="reuseTopic/podoP"/>
I create all example topics in Oxygen standalone Xml Editor - all my cases work great.
How should I solve this problem? May be I should use you first suggestion with KeyDefinitionManager ? How I should resolve this key
Code: Select all
<keydef keys="reuseTopic" href="reuseTopic.dita" format="dita"/>
Regards, Alex.
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
What I've noticed in the given snapshots:
1. Inside the map the href attribute value is reuseTopic.dita and a little further down, you talk about reuseTopic.xml (so the extensions differ). Please make sure the correct extension is being used in the keydef.
2. Inside the topic file, the reuse content has id keyP, not podoP. I think the conkeyref should look like this:
Code: Select all
<p conkeyref="reuseTopic/keyP"/>
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I am sorry for my mistakes in the previous post.
Now, I used correct reuseTopic.dita file and I insert correct conkeyref attribute
Code: Select all
<p conkeyref="reuseTopic/keyP"/>
As I wrote above,I create all topics in Oxygen Standalone Xml Editor - all my cases work great.
How Oxygen will know where it need to load reuseTopic.dita file?
May be I should used implements some filter for resolving links?
I am using integrated Oxygen Web Component for our web application - when Oxygen Auhtor Component need resolve conref or other links we send http request for special HttpServlet and return InputStream in Oxygen. May be I need to change value in keyref href attributies?
Best regards, Alex
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
What version of Author Component are you using? I've also tested the sample files inside our sample applet implementation and it worked just fine. Could you try it too (the scenario inside the sample project) and tell me if it works for you too? Inside AuthorComponentSample, I've changed DEFAULT_DOC_CONTENT to contain <p conkeyref="reuseTopic/keyP"/> and I've loaded the map at the end of the constructor:
Code: Select all
// Load the MAP.
DITAMapTreeComponentProvider mapProvider = AuthorComponentFactory.getInstance().createDITAMapTreeComponentProvider();
try {
mapProvider.load(URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\rootMap.ditamap")), null);
} catch (MalformedURLException e) {
e.printStackTrace();
}
The map loaded inside the DITAMapTreeComponentProvider will be parsed and all key definition will be collected. The process knows that the key reuseTopic is mapped to reuseTopic.dita and will know to parse reuseTopic.dita when that particular key is encountered. The whole mechanism, the needed resolver, are built-in inside DITAExtensionsBundle. I don't think you need to do anything else to make it work. Have you, by any chance, overridden createAuthorReferenceResolver() from DITAExtensionsBundle?How Oxygen will know where it need to load reuseTopic.dita file?
May be I should used implements some filter for resolving links?
If you are using an AuthorComponent version 15 or later, you can also set the root map like this:
Code: Select all
try {
AuthorComponentFactory.getInstance().setObjectProperty("keys.context", URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\rootMap.ditamap")).toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
Thank you for your suggestions, but I have not solved problem.
As I wrote above, I am using integrated Oxygen Web Component for our web application - when Oxygen Auhtor Component need resolve conref or other links we send http request for special HttpServlet and return InputStream in Oxygen.
In your examples you used file(contextMap.ditamap) from local filesystem and you create URL for this as
Code: Select all
URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\contextMap.ditamap"))
But I have not this file in local filesystem - I load this file from ContentRepository with special HttpServlet: I generate URL as
Code: Select all
StringBuilder request = new StringBuilder(urlServerBaseHref);
request.append('/').append("repository_root?");
request.append("sourceDocPath").append("=null");
request.append('&').append("destDocPath").append('=');
request.append(URLEncoder.encode(path, "UTF-8"));
.
Then I create create DITAMapTreeComponentProvider
Code: Select all
if (ditaMapTreeComponentProvider == null) {
try {
ditaMapTreeComponentProvider = AuthorComponentFactory.getInstance().createDITAMapTreeComponentProvider();
} catch (AuthorComponentException e) {
e.printStackTrace();
}
}
Code: Select all
StringBuilder request = new StringBuilder(urlServerBaseHref);
request.append('/').append("repository_root?");
request.append("sourceDocPath").append("=null");
request.append('&').append("destDocPath").append('=');
request.append(URLEncoder.encode(path, "UTF-8"));
String urlText = request.toString();
URL url = new URL(urlText);
ditaMapTreeComponentProvider.load(url, null);
So I decide load map before call ditaMapTreeComponentProvider.load() - I used this code
Code: Select all
protected InputStream loadBufferingContent(final URL url) {
final Future<InputStream> future = BACKGROUND_EXECUTOR.submit(new Callable<InputStream>() {
@Override
public InputStream call() throws Exception {
final URLConnection connection = url.openConnection();
connection.setUseCaches(false);
final InputStream source = connection.getInputStream();
try {
final ByteArrayOutputStream temp = new ByteArrayOutputStream();
final byte[] buffer = new byte[512];
for (int lenght = source.read(buffer); lenght != -1; lenght = source.read(buffer)) {
temp.write(buffer, 0, lenght);
}
if (temp.size() < 1) {
return null;
}
return new ByteArrayInputStream(temp.toByteArray());
} finally {
source.close();
}
}
});
try {
return future.get();
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (final ExecutionException e) {
e.printStackTrace();
}
return null;
}
Code: Select all
URL url = new URL(urlText);
InputStream loadBufferingContent = loadBufferingContent(url);
ditaMapTreeComponentProvider.load(url, new InputStreamReader(loadBufferingContent));
I have DITAReferenceResolver class(implements AuthorReferenceResolver) for resolving conrefs. I this class I make some changes for resolving links as this
- I used the same method for load contextMap( loadBufferingContent ) - but then nothing changes if I insert content like this<keydef keys="reuseTopic" href="reuseTopic.dita" format="dita"/>
.<p conkeyref="reuseTopic/keyP"/>
How I can solved this problem?
I try to used your first suggestion -
Code: Select all
AuthorComponentFactory.getInstance().setDITAKeyDefinitionManager(new KeyDefinitionManager() {
@Override
public List<KeyDefinitionInfo> getContextKeyDefinitions() {
List<KeyDefinitionInfo> kds = new ArrayList<KeyDefinitionInfo>();
}
}
I set in DEFINITION_LOCATION property URL like this
.
How I can solved URL problems?
Best regards, Alex
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
Oxygen should have no problem reading from an URL like that. One thing that wont work well with it though, is the relative path resolving. When the URL to reuseTopic.xml will be computed, it will be done similar with the code below.
Code: Select all
String mapLocation = "http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=%2FDitaWorks+Root+Folder%2FSANCHO_ORG%2FNEW_PROJECT%2FMain%2FContent%2Flibrary%2Froot%2FcontextMap.ditamap";
System.out.println(new URL(new URL(mapLocation), "reuseTopic.xml"));
So I suggest that before loading the map, to add a resolver that knows how to create the absolute URLs from the relative locations inside the map:
Code: Select all
final String map = "http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=%2FDitaWorks+Root+Folder%2FSANCHO_ORG%2FNEW_PROJECT%2FMain%2FContent%2Flibrary%2Froot%2FcontextMap.ditamap";
final URL resolvedMap = URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\rootMap.ditamap"));
factory.getXMLUtilAccess().addPriorityURIResolver(new URIResolver() {
public Source resolve(String href, String base) throws TransformerException {
if (base != null && base.equals(map)) {
return new StreamSource(URLUtil.resolveRelativeSystemIDs(resolvedMap, href).toExternalForm());
}
return null;
}
});
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I don;t understand why in previous example you have written
, because the way to my contextMap contains in variablefinal URL resolvedMap = URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\rootMap.ditamap"));
.final String map
Oxygen load contextMap in temp file in local fileSystem?
Could you explain once again this moment?
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
That's just an example on how I tested to see if it works. In my case I had to resolve to something that made sense on my machine. In your case you should probably resolve into something like:
[pre]http://nobrui.com:8888/repository_root? ... %2Flibrary
%2Froot%2FreuseTopic.dita[/pre]
But you know better than me how to resolve reuseTopic.dita relative to the map URL...
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I tried to use your last suggestion but it didn't work.
Code: Select all
AuthorComponentFactory.getInstance().getXMLUtilAccess().addPriorityURIResolver(new URIResolver() {
public Source resolve(String href, String base) throws TransformerException {
System.out.println("Resolve link " + href + " " + base);
}
}
Resolve link XSD2Schtrn.xsl jar:http://nobrui.com:8888/oxygen-editor/li ... atcher.xsl
Resolve link RNG2Schtrn.xsl jar:http://nobrui.com:8888/oxygen-editor/li ... atcher.xsl
Resolve link iso_schematron_skeleton.xsl jar:http://nobrui.com:8888/oxygen-editor/li ... essage.xsl
I used ditaMapTreeComponentProvider.load(url, null) for load contextMap.
Rather than this method differs from my override DITAReferenceResolver, where I resolved <keydef href=""> links?
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I think, that your first suggestion (used KeyDefinitionManager) more flexible method to solve our problem.
For example, I have contextMap.ditamap file - it is this source
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<map id="contextMap" xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:oasis:names:tc:dita:xsd:map.xsd">
<title/>
<keydef keys="sheldonKey">
<topicmeta>
<keywords>
<keyword>This is Sheldon</keyword>
</keywords>
</topicmeta>
</keydef>
<keydef keys="podoKey">
<topicmeta>
<keywords>
<keyword>This is PODO</keyword>
</keywords>
</topicmeta>
</keydef>
<keydef format="dita" href="..%2F..%2FDITA%2FTopics%2FTopic%2FTOPIC_DW_Professional_1.1.56.dita" keys="conkeyrefchunk_podo_Test" navtitle="podo_Test" props="p p_topic_body_p"/>
</map>
and for<keydef keys="podoKey">
elements.<keydef format="dita" href="..%2F..%2FDITA%2FTopics%2FTopic%2FTOPIC_DW_Professional_1.1.56.dita" keys="conkeyrefchunk_podo_Test" navtitle="podo_Test" props="p p_topic_body_p"/>
I tried to use KeyDefinitionInfo.NAME and KeyDefinitionInfo.DESCRIPTION for
element but it doesn't work without KeyDefinitionInfo.DEFINITION_LOCATION.<keydef keys="podoKey">
When I used KeyDefinitionInfo.DEFINITION_LOCATION for
element I have problem with resolve URL.<keydef format="dita" href="..%2F..%2FDITA%2FTopics%2FTopic%2FTOPIC_DW_Professional_1.1.56.dita" keys="conkeyrefchunk_podo_Test" navtitle="podo_Test" props="p p_topic_body_p"/>
My map location is
Code: Select all
String mapLocation = "http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=%2FDitaWorks+Root+Folder%2FSANCHO_ORG%2FNEW_PROJECT%2FMain%2FContent%2Flibrary%2Froot%2FcontextMap.ditamap";
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
Some additions for previous post.
in KeyDefinitionInfo property I added
Code: Select all
new URL(http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=/DitaWorks%20Root%20Folder/SANCHO_ORG/NEW_PROJECT/Main/Content/library/root/contextMap.ditamap)
element.<keydef keys="podoKey">
Then I insert content like this
Code: Select all
<keyword keyref="podoKey"/>
Code: Select all
18:49:01,171 215314 ERROR [ AutomaticallyValidation ] ro.sync.exml.editor.lb - Automatically validation thread stopped because java.lang.NullPointerException
java.lang.NullPointerException
at ro.sync.util.URLUtil.getEditorLocationKey(Unknown Source)
at ro.sync.ecss.dita.d.b.f.i(Unknown Source)
at ro.sync.exml.q.b.h.l(Unknown Source)
at ro.sync.exml.q.g.d(Unknown Source)
at ro.sync.exml.editor.validate.c.e(Unknown Source)
at ro.sync.exml.editor.validate.o.v(Unknown Source)
at ro.sync.exml.editor.validate.o.l(Unknown Source)
at ro.sync.exml.editor.validate.o.g(Unknown Source)
at ro.sync.exml.editor.lb.e(Unknown Source)
at ro.sync.exml.editor.lb$1.jnd(Unknown Source)
at ro.sync.ui.application.u.run(Unknown Source)
Alex
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
I really expected the resolver to solve the problem. You set the URI resolver before loading the map, right? Please try to set it again just before loading the topic that uses the keys... perhaps there is some code that resets the resolvers (if that happens, that would be a problem on our part).
It might be useful if you could send the DITAReferenceResolver on our support list.
Regarding the KeyDefinitionManager, here is a sample on how to create one:
Code: Select all
AuthorComponentFactory.getInstance().setDITAKeyDefinitionManager(new KeyDefinitionManager() {
@Override
public List<KeyDefinitionInfo> getContextKeyDefinitions() {
List<KeyDefinitionInfo> kds = new ArrayList<KeyDefinitionInfo>();
try {
URL mapLocation = URLUtil.correct(new File("D:\\Desktop\\support\\alexmprog\\rootMap.ditamap"));
KeyDefinitionInfo kdInfo = new KeyDefinitionInfo();
kdInfo.setProperty(KeyDefinitionInfo.NAME, "reuseTopic");
kdInfo.setProperty(KeyDefinitionInfo.HREF, "reuseTopic.xml");
kdInfo.setProperty(KeyDefinitionInfo.DEFINITION_LOCATION, mapLocation);
kds.add(kdInfo);
kdInfo = new KeyDefinitionInfo();
kdInfo.setProperty(KeyDefinitionInfo.NAME, "keyFirst");
// TODO If a HREF is not available, give the map location.
kdInfo.setProperty(KeyDefinitionInfo.HREF, mapLocation.toExternalForm());
kdInfo.setProperty(KeyDefinitionInfo.META_CONTENT_PROVIDER, new MetaContentProvider() {
@Override
public String getContent(String nodeClass) {
return "This is first key";
}
});
kdInfo.setProperty(KeyDefinitionInfo.DEFINITION_LOCATION, mapLocation);
kds.add(kdInfo);
} catch (Exception e) {
e.printStackTrace();
}
return kds;
}
});
1) for keyFirst, even though it doesn't have a HREF, I've linked it to the location of the map. If you leave it unbound, you get that NullPointerException you've reported. I'll add an issue to further investigate this.
2) for reuseTopic I've used a relative value for HREF. In your case, please try and build an absolute URI, so that no resolving will be necessary:
Code: Select all
kdInfo.setProperty(KeyDefinitionInfo.HREF, "http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=%2FDitaWorks+Root+Folder%2FSANCHO_ORG%2FNEW_PROJECT%2FMain%2FContent%2Flibrary%2Froot%2F..%2F..%2FDITA%2FTopics%2FTopic%2FTOPIC_DW_Professional_1.1.56.dita");
Code: Select all
<keydef format="dita" href="..%2F..%2FDITA%2FTopics%2FTopic%2FTOPIC_DW_Professional_1.1.56.dita" keys="conkeyrefchunk_podo_Test" navtitle="podo_Test" props="p p_topic_body_p"/>
Code: Select all
http://nobrui.com:8888/repository_root?sourceDocPath=null&destDocPath=%2FDitaWorks+Root+Folder%2FSANCHO_ORG%2FNEW_PROJECT%2FMain%2FContent%2Flibrary%2Froot%2FcontextMap.ditamap
Best regards,
Alex
-
- Posts: 19
- Joined: Tue Mar 11, 2014 11:56 am
Re: Specifying a root map for key references resolving progr
Post by alexandr.golovach »
I tried to used you suggestions for resolve keywords element - it works great.
For conkeyref element resolving I changed our AuthorReferenceResolver implementation and added conkeyref resolving - it works great too.
Now, I have some problem - when I create new KeyDefinitionInfo list, I want to reload AuthorComponent content and resolve actual values in editor. I tried to used this code
Code: Select all
WSAuthorComponentEditorPage.refresh()
How can I reload all conkeyref elements programmatically using Author Component API?
Best regards,
Alex.
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Specifying a root map for key references resolving progr
Post by alex_jitianu »
I can't tell you how glad I am that we are making progress!
First of all, I understand you continued on the KeyDefinitionManager path. One aspect that I feel necessary to be mentioned is that the getContextKeyDefinitions() method can be called quite often so it might be a good idea to implement some sort of cache for list of keys.
Next, like you've already noticed, WSAuthorComponentEditorPage.refresh() only refreshes the keyrefs. If you want to refresh conref/conkeyrefs, then you can invoke the "Refresh References" action, like this:
Code: Select all
AuthorActionsProvider actionsProvider = authorAccess.getEditorAccess().getActionsProvider();
Map<String, Object> authorCommonActions = actionsProvider.getAuthorCommonActions();
Object refreshRefAction = authorCommonActions.get("Author/Refresh_references");
actionsProvider.invokeAction(refreshRefAction);
Best regards,
Alex
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service