All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.mihosoft.vmf.vmftext.grammar.impl.AlternativeImpl Maven / Gradle / Ivy

The newest version!

package eu.mihosoft.vmf.vmftext.grammar.impl;

// vmf imports
//import eu.mihosoft.vmf.runtime.core.*;
//import eu.mihosoft.vmf.runtime.core.internal.*;
import eu.mihosoft.vcollections.*;
import eu.mihosoft.vmf.vmftext.grammar.*;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.Arrays;

// property types imports
import eu.mihosoft.vcollections.*;

// implementation

/**
 * An implementation of the model object {@code eu.mihosoft.vmf.vmftext.grammar.Alternative}.
 */
@SuppressWarnings("deprecation")
class AlternativeImpl implements Alternative, eu.mihosoft.vmf.runtime.core.internal.VObjectInternalModifiable, VCloneableInternal {

  // --------------------------------------------------------------------
  // --- declaration of member variables
  // --------------------------------------------------------------------


  /*package private*/ eu.mihosoft.vcollections.VList elements;
  /*package private*/ int id;
  /*package private*/ eu.mihosoft.vmf.vmftext.grammar.UPRuleBase parentRule;
  /*package private*/ java.lang.String text;


// --------------------------------------------------------------------
// --- declaration of delegation variables
// --------------------------------------------------------------------

  private eu.mihosoft.vmf.vmftext.grammar.unparser.SubRuleIndexUpdater _vmf_delegate0;

  private PropertyChangeSupport propertyChanges;

  // referenced by
  private final VList referencedBy = VList.newInstance(new java.util.ArrayList<>());
  // references
  private final VList references = VList.newInstance(new java.util.ArrayList<>());

  // --------------------------------------------------------------------
  // --- public constructors
  // --------------------------------------------------------------------

  public AlternativeImpl() {

// --------------------------------------------------------------------
// --- declaration of delegation methods
// --------------------------------------------------------------------


    if(_vmf_delegate0==null) {
      _vmf_delegate0 = new eu.mihosoft.vmf.vmftext.grammar.unparser.SubRuleIndexUpdater();
      _vmf_delegate0.setCaller(this);
    }

    _vmf_delegate0.onAlternativeBaseInstantiated();


// --------------------------------------------------------------------
// --- initialization of default values
// --------------------------------------------------------------------
    // property 0
    // -> no default value is present
    // property 1
    // -> no default value is present
    // property 2
    // -> no default value is present
    // property 3
    // -> no default value is present

  }

  // --------------------------------------------------------------------
  // --- public getter methods for accessing properties
  // --------------------------------------------------------------------


