blob: 50b0fb15e6058c25ac7c1b35ed3228f9d8280b12 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.cauldron.bld.obr;
import java.util.ArrayList;
import java.util.List;
import org.cauldron.sigil.model.common.LDAPExpr;
import org.cauldron.sigil.model.common.LDAPParseException;
import org.cauldron.sigil.model.common.LDAPParser;
import org.cauldron.sigil.model.common.Not;
import org.cauldron.sigil.model.common.Ops;
import org.cauldron.sigil.model.common.SimpleTerm;
import org.cauldron.sigil.model.common.VersionRange;
import org.osgi.framework.Version;
class VersionRangeHelper {
// e.g. (&(version>=1.0.0)(version<=2.0.0)) (&(version>1.0.0)(version<2.0.0)) (&(!(version<1.0.0))(!(version>2.0.0))) (&(!(version<=1.0.0))(!(version>=2.0.0))) (version=1.0.0) (version>=1.0.0) (version<=2.0.0) (version>1.0.0) (version<2.0.0) (!(version>2.0.0)) (!(version<1.0.0)) (!(version>=2.0.0)) (!(version<=1.0.0))
public static void main(String[] args) throws LDAPParseException {
for ( String arg : args ) {
LDAPExpr expr = LDAPParser.parseExpression(arg.trim());
System.out.println( expr + " -> " + decodeVersions(expr) );
}
}
static VersionRange decodeVersions(LDAPExpr expr) throws NumberFormatException {
ArrayList<LDAPExpr> terms = new ArrayList<LDAPExpr>(1);
findExpr("version", expr, terms);
if ( terms.isEmpty() ) {
// woo hoo!
return VersionRange.ANY_VERSION;
}
else {
switch ( terms.size() ) {
case 1: {
return parseSimpleVersionRange(terms.get(0));
}
case 2: {
return parseCompoundVersionRange(terms.get(0), terms.get(1));
}
default: {
// (&(version>=min)(!(version=min))(version<=max)(!(version=max))) - (min,max) - not dealt with!!
// (&(|(version>min)(version=min))(|(version<max)(version=max))) - [min,max] - not dealt with!!
throw new NumberFormatException("Failed to parse complicated version expression " + expr);
}
}
}
}
// (&(version>=min)(version<=max)) - [min,max]
// (&(version>min)(version<max)) - (min,max)
//
// (&(!(version<min))(!(version>max))) - [min,max]
// (&(!(version<=min))(!(version>=max)) - (min,max)
private static VersionRange parseCompoundVersionRange(LDAPExpr left, LDAPExpr right) throws NumberFormatException {
VersionRange one = parseSimpleVersionRange(left);
VersionRange two = parseSimpleVersionRange(right);
// sanity check
if ( one.isPointVersion() || two.isPointVersion() ) {
throw new NumberFormatException("Unexpected point version in compound expression " + left);
}
VersionRange max = one.getFloor().equals( Version.emptyVersion ) ? one : two;
VersionRange min = max == one ? two : one;
return new VersionRange( min.isOpenFloor(), min.getFloor(), max.getCeiling(), max.isOpenCeiling() );
}
// possible variations
// (version=v) - [v,v]
//
// (version>=min) - [min,*)
// (version<=max) - [0,max]
//
// (version>min) - (min,*)
// (version<max) - [0,max)
//
// (!(version>max)) - [0,max]
// (!(version<min)) - [min,*)
// (!(version>=max)) - [0,max)
// (!(version<=min)) - (0,*)
private static VersionRange parseSimpleVersionRange(LDAPExpr expr) throws NumberFormatException {
Version min = Version.emptyVersion;
Version max = VersionRange.INFINITE_VERSION;
boolean openFloor = false;
boolean openCeiling = false;
if ( expr instanceof Not ) {
Not n = (Not) expr;
SimpleTerm t = (SimpleTerm) n.getEx();
if ( t.getOp() == Ops.EQ ) {
throw new NumberFormatException("Unexpected point version in negated expression " + expr);
}
if ( !isMax(t.getOp()) ) {
max = toVersion(t);
openCeiling = !openFloor(t);
}
else if ( !isMin(t.getOp()) ) {
min = toVersion(t);
openFloor = !openCeiling(t);
}
else {
throw new IllegalStateException("Unexpected operator " + t.getOp());
}
}
else {
SimpleTerm t = (SimpleTerm) expr;
if ( t.getOp().equals( Ops.EQ ) ) {
max = toVersion(t);
min = max;
openFloor = false;
openCeiling = false;
}
else if ( isMax(t.getOp()) ) {
max = toVersion(t);
openCeiling = openCeiling(t);
}
else if ( isMin(t.getOp()) ) {
min = toVersion(t);
openFloor = openFloor(t);
}
else {
throw new IllegalStateException("Unexpected operator " + t.getOp());
}
}
return new VersionRange( openFloor, min, max, openCeiling );
}
private static Version toVersion(SimpleTerm t) {
return new Version(t.getRval());
}
private static boolean isMax(Ops op) {
return op == Ops.LE || op == Ops.LT;
}
private static boolean isMin(Ops op) {
return op == Ops.GE || op == Ops.GT;
}
private static boolean openFloor(SimpleTerm t) {
return t.getOp() == Ops.GT;
}
private static boolean openCeiling(SimpleTerm t) {
return t.getOp() == Ops.LT;
}
private static void findExpr(String string, LDAPExpr expr, List<LDAPExpr> terms) {
if ( expr instanceof SimpleTerm ) {
SimpleTerm term = (SimpleTerm) expr;
if ( term.getName().equals(string) ) {
terms.add(term);
}
}
else if ( expr instanceof Not ) {
Not not = (Not) expr;
if ( not.getEx() instanceof SimpleTerm ) {
SimpleTerm term = (SimpleTerm) not.getEx();
if ( term.getName().equals(string) ) {
terms.add(not);
}
}
}
else {
for ( LDAPExpr c : expr.getChildren() ) {
findExpr(string, c, terms);
}
}
}
}