/*******************************************************************************
* Copyright (c) 2009 University of Edinburgh.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the BSD Licence, which accompanies this feature
* and can be downloaded from http://groups.inf.ed.ac.uk/pepa/update/licence.txt
******************************************************************************/
package uk.ac.ed.inf.biopepa.core.compiler;
import java.util.ArrayList;
import java.util.List;
import uk.ac.ed.inf.biopepa.core.BioPEPAException;
import uk.ac.ed.inf.biopepa.core.dom.*;
/**
* Visits the definition of a species.
*
* @author Mirco
*
*/
public class SpeciesDefinitionCompiler extends AbstractDefinitionCompiler {
public SpeciesDefinitionCompiler(ModelCompiler compiler, VariableDeclaration dec) {
super(compiler, VariableDeclaration.Kind.SPECIES, dec);
}
private List<SpeciesData> getSpeciesData() throws BioPEPAException {
Name name = dec.getName();
List<SpeciesData> species = new ArrayList<SpeciesData>();
SpeciesData data;
if (name instanceof LocatedName) {
LocatedName lName = ((LocatedName) name);
List<Name> names = lName.getLocations().names();
CompartmentData compartmentData;
for (int i = names.size() - 1; i >= 0; i--) {
compartmentData = compiler.checkAndGetCompartmentData(names.get(i).getIdentifier());
if (compartmentData == null) {
compiler.problemRequestor.accept(ProblemKind.LOCATION_USED_BUT_NOT_DEFINED, name);
throw new CompilerException();
}
data = new SpeciesData(lName.getIdentifier(i), dec);
data.setCompartment(compartmentData);
species.add(data);
}
} else {
data = new SpeciesData(name.getIdentifier(), dec);
species.add(data);
}
PropertyInitialiser init = (PropertyInitialiser) dec.getRightHandSide();
CompiledNumber enn;
for (Expression expression : init.properties()) {
if (!(expression instanceof InfixExpression))
throw new IllegalArgumentException("Expected an infix expression");
InfixExpression property = (InfixExpression) expression;
if (!(property.getLeftHandSide() instanceof PropertyLiteral))
throw new IllegalArgumentException("Expected a property literal");
PropertyLiteral literal = (PropertyLiteral) property.getLeftHandSide();
try {
if (species.get(0).isSetProperty(literal)) {
compiler.problemRequestor.accept(ProblemKind.DUPLICATE_PROPERTY_DEFINITION, literal);
continue;
}
} catch (IllegalArgumentException e) {
compiler.problemRequestor.accept(ProblemKind.ILLEGAL_PROPERTY, literal);
continue;
}
ExpressionEvaluatorVisitor v = new ExpressionEvaluatorVisitor(compiler);
property.getRightHandSide().accept(v);
if (!(v.getExpressionNode() instanceof CompiledNumber)) {
compiler.problemRequestor.accept(ProblemKind.DYNAMIC_VALUE, property);
throw new CompilerException();
}
enn = (CompiledNumber) v.getExpressionNode();
if (!enn.evaluatesToLong()) {
compiler.problemRequestor.accept(ProblemKind.NON_INTEGER_VALUE, property);
throw new CompilerException();
}
try {
for (SpeciesData sd : species)
sd.setProperty(literal, enn.longValue());
} catch (PropertySetterException e) {
compiler.problemRequestor.accept(e.getExplanation(), property);
throw new CompilerException();
}
}
if (!species.get(0).isSetProperty(PropertyLiteral.Kind.MAX)) {
compiler.problemRequestor.accept(ProblemKind.MAXIMUM_COUNT_MUST_BE_SPECIFIED, dec);
throw new CompilerException();
}
return species;
}
@Override
/**
* Throws UnsupportedOperationException()
*/
protected Data doGetData() throws BioPEPAException {
throw new UnsupportedOperationException();
}
protected List<SpeciesData> doGetDataList() throws BioPEPAException {
return getSpeciesData();
}
}