  @Override
  public eu.mihosoft.vcollections.VList getElements() {

    if(this.elements==null) {
      this.elements = VList.newInstance(new java.util.ArrayList<>());

      this.elements.addChangeListener((evt)-> {
            evt.added().elements().forEach((e)->{

                if(e==null) return;

                // remove element from previous collection
                // TODO use bulk operations if possible
                if(e.getParentAlt()!=null) {
                  e.getParentAlt().getElements().remove(e);
                }

                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parentAlt");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, this);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     AlternativeImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }



                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }

            }); // end of evt.added()

            evt.removed().elements().forEach((e)->{
              if(e==null) return;
                
                try {
                  java.lang.reflect.Field field =
                    e.getClass().getDeclaredField("parentAlt");
                  field.setAccessible(true);
                  Object oldOpposite = field.get(e);
                  field.set(e, null);
                  // not generating change event (disableFireEventValue=true)
                } catch (Exception ex) {
                  java.util.logging.Logger.getLogger(
                     AlternativeImpl.class.getName()).
                     log(java.util.logging.Level.SEVERE, null, ex);
                }




                if(e!=null && this!=null) {
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(e);
                  ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)e)._vmf_referencedBy().add(this);
                }
            }); // end of evt.removed()
            
        }); // end of change listener

    } // end of "lazy init" if(this.elements==null)

    return this.elements;

    // return VContainmentUtil.asContainmentList(this.elements, "parentAlt");
  } // end of eu.mihosoft.vcollections.VList getElements()
  @Override
  public int getId() {
    return this.id;

  } // end of int getId()
  @Override
  public eu.mihosoft.vmf.vmftext.grammar.UPRuleBase getParentRule() {
    return this.parentRule;

  } // end of eu.mihosoft.vmf.vmftext.grammar.UPRuleBase getParentRule()
  @Override
  public java.lang.String getText() {
    return this.text;

  } // end of java.lang.String getText()

  // --------------------------------------------------------------------
  // --- public setter methods for setting properties
  // --------------------------------------------------------------------


   @Override
   public void setId(int id) {

    // return early if identical value has been set
    if (this.id == id) {
      return;
    }

    // set the new value
    int oldValue = this.id;
    this.id = id;

    // fire property change event
    _vmf_firePropertyChangeIfListenersArePresent("id", oldValue, this.id);
 

  } // setterDeclaration (setter method)
      @Override
  public void setParentRule(eu.mihosoft.vmf.vmftext.grammar.UPRuleBase parentRule) {

    // opposite is a collection type. we just need to add this to the
    // opposite collection which will handle the containment just fine

    // nothing to do, values are identical
    if(this.parentRule == parentRule) {
      return;
    }

    // remove this from previous opposite
    if(this.parentRule!=null) {
        this.parentRule.getAlternatives().remove(this);
    }

    // add this to new opposite
    if(parentRule!=null) {
        parentRule.getAlternatives().add(this);
    }
  }
    @Override
   public void setText(java.lang.String text) {

    // return early if identical value has been set
    if (this.text == text) {
      return;
    }

    // set the new value
    java.lang.String oldValue = this.text;
    this.text = text;

    // fire property change event
    _vmf_firePropertyChangeIfListenersArePresent("text", oldValue, this.text);
 

  } // setterDeclaration (setter method)
   
  // --------------------------------------------------------------------
  // --- Object methods (equals(), toString() etc.)
  // --------------------------------------------------------------------


  // --------------------------- BEGIN TO_STRING -----------------------------
  @Override
  public String toString() {

    boolean entry = _vmf_getThreadLocalToString().get().isEmpty();
    try {
        // test if "this" has been seen before
        // implementation based on http://stackoverflow.com/a/11300376/1493549
        boolean isImmutable = (this instanceof eu.mihosoft.vmf.runtime.core.Immutable);
        if (!isImmutable && _vmf_getThreadLocalToString().get().containsKey(this)) {
          return "{skipping recursion}";
        } else {
          if(!isImmutable) {
            _vmf_getThreadLocalToString().get().put(this, null);
          }
          entry = true;
        }
        return "{\"@type\":\"Alternative\"" +
        ", " + (this.elements==null?"[]":this.elements) +
          ", \"id\": \"" + this.id + "\"" +
           ", \"text\": \"" + this.text + "\"" +
           "}";
    } finally {
        if (entry) {
            _vmf_getThreadLocalToString().get().clear();
            _vmf_fToStringChecker = null;
        }
    }
  }

  private ThreadLocal> _vmf_getThreadLocalToString() {
    if (_vmf_fToStringChecker==null) {
      _vmf_fToStringChecker = ThreadLocal.withInitial(
        () -> new java.util.IdentityHashMap<>());
    }

    return _vmf_fToStringChecker;
  }

  private ThreadLocal> _vmf_fToStringChecker;

  // end toString()
  // ---------------------------- END TO_STRING ------------------------------


  // --------------------------- BEGIN EQUALITY -----------------------------
  @Override
  public boolean equals(Object o) {

    boolean entry = _vmf_getThreadLocalEquals().get().isEmpty();
    try {
      // test if the object pair (this,o) has been checked before
      boolean isImmutable = (o instanceof eu.mihosoft.vmf.runtime.core.Immutable);
      if (!isImmutable && _vmf_getThreadLocalEquals().get().containsKey(new EqualsPair(this, o))) {
        // This pair has been seen before. That's why we return true now.
        // If this pair wasn't equal, we wouldn't need to do a second
        // comparison. Returning 'true' is equivalent to ignoring this
        // particular test in the calling 'equals()' method.
        return true;
      } else {
        if(!isImmutable) {
          _vmf_getThreadLocalEquals().get().put(new EqualsPair(this, o), null);
        }
        entry = true;
      }

      if (o==null) return false;
      else if (this==o) return true;

      // if object is read-only wrapper then unwrap the actual object
      if(o instanceof ReadOnlyAlternativeImpl) {
        o = ((ReadOnlyAlternativeImpl)o)._vmf_getMutableObject();
      }

      // -- try our interface/implementation --

      // perform the actual comparison for each property
      if (o instanceof AlternativeImpl) {
        AlternativeImpl other = (AlternativeImpl) o;
        return           _vmf_equals(this.elements, other.elements) &&
          _vmf_equals(this.id, other.id) &&
          _vmf_equals(this.text, other.text);
      }

      // -- try every implementation that implements our interface --

      // perform the actual comparison for each property
      if (o instanceof LabeledAlternativeImpl) {
        LabeledAlternativeImpl other = (LabeledAlternativeImpl) o;
        return           _vmf_equals(this.elements, other.elements) &&
          _vmf_equals(this.id, other.id) &&
          _vmf_equals(this.text, other.text);
      }

      // no implementation matched. we end the comparison.
      return false;
    } finally {
      if (entry) {
          _vmf_getThreadLocalEquals().get().clear();
          _vmf_fEqualsChecker = null;
      }
    }
  } // end equals()

  private static boolean _vmf_equals(Object o1, Object o2) {
    boolean oneAndOnlyOneIsNull = (o1 == null) != (o2 == null);
    boolean collectionType = o1 instanceof VList || o2 instanceof VList;

    // since we support lazy initialization for collections,
    // uninitialized empty collection values are defined as equal to null
    // otherwise we would have to initialize these values, which would then
    // neutralize or even negate the positive effect of lazy initialization
    if(oneAndOnlyOneIsNull && collectionType) {
      if(o1==null) {
        return ((VList)o2).isEmpty();
      } else {
        return ((VList)o1).isEmpty();
      }
    } else {
      return Objects.equals(o1,o2);
    }
  }

  @Override
  public int hashCode() {
      boolean entry = _vmf_getThreadLocalHashCode().get().isEmpty();
      try {
          // test if "this class" has been seen before
          //
          // WARNING we use `System.identityHashCode(this)` to prevent recursive
          // hashCode() calls before we do the actual test. This would eliminate
          // the effect of the thread-local map
          if (_vmf_getThreadLocalHashCode().get().containsKey(System.identityHashCode(this))) {
            return 0; // already visited
          } else {
            _vmf_getThreadLocalHashCode().get().put(System.identityHashCode(this), null);
            int value = _vmf_deepHashCode(
            this.elements,            this.id,            this.text        );
            entry = true;
            return value;
          }

      } finally {
          if (entry) {
              _vmf_getThreadLocalHashCode().get().clear();
              _vmf_fHashCodeChecker = null;
          }
      }

  } // end hashCode()

  // fixes 'array discovery problems' with the 'Objects.hash(...)' method
  // see http://stackoverflow.com/questions/30385018/how-to-use-java-7-objects-hash-with-arrays
  private int _vmf_deepHashCode(Object... fields) {
      // WARNING we are not allowed to pass arrays that contain itself
      //         or are contained in nested arrays
      return Arrays.deepHashCode(fields);
  } // end _vmf_deepHashCode()

  /**
   * The purpose of this class is to store a pair of objects used for equals().
   * This class's equals() method checks equality by object identity. Same
   * for hashCode() which uses identity hashes of 'first' and 'second' to
   * compute the hash.
   *
   * This class can be used in conjunction with a regular HashMap to get
   * similar results to an IdentityHashMap, except that in this case identity
   * pairs can be used. And we don't have to use a map implementation that is
   * deliberately broken by design.
   */
  private static class EqualsPair {

      final Object first;
      final Object second;

      public EqualsPair(Object first, Object second) {
          this.first = first;
          this.second = second;
      }

      @Override
      public int hashCode() {
          return Objects.hash(System.identityHashCode(first),
                  System.identityHashCode(second));
      }

      @Override
      public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final EqualsPair other = (EqualsPair) obj;
        if (this.first!=other.first) {
            return false;
        }
        if (this.second!=other.second) {
            return false;
        }
        return true;
      }
  }

  private ThreadLocal> _vmf_getThreadLocalEquals() {
    if (_vmf_fEqualsChecker==null) {
      _vmf_fEqualsChecker = ThreadLocal.withInitial(
        () -> new java.util.HashMap<>());
    }

    return _vmf_fEqualsChecker;
  }

  private ThreadLocal> _vmf_getThreadLocalHashCode() {
    if (_vmf_fHashCodeChecker==null) {
      _vmf_fHashCodeChecker = ThreadLocal.withInitial(
        () -> new java.util.HashMap<>());
    }

    return _vmf_fHashCodeChecker;
  }

  private ThreadLocal> _vmf_fEqualsChecker;


  private ThreadLocal> _vmf_fHashCodeChecker;
  // ---------------------------- END EQUALITY ------------------------------


  // --------------------------- BEGIN CLONING -----------------------------
  /**
   * Package private copy constructor.
   * It creates a deep or shallow copy of the specified other object.
   * @param other other object
   * @param deepCopy defines whether to perform a deep copy
   */
  AlternativeImpl (
    AlternativeImpl other,
    boolean deepCopy, java.util.IdentityHashMap identityMap
  ) {
    identityMap.put(other,this);

    if(deepCopy) {
      if(other.elements!=null) {
        // element type is a model type
        for(UPElement e : other.elements) {
          // TODO do a bulk operation instead
          eu.mihosoft.vmf.runtime.core.internal.VObjectInternal eClone = (eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)(UPElement)((VCloneableInternal)e)._vmf_deepCopy(identityMap);
          this.getElements().add((UPElement)eClone);
        }
       } else {
        // nothing to copy
      }
    } else {
      this.elements = other.elements;
    }
    if(this.elements!=null) {
      this.elements.forEach((e) -> {
          
        try {
          java.lang.reflect.Field field =
            e.getClass().getDeclaredField("parentAlt");
          field.setAccessible(true);
          Object oldOpposite = field.get(e);
          field.set(e, this);
          // not generating change event (disableFireEventValue=true)
        } catch (Exception ex) {
          java.util.logging.Logger.getLogger(
             AlternativeImpl.class.getName()).
             log(java.util.logging.Level.SEVERE, null, ex);
        }

      });
    }
           // property type is an external type (TODO implement cloning strategy)
      this.setId(other.id);
            // property type is an external type (TODO implement cloning strategy)
      this.setText(other.text);
    
   } // end copy constructor

   @Override
   public AlternativeImpl _vmf_deepCopy(java.util.IdentityHashMap identityMap) {
      if(identityMap.containsKey(this)) {
        return (AlternativeImpl)identityMap.get(this);
      } else {
        AlternativeImpl clonedVal = new AlternativeImpl(this, true, identityMap);
        return clonedVal;
      }
   }

   @Override
   public AlternativeImpl _vmf_shallowCopy(java.util.IdentityHashMap identityMap) {
      if(identityMap.containsKey(this)) {
        return (AlternativeImpl)identityMap.get(this);
      } else {
        AlternativeImpl clonedVal = new AlternativeImpl(this, false, identityMap);
        return clonedVal;
      }
   }
  @Override
  public AlternativeImpl clone() /*throws CloneNotSupportedException*/ {
    // http://stackoverflow.com/questions/12886036/deep-copying-a-graph-structure
    // http://softwareengineering.stackexchange.com/questions/228848/how-does-java-handle-cyclic-data-references-when-serializing-an-object
    // https://gist.github.com/kanrourou/47223bdaf481505d4c7e
    // http://www.programcreek.com/2012/12/leetcode-clone-graph-java/
    java.util.IdentityHashMap identityMap =
      new java.util.IdentityHashMap<>();
    return _vmf_deepCopy(identityMap);
  }
  // ---------------------------- END CLONING ------------------------------


