/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.backend.java.lib.runtime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import abs.backend.java.codegeneration.dynamic.DynamicException;
import abs.backend.java.lib.types.ABSUnit;
import abs.backend.java.lib.types.ABSValue;
import abs.backend.java.observing.COGView;
import abs.backend.java.observing.ClassView;
import abs.backend.java.observing.ObjectObserver;
import abs.backend.java.observing.ObjectView;
public class ABSDynamicObject extends ABSObject {
private ABSDynamicClass clazz;
private Map<String,ABSValue> fields;
public ABSDynamicObject(ABSDynamicClass clazz, ABSValue... params) {
this.clazz = clazz;
initializeFields(params);
}
public ABSDynamicObject(COG cog, ABSDynamicClass clazz, ABSValue... params) {
super(cog);
this.clazz = clazz;
initializeFields(params);
}
private void initializeFields(ABSValue[] params) {
fields = new HashMap<String,ABSValue>();
// parameters
if (params.length != clazz.getParams().size()) throw new DynamicException("Type mismatch");
for (int i = 0; i < params.length; i++) {
setFieldValue(clazz.getParams().get(i), params[i]);
}
// all other fields
for (String f : clazz.getFieldNames()) {
if (! fields.containsKey(f)) {
setFieldValue(f, clazz.getField(f).init(this));
}
}
this.getCOG().objectCreated(this);
// for (String s : getFieldNames()) {
// System.out.println("*** Class " + clazz.getName() + ": Field " + s + " = " + getFieldValue_Internal(s));
// }
}
@Override
public final ABSDynamicRuntime __ABS_getRuntime() {
ABSRuntime runtime = super.__ABS_getRuntime();
if (runtime instanceof ABSDynamicRuntime)
return (ABSDynamicRuntime)super.__ABS_getRuntime();
else
throw new DynamicException("Dynamic ABS Java code detected. Please run with -dynamic switch.");
}
public String getClassName() {
return getClazz().getName();
}
public void setCOG(COG cog) {
this.__cog = cog;
}
public void setClazz(ABSDynamicClass clazz) {
this.clazz = clazz;
}
public ABSDynamicClass getClazz() {
return clazz;
}
public List<String> getFieldNames() {
return new ArrayList<String>(clazz.getFieldNames());
}
public ABSValue getFieldValue(String field) throws NoSuchFieldException {
if (fields.containsKey(field))
return fields.get(field);
else
throw new NoSuchFieldException(field);
}
public ABSValue getFieldValue_Internal(String field) {
try {
return getFieldValue(field);
} catch (NoSuchFieldException e) {
throw new DynamicException("Field not found: " + field);
}
}
public void setFieldValue(String fieldName, ABSValue val) {
fields.put(fieldName, val);
}
public void __ABS_init() {
clazz.getConstructor().exec(this);
this.getCOG().objectInitialized(this);
}
public ABSValue dispatch(String mName, ABSValue... params) {
ABSClosure method = clazz.getMethod(mName);
return method.exec(this, params);
}
public ABSUnit run() {
ABSClosure cl = clazz.getMethod("run");
if (cl != null) {
cl.exec(this);
}
return ABSUnit.UNIT;
}
public synchronized ObjectView getView() {
if (__view == null) {
__view = new View();
}
return __view;
}
private class View implements ObjectView {
@Override
public COGView getCOG() {
return __cog.getView();
}
@Override
public ClassView getClassView() {
return clazz.getView();
}
@Override
public ABSValue getFieldValue(String fieldName) throws NoSuchFieldException {
return ABSDynamicObject.this.getFieldValue(fieldName);
}
@Override
public void registerObjectObserver(ObjectObserver l) {
// FIXME: implement
}
@Override
public String toString() {
return ABSDynamicObject.this.toString();
}
@Override
public long getID() {
return ABSDynamicObject.this.__id;
}
@Override
public String getClassName() {
return clazz.getName();
}
@Override
public List<String> getFieldNames() {
if (fields == null) return Collections.emptyList();
return new ArrayList<String>(fields.keySet());
}
}
}