Custom ID auto generation pattern.
Oxygen general issues.
-
- Posts: 58
- Joined: Sat Aug 01, 2009 12:57 am
Custom ID auto generation pattern.
I want to change ID auto generation features of DocBook. I want to support m a format like
${ancestorID} - is the id of closest ancestor that have auto id generation enabled
${position} - is the position of the element within context of closest ancestor
I would like to keep the functionality provided by DocBook extension and just build on it but there seems to be no way to easily extend it, unless I copy DocBook extension sources and tweek it directly in files. Is this an acceptable approach? I am developing this for in company use; there should not be any license issues?
Code: Select all
${ancestorID}.${localName}${position}
${position} - is the position of the element within context of closest ancestor
I would like to keep the functionality provided by DocBook extension and just build on it but there seems to be no way to easily extend it, unless I copy DocBook extension sources and tweek it directly in files. Is this an acceptable approach? I am developing this for in company use; there should not be any license issues?
-
- Posts: 9446
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Custom ID auto generation pattern.
Hi Mike,
We offer the Java sources for all the bundled frameworks for which Oxygen has special Author support in order to help you build or customize a specific framework. So there are no licensing issues.
The easiest way would be to extend the:
ro/sync/ecss/extensions/docbook/id/Docbook5UniqueAttributesRecognizer.java
and overwrite the method:
You will have access to the AuthorElement which will also give you access to its parent and the parent has a list of child nodes so you can also compute the position of the child in the parent. The method returns the generated ID.
Regards,
Radu
We offer the Java sources for all the bundled frameworks for which Oxygen has special Author support in order to help you build or customize a specific framework. So there are no licensing issues.
The easiest way would be to extend the:
ro/sync/ecss/extensions/docbook/id/Docbook5UniqueAttributesRecognizer.java
and overwrite the method:
Code: Select all
ro.sync.ecss.extensions.docbook.id.Docbook5UniqueAttributesRecognizer.generateUniqueIDFor(String, AuthorElement)
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 58
- Joined: Sat Aug 01, 2009 12:57 am
Re: Custom ID auto generation pattern.
I prefer to leave provided code along for easier upgrading later and to keep jar down in size.
All I see
inside DefaultUniqueAttributesRecognizer but it uses GenerateIDElementsInfo class that is also used by DocbookConfigureAutoIDElementsOperation. So if I override the generateUniqueIDFor method I'll lose some of the functionality of GenerateIDElementsInfo. I can work around it by running it through GenerateIDElementsInfo.generateID and then through my custom method, but the DocbookConfigureAutoIDElementsOperation would not be changed, it will not have a new tooltip that details the format.
Anyways I think this approach will work. Thanks for all of the help. I did not notice at first that authorAccess in DefaultUniqueAttributesRecognizer is protected and not private.
All I see
Code: Select all
protected String generateUniqueIDFor(String idGenerationPattern, AuthorElement element)
Anyways I think this approach will work. Thanks for all of the help. I did not notice at first that authorAccess in DefaultUniqueAttributesRecognizer is protected and not private.
-
- Posts: 58
- Joined: Sat Aug 01, 2009 12:57 am
Re: Custom ID auto generation pattern.
GenerateIDElementsInfo on constructor
does not respect the default IDGenerationPattern provided in defaultOptions. Why? This makes this class impossible to override. Worse yet, this class is included in oxygen.jar so even if I change the code in GenerateIDElementsInfo.java it gets ignored.
I don't know what to do.
Code: Select all
public GenerateIDElementsInfo(AuthorAccess authorAccess, GenerateIDElementsInfo defaultOptions) {
//Read the Auto ID Elements Info from options.
this(isAutoGenerateIDs(authorAccess, defaultOptions),
getIDGenerationPattern(authorAccess),
getIDGenerationElements(authorAccess, defaultOptions));
}
I don't know what to do.

-
- Posts: 9446
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Custom ID auto generation pattern.
Hi Mike,
First about the OptionsStorage:
Using this API you save your preferences in the Oxygen XML preferences files usually located in the folder:
%APPDATA%\com.oxygenxml (for Oxygen for XML Editor)
or:
%APPDATA%\com.oxygenxml.author (for Oxygen XML Author)
About the method I suggested you to overwrite, I enclosed the signature between bold tags and the forum truncated the signature (I fixed it now), it is the same signature you discovered.
The GenerateIDElementsInfo has two constructors, one of them takes the patterns as parameters:
The other constructor receives as a parameter the default GenerateIDElementsInfo value as sent for example by the
About modifying classes from the ro.sync.ecss.extensions.commons package:
Indeed they are also present in the oxygen.jar so any modifications that you make directly to them will be ignored.
but:
You can rename the package ro.sync.ecss.extensions.commons in your Java sources to something else. In this way your customization will use the modified package and the class loader will not prefer the oxygen.jar
Regards,
Radu
First about the OptionsStorage:
Using this API you save your preferences in the Oxygen XML preferences files usually located in the folder:
%APPDATA%\com.oxygenxml (for Oxygen for XML Editor)
or:
%APPDATA%\com.oxygenxml.author (for Oxygen XML Author)
About the method I suggested you to overwrite, I enclosed the signature between bold tags and the forum truncated the signature (I fixed it now), it is the same signature you discovered.
The GenerateIDElementsInfo has two constructors, one of them takes the patterns as parameters:
Code: Select all
public GenerateIDElementsInfo(boolean autoGenerateIds, String idGenerationPattern, String[] elementsWithIDGeneration)
Code: Select all
Docbook4UniqueAttributesRecognizer.GENERATE_ID_DEFAULTS
Indeed they are also present in the oxygen.jar so any modifications that you make directly to them will be ignored.
but:
You can rename the package ro.sync.ecss.extensions.commons in your Java sources to something else. In this way your customization will use the modified package and the class loader will not prefer the oxygen.jar
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 58
- Joined: Sat Aug 01, 2009 12:57 am
Re: Custom ID auto generation pattern.
Thank you for comprehensive answer. I'll look into renaming the package in my sources. I was really hopping to avoid such implementation though. So far I was able to implement everything I need just by extending Docbook5UniqueAttributesRecognizer and GenerateIDElementsInfo. And if it was not for the weird behavior in GenerateIDElementsInfo constructor everything would be fine.
Is there really a reason why "generation ID pattern" provided by "defaultOptions" argument is ignored in constructor and static value is used? Code like following would work much better and still be perfectly compatible with all other existing code.
Also with current implementation, there is a false sense that all ID generation defaults are defined in Docbook4UniqueAttributesRecognizer.GENERATE_ID_DEFAULTS. Only the "auto-generate" flag and list of elements are respected. The default ID generation pattern is ignored, it just happens to work because it is pulled from the same place of GenerateIDElementsInfo class that constructor uses.
What if someone was to ask you how they can override just the default ID generation pattern? Would you have them copy the sources, rename the packages and re implement bunch of classes? It seems like too much work for such simple task.
Anyways, it seems like a bug. Please tell me what you think of this and whether you are planning on fixing it. I think for now I can work around it by overriding default on every installation, but if you are not planning on fixing this I will start including your code and renaming packages.

