Package org.apache.felix.sigil.common.obr.impl

Source Code of org.apache.felix.sigil.common.obr.impl.VersionRangeHelper

/*
* 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.apache.felix.sigil.common.obr.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.felix.sigil.common.osgi.LDAPExpr;
import org.apache.felix.sigil.common.osgi.Not;
import org.apache.felix.sigil.common.osgi.Ops;
import org.apache.felix.sigil.common.osgi.SimpleTerm;
import org.apache.felix.sigil.common.osgi.VersionRange;
import org.apache.felix.sigil.common.osgi.VersionTable;
import org.osgi.framework.Version;

public class VersionRangeHelper
{

    public 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 VersionTable.getVersion(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);
            }
        }
    }
}
TOP

Related Classes of org.apache.felix.sigil.common.obr.impl.VersionRangeHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.