/**
* Copyright (c) 2011 - 2015, Lunifera GmbH (Gross Enzersdorf), Loetz KG (Heidelberg)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.lunifera.dsl.semantic.common.helper;
import org.lunifera.dsl.semantic.common.types.LFeature;
import org.lunifera.dsl.semantic.common.types.LLowerBound;
import org.lunifera.dsl.semantic.common.types.LMultiplicity;
import org.lunifera.dsl.semantic.common.types.LUpperBound;
/**
* Keeps lower and upper bound
*/
public class Bounds {
private final LLowerBound lower;
private final LUpperBound upper;
public static Bounds createZeroToOne(){
return new Bounds(LLowerBound.ZERO, LUpperBound.ONE);
}
public static Bounds createFor(LFeature prop) {
if (prop == null) {
return new Bounds(LLowerBound.ZERO, LUpperBound.ONE);
}
LMultiplicity multiplicity = prop.getMultiplicity();
LLowerBound lb = null;
LUpperBound ub = null;
if (multiplicity != null) {
lb = multiplicity.getLower();
ub = multiplicity.getUpper();
}
LLowerBound lower = LLowerBound.ZERO;
LUpperBound upper = LUpperBound.ONE;
if (lb != null) {
if (ub != null && ub != LUpperBound.NULL) {
// Lower and upper bound [x..y] where x = 0/1/?/+/* and y = 1/*
switch (lb) {
case ZERO: // [0..]
case OPTIONAL: // [?..] -> same as [0..] -> should be warning
lower = LLowerBound.ZERO;
break;
case ONE: // [1..]
case ATLEASTONE: // [+..] -> same as [1..] -> should be warning
lower = LLowerBound.ONE;
break;
case MANY: // [*..]
lower = LLowerBound.MANY;
// [*..*]
// [*..1] -> error: upper must be greather than lower bound!
break;
case NULL:
throw new IllegalArgumentException("unexpected NULL value");
}
upper = ub;
} else {
// No upper bound.
switch (lb) {
case ZERO: // [0] -> makes only sense with upper bound
case OPTIONAL: // [?]
lower = LLowerBound.ZERO;
upper = LUpperBound.ONE;
break;
case ONE: // [1] -> implies notnull
case ATLEASTONE: // [+]
lower = LLowerBound.ONE;
upper = LUpperBound.ONE;
break;
case MANY: // [*]
lower = LLowerBound.ZERO;
upper = LUpperBound.MANY;
break;
case NULL:
lower = LLowerBound.ZERO;
upper = LUpperBound.MANY;
break;
}
}
}
return new Bounds(lower, upper);
}
public Bounds(LLowerBound lower, LUpperBound upper) {
super();
this.lower = lower;
this.upper = upper;
}
public LLowerBound getLower() {
return lower;
}
public LUpperBound getUpper() {
return upper;
}
/**
* Returns true if the upper bound is many.
*
* @return
*/
public boolean isToMany() {
return upper == LUpperBound.MANY;
}
/**
* Returns true if the lower bound is one.
*
* @return
*/
public boolean isRequired() {
return lower == LLowerBound.ONE;
}
/**
* Returns true if the lower bound is zero.
*
* @return
*/
public boolean isOptional() {
return lower == LLowerBound.ZERO;
}
}