use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PRED_current_user_2 method exec.
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
if (a1 instanceof VariableTerm) {
throw new PInstantiationException(this, 1);
}
if (!a2.unify(createUser(engine, a1), engine.trail)) {
return engine.fail();
}
return cont;
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class SubmitRuleEvaluator method evaluate.
/**
* Evaluate the submit rules.
*
* @return List of {@link SubmitRecord} objects returned from the evaluated rules, including any
* errors.
*/
public List<SubmitRecord> evaluate() {
initOptions();
Change c = control.getChange();
if (!opts.allowClosed() && c.getStatus().isClosed()) {
SubmitRecord rec = new SubmitRecord();
rec.status = SubmitRecord.Status.CLOSED;
return Collections.singletonList(rec);
}
if (!opts.allowDraft()) {
try {
initPatchSet();
} catch (OrmException e) {
return ruleError("Error looking up patch set " + control.getChange().currentPatchSetId(), e);
}
if (c.getStatus() == Change.Status.DRAFT || patchSet.isDraft()) {
return cannotSubmitDraft();
}
}
List<Term> results;
try {
results = evaluateImpl("locate_submit_rule", "can_submit", "locate_submit_filter", "filter_submit_results", control.getUser());
} catch (RuleEvalException e) {
return ruleError(e.getMessage(), e);
}
if (results.isEmpty()) {
// whether or not that is actually possible given the permissions.
return ruleError(String.format("Submit rule '%s' for change %s of %s has no solution.", getSubmitRuleName(), cd.getId(), getProjectName()));
}
return resultsToSubmitRecord(getSubmitRule(), results);
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class SubmitRuleEvaluator method getSubmitType.
/**
* Evaluate the submit type rules to get the submit type.
*
* @return record from the evaluated rules.
*/
public SubmitTypeRecord getSubmitType() {
initOptions();
try {
initPatchSet();
} catch (OrmException e) {
return typeError("Error looking up patch set " + control.getChange().currentPatchSetId(), e);
}
try {
if (control.getChange().getStatus() == Change.Status.DRAFT && !control.isDraftVisible(cd.db(), cd)) {
return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found");
}
if (patchSet.isDraft() && !control.isDraftVisible(cd.db(), cd)) {
return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found");
}
} catch (OrmException err) {
String msg = "Cannot read patch set " + patchSet.getId();
log.error(msg, err);
return SubmitTypeRecord.error(msg);
}
List<Term> results;
try {
results = evaluateImpl("locate_submit_type", "get_submit_type", "locate_submit_type_filter", "filter_submit_type_results", // have a consistent view of the submit type.
null);
} catch (RuleEvalException e) {
return typeError(e.getMessage(), e);
}
if (results.isEmpty()) {
// Should never occur for a well written rule
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + getProjectName() + " has no solution.");
}
Term typeTerm = results.get(0);
if (!(typeTerm instanceof SymbolTerm)) {
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + getProjectName() + " did not return a symbol.");
}
String typeName = ((SymbolTerm) typeTerm).name();
try {
return SubmitTypeRecord.OK(SubmitType.valueOf(typeName.toUpperCase()));
} catch (IllegalArgumentException e) {
return typeError("Submit type rule " + getSubmitRule() + " for change " + cd.getId() + " of " + getProjectName() + " output invalid result: " + typeName);
}
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method resultsToSubmitRecord.
/**
* Convert the results from Prolog Cafe's format to Gerrit's common format.
*
* <p>can_submit/1 terminates when an ok(P) record is found. Therefore walk the results backwards,
* using only that ok(P) record if it exists. This skips partial results that occur early in the
* output. Later after the loop the out collection is reversed to restore it to the original
* ordering.
*/
public SubmitRecord resultsToSubmitRecord(Term submitRule, List<Term> results) {
checkState(!results.isEmpty(), "the list of Prolog terms must not be empty");
SubmitRecord resultSubmitRecord = new SubmitRecord();
resultSubmitRecord.labels = new ArrayList<>();
for (int resultIdx = results.size() - 1; 0 <= resultIdx; resultIdx--) {
Term submitRecord = results.get(resultIdx);
if (!(submitRecord instanceof StructureTerm) || 1 != submitRecord.arity()) {
return invalidResult(submitRule, submitRecord);
}
if (!"ok".equals(submitRecord.name()) && !"not_ready".equals(submitRecord.name())) {
return invalidResult(submitRule, submitRecord);
}
// the change to be submittable when at least one result is OK.
if ("ok".equals(submitRecord.name())) {
resultSubmitRecord.status = SubmitRecord.Status.OK;
} else if ("not_ready".equals(submitRecord.name()) && resultSubmitRecord.status == null) {
resultSubmitRecord.status = SubmitRecord.Status.NOT_READY;
}
// Unpack the one argument. This should also be a structure with one
// argument per label that needs to be reported on to the caller.
//
submitRecord = submitRecord.arg(0);
if (!(submitRecord instanceof StructureTerm)) {
return invalidResult(submitRule, submitRecord);
}
for (Term state : ((StructureTerm) submitRecord).args()) {
if (!(state instanceof StructureTerm) || 2 != state.arity() || !"label".equals(state.name())) {
return invalidResult(submitRule, submitRecord);
}
SubmitRecord.Label lbl = new SubmitRecord.Label();
resultSubmitRecord.labels.add(lbl);
lbl.label = checkLabelName(state.arg(0).name());
Term status = state.arg(1);
try {
if ("ok".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.OK;
appliedBy(lbl, status);
} else if ("reject".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.REJECT;
appliedBy(lbl, status);
} else if ("need".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.NEED;
} else if ("may".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.MAY;
} else if ("impossible".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.IMPOSSIBLE;
} else {
return invalidResult(submitRule, submitRecord);
}
} catch (UserTermExpected e) {
return invalidResult(submitRule, submitRecord, e.getMessage());
}
}
if (resultSubmitRecord.status == SubmitRecord.Status.OK) {
break;
}
}
Collections.reverse(resultSubmitRecord.labels);
return resultSubmitRecord;
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method getSubmitType.
/**
* Evaluate the submit type rules to get the submit type.
*
* @return record from the evaluated rules.
*/
public SubmitTypeRecord getSubmitType() {
try {
if (projectState == null) {
throw new NoSuchProjectException(cd.project());
}
} catch (NoSuchProjectException e) {
return typeError("Error looking up change " + cd.getId(), e);
}
List<Term> results;
try {
results = evaluateImpl("locate_submit_type", "get_submit_type", "locate_submit_type_filter", "filter_submit_type_results");
} catch (RuleEvalException e) {
return typeError(e.getMessage(), e);
}
if (results.isEmpty()) {
// Should never occur for a well written rule
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + projectState.getName() + " has no solution.");
}
Term typeTerm = results.get(0);
if (!(typeTerm instanceof SymbolTerm)) {
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + projectState.getName() + " did not return a symbol.");
}
String typeName = typeTerm.name();
try {
return SubmitTypeRecord.OK(SubmitType.valueOf(typeName.toUpperCase()));
} catch (IllegalArgumentException e) {
return typeError("Submit type rule " + getSubmitRule() + " for change " + cd.getId() + " of " + projectState.getName() + " output invalid result: " + typeName);
}
}
Aggregations