Avoid automatic generation value for required attributes

Post here questions and problems related to oXygen frameworks/document types.
Johann
Posts: 198
Joined: Wed Jun 17, 2015 12:46 pm

Avoid automatic generation value for required attributes

Post by Johann »

Hello,

I am using Author web 22.1.0.0 but I encounter the same behaviour in Oxygen Editor 20.1.

I open an XML file which is associated with a DTD file.

In this DTD file some elements have attributes that are required.

Let's imagine that the DTD says that under my "root" element there is a "chapter" element and in this chapter element a "para" element.
The "chapter" element has an attribute "code" required.

My document is opened in "Author" mode, and it contains only the "root" element.
If if add a "chapter" in my "root" element, it comes with an empty "code" attribute.

Code: Select all

<root>
<chapter code=""></chapter>
</root>
I remove the "chapter" element and instead of adding "chapter" element, I ask to add directly "para" element in my "root" element.
In that case, "chapter" element is automatically generated and as child, "para" element has been created.
The difference is the code attribute of "chapter" element which is not empty but with a generated value.

Code: Select all

<root>
<chapter code="code_brj_rsl_v4b"><para/></chapter>
</root>
How can we avoid this automatic generation of attribute value ?
I have implemented an automatic generation of attributes values by using DocumentFilter in my framework but the behavior I described takes over.

Thanks for your help,

Johann
cristi_talau
Posts: 489
Joined: Thu Sep 04, 2014 4:22 pm

Re: Avoid automatic generation value for required attributes

Post by cristi_talau »

Hello,

I understand that you want to fully control the generation of the values for ID attributes (code in your case). I assume you implemented the "insertFragment" method of AuthorDocumentFilter.

The automatic generation of ID attribute values is implemented in the AuthorDocumentFilterBypass.insertFragment. And you have several ways to control it:
  • Implement also the "setAttribute" method of the filter, and when invoked during the "insertFragment" method, override the default behavior.
  • The generation of ID attributes is governed by an UniqueAttributeRecognizer returned by ro.sync.ecss.extensions.api.ExtensionsBundle.getUniqueAttributesIdentifier(). You can override this method In your framework to return a recognizer that does not automatically generate ids.
Best,
Cristian
Johann
Posts: 198
Joined: Wed Jun 17, 2015 12:46 pm

Re: Avoid automatic generation value for required attributes

Post by Johann »

Hello Cristian,

About your first solution:
Implement also the "setAttribute" method of the filter, and when invoked during the "insertFragment" method, override the default behavior.
Indeed the "setAttribute" method of the filter is triggered when missing elements with required attributes are automatically generated. I could override this method to put my own attribute value generation. But the problem is that the "setAttribute" method is also triggered when a user edits an attribute with the widget. I do not want to perform an automatic attribute value generation when the user sets by himself the value of an attribute. I do not find a way to know if "setAttrbute" is triggered because of the automatic generation of elements and required attributes OR the "normal" way.

About the second solution:
The generation of ID attributes is governed by an UniqueAttributeRecognizer returned by ro.sync.ecss.extensions.api.ExtensionsBundle.getUniqueAttributesIdentifier(). You can override this method In your framework to return a recognizer that does not automatically generate ids.
I tried to implement my own DefaultUniqueAttributeRecognizer. I made sure that "isAutoIDGenerationActive" method return false. I see that I do not enter in "assignUniqueIDs" and "generateUniqueIDs" methods. After all, "setAttribute" is still triggered with a value "code_brj_rsl_v4b".
What did I miss ?

Regards,

Johann
cristi_talau
Posts: 489
Joined: Thu Sep 04, 2014 4:22 pm

Re: Avoid automatic generation value for required attributes

Post by cristi_talau »

Hello,

Regarding the first approach, if the IDs are automatically generated for an inserted fragment. the call stack looks like

Code: Select all

YourFilter.setAttribute
.....
OxygenFilterBypass.insertFragment
YourFilter.insertFragment
You can set a field in your filter when it enters the insertFragment method and clear it when it exits. If the flag is set, in the setAttribute method, then there is an automatic attribute generation.

Regarding the second approach, it may be that the "UniqueAttributesRecognizer" is not registered correctly. Can you check that the "isAutoIDGenerationActive" method is called? Another reason may be that another UniqueAttributesProcessor is registered by the following API:
ro.sync.ecss.extensions.api.AuthorDocumentController.addUniqueAttributesProcessor(UniqueAttributesProcessor).

Best,
Cristian
Johann
Posts: 198
Joined: Wed Jun 17, 2015 12:46 pm

Re: Avoid automatic generation value for required attributes

Post by Johann »

Hello,

Ok for the first approach, I will try that.

Concerning the second approach. I used the field "attributesRecognizer" in the framework:

Code: Select all

<field name="attributesRecognizer">							 
   <String>com.mypackage.MyUniqueAttributesRecognizer</String>
</field>
No other specific class is called in my framework.

Code: Select all

    MyUniqueAttributesRecognizer  extends DefaultUniqueAttributesRecognizer 
I saw the debugger had passed in the method:

Code: Select all

    public boolean isAutoIDGenerationActive() {
        return false;
    }
and it had not passed in "assignUniqueIDs" and in "generateUniqueIDs" methods. However an attribute is still generated. :cry:

Regards,

Johann
cristi_talau
Posts: 489
Joined: Thu Sep 04, 2014 4:22 pm

Re: Avoid automatic generation value for required attributes

Post by cristi_talau »

Hello,

To troubleshoot the second approach you can set a breakpoint in the setAttribute method of the filter and look at the stack trace to see the code responsible for setting the attribute.

The stack trace is obfuscated but you can share it with us if you do not understand where the call comes from. Use the technical support form to submit it securely: https://www.oxygenxml.com/techSupport.html .

Best,
Cristian
Post Reply