2016-10-06 4 views
0

Je crée un constructeur de règle semblable à celui-ci:GWT emboîtées Rédacteurs - rinçage Pas du cycle correctement ou donnant détecté une erreur

enter image description here

Il peut y avoir deux types d'objets de règle:

  • JoinMetadataCondition: contient le type de jointure ("et" ou "ou") et une liste d'autres conditions de métadonnées à joindre
  • LeafMet adataCondition: il contient une définition de règle (variable, opérateur, valeur)

Ces deux conditions mettre en œuvre une MetadataCondition l'interface.

Approche 1

J'ai utilisé trois différents éditeurs pour tenter de modifier les règles, mais je me fais un cycle erreur détectée qui est logique que les règles sont récursives. Voici les trois éditeurs.

MetadataConditionEditor

Il utilise le AbstractSubTypeEditor décrit here et here

C'est le point d'entrée dans les éditeurs de règles. Il recevra la condition de métadonnées de niveau supérieur et, à partir de là, il attachera l'éditeur approprié.

public class MetadataConditionEditor extends Composite implements Editor<MetadataCondition> { 
interface Binder extends UiBinder<Widget, MetadataConditionEditor> {} 

@Ignore 
final JoinMetadataConditionEditor joinMetadataEditor = LibsFactory.injector().getJoinMetadataConditionEditor(); 

@Path("") 
final AbstractSubTypeEditor<MetadataCondition, JoinMetadataCondition, JoinMetadataConditionEditor> joinMetadataEditorWrapper = 
    new AbstractSubTypeEditor<MetadataCondition, JoinMetadataCondition, JoinMetadataConditionEditor>(joinMetadataEditor) { 
     @Override 
     public void setValue(final MetadataCondition value) 
     { 
      setValue(value, isJoinMetadataCondition(value)); 
      if(isJoinMetadataCondition(value)) { 
       container.clear(); 
       container.add(joinMetadataEditor); 
      } 
     } 
}; 


@Ignore 
final LeafMetadataConditionEditor leafMetadataEditor = LibsFactory.injector().getLeafMetadataConditionEditor(); 

@Path("") 
final AbstractSubTypeEditor<MetadataCondition, LeafMetadataCondition, LeafMetadataConditionEditor> leafMetadataEditorWrapper = 
    new AbstractSubTypeEditor<MetadataCondition, LeafMetadataCondition, LeafMetadataConditionEditor>(leafMetadataEditor) { 
     @Override 
     public void setValue(final MetadataCondition value) 
     { 
      setValue(value, !isJoinMetadataCondition(value)); 
      if(!isJoinMetadataCondition(value)) { 
       container.clear(); 
       container.add(leafMetadataEditor); 
      } 
     } 
}; 


@UiField @Ignore SimplePanel container; 


public MetadataConditionEditor() { 
    initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); 
} 


private Boolean isJoinMetadataCondition(MetadataCondition value) { 
    return value instanceof JoinMetadataCondition; 
}} 

JoinMetadataConditionEditor

Utilisé pour éditer les objets JoinMetadataCondition

JoinMetadataConditionEditor public class étend Composite Editor {implémente l'interface Binder étend UiBinder {}

@UiField @Ignore FlowPanel container; 

@UiField 
@Path("type") 
ManualSelectEditor type; 

@Path("conditions") 
ListEditor<MetadataCondition, MetadataConditionEditor> conditions; 


public JoinMetadataConditionEditor() { 
    initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); 

    conditions = ListEditor.of(new MetadataEditorSource()); 
    type.setSelectOptions(EditorConstants.metadataJoins); 
} 


private class MetadataEditorSource extends EditorSource<MetadataConditionEditor> 
{ 
    @Override 
    public MetadataConditionEditor create(int index) 
    { 
     final MetadataConditionEditor subEditor = new MetadataConditionEditor(); 

     container.insert(subEditor, index); 

     return subEditor; 
    } 

    public void dispose(MetadataConditionEditor subEditor) { 
     container.remove(subEditor); 
    } 
}} 

LeafM etadataConditionEditor

Enfin l'éditeur utilisé pour la LeafMetadataCondition

public class LeafMetadataConditionEditor extends Composite implements Editor<LeafMetadataCondition> { 
    interface Binder extends UiBinder<Widget, LeafMetadataConditionEditor> {} 

    @UiField TextBoxEditor name; 
    @UiField TextBoxEditor value; 
    @UiField ManualSelectEditor operator; 


    public LeafMetadataConditionEditor() { 
     initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); 
     operator.setSelectOptions(EditorConstants.metadataOperators); 
    } 
} 

Question

La question est: Comment puis-je éviter le cycle détecté une erreur ou construire cette récursivité d'une manière qui fonctionne ?

