package simulator; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import models.algebra.Constant; import models.algebra.Expression; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.ResourceHierarchy; import simulator.states.*; public class Resource { private Resource parent = null; private Map<String, Resource> children = null; private ResourceHierarchy resourceHierarchy = null; private ResourceState state = null; private Constant parameter = null; public Resource(Resource resource) { this.resourceHierarchy = resource.resourceHierarchy; this.parent = resource.parent; this.state = (ResourceState) resource.state.clone(); this.parameter = resource.parameter; } public Resource(ResourceHierarchy resourceHierarchy) { this.resourceHierarchy = resourceHierarchy; Type resType = resourceHierarchy.getResourceStateType(); if (resourceHierarchy.getChildren().size() > 0 || DataConstraintModel.typeList.isAncestorOf(resType) || DataConstraintModel.typeMap.isAncestorOf(resType) || DataConstraintModel.typeJson.isAncestorOf(resType)) { if (resType != null && DataConstraintModel.typeList.isAncestorOf(resType)) { // List resource state = new ListResourceState(); } else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) { // Map resource state = new MapResourceState(); } else { // Json resource if (resType == null) { resType = DataConstraintModel.typeJson; resourceHierarchy.setResourceStateType(resType); } state = new JsonResourceState(); children = new LinkedHashMap<>(); for (ResourceHierarchy child: resourceHierarchy.getChildren()) { Resource cRes = new Resource(child, this); ((JsonResourceState) state).addChildState(child.getResourceName(), cRes.getState()); children.put(child.getResourceName(), cRes); } } } else { Expression initValue = resourceHierarchy.getInitialValue(); if (initValue != null && initValue instanceof Constant) { state = new PrimitiveResourceState((Constant) resourceHierarchy.getInitialValue()); } else { state = new PrimitiveResourceState(null); } } } public Resource(ResourceHierarchy resourceHierarchy, Resource parent) { this(resourceHierarchy); this.parent = parent; } public Resource(ResourceHierarchy resourceHierarchy, Resource parent, ResourceState state) { this.resourceHierarchy = resourceHierarchy; this.parent = parent; this.state = state; } public Resource(ResourceHierarchy resourceHierarchy, Resource parent, Constant parameter, ResourceState state) { this.resourceHierarchy = resourceHierarchy; this.parent = parent; this.parameter = parameter; this.state = state; } public Resource getParent() { return parent; } public void setParent(Resource parent) { this.parent = parent; } public ResourceHierarchy getResourceHierarchy() { return resourceHierarchy; } public ResourceIdentifier getResourceIdentifier() { ResourceIdentifier resId = null; if (parent != null) { ResourceIdentifier parentResId = parent.getResourceIdentifier(); if (resourceHierarchy.getNumParameters() == 0) { resId = new ResourceIdentifier(parentResId, resourceHierarchy.getResourceName(), resourceHierarchy); } else { resId = new ResourceIdentifier(parentResId, parameter, resourceHierarchy); } } else { resId = new ResourceIdentifier(resourceHierarchy.getResourceName(), resourceHierarchy); } return resId; } public ResourceState getState() { return state; } public void changeState(ResourceState state) { this.state = state; } public Constant getParameter() { return parameter; } public Collection<Resource> getChildren() { Map<String, Resource> childrenMap = getChildrenMap(); if (childrenMap == null) return null; return childrenMap.values(); } public Map<String, Resource> getChildrenMap() { Map<String, Resource> children = null; if (resourceHierarchy.getChildren().size() > 0) { children = new LinkedHashMap<>(); ResourceHierarchy childRes = resourceHierarchy.getChildren().iterator().next(); if (childRes.getNumParameters() > 0) { // List or Map type. if (state instanceof CompositeResourceState) { // If the list or map is not nil. Map<String, ResourceState> childStates = ((CompositeResourceState) state).getChildStates(); for (Map.Entry<String, ResourceState> childEnt: childStates.entrySet()) { String childParam = childEnt.getKey(); ResourceState childState = childEnt.getValue(); Type thisType = resourceHierarchy.getResourceStateType(); if (DataConstraintModel.typeList.isAncestorOf(thisType)) { children.put(childParam, new Resource(childRes, this, new Constant(childParam, DataConstraintModel.typeInt), childState)); } else if (DataConstraintModel.typeMap.isAncestorOf(thisType)) { children.put(childParam, new Resource(childRes, this, new Constant(childParam, DataConstraintModel.typeString), childState)); } } } } else { // Json type. Map<String, ResourceState> childStates = ((CompositeResourceState) state).getChildStates(); if (this.children == null || this.children.size() < childStates.size()) { for (Map.Entry<String, ResourceState> childEnt: childStates.entrySet()) { String childParam = childEnt.getKey(); ResourceState childState = childEnt.getValue(); Type thisType = resourceHierarchy.getResourceStateType(); for (ResourceHierarchy c: resourceHierarchy.getChildren()) { if (c.getResourceName().equals(childParam.replace("\"", ""))) { childRes = c; break; } } if (DataConstraintModel.typeJson.isAncestorOf(thisType)) { children.put(childParam, new Resource(childRes, this, new Constant(childParam, DataConstraintModel.typeString), childState)); } } this.children = children; } return this.children; } } return children; } public Resource getDescendant(ResourceIdentifier resId) { if (this.getResourceIdentifier().equals(resId)) return this; if (!resId.startsWith(this.getResourceIdentifier())) return null; for (Resource child: getChildren()) { Resource res = child.getDescendant(resId); if (res != null) return res; } return null; } public Resource getDescendant(String resId) { if (this.getResourceIdentifier().toString().equals(resId)) return this; if (!resId.startsWith(this.getResourceIdentifier().toString())) return null; for (Resource child: getChildren()) { Resource res = child.getDescendant(resId); if (res != null) return res; } return null; } }