// --------------------------------------------------------------------
// --- Builder methods
// --------------------------------------------------------------------

public static class BuilderImpl implements Alternative.Builder {

  private eu.mihosoft.vcollections.VList elements;
  private int id;
  private eu.mihosoft.vmf.vmftext.grammar.UPRuleBase parentRule;
  private java.lang.String text;

  private boolean appendCollections = true;

  public BuilderImpl() {}

    public Alternative.Builder withElements(eu.mihosoft.vcollections.VList elements) {
      // ensure that this collection property is really immutable
      this.elements = VList.newInstance(
        java.util.Collections.
        unmodifiableList(
          new java.util.ArrayList(elements)
        )
      );
      return this;
    }
    public Alternative.Builder withId(int id) {
      this.id = id;
      return this;
    }
    public Alternative.Builder withText(java.lang.String text) {
      this.text = text;
      return this;
    }

  public Builder appendCollections(boolean value) {
    this.appendCollections = value;
    return this;
  }

  public Alternative build() {
    AlternativeImpl result = new AlternativeImpl();
    if(this.elements !=null) {
      result.getElements().addAll(this.elements);
    }
    result.id = this.id;
    result.parentRule = this.parentRule;
    // PROP: parentRule
        
      if(result.parentRule!=null && result!=null) {
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result)._vmf_references().add(result.parentRule);
        ((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)result.parentRule)._vmf_referencedBy().add(result);
      }