Note: Je suis ouvert à de nouvelles façons de le faire. J'ai essayé quelques autres routes telles qu'initialiser des pilotes pour chaque sous-éditeur et les rendre tous CompositeEditors. Cela a été compilé et chargé, mais au moment de vider les pilotes, les valeurs du sous-éditeur n'étaient pas correctement construites, même si les méthodes flush() semblaient être appelées, mais les éditeurs parents ne les utilisaient pas.

Approche 2

La seconde approche consiste à utiliser un CompositeEditor et ayant les éditeurs sous créer leurs propres pilotes qui sont ensuite rincée pour créer le résultat final.

MetadataConditionEditor

public class MetadataConditionEditor extends Composite implements 
          CompositeEditor<MetadataCondition, MetadataCondition, SimpleDriverEditor<MetadataCondition>>, 
          LeafValueEditor<MetadataCondition> 
{ 
    interface Binder extends UiBinder<Widget, MetadataConditionEditor> {} 

// private SimpleBeanEditorDriver<MetadataCondition, ? extends Editor<MetadataCondition>> subDriver; 
    private EditorChain<MetadataCondition, SimpleDriverEditor<MetadataCondition>> chain; 
    private SimpleDriverEditor<MetadataCondition> subEditor; 
    private EditorDelegate<MetadataCondition> delegate; 
    private MetadataCondition value; 

    @UiField @Ignore SimplePanel container; 


    public MetadataConditionEditor() { 
     initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); 
    } 


    @Override 
    public void flush() 
    { 
     if(Utils.isNull(subEditor)) 
      return; 

     GWT.log("----- flush-pre - " + System.identityHashCode(this) + " - " + value);// TODO 

     value = subEditor.flush(); 

     GWT.log("----- flush-post-1 - " + System.identityHashCode(this) + " - " + value.toJson());// TODO 

    } 

    @Override 
    public void onPropertyChange(String... paths) {} 

    @Override 
    @SuppressWarnings("unchecked") 
    public void setValue(MetadataCondition value) 
    { 
     this.value = value; 
//  subDriver = null; 

     if(Utils.isNull(value)) 
      return; 

     GWT.log("----- setValue - " + value);// TODO 

     if(value instanceof JoinMetadataCondition) { 
      SimpleDriverEditor<JoinMetadataCondition> newSubEditor = LibsFactory.injector().getJoinMetadataConditionEditor(); 
      SimpleDriverEditor<? extends MetadataCondition> newSubEditor1 = newSubEditor; 
      subEditor = (SimpleDriverEditor<MetadataCondition>) newSubEditor1; 

      newSubEditor.edit((JoinMetadataCondition) value); 
     } 

     container.clear(); 
     container.add(subEditor); 
    } 

    @Override 
    public void setDelegate(EditorDelegate<MetadataCondition> delegate) { 
     GWT.log("----- setDelegate - " + delegate);// TODO 
     this.delegate = delegate; 
    } 

    @Override 
    public MetadataCondition getValue() { 
     GWT.log("----- getValue - " + System.identityHashCode(this) + " - " + value);// TODO 
     return value; 
    } 

    @Override 
    public SimpleDriverEditor<MetadataCondition> createEditorForTraversal() { 
     GWT.log("----- createEditorForTraversal - " + subEditor);// TODO 
     return subEditor; 
    } 

    @Override 
    public String getPathElement(SimpleDriverEditor<MetadataCondition> subEditor) { 
     GWT.log("----- getPathElement - " + delegate.getPath());// TODO 
     return delegate.getPath(); 
    } 

    @Override 
    public void setEditorChain(EditorChain<MetadataCondition, SimpleDriverEditor<MetadataCondition>> chain) { 
     GWT.log("----- setEditorChain - " + chain);// TODO 
     this.chain = chain; 
    } 
} 

JoinMetadataConditionEditor

public class JoinMetadataConditionEditor extends Composite implements SimpleDriverEditor<JoinMetadataCondition> 
{ 
    interface Binder extends UiBinder<Widget, JoinMetadataConditionEditor> {} 
    interface Driver extends SimpleBeanEditorDriver<JoinMetadataCondition, JoinMetadataConditionEditor> {} 

    private Driver driver = GWT.create(Driver.class); 

    @Inject 
    ModelFactory factory; 

    @UiField @Ignore HTML label; 
    @UiField @Ignore FlowPanel container; 
    @UiField @Ignore Button deleteMetadata; 

    @UiField 
    @Path("type") 
    ManualSelectEditor type; 

    @Path("conditions") 
    ListEditor<MetadataCondition, MetadataConditionEditor> conditions = ListEditor.of(new MetadataEditorSource()); 


