/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic 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.
*
* FenixEdu Academic 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 FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.domain;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.academic.util.EvaluationType;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.fenixedu.commons.i18n.LocalizedString;
public enum GradeScale {
TYPE20(true, new GradeScaleLogic() {
@Override
public boolean checkFinal(final Grade grade) {
final String value = grade.getValue();
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final int intValue = Integer.parseInt(value);
return intValue >= 10 && intValue <= 20;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean checkNotFinal(final Grade grade) {
final String value = grade.getValue();
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final double doubleValue = Double.parseDouble(value);
return doubleValue >= 0 && doubleValue <= 20;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public String qualify(final Grade grade) {
if (grade.getGradeScale() != GradeScale.TYPE20) {
return StringUtils.EMPTY;
}
try {
final int intValue = Integer.parseInt(grade.getValue());
if (18 <= intValue && intValue <= 20) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.a");
} else if (16 <= intValue && intValue <= 17) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.b");
} else if (14 <= intValue && intValue <= 15) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.c");
} else if (10 <= intValue && intValue <= 13) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.d");
} else {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
} catch (NumberFormatException e) {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
}
@Override
public boolean isNotEvaluated(final Grade grade) {
final String value = grade.getValue();
return grade.isEmpty() || value.equals(GradeScale.NA);
}
@Override
public boolean isNotApproved(final Grade grade) {
final String value = grade.getValue();
if (value.equals(GradeScale.RE) || isNotEvaluated(grade)) {
return true;
}
try {
return Integer.parseInt(value) < 10;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean isApproved(final Grade grade) {
final String value = grade.getValue();
if (value.equals(GradeScale.AP)) {
return true;
}
try {
final int intValue = Integer.parseInt(value);
return 10 <= intValue && intValue <= 20;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean belongsTo(final String value) {
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final double doubleValue = Double.parseDouble(value);
return doubleValue >= 0 && doubleValue <= 20;
} catch (NumberFormatException e) {
return false;
}
}
}),
TYPE5(true, new GradeScaleLogic() {
@Override
public boolean checkFinal(final Grade grade) {
final String value = grade.getValue();
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final int intValue = Integer.parseInt(value);
return intValue >= 3 && intValue <= 5;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean checkNotFinal(final Grade grade) {
final String value = grade.getValue();
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final double doubleValue = Double.parseDouble(value);
return doubleValue >= 0 && doubleValue <= 20;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public String qualify(final Grade grade) {
if (grade.getGradeScale() != GradeScale.TYPE5) {
return StringUtils.EMPTY;
}
try {
final int intValue = Integer.parseInt(grade.getValue());
if (intValue == 5) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.a");
} else if (intValue == 4) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.b");
} else if (intValue == 3) {
return BundleUtil.getString(Bundle.APPLICATION, "label.grade.c");
} else {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
} catch (NumberFormatException e) {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
}
@Override
public boolean isNotEvaluated(final Grade grade) {
if (grade.isEmpty()) {
return true;
}
return grade.getValue().equals(GradeScale.NA);
}
@Override
public boolean isNotApproved(final Grade grade) {
final String value = grade.getValue();
if (value.equals(GradeScale.RE) || isNotEvaluated(grade)) {
return true;
}
try {
return Integer.parseInt(value) < 3;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean isApproved(final Grade grade) {
try {
final int intValue = Integer.parseInt(grade.getValue());
return 3 <= intValue && intValue <= 5;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean belongsTo(final String value) {
if (value.equals(NA) || value.equals(RE)) {
return true;
}
try {
final double doubleValue = Double.parseDouble(value);
return doubleValue >= 0 && doubleValue <= 5;
} catch (NumberFormatException e) {
return false;
}
}
}),
TYPEAP(true, new GradeScaleLogic() {
@Override
public boolean checkFinal(final Grade grade) {
final String value = grade.getValue();
return value.equals(NA) || value.equals(RE) || value.equals(AP);
}
@Override
public boolean checkNotFinal(final Grade grade) {
final String value = grade.getValue();
return value.equals(NA) || value.equals(RE) || value.equals(AP);
}
@Override
public String qualify(final Grade grade) {
if (grade.getGradeScale() != GradeScale.TYPEAP) {
return StringUtils.EMPTY;
}
final String value = grade.getValue();
if (value.equals(AP)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.approved");
} else if (value.equals(RE)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.notApproved");
} else if (value.equals(NA)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.notEvaluated");
} else {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
}
@Override
public boolean isNotEvaluated(final Grade grade) {
final String value = grade.getValue();
return grade.isEmpty() || value.equals(GradeScale.NA);
}
@Override
public boolean isNotApproved(final Grade grade) {
final String value = grade.getValue();
return value.equals(GradeScale.RE) || isNotEvaluated(grade);
}
@Override
public boolean isApproved(final Grade grade) {
final String value = grade.getValue();
return value.equals(GradeScale.AP);
}
@Override
public boolean belongsTo(final String value) {
return value.equals(NA) || value.equals(RE) || value.equals(AP);
}
}),
TYPEAPT(false, new GradeScaleLogic() {
@Override
public boolean checkFinal(final Grade grade) {
final String value = grade.getValue();
return value.equals(NA) || value.equals(RE) || value.equals(APT);
}
@Override
public boolean checkNotFinal(final Grade grade) {
final String value = grade.getValue();
return value.equals(NA) || value.equals(RE) || value.equals(APT);
}
@Override
public String qualify(final Grade grade) {
if (grade.getGradeScale() != GradeScale.TYPEAPT) {
return StringUtils.EMPTY;
}
final String value = grade.getValue();
if (value.equals(APT)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.apt");
} else if (value.equals(RE)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.notApproved");
} else if (value.equals(NA)) {
return BundleUtil.getString(Bundle.APPLICATION, "msg.notEvaluated");
} else {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
}
@Override
public boolean isNotEvaluated(final Grade grade) {
final String value = grade.getValue();
return grade.isEmpty() || value.equals(GradeScale.NA);
}
@Override
public boolean isNotApproved(final Grade grade) {
final String value = grade.getValue();
return value.equals(GradeScale.RE) || isNotEvaluated(grade);
}
@Override
public boolean isApproved(final Grade grade) {
final String value = grade.getValue();
return value.equals(GradeScale.APT);
}
@Override
public boolean belongsTo(final String value) {
return value.equals(NA) || value.equals(RE) || value.equals(APT);
}
}),
TYPEECTS(false, new GradeScaleLogic() {
@Override
public boolean belongsTo(String value) {
return value.equals("A") || value.equals("B") || value.equals("C") || value.equals("D") || value.equals("E")
|| value.equals("F") || value.equals(NA);
}
@Override
public boolean checkFinal(Grade grade) {
return false;
}
@Override
public boolean checkNotFinal(Grade grade) {
return false;
}
@Override
public boolean isApproved(Grade grade) {
return !(isNotEvaluated(grade) || isNotApproved(grade));
}
@Override
public boolean isNotApproved(Grade grade) {
return grade.getValue().equals("F");
}
@Override
public boolean isNotEvaluated(Grade grade) {
return grade.getValue().equals(NA);
}
@Override
public String qualify(Grade grade) {
return null;
}
}),
TYPEQUALITATIVE(true, new GradeScaleLogic() {
@Override
public boolean belongsTo(String value) {
return NA.equals(value) || RE.equals(value) || S.equals(value) || B.equals(value) || MB.equals(value)
|| E.equals(value);
}
@Override
public boolean checkFinal(Grade grade) {
return false;
}
@Override
public boolean checkNotFinal(Grade grade) {
return false;
}
@Override
public boolean isApproved(Grade grade) {
return !(isNotEvaluated(grade) || isNotApproved(grade));
}
@Override
public boolean isNotApproved(Grade grade) {
return RE.equals(grade.getValue());
}
@Override
public boolean isNotEvaluated(Grade grade) {
return NA.equals(grade.getValue());
}
@Override
public String qualify(Grade grade) {
return null;
}
});
public static interface GradeScaleLogic {
@Deprecated
boolean checkFinal(final Grade grade);
@Deprecated
boolean checkNotFinal(final Grade grade);
@Deprecated
String qualify(final Grade grade);
boolean isNotEvaluated(final Grade grade);
boolean isNotApproved(final Grade grade);
boolean isApproved(final Grade grade);
boolean belongsTo(final String value);
default LocalizedString getExtendedValue(Grade grade) {
return BundleUtil.getLocalizedString(Bundle.ENUMERATION, GradeScale.class.getSimpleName() + "." + grade.getValue());
}
default int compareGrades(Grade grade1, Grade grade2) {
if (grade2 == null) {
return 1;
}
final boolean isApproved1 = isApproved(grade1);
final boolean isApproved2 = isApproved(grade2);
if (isApproved1 && isApproved2) {
if (grade1.getValue().equals(GradeScale.AP)) {
return 1;
} else if (grade2.getValue().equals(GradeScale.AP)) {
return -1;
} else if (grade1.getGradeScale().equals(grade2.getGradeScale())) {
return grade1.getValue().compareTo(grade2.getValue());
} else {
throw new DomainException("Grade.unsupported.comparassion.of.grades.of.different.scales");
}
} else if (isApproved1 || grade2.getValue().equals(GradeScale.NA) || grade2.getValue().equals(GradeScale.RE)) {
return 1;
} else if (isApproved2 || grade1.getValue().equals(GradeScale.NA) || grade1.getValue().equals(GradeScale.RE)) {
return -1;
} else {
return grade1.getValue().compareTo(grade2.getValue());
}
}
}
private boolean isPublic;
private GradeScaleLogic logic;
static final public String NA = "NA";
static final public String RE = "RE";
static final public String AP = "AP";
static final public String APT = "APT";
static final public String I = "I";
static final public String S = "S";
static final public String B = "B";
static final public String MB = "MB";
static final public String MBDL = "MBDL";
static final public String BD = "BD";
static final public String E = "E";
static final public String R = "R";
static final public String AD = "AD";
static final public String ADL = "ADL";
static final public String A = "A";
static final public String AMB = "AMB";
private GradeScale(final boolean isPublic, GradeScaleLogic logic) {
setPublic(isPublic);
setLogic(logic);
}
public String getName() {
return name();
}
public void setLogic(GradeScaleLogic logic) {
this.logic = logic;
}
@Deprecated
public boolean isValid(final String value, final EvaluationType evaluationType) {
try {
final Grade grade = Grade.createGrade(value, this);
if (grade.isEmpty()) {
return false;
}
if (EvaluationType.FINAL_TYPE.equals(evaluationType)) {
return logic.checkFinal(grade);
} else {
return logic.checkNotFinal(grade);
}
} catch (DomainException de) {
return false;
}
}
public boolean isNotEvaluated(final Grade grade) {
return logic.isNotEvaluated(grade);
}
public boolean isNotApproved(final Grade grade) {
return logic.isNotApproved(grade);
}
public boolean isApproved(final Grade grade) {
return logic.isApproved(grade);
}
public boolean belongsTo(final String grade) {
return logic.belongsTo(grade);
}
public boolean belongsTo(final Grade grade) {
return logic.belongsTo(grade.getValue());
}
public LocalizedString getExtendedValue(Grade grade) {
return logic.getExtendedValue(grade);
}
@Deprecated
final public String getQualifiedName(final String value) {
final Grade grade = Grade.createGrade(value, this);
if (logic.isApproved(grade)) {
return logic.qualify(grade);
} else {
throw new DomainException("GradeScale.unable.to.qualify.given.grade");
}
}
public boolean isPublic() {
return isPublic;
}
public void setPublic(boolean isPublic) {
this.isPublic = isPublic;
}
static public List<GradeScale> getPublicGradeScales() {
List<GradeScale> publicGradeScales = new ArrayList<GradeScale>();
for (GradeScale gradeScale : values()) {
if (gradeScale.isPublic) {
publicGradeScales.add(gradeScale);
}
}
return publicGradeScales;
}
public String getDescription() {
return BundleUtil.getString(Bundle.ENUMERATION, name());
}
public String getPossibleValueDescription(boolean isFinal) {
final String key = isFinal ? "TYPE.final" : name() + ".description";
return BundleUtil.getString(Bundle.ENUMERATION, key);
}
public int compareGrades(Grade grade1, Grade grade2) {
return logic.compareGrades(grade1, grade2);
}
}