    result.text = this.text;
    return result;
  }

  public Builder applyFrom(Alternative o) {
      if(!this.appendCollections||this.elements==null) {
        // ensure that this collection property is really immutable
        this.elements = VList.newInstance(
          java.util.Collections.
          unmodifiableList(
              new java.util.ArrayList(o.getElements())
          )
        );
      } else {
        this.elements.addAll(o.getElements());
      }
      this.id = o.getId();
      this.parentRule = o.getParentRule();
      this.text = o.getText();

    return this;
  }
  public Builder applyTo(Alternative o) {

      if(!this.appendCollections) {
        o.getElements().clear();
      }
      o.getElements().addAll(elements);
      o.setId(id);
      o.setText(text);

    return this;
  }
} // end class BuilderImpl


// --------------------------------------------------------------------
// --- declaration of delegation methods
// --------------------------------------------------------------------


  // --------------------------------------------------------------------
  // --- Utility methods
  // --------------------------------------------------------------------

  @Override
  public void addPropertyChangeListener(PropertyChangeListener l) {
      _vmf_getPropertyChanges().addPropertyChangeListener(l);
  }
  @Override
  public void removePropertyChangeListener(PropertyChangeListener l) {
      _vmf_getPropertyChanges().removePropertyChangeListener(l);

      if(_vmf_getPropertyChanges().getPropertyChangeListeners().length==0) {
          propertyChanges = null;
      }
  }

  private PropertyChangeSupport _vmf_getPropertyChanges() {

      if(propertyChanges==null) {
          propertyChanges = new PropertyChangeSupport(this);
      }

      return propertyChanges;
  }

  private boolean _vmf_hasListeners() {
      return propertyChanges!=null;
  }

  private void _vmf_firePropertyChangeIfListenersArePresent(
    String propertyName, Object oldValue, Object newValue) {
      if(_vmf_hasListeners()) {
          _vmf_getPropertyChanges().
                  firePropertyChange(propertyName, oldValue, newValue);
      }
  }

  // --------------------------------------------------------------------
  // --- Public VMF API
  // --------------------------------------------------------------------

 private eu.mihosoft.vmf.runtime.core.VMF vmf;

  @Override
  public eu.mihosoft.vmf.runtime.core.VMF vmf() {
    if(vmf==null) {
      vmf = new eu.mihosoft.vmf.runtime.core.VMF() {
        public eu.mihosoft.vmf.runtime.core.Content content() {
          return new eu.mihosoft.vmf.runtime.core.Content() {
            public eu.mihosoft.vmf.runtime.core.VIterator iterator() {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(AlternativeImpl.this);
            }
            public java.util.stream.Stream stream() {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(AlternativeImpl.this).asStream();
            }

            public eu.mihosoft.vmf.runtime.core.VIterator iterator(eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(AlternativeImpl.this, strategy);
            }
            public java.util.stream.Stream stream(eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return eu.mihosoft.vmf.runtime.core.VIterator.of(AlternativeImpl.this, strategy).asStream();
            }
            public  java.util.stream.Stream stream(Class type) {
              return stream().filter(e->type.isAssignableFrom(e.getClass())).map(e->(T)e);
            }
            public  java.util.stream.Stream stream(Class type, eu.mihosoft.vmf.runtime.core.VIterator.IterationStrategy strategy) {
              return stream(strategy).filter(e->type.isAssignableFrom(e.getClass())).map(e->(T)e);
            }
            public VList referencedBy() {
              return _vmf_referencedBy().asUnmodifiable();
            }
            public VList references() {
              return _vmf_references().asUnmodifiable();
            }


            @Override
            public Alternative deepCopy() {
               java.util.IdentityHashMap identityMap =
               new java.util.IdentityHashMap<>();
               return _vmf_deepCopy(identityMap);
            }

            @Override
            public Alternative shallowCopy() {
              return AlternativeImpl.
                this._vmf_shallowCopy(new java.util.IdentityHashMap<>());
              }
            };
          }

          private eu.mihosoft.vmf.runtime.core.internal.ChangesImpl changes;

          public eu.mihosoft.vmf.runtime.core.Changes changes() {
            if (changes==null) {
              changes = new eu.mihosoft.vmf.runtime.core.internal.ChangesImpl();
              changes.setModel(AlternativeImpl.this);
            }

            return changes;
          }

          private eu.mihosoft.vmf.runtime.core.internal.ReflectImpl reflect;

          public eu.mihosoft.vmf.runtime.core.Reflect reflect() {
            if (reflect==null) {
              reflect = new eu.mihosoft.vmf.runtime.core.internal.ReflectImpl();
              reflect.setModel(AlternativeImpl.this);
            }

            return reflect;
          }


        }; // end vmf
      } // end if null

      return vmf;
  }

  private ReadOnlyAlternative readOnlyInstance;

  @Override
  public ReadOnlyAlternative asReadOnly() {

    if(readOnlyInstance==null) {
      readOnlyInstance = new eu.mihosoft.vmf.vmftext.grammar.impl.
        ReadOnlyAlternativeImpl(this);
    }

    return readOnlyInstance;
  }

  // --------------------------------------------------------------------
  // --- Reflection methods
  // --------------------------------------------------------------------

  // type id for improved reflection performance
  public static final int _VMF_TYPE_ID = 0;

  @Override
  public int _vmf_getTypeId() {
    return _VMF_TYPE_ID;
  }


  static final String[] _VMF_PROPERTY_NAMES = {
    "elements",
    "id",
    "parentRule",
    "text"
  };

  static final String[] _VMF_PROPERTY_TYPE_NAMES = {
    "eu.mihosoft.vcollections.VList", // type id -2
    "int", // type id -1
    "eu.mihosoft.vmf.vmftext.grammar.UPRuleBase", // type id 48
    "java.lang.String"  // type id -1
  };

  static final int[] _VMF_PROPERTY_TYPES = {
       -2, // type eu.mihosoft.vcollections.VList
       -1, // type int
       48, // type eu.mihosoft.vmf.vmftext.grammar.UPRuleBase
       -1  // type java.lang.String
  };


  /**
   * - indices of model objects as properties
   * - parents, i.e., containers are skipped
   * - only indices of reference properties and contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_TYPES_INDICES = {
  };

  /**
   * - indices of lists that contain model objects as elements
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_ELEMENT_TYPES_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
  };

  /**
   * - indices of model objects as properties and model objects as
   *   elements of lists
   * - parents, i.e., containers are skipped
   * - only indices of reference properties and contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_PROPERTIES_WITH_MODEL_TYPE_OR_ELEMENT_TYPES_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
  };

  /**
   * - indices of model children
   * - parents, i.e., containers and pure references are skipped
   * - only indices of contained elements, i.e.,
   *   children are listed here
   */
  static final int[] _VMF_CHILDREN_INDICES = {
        0, // type eu.mihosoft.vcollections.VList
  };

  @Override
  public String[] _vmf_getPropertyNames() {
    return _VMF_PROPERTY_NAMES;
  }

  @Override
  public int[] _vmf_getPropertyTypes() {
    return _VMF_PROPERTY_TYPES;
  }

  @Override
  public String[] _vmf_getPropertyTypeNames() {
    return _VMF_PROPERTY_TYPE_NAMES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelElementTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_ELEMENT_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getIndicesOfPropertiesWithModelTypeOrElementTypes() {
    return _VMF_PROPERTIES_WITH_MODEL_TYPE_OR_ELEMENT_TYPES_INDICES;
  }

  @Override
  public int[] _vmf_getChildrenIndices() {
    return _VMF_CHILDREN_INDICES;
  }

  @Override
  public Object _vmf_getPropertyValueById(int propertyId) {

    switch(propertyId) {
      case 0:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getElements();
      case 1:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getId();
      case 2:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getParentRule();
      case 3:
        // TODO check whether we can prevent lazy initialized properties from
        //      being initialized just for iterating the object graph
        return getText();
    }

    return null;
  }

  @Override
  public int _vmf_getPropertyIdByName(String propertyName) {
    switch(propertyName) {
      case "elements":
        return 0;
      case "id":
        return 1;
      case "parentRule":
        return 2;
      case "text":
        return 3;
      default:
        return -1;
    } // end switch
  }

  @Override
  public void _vmf_setPropertyValueById(int propertyId, Object value) {
    switch(propertyId) {
      case 1: // normal property (no collection and no containment)
        setId((int)value);
        break;
      case 3: // normal property (no collection and no containment)
        setText((java.lang.String)value);
        break;
      default:
            throw new RuntimeException("Cannot set property with id="+propertyId +": property is not writable.");
    } // end switch
  }

  @Override
  public Object _vmf_getDefaultValueById(int propertyId) {

    switch(propertyId) {
      case 0:
        Object __vmf_default_value_tmpElements = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpElements==null) {
            return null;
        } else {
            return __vmf_default_value_tmpElements;
        }

      case 1:
        Object __vmf_default_value_tmpId = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpId==null) {
            return
             0;
        } else {
            return __vmf_default_value_tmpId;
        }    

      case 2:
        Object __vmf_default_value_tmpParentRule = _VMF_DEFAULT_VALUES[1];
        if(__vmf_default_value_tmpParentRule==null) {
            return null;
        } else {
            return __vmf_default_value_tmpParentRule;
        }

      case 3:
        Object __vmf_default_value_tmpText = _VMF_DEFAULT_VALUES[0];
        if(__vmf_default_value_tmpText==null) {
            return null;
        } else {
            return __vmf_default_value_tmpText;
        }

    } // end switch

    return null;
  }

  @Override
  public void _vmf_setDefaultValueById(int propertyId, Object defaultValue) {

    // property elements
    if(propertyId == 0) { 
      throw new RuntimeException("Cannot set default value for property 'elements' with id="+propertyId +": property is a containment property and not writable.");
    }
    // property parentRule
    if(propertyId == 2) { 
      throw new RuntimeException("Cannot set default value for property 'parentRule' with id="+propertyId +": property is a containment property and not writable.");
    }

    // if the value was previously unset then we need to update
    // the value to the new default value
    boolean isSetBeforeDefaultUpdate = _vmf_isSetById(propertyId);
    _VMF_DEFAULT_VALUES[propertyId] = defaultValue;
    if(!isSetBeforeDefaultUpdate) {
      _vmf_unsetById(propertyId);
    }
  }

  @Override
  public boolean _vmf_isSetById(int propertyId) {
    return !java.util.Objects.equals(_vmf_getDefaultValueById(propertyId), _vmf_getPropertyValueById(propertyId));
  }

  @Override
  public void _vmf_unsetById(int propertyId) {
    _vmf_setPropertyValueById(propertyId, _vmf_getDefaultValueById(propertyId));
  }

  final Object[] _VMF_DEFAULT_VALUES = {
    null, // type elements (containment type, no defaut value possible)  
    null, // type id   
    null, // type parentRule (containment type, no defaut value possible)  
    null  // type text   
  };

  // --------------------------------------------------------------------
  // --- Id related methods
  // --------------------------------------------------------------------

  // id management is currently not part of VMF (TODO how should we support this?)

  // --------------------------------------------------------------------
  // --- Reference methods
  // --------------------------------------------------------------------

  @Override
  public VList _vmf_referencedBy() { return this.referencedBy;}
  @Override
  public VList _vmf_references() { return this.references;}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy