org.eolang.core.EOObject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eo-runtime Show documentation
Show all versions of eo-runtime Show documentation
org.eolang runtime library
The newest version!
package org.eolang.core;
import org.eolang.core.data.EOData;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Declares the base EO object.
* All the objects in the target Java platform environment are constructed
* based on this abstract class (both standard and user-defined).
*/
public abstract class EOObject implements Cloneable {
/**
* User-defined class (i.e., one generated by transpiler) overrides this method
* to declare its decoratee (i.e., an object it decorates).
* By default, this method returns null, which means that objects that do not override it have no decoratee objects.
*
* @return The decoratee of this object, or null if it is not present.
*/
protected EOObject _decoratee() {
return null;
}
/**
* User-defined class (i.e., one generated by transpiler) overrides this method
* to declare its parent (i.e., an object it belongs to).
* By default, this method returns null, which means that objects that do not override it
* have no parent objects (i.e., they are not nested, but package-scoped (global) objects).
*
* @return The parent of this object, or null if it is not present.
*/
protected EOObject _parent() {
return null;
}
/**
* Provides checked (safe) access to the decoratee of this object.
* This method is used when the decoratee object is explicitly accessed in the user-defined code through the '@' symbol.
*
* @return The decoratee of this object if it is present.
* @throws RuntimeException Thrown when the decoratee object is not declared for this object.
*/
public EOObject _getDecoratedObject() {
EOObject decoratee = _decoratee();
if (decoratee == null) {
throw new RuntimeException(String.format("Can't access the decoratee object of the %s object: the @ attribute is not bound.", getClass().getTypeName()));
} else {
return decoratee;
}
}
/**
* Provides checked (safe) access to the parent of this object.
* This method is used when the parent object is explicitly accessed in the user-defined code through the '^' symbol.
*
* @return The parent of this object if it is present.
* @throws RuntimeException Thrown when the parent object is not declared for this object.
*/
public EOObject _getParentObject() {
EOObject parent = _parent();
if (parent == null) {
throw new RuntimeException(String.format("Can't access the parent object of the %s object.", getClass().getTypeName()));
} else {
return parent;
}
}
/**
* Retrieves data behind this object (i.e., performs dataization operation over the object).
*
* @return Data behind this object.
* @throws RuntimeException Thrown when this object cannot be dataized since it has nor data behind it, neither a decoratee to rely on.
*/
public EOData _getData() {
final EOObject decoratedObject = _decoratee();
if (decoratedObject == null) {
throw new RuntimeException(String.format("Object %s cannot be dataized: it has nor data behind it, neither a decoratee to rely on.", getClass().getTypeName()));
}
return decoratedObject._getData();
}
/**
* Instantiates the attribute object {@code name} of this object.
* Performs lookup of the attribute in the class that declares this object + in the decoration hierarchy.
*
* @param name The name of the attribute being accessed.
* @param arguments The arguments that are passed to the attribute object application/instantiation method.
* @return The attribute object instantiated with the provided arguments.
* @throws RuntimeException Thrown when the attribute is not present in this object.
*/
public EOObject _getAttribute(String name, EOObject... arguments) {
try {
Method method = Arrays.stream(getClass().getMethods()).filter(mthd -> mthd.getName().equals(name)).findFirst().get();
Parameter[] methodParams = method.getParameters();
method.setAccessible(true);
return (EOObject) method.invoke(this, _prepareFreeAtt(methodParams, arguments));
} catch (Exception e) {
if (_decoratee() != null && _decoratee() != this) {
return _decoratee()._getAttribute(name, arguments);
} else {
e.printStackTrace();
throw new RuntimeException(String.format("Can't access the %s attribute of the %s object", name, getClass().getTypeName()));
}
}
}
private Object[] _prepareFreeAtt(Parameter[] methodParams, EOObject... arguments) {
List