All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.core.packageManagement.VersionRangePackageConstraint Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This version represents the developer version, the "bleeding edge" of development, you could say. New functionality gets added to this version.

There is a newer version: 3.9.6
Show newest version
/*
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see .
 */

/*
 *    VersionRangePackageConstraint.java
 *    Copyright (C) 2015 University of Waikato, Hamilton, New Zealand
 *
 */
package weka.core.packageManagement;

/**
 * A concrete implementation of PackgageConstraint that encapsulates ranged
 * version number constraints. Handles constraints of the form (u.v.w < package
 * < x.y.z) and (package < u.v.w OR package > x.y.z)
 * 
 * @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
 * @version $Revision: 44030 $
 */
public class VersionRangePackageConstraint extends PackageConstraint {

  /** the lower bound */
  protected String m_lowerBound;

  /** the comparison for the lower bound */
  protected VersionPackageConstraint.VersionComparison m_lowerConstraint;

  /** the upper bound */
  protected String m_upperBound;

  /** the comparison for the upper bound */
  protected VersionPackageConstraint.VersionComparison m_upperConstraint;

  /** is false for version1 <= package <= version2 */
  protected boolean m_boundOr;

  /**
   * Constructor
   * 
   * @param p the package to base this constraint on
   */
  public VersionRangePackageConstraint(Package p) {
    setPackage(p);
  }

  /**
   * Set the range bounds and constraints.
   * 
   * @param bound1 the first bound
   * @param comp1 the first comparison
   * @param bound2 the second bound
   * @param comp2 the second comparison
   * @throws Exception if the range constraint is malformed
   */
  public void setRangeConstraint(String bound1,
    VersionPackageConstraint.VersionComparison comp1, String bound2,
    VersionPackageConstraint.VersionComparison comp2) throws Exception {

    // ranged constraint doesn't allow =
    if (comp1 == VersionPackageConstraint.VersionComparison.EQUAL
      || comp2 == VersionPackageConstraint.VersionComparison.EQUAL) {
      throw new Exception("[VersionRangePackageConstraint] malformed version "
        + "range constraint (= not allowed)!");
    }

    // if both inequalities are in the same direction then a plain
    // VersionPackageConstraint could be used to cover them both
    if (comp1.compatibleWith(comp2)) {
      throw new Exception("[VersionRangePackageConstraint] malformed "
        + "version range constraint!");
    }

    // determine which type of range this is
    VersionPackageConstraint.VersionComparison boundsComp =
      VersionPackageConstraint.compare(bound1, bound2);

    if (boundsComp == VersionPackageConstraint.VersionComparison.EQUAL) {
      throw new Exception("[VersionRangePackageConstraint] malformed version"
        + " range - both bounds are equal!");
    }

    if (comp1 == VersionPackageConstraint.VersionComparison.GREATERTHAN
      || comp1 == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {

      if (boundsComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
        m_boundOr = true; // it is an OR with respect to the two inequalities
      }
    } else {
      if (boundsComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
        m_boundOr = true; // it is an OR with respect to the two inequalities
      }
    }

    // store bounds in ascending order
    if (boundsComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
      m_lowerBound = bound1;
      m_lowerConstraint = comp1;
      m_upperBound = bound2;
      m_upperConstraint = comp2;
    } else {
      m_lowerBound = bound2;
      m_lowerConstraint = comp2;
      m_upperBound = bound1;
      m_upperConstraint = comp1;
    }
  }

  /**
   * Get the lower bound of this range
   * 
   * @return the lower bound
   */
  public String getLowerBound() {
    return m_lowerBound;
  }

  /**
   * Get the upper bound of this range
   * 
   * @return the upper bound
   */
  public String getUpperBound() {
    return m_upperBound;
  }

  /**
   * Get the lower comparison
   * 
   * @return the lower comparison
   */
  public VersionPackageConstraint.VersionComparison getLowerComparison() {
    return m_lowerConstraint;
  }

  /**
   * Get the upper comparison
   * 
   * @return the upper comparison
   */
  public VersionPackageConstraint.VersionComparison getUpperComparison() {
    return m_upperConstraint;
  }

  /**
   * Returns true if this is a bounded OR type of constraint
   * 
   * @return true if this is a bounded OR type of constraint
   */
  public boolean isBoundOR() {
    return m_boundOr;
  }

  protected static boolean checkConstraint(String toCheck,
    VersionPackageConstraint.VersionComparison comp1, String bound1,
    VersionPackageConstraint.VersionComparison comp2, String bound2,
    boolean boundOr) {

    boolean result1 =
      VersionPackageConstraint.checkConstraint(toCheck, comp1, bound1);
    boolean result2 =
      VersionPackageConstraint.checkConstraint(toCheck, comp2, bound2);

    if (boundOr) {
      return (result1 || result2);
    } else {
      return (result1 && result2);
    }
  }

  /**
   * Check the target package against the constraint embodied in this
   * PackageConstraint.
   * 
   * @param target a package to check with respect to the encapsulated package
   *          and the constraint.
   * 
   * @return true if the constraint is met by the target package with respect to
   *         the encapsulated package + constraint.
   * @throws Exception if the constraint can't be checked for some reason.
   */
  @Override
  public boolean checkConstraint(Package target) throws Exception {
    if (m_lowerConstraint == null || m_upperConstraint == null) {
      throw new Exception("[VersionRangePackageConstraint] No constraint has"
        + " been set!");
    }

    String targetVersion =
      target.getPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY)
        .toString();

    return checkConstraint(targetVersion, m_lowerConstraint, m_lowerBound,
      m_upperConstraint, m_upperBound, m_boundOr);
  }

