package er.rest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.webobjects.eocontrol.EOClassDescription;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableArray;
/**
* MapClassDescription is an EOClassDescription that is made on the
* fly based on a Map (NSDictionary, etc) so that ERRest can render
* a dictionary as a node where the keys of the node are the keys
* of the dictionary.
*
* @author mschrag
*/
public class MapClassDescription extends EOClassDescription implements IERXNonEOClassDescription {
private Map<String, ?> _map;
public MapClassDescription() {
this(new HashMap<>());
}
public MapClassDescription(Map<String, ?> map) {
_map = map;
}
@Override
public String entityName() {
String entityName = (String) _map.get("entityName");
if (entityName == null) {
if (_map instanceof NSDictionary) {
entityName = "NSDictionary";
}
else {
entityName = "HashMap";
}
}
return entityName;
}
protected boolean isAttribute(Class type) {
return ERXRestUtils.isPrimitive(type);
}
protected boolean isToMany(Class type) {
return List.class.isAssignableFrom(type);
}
@Override
public NSArray<String> attributeKeys() {
NSMutableArray<String> attributes = new NSMutableArray<>();
for (Map.Entry<String, ?> entry : _map.entrySet()) {
Class type = entry.getValue().getClass();
if (isAttribute(type)) {
attributes.addObject(entry.getKey());
}
}
return attributes;
}
@Override
public NSArray<String> toOneRelationshipKeys() {
NSMutableArray<String> relationships = new NSMutableArray<>();
for (Map.Entry<String, ?> entry : _map.entrySet()) {
Class type = entry.getValue().getClass();
if (!isAttribute(type) && !isToMany(type)) {
relationships.addObject(entry.getKey());
}
}
return relationships;
}
@Override
public NSArray<String> toManyRelationshipKeys() {
NSMutableArray<String> relationships = new NSMutableArray<>();
for (Map.Entry<String, ?> entry : _map.entrySet()) {
Class type = entry.getValue().getClass();
if (isToMany(type)) {
relationships.addObject(entry.getKey());
}
}
return relationships;
}
@Override
public EOClassDescription classDescriptionForDestinationKey(String detailKey) {
Object obj = _map.get(detailKey);
if (obj != null) {
Class type = obj.getClass();
if (isToMany(type)) {
return ERXRestClassDescriptionFactory.classDescriptionForClass(Object.class, true);
}
else {
return ERXRestClassDescriptionFactory.classDescriptionForClass(type, false);
}
}
else {
return ERXRestClassDescriptionFactory.classDescriptionForClass(Object.class, true);
}
}
@Override
public Object createInstance() {
return new HashMap<String, Object>(_map); // not much else we can do here ... fucking clone method.
}
}