Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/UserDefinedOptimizationFunction.java')
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/UserDefinedOptimizationFunction.java198
1 files changed, 198 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/UserDefinedOptimizationFunction.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/UserDefinedOptimizationFunction.java
new file mode 100644
index 000000000..6a8d69cc4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/UserDefinedOptimizationFunction.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Daniel Le Berre and others. 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:
+ * Daniel Le Berre - initial API and implementation
+ * Red Hat, Inc. - support for remediation page
+ ******************************************************************************/
+package org.eclipse.equinox.internal.p2.director;
+
+import java.math.BigInteger;
+import java.util.*;
+import org.eclipse.equinox.internal.p2.director.Projector.AbstractVariable;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.query.*;
+import org.sat4j.pb.tools.*;
+import org.sat4j.specs.ContradictionException;
+
+public class UserDefinedOptimizationFunction extends OptimizationFunction {
+ private Collection<IInstallableUnit> alreadyExistingRoots;
+ private LexicoHelper<Object, Explanation> dependencyHelper;
+ private IQueryable<IInstallableUnit> picker;
+ private List changeVariables = new ArrayList();
+ private List removalVariables = new ArrayList();
+ private List newVariables = new ArrayList();
+
+ public UserDefinedOptimizationFunction(IQueryable<IInstallableUnit> lastState, List<AbstractVariable> abstractVariables, List<AbstractVariable> optionalVariables, IQueryable<IInstallableUnit> picker, IInstallableUnit selectionContext, Map<String, Map<Version, IInstallableUnit>> slice, DependencyHelper<Object, Explanation> dependencyHelper, Collection<IInstallableUnit> alreadyInstalledIUs) {
+ super(lastState, abstractVariables, optionalVariables, picker, selectionContext, slice);
+ this.picker = picker;
+ this.slice = slice;
+ this.dependencyHelper = (LexicoHelper<Object, Explanation>) dependencyHelper;
+ this.alreadyExistingRoots = alreadyInstalledIUs;
+ }
+
+ public List<WeightedObject<? extends Object>> createOptimizationFunction(IInstallableUnit metaIu, Collection<IInstallableUnit> newRoots) {
+ List weightedObjects = new ArrayList();
+ List objects = new ArrayList();
+ BigInteger weight = BigInteger.valueOf(slice.size() + 1);
+ String[] criteria = new String[] {"+new", "-removed", "-changed"};
+ BigInteger currentWeight = weight.pow(criteria.length - 1);
+ int formermaxvarid = dependencyHelper.getSolver().nextFreeVarId(false);
+ int newmaxvarid;
+ boolean maximizes;
+ Object thing;
+ for (int i = 0; i < criteria.length; i++) {
+ if (criteria[i].endsWith("new")) {
+ weightedObjects.clear();
+ newRoots(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ currentWeight = currentWeight.divide(weight);
+ } else if (criteria[i].endsWith("removed")) {
+ weightedObjects.clear();
+ removedRoots(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ currentWeight = currentWeight.divide(weight);
+ // } else if (criteria[i].endsWith("notuptodate")) {
+ // weightedObjects.clear();
+ // notuptodate(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ // currentWeight = currentWeight.divide(weight);
+ // } else if (criteria[i].endsWith("unsat_recommends")) {
+ // weightedObjects.clear();
+ // optional(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ // currentWeight = currentWeight.divide(weight);
+ // } else if (criteria[i].endsWith("versionchanged")) {
+ // weightedObjects.clear();
+ // versionChanged(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ } else if (criteria[i].endsWith("changed")) {
+ weightedObjects.clear();
+ changedRoots(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+ currentWeight = currentWeight.divide(weight);
+ // } else if (criteria[i].contains("sum")) {
+ // weightedObjects.clear();
+ // sum(weightedObjects, criteria[i].charAt(0) == '-', metaIu, Options.extractSumProperty(criteria[i]));
+ // dependencyHelper.addWeightedCriterion(weightedObjects);
+ // System.out.println("# criteria " + criteria[i].substring(1) + " size is " + weightedObjects.size());
+ // continue;
+ // } else {
+ // System.out.println("Skipping unknown criteria:" + criteria[i]);
+ }
+ objects.clear();
+ maximizes = criteria[i].startsWith("+");
+ for (Iterator it = weightedObjects.iterator(); it.hasNext();) {
+ thing = ((WeightedObject) it.next()).thing;
+ if (maximizes) {
+ thing = dependencyHelper.not(thing);
+ }
+ objects.add(thing);
+ }
+ dependencyHelper.addCriterion(objects);
+ newmaxvarid = dependencyHelper.getSolver().nextFreeVarId(false);
+ // System.out.println("# criteria " + criteria[i].substring(1) + " size is " + objects.size() + " using new vars " + formermaxvarid + " to " + newmaxvarid);
+ formermaxvarid = newmaxvarid;
+ }
+ weightedObjects.clear();
+ return null;
+ }
+
+ protected void changedRoots(List<WeightedObject<?>> weightedObjects, BigInteger weight, IInstallableUnit entryPointIU) {
+ Collection<IRequirement> requirements = entryPointIU.getRequirements();
+ for (IRequirement req : requirements) {
+ IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery(req.getMatches());
+ IQueryResult<IInstallableUnit> matches = picker.query(query, null);
+ Object[] changed = new Object[matches.toUnmodifiableSet().size()];
+ int i = 0;
+ for (IInstallableUnit match : matches) {
+ changed[i++] = isInstalledAsRoot(match) ? dependencyHelper.not(match) : match;
+ }
+ try {
+ Projector.AbstractVariable abs = new Projector.AbstractVariable("CHANGED"); //TODO
+ changeVariables.add(abs);
+ // abs <=> iuv1 or not iuv2 or ... or not iuvn
+ dependencyHelper.or(FakeExplanation.getInstance(), abs, changed);
+ weightedObjects.add(WeightedObject.newWO(abs, weight));
+ } catch (ContradictionException e) {
+ // TODO Auto-generated catch block TODO
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void newRoots(List<WeightedObject<?>> weightedObjects, BigInteger weight, IInstallableUnit entryPointIU) {
+ Collection<IRequirement> requirements = entryPointIU.getRequirements();
+ for (IRequirement req : requirements) {
+ IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery(req.getMatches());
+ IQueryResult<IInstallableUnit> matches = picker.query(query, null);
+ boolean oneInstalled = false;
+ for (IInstallableUnit match : matches) {
+ oneInstalled = oneInstalled || isInstalledAsRoot(match);
+ }
+ if (!oneInstalled) {
+ try {
+ Projector.AbstractVariable abs = new Projector.AbstractVariable("NEW"); //TODO
+ newVariables.add(abs);
+ // a <=> iuv1 or ... or iuvn
+ dependencyHelper.or(FakeExplanation.getInstance(), abs, matches.toArray(IInstallableUnit.class));
+ weightedObjects.add(WeightedObject.newWO(abs, weight));
+ } catch (ContradictionException e) {
+ // should not happen
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ protected void removedRoots(List<WeightedObject<?>> weightedObjects, BigInteger weight, IInstallableUnit entryPointIU) {
+ Collection<IRequirement> requirements = entryPointIU.getRequirements();
+ for (IRequirement req : requirements) {
+ IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery(req.getMatches());
+ IQueryResult<IInstallableUnit> matches = picker.query(query, null);
+ boolean installed = false;
+ Object[] literals = new Object[matches.toUnmodifiableSet().size()];
+ int i = 0;
+ for (IInstallableUnit match : matches) {
+ installed = installed || isInstalledAsRoot(match);
+ literals[i++] = dependencyHelper.not(match);
+ }
+ if (installed) {
+ try {
+ Projector.AbstractVariable abs = new Projector.AbstractVariable("REMOVED"); //TODO
+ removalVariables.add(abs);
+ // abs <=> not iuv1 and ... and not iuvn
+ dependencyHelper.and(FakeExplanation.getInstance(), abs, literals);
+ weightedObjects.add(WeightedObject.newWO(abs, weight));
+ } catch (ContradictionException e) {
+ // should not happen TODO
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static class FakeExplanation extends Explanation {
+ private static Explanation singleton = new FakeExplanation();
+
+ public static Explanation getInstance() {
+ return singleton;
+ }
+
+ protected int orderValue() {
+ return Explanation.OTHER_REASON;
+ }
+
+ @Override
+ public int shortAnswer() {
+ return 0;
+ }
+
+ }
+
+ private boolean isInstalledAsRoot(IInstallableUnit isInstalled) {
+ for (IInstallableUnit installed : alreadyExistingRoots) {
+ if (isInstalled.equals(installed))
+ return true;
+ }
+ return false;
+ }
+
+}

Back to the top