  protected PackageConstraint checkTargetVersionRangePackageConstraint(
    VersionRangePackageConstraint target) throws Exception {
    // TODO

    String targetLowerBound = target.getLowerBound();
    String targetUpperBound = target.getUpperBound();

    VersionPackageConstraint.VersionComparison targetLowerComp =
      target.getLowerComparison();
    VersionPackageConstraint.VersionComparison targetUpperComp =
      target.getUpperComparison();

    if (!m_boundOr) {
      if (target.isBoundOR()) {
        // construct two VersionPackageConstraints to represent the two
        // target open-ended inequalities
        Package p = (Package) target.getPackage().clone();
        p.setPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY,
          target.getLowerBound());
        VersionPackageConstraint lowerC = new VersionPackageConstraint(p);
        lowerC.setVersionConstraint(target.getLowerComparison());

        p = (Package) p.clone();
        p.setPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY,
          target.getUpperBound());
        VersionPackageConstraint upperC = new VersionPackageConstraint(p);
        upperC.setVersionConstraint(target.getUpperComparison());

        PackageConstraint coveringLower =
          checkTargetVersionPackageConstraint(lowerC);
        if (coveringLower != null) {
          // return this one. It is possible that both could be covered, but one
          // is
          // sufficient (and we have no mechanism for handling two fully bounded
          // ranges!
          return coveringLower;
        }

        PackageConstraint coveringUpper =
          checkTargetVersionPackageConstraint(upperC);
        return coveringUpper; // if we can't cover target at all then this will
                              // be null
      } else {
        // us and target are both bounded AND
        String resultLowerBound = null;
        String resultUpperBound = null;
        VersionPackageConstraint.VersionComparison resultLowerComp = null;
        VersionPackageConstraint.VersionComparison resultUpperComp = null;

        VersionPackageConstraint.VersionComparison lowerComp =
          VersionPackageConstraint.compare(m_lowerBound, targetLowerBound);
        if (lowerComp == VersionPackageConstraint.VersionComparison.EQUAL) {
          resultLowerBound = m_lowerBound;
          resultLowerComp =
            VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL;
          // select the most restrictive inequality
          if (targetLowerComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
            || m_lowerConstraint == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            resultLowerComp =
              VersionPackageConstraint.VersionComparison.GREATERTHAN;
          }
        } else if (lowerComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
          resultLowerBound = m_lowerBound;
          resultLowerComp = m_lowerConstraint;
        } else {
          resultLowerBound = targetLowerBound;
          resultLowerComp = targetLowerComp;
        }

        VersionPackageConstraint.VersionComparison upperComp =
          VersionPackageConstraint.compare(m_upperBound, targetUpperBound);
        if (upperComp == VersionPackageConstraint.VersionComparison.EQUAL) {
          resultUpperBound = m_upperBound;
          resultUpperComp =
            VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL;
          // select the most restrictive inequality
          if (targetUpperComp == VersionPackageConstraint.VersionComparison.LESSTHAN
            || m_upperConstraint == VersionPackageConstraint.VersionComparison.LESSTHAN) {
            resultUpperComp =
              VersionPackageConstraint.VersionComparison.LESSTHAN;
          }
        } else if (upperComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
          resultUpperBound = m_upperBound;
          resultUpperComp = m_upperConstraint;
        } else {
          resultUpperBound = targetUpperBound;
          resultUpperComp = targetUpperComp;
        }

        // now check for incompatibility - if resultUpper is less than result
        // lower
        // then the ranges are disjoint
        VersionPackageConstraint.VersionComparison disjointCheck =
          VersionPackageConstraint.compare(resultUpperBound, resultLowerBound);
        if (disjointCheck == VersionPackageConstraint.VersionComparison.LESSTHAN
          || disjointCheck == VersionPackageConstraint.VersionComparison.EQUAL) {
          // TODO if EQUAL then could actually return a VersionPackageConstraint
          // with an EQUAL constraint.
          return null;
        }

        // otherwise, we're good to go...
        VersionRangePackageConstraint result =
          new VersionRangePackageConstraint(getPackage());
        result.setRangeConstraint(resultLowerBound, resultLowerComp,
          resultUpperBound, resultUpperComp);

        return result;
      }
    } else {
      // we are bounded OR
      if (!target.isBoundOR()) {
        // construct two VersionPackageConstraints to represent our two
        // open-ended inequalities
        Package p = (Package) getPackage().clone();
        p.setPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY,
          m_lowerBound);
        VersionPackageConstraint lowerC = new VersionPackageConstraint(p);
        lowerC.setVersionConstraint(m_lowerConstraint);

        p = (Package) p.clone();
        p.setPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY,
          m_upperBound);
        VersionPackageConstraint upperC = new VersionPackageConstraint(p);
        upperC.setVersionConstraint(m_upperConstraint);

        PackageConstraint coveringLower =
          target.checkTargetVersionPackageConstraint(lowerC);
        if (coveringLower != null) {
          // return this one. It is possible that both could be covered, but one
          // is
          // sufficient (and we have no mechanism for handling two fully bounded
          // ranges!
          return coveringLower;
        }

        PackageConstraint coveringUpper =
          checkTargetVersionPackageConstraint(upperC);
        return coveringUpper; // if the target can't cover us then this will be
                              // null
      } else {
        // both us and target are bounded ORs. Just need the greatest upper
        // bound
        // and the smallest lower bound of the two
        String resultLowerBound = null;
        String resultUpperBound = null;
        VersionPackageConstraint.VersionComparison resultLowerComp = null;
        VersionPackageConstraint.VersionComparison resultUpperComp = null;

        VersionPackageConstraint.VersionComparison lowerComp =
          VersionPackageConstraint.compare(m_lowerBound, targetLowerBound);
        if (lowerComp == VersionPackageConstraint.VersionComparison.EQUAL) {
          resultLowerBound = m_lowerBound;
          resultLowerComp =
            VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL;
          // select the most restrictive inequality
          if (targetLowerComp == VersionPackageConstraint.VersionComparison.LESSTHAN
            || m_lowerConstraint == VersionPackageConstraint.VersionComparison.LESSTHAN) {
            resultLowerComp =
              VersionPackageConstraint.VersionComparison.LESSTHAN;
          }
        } else if (lowerComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
          resultLowerBound = m_lowerBound;
          resultLowerComp = m_lowerConstraint;
        } else {
          resultLowerBound = targetLowerBound;
          resultLowerComp = targetLowerComp;
        }

        VersionPackageConstraint.VersionComparison upperComp =
          VersionPackageConstraint.compare(m_upperBound, targetUpperBound);
        if (upperComp == VersionPackageConstraint.VersionComparison.EQUAL) {
          resultUpperBound = m_upperBound;
          resultUpperComp =
            VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL;
          // select the most restrictive inequality
          if (targetUpperComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
            || m_upperConstraint == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            resultUpperComp =
              VersionPackageConstraint.VersionComparison.GREATERTHAN;
          }
        } else if (upperComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
          resultUpperBound = m_upperBound;
          resultUpperComp = m_upperConstraint;
        } else {
          resultUpperBound = targetUpperBound;
          resultUpperComp = targetUpperComp;
        }

        VersionRangePackageConstraint result =
          new VersionRangePackageConstraint(getPackage());
        result.setRangeConstraint(resultLowerBound, resultLowerComp,
          resultUpperBound, resultUpperComp);

        return result;
      }
    }
  }

  protected PackageConstraint checkTargetVersionPackageConstraint(
    VersionPackageConstraint target) throws Exception {

    VersionPackageConstraint.VersionComparison targetComp =
      target.getVersionComparison();

    String targetVersion =
      target.getPackage()
        .getPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY)
        .toString();

    VersionPackageConstraint.VersionComparison lowerComp =
      VersionPackageConstraint.compare(targetVersion, m_lowerBound);
    VersionPackageConstraint.VersionComparison upperComp =
      VersionPackageConstraint.compare(targetVersion, m_upperBound);

    boolean lowerCheck = false;
    boolean upperCheck = false;
    String coveringLowerBound = null;
    String coveringUpperBound = null;
    VersionPackageConstraint.VersionComparison coveringLowerConstraint = null;
    VersionPackageConstraint.VersionComparison coveringUpperConstraint = null;

    // equals is easy
    if (targetComp == VersionPackageConstraint.VersionComparison.EQUAL) {

      // If our range contains the target version number then the target
      // is the least restrictive constraint that covers both
      if (checkConstraint(target.getPackage())) {
        return target;
      } else {
        return null; // incompatible
      }
    } else {
      if (m_boundOr) {
        // Check against our lower bound (our lower bound is a < or <=)
        // --------------
        // lower bound < case
        if (m_lowerConstraint == VersionPackageConstraint.VersionComparison.LESSTHAN) {
          if (lowerComp == VersionPackageConstraint.VersionComparison.EQUAL
            || lowerComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {
              // not compatible with our lower bound
              lowerCheck = false;
            } else {
              lowerCheck = true;
              // adjust the bounds
              coveringLowerBound = m_lowerBound;
              coveringLowerConstraint = m_lowerConstraint;
            }
          } else if (lowerComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
            lowerCheck = true;
            coveringLowerBound = targetVersion;
            coveringLowerConstraint = targetComp;
            if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
              coveringUpperBound = null; // same direction as our lower
                                         // constraint (so no upper bound)
            } else {
              // target's comparison is > or >= (new upper bound = our lower
              // bound)
              coveringUpperBound = m_lowerBound;
              coveringUpperConstraint = m_lowerConstraint;
            }
          }
        } else {
          // lower bound <= case
          if (lowerComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {
              // not compatible with our lower bound
              lowerCheck = false;
            } else {
              lowerCheck = true;
              // adjust bounds
              coveringLowerBound = m_lowerBound;
              coveringLowerConstraint = m_lowerConstraint;
            }
          } else if (lowerComp == VersionPackageConstraint.VersionComparison.EQUAL) {
            // if the target version is equal to our lower bound then the target
            // constraint
            // can't be >
            if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
              lowerCheck = false;
            } else {
              // target constraint is < or <=
              lowerCheck = true;
              coveringLowerBound = targetVersion;
              coveringLowerConstraint = targetComp;

              coveringUpperBound = null; // same direction as our lower bound
                                         // (so no upper bound)
            }
          } else {
            // target version is < or = to our lower bound
            lowerCheck = true;
            coveringLowerBound = targetVersion;
            coveringLowerConstraint = targetComp;
            if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
              coveringUpperBound = null; // same direction as our lower
                                         // constraint (so no upper bound)
            } else {
              // target's comparison is > or >= (new upper bound = our lower
              // bound)
              coveringUpperBound = m_lowerBound;
              coveringUpperConstraint = m_lowerConstraint;
            }
          }
        }
        // end check against our lower bound ----------------

        // check against our upper bound (if necessary)
        if (!lowerCheck) {
          // Check against our upper bound (our upper bound is a > or >=)
          // --------------
          // upper bound > case
          if (m_upperConstraint == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            if (upperComp == VersionPackageConstraint.VersionComparison.EQUAL
              || upperComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
              if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
                || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
                // not compatible with our upper bound
                upperCheck = false;
              } else {
                lowerCheck = true;
                // adjust the bounds
                coveringUpperBound = m_upperBound;
                coveringUpperConstraint = m_upperConstraint;
              }
            } else if (upperComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
              upperCheck = true;
              coveringUpperBound = targetVersion;
              coveringUpperConstraint = targetComp;
              if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
                || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {
                coveringLowerBound = null; // same direction as our upper
                                           // constraint (so no lower bound)
              } else {
                // target's comparison is < or <= (new lower bound = our upper
                // bound)
                coveringLowerBound = m_upperBound;
                coveringLowerConstraint = m_upperConstraint;
              }
            }
          } else {
            // upper bound >= case
            if (upperComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
              if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
                || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
                // not compatible with our upper bound
                upperCheck = false;
              } else {
                upperCheck = true;
                // adjust bounds
                coveringUpperBound = m_upperBound;
                coveringUpperConstraint = m_upperConstraint;
              }
            } else if (upperComp == VersionPackageConstraint.VersionComparison.EQUAL) {
              // if the target version is equal to our upper bound then the
              // target constraint
              // can't be <
              if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
                upperCheck = false;
              } else {
                // target constraint is > or >=
                upperCheck = true;
                coveringUpperBound = targetVersion;
                coveringUpperConstraint = targetComp;

                coveringLowerBound = null; // same direction as our upper bound
                                           // (so no lower bound)
              }
            } else {
              // target version is > or = to our upper bound
              upperCheck = true;
              coveringUpperBound = targetVersion;
              coveringUpperConstraint = targetComp;
              if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
                || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {
                coveringLowerBound = null; // same direction as our upper
                                           // constraint (so no lower bound)
              } else {
                // target's comparison is < or <= (new lower bound = our upper
                // bound)
                coveringLowerBound = m_upperBound;
                coveringLowerConstraint = m_upperConstraint;
              }
            }
          }
        }

        // now return the appropriate type of package constraint to cover this
        // and the
        // target

        if (!lowerCheck && !upperCheck) {
          // this shouldn't be possible
          throw new Exception(
            "[VersionRangePackageConstraint] This shouldn't be possible!!");
        }

        if (coveringLowerBound != null && coveringUpperBound != null) {
          VersionRangePackageConstraint result =
            new VersionRangePackageConstraint(getPackage());
          result.setRangeConstraint(coveringLowerBound,
            coveringLowerConstraint, coveringUpperBound,
            coveringUpperConstraint);
          return result;
        }

        String newVersionNumber =
          (coveringLowerBound != null) ? coveringLowerBound
            : coveringUpperBound;
        VersionPackageConstraint.VersionComparison newConstraint =
          (coveringLowerConstraint != null) ? coveringLowerConstraint
            : coveringUpperConstraint;
        Package p = (Package) getPackage().clone();

        p.setPackageMetaDataElement(VersionPackageConstraint.VERSION_KEY,
          newVersionNumber);
        VersionPackageConstraint result = new VersionPackageConstraint(p);
        result.setVersionConstraint(newConstraint);

        return result;
      } // end bounded OR case //////////
      else {
        // bounded AND case
        if (lowerComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
          if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
            || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL
            || targetComp == VersionPackageConstraint.VersionComparison.EQUAL) {
            // outside of our range and inequality is in the wrong direction
            lowerCheck = false;
          } else {
            // outside our range, but inequality in right direction - our range
            // satisfies both
            lowerCheck = true;
            coveringLowerBound = m_lowerBound;
            coveringLowerConstraint = m_lowerConstraint;
            coveringUpperBound = m_upperBound;
            coveringUpperConstraint = m_upperConstraint;
          }
        } else if (lowerComp == VersionPackageConstraint.VersionComparison.EQUAL) {
          // satisfiable if target comp is > or >=
          if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL
            || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            lowerCheck = true;
            coveringLowerBound = m_lowerBound;
            coveringLowerConstraint =
              (m_lowerConstraint == VersionPackageConstraint.VersionComparison.GREATERTHAN || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) ? VersionPackageConstraint.VersionComparison.GREATERTHAN
                : VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL;
            coveringUpperBound = m_upperBound;
            coveringUpperConstraint = m_upperConstraint;
          } else {
            // target comp is < or <= - can satisfy only if <= and our lower
            // constraint is >=
            if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL
              && m_lowerConstraint == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL) {
              VersionPackageConstraint.VersionComparison newComp =
                VersionPackageConstraint.VersionComparison.EQUAL;
              VersionPackageConstraint result =
                new VersionPackageConstraint(target.getPackage());
              result.setVersionConstraint(newComp);
              // we're done
              return result;
            }
          }
        } else if (lowerComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
          // handle the within range (but not on the upper boundary) case here
          if (upperComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
            if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
              lowerCheck = true;
              upperCheck = true;
              coveringLowerBound = m_lowerBound;
              coveringLowerConstraint = m_lowerConstraint;
              coveringUpperBound = targetVersion;
              coveringUpperConstraint = targetComp;
            } else {
              coveringLowerBound = targetVersion;
              coveringLowerConstraint = targetComp;
              coveringUpperBound = m_upperBound;
              coveringUpperConstraint = m_upperConstraint;
            }
          }
        }

        if (coveringLowerBound == null || coveringUpperBound == null) {
          // consider the upper bound
          if (upperComp == VersionPackageConstraint.VersionComparison.EQUAL) {
            // satisfiable if target comp is < or <=
            if (targetComp == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL
              || targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN) {
              upperCheck = true;
              coveringUpperBound = m_upperBound;
              coveringUpperConstraint =
                (m_upperConstraint == VersionPackageConstraint.VersionComparison.LESSTHAN || targetComp == VersionPackageConstraint.VersionComparison.LESSTHAN) ? VersionPackageConstraint.VersionComparison.LESSTHAN
                  : VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL;
              coveringLowerBound = m_lowerBound;
              coveringLowerConstraint = m_lowerConstraint;
            } else {
              // target comp is > or >= - can satisfy only if >= and our upper
              // constraint is <=
              if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL
                && m_upperConstraint == VersionPackageConstraint.VersionComparison.LESSTHANOREQUAL) {
                VersionPackageConstraint.VersionComparison newComp =
                  VersionPackageConstraint.VersionComparison.EQUAL;
                VersionPackageConstraint result =
                  new VersionPackageConstraint(target.getPackage());
                result.setVersionConstraint(newComp);
                // we're done
                return result;
              }
            }
          } else if (upperComp == VersionPackageConstraint.VersionComparison.GREATERTHAN) {
            if (targetComp == VersionPackageConstraint.VersionComparison.GREATERTHAN
              || targetComp == VersionPackageConstraint.VersionComparison.GREATERTHANOREQUAL
              || targetComp == VersionPackageConstraint.VersionComparison.EQUAL) {
              // outside of our range and inequality is in the wrong direction
              upperCheck = false;
            } else {
              // outside our range, but inequality in right direction - our
              // range satisfies both
              upperCheck = true;
              coveringUpperBound = m_upperBound;
              coveringUpperConstraint = m_upperConstraint;
              coveringLowerBound = m_lowerBound;
              coveringLowerConstraint = m_lowerConstraint;
            }
          }
        }

        if (coveringUpperBound == null && coveringLowerBound == null) {
          // we can't satisfy both
          return null;
        }

        if (coveringUpperBound == null || coveringLowerBound == null) {
          // this shouldn't happen - either we can't cover it (in which case
          // both should be null) or we can (in which case both are non-null).
          throw new Exception(
            "[VersionRangePackageConstraint] This shouldn't be possible!!");
        }

        VersionRangePackageConstraint result =
          new VersionRangePackageConstraint(getPackage());

        result.setRangeConstraint(coveringLowerBound, coveringLowerConstraint,
          coveringUpperBound, coveringUpperConstraint);
        return result;
      }
      // check for incompatible first
      /*
       * boolean checkLower =
       * VersionPackageConstraint.checkConstraint(targetVersion,
       * m_lowerConstraint, m_lowerBound);
       */

      /*
       * VersionPackageConstraint lowerBoundCover = new
       * VersionPackageConstraint((Package)(getPackage().clone()));
       * lowerBoundCover.setVersionConstraint(m_lowerConstraint);
       */

    }
  }

  @Override
  public PackageConstraint checkConstraint(PackageConstraint target)
    throws Exception {

    if (m_lowerConstraint == null || m_upperConstraint == null) {
      throw new Exception("[VersionRangePackageConstraint] No constraint has"
        + " been set!");
    }

    // have to cover the case where the target is a VersionPackageConstraint or
    // a VersionRangePackageConstraint
    if (!(target instanceof VersionRangePackageConstraint)
      && !(target instanceof VersionPackageConstraint)) {
      throw new Exception("[VersionRangePackageConstraint] incompatible "
        + "target constraint!");
    }

    // target is a VersionPackageConstraint
    if (target instanceof VersionPackageConstraint) {
      PackageConstraint result =
        checkTargetVersionPackageConstraint((VersionPackageConstraint) target);
      return result;
    } else if (target instanceof VersionRangePackageConstraint) {
      // target is VersionRangePackageConstraint
      PackageConstraint result =
        checkTargetVersionRangePackageConstraint((VersionRangePackageConstraint) target);
      return result;
    }

    return null;
  }

  @Override
  public String toString() {
    String result =
      m_thePackage.getPackageMetaDataElement("PackageName").toString() + " ("
        + m_lowerConstraint + m_lowerBound + "|" + m_upperConstraint
        + m_upperBound + ")";
    return result;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy