eu.mihosoft.vmf.vmftext.grammar.impl.RuleClassImpl 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.RuleClass}.
*/
@SuppressWarnings("deprecation")
class RuleClassImpl implements RuleClass, eu.mihosoft.vmf.runtime.core.internal.VObjectInternalModifiable, VCloneableInternal {
// --------------------------------------------------------------------
// --- declaration of member variables
// --------------------------------------------------------------------
/*package private*/ eu.mihosoft.vcollections.VList childClasses;
/*package private*/ eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange;
/*package private*/ eu.mihosoft.vcollections.VList customProperties;
/*package private*/ eu.mihosoft.vcollections.VList customRuleAnnotations;
/*package private*/ eu.mihosoft.vcollections.VList delegationMethods;
/*package private*/ eu.mihosoft.vmf.vmftext.grammar.GrammarModel model;
/*package private*/ java.lang.String name;
/*package private*/ eu.mihosoft.vcollections.VList properties;
/*package private*/ boolean root;
/*package private*/ eu.mihosoft.vmf.vmftext.grammar.RuleClass superClass;
/*package private*/ eu.mihosoft.vcollections.VList superInterfaces;
// --------------------------------------------------------------------
// --- declaration of delegation variables
// --------------------------------------------------------------------
private eu.mihosoft.vmf.vmftext.grammar.NameDelegate _vmf_delegate4;
private eu.mihosoft.vmf.vmftext.grammar.StringUtilDelegate _vmf_delegate5;
private eu.mihosoft.vmf.vmftext.grammar.CheckPropertiesDelegate _vmf_delegate6;
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 RuleClassImpl() {
// --------------------------------------------------------------------
// --- declaration of delegation methods
// --------------------------------------------------------------------
if(_vmf_delegate6==null) {
_vmf_delegate6 = new eu.mihosoft.vmf.vmftext.grammar.CheckPropertiesDelegate();
_vmf_delegate6.setCaller(this);
}
_vmf_delegate6.onRuleClassInstantiated();
// --------------------------------------------------------------------
// --- 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
// property 4
// -> no default value is present
// property 5
// -> no default value is present
// property 6
// -> no default value is present
// property 7
// -> no default value is present
// property 8
// -> no default value is present
// property 9
// -> no default value is present
// property 10
// -> no default value is present
}
// --------------------------------------------------------------------
// --- public getter methods for accessing properties
// --------------------------------------------------------------------
@Override
public eu.mihosoft.vcollections.VList getChildClasses() {
if(this.childClasses==null) {
this.childClasses = VList.newInstance(new java.util.ArrayList<>());
this.childClasses.addChangeListener((evt)-> {
evt.added().elements().forEach((e)->{
if(e==null) return;
// remove element from previous collection
// TODO use bulk operations if possible
if(e.getSuperClass()!=null) {
e.getSuperClass().getChildClasses().remove(e);
}
try {
java.lang.reflect.Field field =
e.getClass().getDeclaredField("superClass");
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(
RuleClassImpl.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("superClass");
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(
RuleClassImpl.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.childClasses==null)
return this.childClasses;
// return VContainmentUtil.asContainmentList(this.childClasses, "superClass");
} // end of eu.mihosoft.vcollections.VList getChildClasses()
@Override
public eu.mihosoft.vmf.vmftext.grammar.CodeRange getCodeRange() {
return this.codeRange;
} // end of eu.mihosoft.vmf.vmftext.grammar.CodeRange getCodeRange()
@Override
public eu.mihosoft.vcollections.VList getCustomProperties() {
if(this.customProperties==null) {
this.customProperties = VList.newInstance(new java.util.ArrayList<>());
this.customProperties.addChangeListener((evt)-> {
evt.added().elements().forEach((e)->{
if(e==null) return;
// remove element from previous collection
// TODO use bulk operations if possible
if(e.getParent()!=null) {
e.getParent().getCustomProperties().remove(e);
}
try {
java.lang.reflect.Field field =
e.getClass().getDeclaredField("parent");
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(
RuleClassImpl.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("parent");
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(
RuleClassImpl.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.customProperties==null)
return this.customProperties;
// return VContainmentUtil.asContainmentList(this.customProperties, "parent");
} // end of eu.mihosoft.vcollections.VList getCustomProperties()
@Override
public eu.mihosoft.vcollections.VList getCustomRuleAnnotations() {
if(this.customRuleAnnotations==null) {
this.customRuleAnnotations = VList.newInstance(new java.util.ArrayList<>());
this.customRuleAnnotations.addChangeListener((evt)-> {
evt.added().elements().forEach((e)->{
if(e==null) return;
// remove element from previous collection
// TODO use bulk operations if possible
if(e.getParent()!=null) {
e.getParent().getCustomRuleAnnotations().remove(e);
}
try {
java.lang.reflect.Field field =
e.getClass().getDeclaredField("parent");
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(
RuleClassImpl.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("parent");
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(
RuleClassImpl.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.customRuleAnnotations==null)
return this.customRuleAnnotations;
// return VContainmentUtil.asContainmentList(this.customRuleAnnotations, "parent");
} // end of eu.mihosoft.vcollections.VList getCustomRuleAnnotations()
@Override
public eu.mihosoft.vcollections.VList getDelegationMethods() {
if(this.delegationMethods==null) {
this.delegationMethods = VList.newInstance(new java.util.ArrayList<>());
this.delegationMethods.addChangeListener((evt)-> {
evt.added().elements().forEach((e)->{
if(e==null) return;
// remove element from previous collection
// TODO use bulk operations if possible
if(e.getParent()!=null) {
e.getParent().getDelegationMethods().remove(e);
}
try {
java.lang.reflect.Field field =
e.getClass().getDeclaredField("parent");
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(
RuleClassImpl.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("parent");
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(
RuleClassImpl.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.delegationMethods==null)
return this.delegationMethods;
// return VContainmentUtil.asContainmentList(this.delegationMethods, "parent");
} // end of eu.mihosoft.vcollections.VList getDelegationMethods()
@Override
public eu.mihosoft.vmf.vmftext.grammar.GrammarModel getModel() {
return this.model;
} // end of eu.mihosoft.vmf.vmftext.grammar.GrammarModel getModel()
@Override
public java.lang.String getName() {
return this.name;
} // end of java.lang.String getName()
@Override
public eu.mihosoft.vcollections.VList getProperties() {
if(this.properties==null) {
this.properties = VList.newInstance(new java.util.ArrayList<>());
this.properties.addChangeListener((evt)-> {
evt.added().elements().forEach((e)->{
if(e==null) return;
// remove element from previous collection
// TODO use bulk operations if possible
if(e.getParent()!=null) {
e.getParent().getProperties().remove(e);
}
try {
java.lang.reflect.Field field =
e.getClass().getDeclaredField("parent");
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(
RuleClassImpl.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("parent");
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(
RuleClassImpl.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.properties==null)
return this.properties;
// return VContainmentUtil.asContainmentList(this.properties, "parent");
} // end of eu.mihosoft.vcollections.VList getProperties()
@Override
public boolean isRoot() {
return this.root;
} // end of boolean isRoot()
@Override
public eu.mihosoft.vmf.vmftext.grammar.RuleClass getSuperClass() {
return this.superClass;
} // end of eu.mihosoft.vmf.vmftext.grammar.RuleClass getSuperClass()
@Override
public eu.mihosoft.vcollections.VList getSuperInterfaces() {
if(this.superInterfaces==null) {
this.superInterfaces = VList.newInstance(new java.util.ArrayList<>());
} // end of "lazy init" if(this.superInterfaces==null)
return this.superInterfaces;
} // end of eu.mihosoft.vcollections.VList getSuperInterfaces()
// --------------------------------------------------------------------
// --- public setter methods for setting properties
// --------------------------------------------------------------------
@Override
public void setCodeRange(eu.mihosoft.vmf.vmftext.grammar.CodeRange codeRange) {
// return early if identical value has been set
if (this.codeRange == codeRange) {
return;
}
// set the new value
eu.mihosoft.vmf.vmftext.grammar.CodeRange oldValue = this.codeRange;
this.codeRange = codeRange;
// fire property change event
_vmf_firePropertyChangeIfListenersArePresent("codeRange", oldValue, this.codeRange);
if(this.codeRange!=null && this!=null) {
((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(this.codeRange);
((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this.codeRange)._vmf_referencedBy().add(this);
}
if(oldValue!=null && this!=null) {
((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)this)._vmf_references().add(oldValue);
((eu.mihosoft.vmf.runtime.core.internal.VObjectInternal)oldValue)._vmf_referencedBy().add(this);
}
} // setterDeclaration (setter method)
@Override
public void setModel(eu.mihosoft.vmf.vmftext.grammar.GrammarModel model) {
// 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.model == model) {
return;
}
// remove this from previous opposite
if(this.model!=null) {
this.model.getRuleClasses().remove(this);
}
// add this to new opposite
if(model!=null) {
model.getRuleClasses().add(this);
}
}
@Override
public void setName(java.lang.String name) {
// return early if identical value has been set
if (this.name == name) {
return;
}
// set the new value
java.lang.String oldValue = this.name;
this.name = name;
// fire property change event
_vmf_firePropertyChangeIfListenersArePresent("name", oldValue, this.name);
} // setterDeclaration (setter method)
@Override
public void setRoot(boolean root) {
// return early if identical value has been set
if (this.root == root) {
return;
}
// set the new value
boolean oldValue = this.root;
this.root = root;
// fire property change event
_vmf_firePropertyChangeIfListenersArePresent("root", oldValue, this.root);
} // setterDeclaration (setter method)
@Override
public void setSuperClass(eu.mihosoft.vmf.vmftext.grammar.RuleClass superClass) {
// 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.superClass == superClass) {
return;
}
// remove this from previous opposite
if(this.superClass!=null) {
this.superClass.getChildClasses().remove(this);
}
// add this to new opposite
if(superClass!=null) {
superClass.getChildClasses().add(this);
}
}
// --------------------------------------------------------------------
// --- 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\":\"RuleClass\"" +
", " + (this.childClasses==null?"[]":this.childClasses) +
", \"codeRange\": \"" + this.codeRange + "\"" +
", " + (this.customProperties==null?"[]":this.customProperties) +
", " + (this.customRuleAnnotations==null?"[]":this.customRuleAnnotations) +
", " + (this.delegationMethods==null?"[]":this.delegationMethods) +
", \"model\": \"" + this.model + "\"" +
", \"name\": \"" + this.name + "\"" +
", " + (this.properties==null?"[]":this.properties) +
", \"root\": \"" + this.root + "\"" +
", \"superInterfaces\": \"" + this.superInterfaces + "\"" +
"}";
} 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 ReadOnlyRuleClassImpl) {
o = ((ReadOnlyRuleClassImpl)o)._vmf_getMutableObject();
}
// -- try our interface/implementation --
// perform the actual comparison for each property
if (o instanceof RuleClassImpl) {
RuleClassImpl other = (RuleClassImpl) o;
return _vmf_equals(this.childClasses, other.childClasses) &&
_vmf_equals(this.codeRange, other.codeRange) &&
_vmf_equals(this.customProperties, other.customProperties) &&
_vmf_equals(this.customRuleAnnotations, other.customRuleAnnotations) &&
_vmf_equals(this.delegationMethods, other.delegationMethods) &&
_vmf_equals(this.model, other.model) &&
_vmf_equals(this.name, other.name) &&
_vmf_equals(this.properties, other.properties) &&
_vmf_equals(this.root, other.root) &&
_vmf_equals(this.superInterfaces, other.superInterfaces);
}
// -- try every implementation that implements our interface --
// 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.childClasses, this.codeRange, this.customProperties, this.customRuleAnnotations, this.delegationMethods, this.model, this.name, this.properties, this.root, this.superInterfaces );
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
*/
RuleClassImpl (
RuleClassImpl other,
boolean deepCopy, java.util.IdentityHashMap