Code: Select all
public GenerateIDElementsInfo(AuthorAccess authorAccess, GenerateIDElementsInfo defaultOptions) {
//Read the Auto ID Elements Info from options.
this(isAutoGenerateIDs(authorAccess, defaultOptions),
getIDGenerationPattern(authorAccess, defaultOptions),
getIDGenerationElements(authorAccess, defaultOptions));
}
private static String getIDGenerationPattern(AuthorAccess authorAccess,GenerateIDElementsInfo defaultOptions) {
return authorAccess.getOptionsStorage().getOption(
GENERATE_ID_PATTERN_KEY, defaultOptions.getIdGenerationPattern());
}
What if someone was to ask you how they can override just the default ID generation pattern? Would you have them copy the sources, rename the packages and re implement bunch of classes? It seems like too much work for such simple task.
Anyways, it seems like a bug. Please tell me what you think of this and whether you are planning on fixing it. I think for now I can work around it by overriding default on every installation, but if you are not planning on fixing this I will start including your code and renaming packages.
-
- Posts: 9446
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Custom ID auto generation pattern.
Hi Mike,
I also think this is a bug, the pattern should be taken from the default options object, we'll correct this in Oxygen 13.
You can also probably make it work using some Java reflection to change the private pattern field after you have delegated to the constructor but it's more of a hack really. I'll also add some public setter methods in the class for easier modifying the fields from user code.
Regards,
Radu
I also think this is a bug, the pattern should be taken from the default options object, we'll correct this in Oxygen 13.
You can also probably make it work using some Java reflection to change the private pattern field after you have delegated to the constructor but it's more of a hack really. I'll also add some public setter methods in the class for easier modifying the fields from user code.
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 58
- Joined: Sat Aug 01, 2009 12:57 am
Re: Custom ID auto generation pattern.
Since you are looking as this, can you provide a way to override the tooltip in SAIDElementsCustomizerDialog. Currently it just gets set to GenerateIDElementsInfo.PATTERN_TOOLTIP (line 227 in SAIDElementsCustomizerDialog.java)
Currently to change it I have to override the whole chain of classes, so I just don't bother, but it would be nice to have a mechanism to do so. A possible way to do it is to move tooltip initialization into showDialog() method and use the available autoIDElementsInfo object.
Code: Select all
//Tooltip for the pattern field idGenerationPatternField.setToolTipText(GenerateIDElementsInfo.PATTERN_TOOLTIP);
Code: Select all
public GenerateIDElementsInfo showDialog(GenerateIDElementsInfo autoIDElementsInfo) { idGenerationPatternField.setToolTipText(autoIDElementsInfo.PATTERN_TOOLTIP);
.....
-
- Posts: 9446
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Custom ID auto generation pattern.
Hi Mike,
I'll see what I can do. I'll probably leave the field public and static with the same name (for backward compatibility) and create a public method which returns it to be used in the dialogs. In this way the method will be overwritten for customizations.
In the meantime, if you still do not want to take the entire commons package over to your implementation (by changing its name) you can use Java reflection to change it's value. But you have to do this before the first show of the dialog (when the AuthorExtensionStateListener is activated for example):
Regards,
Radu
I'll see what I can do. I'll probably leave the field public and static with the same name (for backward compatibility) and create a public method which returns it to be used in the dialogs. In this way the method will be overwritten for customizations.
In the meantime, if you still do not want to take the entire commons package over to your implementation (by changing its name) you can use Java reflection to change it's value. But you have to do this before the first show of the dialog (when the AuthorExtensionStateListener is activated for example):
Code: Select all
try {
Field field = GenerateIDElementsInfo.class.getField("PATTERN_TOOLTIP");
field.setAccessible(true);
field.set(null, "YOUR CUSTOM VALUE HERE");
} catch (Exception e1) {
e1.printStackTrace();
}
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ Artificial Intelligence (AI Positron Assistant add-on)
- ↳ 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