    public JoinMetadataConditionEditor() { 
     initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this)); 
     type.setSelectOptions(EditorConstants.metadataJoins); 
    } 


    public SimpleBeanEditorDriver<JoinMetadataCondition, JoinMetadataConditionEditor> createDriver() { 
     driver.initialize(this); 
     return driver; 
    } 


    @Override 
    public JoinMetadataCondition flush() 
    { 
     GWT.log("---------- flush-pre - " + System.identityHashCode(this) + " - " + type.getValue());// TODO 
     GWT.log("---------- flush-pre - " + System.identityHashCode(this) + " - " + conditions.getList());// TODO 
     JoinMetadataCondition value = driver.flush(); 
     GWT.log("---------- flush-post - " + System.identityHashCode(this) + " - " + value.toJson());// TODO 
     return value; 
    } 


    @Override 
    public void edit(JoinMetadataCondition object) { 
     createDriver(); 
     driver.edit(object); 
     label.setText(getLabel(object)); 
    } 


    private String getLabel(JoinMetadataCondition value) { 
     if(StringUtils.equals(value.getType(), JoinMetadataTypes.AND.value())) 
      return LibsFactory.lang().allConditionsAreTrue(); 
     return LibsFactory.lang().anyConditionsAreTrue(); 
    } 


    @Override 
    public HandlerRegistration addDeleteHandler(MetadataDeletedHandler handler) { 
     return addHandler(handler, MetadataDeletedEvent.TYPE); 
    } 


    @UiHandler("deleteMetadata") 
    protected void onDeleteMetadata(ClickEvent event) { 
     fireEvent(new MetadataDeletedEvent((Event) event.getNativeEvent())); 
    } 


    @UiHandler("addAllMetadata") 
    protected void onAddAllMetadata(ClickEvent event) { 
     add(factory.newJoinMetadataCondition(JoinMetadataTypes.AND)); 
    } 


    @UiHandler("addOrMetadata") 
    protected void onAddOrMetadata(ClickEvent event) { 
     add(factory.newJoinMetadataCondition(JoinMetadataTypes.OR)); 
    } 

    @UiHandler("addLeafMetadata") 
    protected void onAddLeafMetadata(ClickEvent event) { 
     add(factory.newLeafMetadataCondition()); 
    } 


    private void add(MetadataCondition metadata) { 
     try { 
      GWT.log("--------------------------------- add() - pre");// TODO 
      conditions.getList().add(metadata); 
      clearErrors(); 
     } catch (Exception e) { 
      GWT.log("--------------------------------- add() - " + e.getMessage()); // TODO 
     } 
    } 


    public void clearErrors() { 
     type.getErrorHandler().clearErrors(); 
    } 


    private class MetadataEditorSource extends EditorSource<MetadataConditionEditor> 
    { 
     @Override 
     public MetadataConditionEditor create(int index) 
     { 
      final MetadataConditionEditor subEditor = new MetadataConditionEditor(); 
      container.insert(subEditor, index); 
      return subEditor; 
     } 

     public void dispose(MetadataConditionEditor subEditor) { 
      container.remove(subEditor); 
     } 
    } 
} 

Problème

Cette deuxième approche semble presque travailler. Le problème est que lorsque je vide le pilote, les sous-pilotes sont également vidés, mais pour une raison quelconque, les éditeurs parents n'incluent pas réellement les valeurs des sous-éditeurs.

Les états de journal générer au-dessus de la sortie suivante lorsque j'ai une condition d'inscription unique imbriqué:

----- flush-pre - 111 - [email protected] 
---------- flush-pre - 761 - null 
---------- flush-pre - 761 - [[email protected]] 
----- flush-pre - 886 - [email protected] 
---------- flush-pre - 929 - and 
---------- flush-pre - 929 - [] 
---------- flush-post - 929 - {"type":"and", "conditions":[]} 
----- flush-post-1 - 886 - {"type":"and", "conditions":[]} 
----- getValue - 886 - [email protected] 
---------- flush-post - 761 - {"type":"and", "conditions":[]} 
----- flush-post-1 - 111 - {"type":"and", "conditions":[]} 
----- getValue - 111 - [email protected] 
{"type":"and", "conditions":[]} 

Comme vous pouvez le voir l'éditeur principal (111) ne comprend pas réellement le contenu de celui-ci est subeditors. Des idées pour lesquelles cela pourrait être?

+0

Avez-vous obtenu n'importe où avec ceci? C'est assez ambitieux! (nice;)) – slugmandrew

+0

Je l'ai fait en fait, mais j'ai essentiellement dû rouler mon propre LeafValueEditor et construire le formulaire à la main :-) –

Répondre

0

Malheureusement, je n'arrivais pas à faire fonctionner ceci en utilisant une approche d'éditeur structurée.

La solution finale consistait à créer un LeafValueEditor et à construire le formulaire «manuellement» en fonction de l'entrée de données fournie par setValue(). J'ai également implémenté HasEditorErrors afin de gérer correctement les erreurs.