How to work with the elements registered with DomExtender?

I wrote my DomExtender and registered in it several new DomElement.
How can I get access to these elements from the code?

Thanks in advance.

10 comments
Comment actions Permalink

What do you mean with "from the code"? What usecase are you trying to solve?

0
Comment actions Permalink

Yann, thank you for having responded.
I will try to describe the problem in more detail.
I have xml like this:

<openerp>
     <record>
          <field name="type">form</field>
          <field name="arch">
               <form>
                    ...
               </form>
          </field>
     </record>     
     <record>
          <field name="type">tree</field>
          <field name="arch">
               <tree>
                    ...
               </tree>
          </field>
     </record>
</openerp>

and extender class:

 
public class OdooDomExtender extends DomExtender<OdooDomElement> {
  @Override
  public void registerExtensions
(@NotNull OdooDomElement element, @NotNull DomExtensionsRegistrar registrar) {
    if (!(element instanceof Field) || !"arch".equals(((Field) element).getName().getValue()))
      return;
    final
String type = findType(element);
    if
(type.equals("form"))
      registrar.registerCustomChildrenExtension(Form.class);
    else if
(type.equals("tree"))
      registrar.registerCustomChildrenExtension(Tree.class);
  
}

  @NotNull
  private static
String findType(OdooDomElement element) {
    final String defaultType = "tree";
    
Record record = element.getParentOfType(Record.class, false);
    if
(record == null)
      return defaultType;
    for
(Field field : record.getFields()) {
      if("type".equals(field.getName().getValue()))
        return StringUtil.isEmpty(field.getValue()) ? defaultType : field.getValue();
    
}
    return defaultType;
  
}
}


Next, I would like to use it:

DomManager manager = DomManager.getDomManager(file.getProject());
Openerp root = manager.getFileElement((XmlFile) file, Openerp.class).getRootElement();
 
// code for the Field instance
Field field = root.getRecords().get(0).getFields().get(0);
//I expected that I could get a instance of Form.class or Tree.class like this:
field.getForm()
field.getTree()
// but my registered "Tree" and "Form" not not available from the field.
0
Comment actions Permalink

Unless you want to have your DOM-extensions mapped to accessor with com.intellij.util.xml.CustomChildren, you probably want to use com.intellij.util.xml.reflect.DomExtensionsRegistrar#registerFixedNumberChildExtension com.intellij.util.xml.reflect.DomExtensionsRegistrar#registerCollectionChildrenExtension for sub-tag(s) instead.

0
Comment actions Permalink

Currently, the class "Field" not have accessors to "Form" and "Tree", because "Field" may be of another type, which does not need a reference to "Form" or "Tree".
I expected that the accessor will be created automatically in implementation of my "Field" interface.
Are there ways to access elements of a registered child without a accessor in parent interface?

0
Comment actions Permalink

Accessors cannot be generated dynamically. You could provide @CustomChildren accessor in parent DOM to gather all "dynamic" sub-elements (and use registerCustomChildrenExtension() again).

0
Comment actions Permalink

In this case, I do not understand how to implement Android plugin.
AndroidDomExtender registers the child elements of the function registerSubtags(), but there is no interface accessors. For example org.jetbrains.android.dom.manifest.ManifestElement is empty, but AndroidDomExtender.registerExtensionsForManifest() add subTags for it.
How does it work?

0
Comment actions Permalink

I assume Android plugin does not need to access DOM programmatically at runtime, but adding custom DOM like this still provides completion, highlighting, navigation etc.

0
Comment actions Permalink

Thank you very much for your answers.
Could you give me a link to example that uses dynamically added child elements at runtime?

0
Comment actions Permalink

Unfortunately I'm not aware of examples in Community Edition besides test (com.intellij.util.xml.DomChildrenTest#testGetDomElementCustomChild and com.intellij.util.xml.DomExtensionsTest#testCustomChildrenAccessFromExtender)

0
Comment actions Permalink

This is just what I was looking for.
Thank you.

0

Please sign in to leave a comment.