/** * This file is part of CloudML [ http://cloudml.org ] * * Copyright (C) 2012 - SINTEF ICT * Contact: Franck Chauvel <franck.chauvel@sintef.no> * * Module: root * * CloudML is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * CloudML is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with CloudML. If not, see * <http://www.gnu.org/licenses/>. */ package org.cloudml.core; import org.cloudml.core.collections.PropertyGroup; import org.cloudml.core.util.OwnedBy; import org.cloudml.core.validation.Report; import org.cloudml.core.visitors.Visitor; public class ExecuteInstance extends WithResources implements DeploymentElement, OwnedBy<Deployment> { private final OptionalOwner<Deployment> owner; private ProvidedExecutionPlatformInstance providedEnd; private RequiredExecutionPlatformInstance requiredEnd; public ExecuteInstance(String name, InternalComponentInstance instance, ProvidedExecutionPlatformInstance platform) { this(name, instance.getRequiredExecutionPlatform(), platform); } public ExecuteInstance(String name, RequiredExecutionPlatformInstance requiredEnd, ProvidedExecutionPlatformInstance providedEnd) { super(name); this.owner = new OptionalOwner<Deployment>(); unlessExpectationsAreMet(providedEnd, requiredEnd); setProvidedEnd(providedEnd); setRequiredEnd(requiredEnd); } @Override public void validate(Report report) { final PropertyGroup demands = getRequiredEnd().getType().getDemands(); for (Property demand : demands) { final PropertyGroup offers = getProvidedEnd().getType().getOffers(); if (!offers.isDefined(demand.getName())) { final String error = String.format("Mismatch between demands and offers! Demanded: %s, but %s is not offered", demand, demand.getName()); report.addError(error); } else { if (!offers.contains(demand)) { final Property offer = offers.get(demand.getName()); final String error = String.format("Mismatch between demands and offers!! Demanded: %s, but offered %s", demand, offer); report.addError(error); } } } } public boolean hasSubject(InternalComponentInstance component) { return getRequiredEnd().getOwner().get().getName().equals(component.getName()); } public boolean isHostedBy(ComponentInstance<? extends Component> host) { return getProvidedEnd().getOwner().get().equals(host); } public ComponentInstance<? extends Component> getHost() { return getProvidedEnd().getOwner().get(); } public InternalComponentInstance getSubject() { return (InternalComponentInstance) getRequiredEnd().getOwner().get(); } public boolean isBetween(String demanderName, String demandName, String providerName, String providedName) { return this.getRequiredEnd().getOwner().get().isNamed(demanderName) && this.getRequiredEnd().isNamed(demandName) && this.getProvidedEnd().getOwner().get().isNamed(providerName) && this.getProvidedEnd().isNamed(providedName); } //TODO: to be refined (we should not only match if values are strictly equals) private void unlessExpectationsAreMet(ProvidedExecutionPlatformInstance provided, RequiredExecutionPlatformInstance required) { for (Property demand : required.getType().getDemands()) { Property offer = provided.getType().getOffers().get(demand.getName()); if (offer == null) { throw new IllegalArgumentException("Missing expectations: " + demand.getName()); } if (!demand.getValue().equals(offer.getValue())) { throw new IllegalArgumentException("Unmet expectation '" + demand.getName() + "' (expected + '" + demand.getValue() + "' but found: '" + offer.getValue() + "')"); } } } @Override public Deployment getDeployment() { return getOwner().get(); } @Override public void accept(Visitor visitor) { visitor.visitExecuteInstance(this); } @Override public String getQualifiedName() { return String.format("%s%s%s", getOwner().getName(), CONTAINED, getName()); } @Override public OptionalOwner<Deployment> getOwner() { return owner; } public RequiredExecutionPlatformInstance getRequiredEnd() { return requiredEnd; } public final void setRequiredEnd(RequiredExecutionPlatformInstance end) { if (end == null) { final String error = String.format("'null' is not a valid required end for '%s'", getQualifiedName()); throw new IllegalArgumentException(error); } this.requiredEnd = end; } public ProvidedExecutionPlatformInstance getProvidedEnd() { return providedEnd; } public final void setProvidedEnd(ProvidedExecutionPlatformInstance end) { if (end == null) { final String error = String.format("'null' is not a valid provided end for '%s'", getQualifiedName()); throw new IllegalArgumentException(error); } this.providedEnd = end; } @Override public boolean equals(Object other){ if(this == other) return true; if(other == null || !(other instanceof ExecuteInstance)) return false; ExecuteInstance otherEI = (ExecuteInstance) other; boolean reqMatch = false; if(this.getRequiredEnd() == null && otherEI.getRequiredEnd()==null) reqMatch = true; else if(this.getRequiredEnd()!=null && otherEI.getRequiredEnd()!=null) reqMatch = this.getRequiredEnd().equals(otherEI.getRequiredEnd()); boolean prvMatch = false; if(this.getProvidedEnd() == null && otherEI.getProvidedEnd() == null) prvMatch = true; else if(this.getProvidedEnd()!=null && otherEI.getProvidedEnd()!=null) prvMatch = this.getProvidedEnd().equals(otherEI.getProvidedEnd()); return reqMatch && prvMatch; } }