/* * 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.ivy.osgi.obr.xml; import java.text.ParseException; import org.apache.ivy.osgi.core.BundleInfo; import org.apache.ivy.osgi.core.BundleRequirement; import org.apache.ivy.osgi.filter.AndFilter; import org.apache.ivy.osgi.filter.CompareFilter; import org.apache.ivy.osgi.filter.CompareFilter.Operator; import org.apache.ivy.osgi.filter.NotFilter; import org.apache.ivy.osgi.filter.OSGiFilter; import org.apache.ivy.osgi.util.Version; import org.apache.ivy.osgi.util.VersionRange; public class RequirementAdapter { private Version startVersion = null; private boolean startExclusive = false; private Version endVersion = null; private boolean endExclusive = false; private String type = null; private String name = null; public static void adapt(BundleInfo info, Requirement requirement) throws UnsupportedFilterException, ParseException { RequirementAdapter adapter = new RequirementAdapter(); adapter.extractFilter(requirement.getFilter()); adapter.adapt(info, requirement.isOptional()); } private void extractFilter(OSGiFilter filter) throws UnsupportedFilterException, ParseException { if (filter instanceof AndFilter) { AndFilter andFilter = (AndFilter) filter; for (OSGiFilter subFilter : andFilter.getSubFilters()) { extractFilter(subFilter); } } else if (filter instanceof CompareFilter) { CompareFilter compareFilter = ((CompareFilter) filter); parseCompareFilter(compareFilter, false); } else if (filter instanceof NotFilter) { NotFilter notFilter = ((NotFilter) filter); if (notFilter.getSubFilter() instanceof CompareFilter) { CompareFilter compareFilter = ((CompareFilter) notFilter.getSubFilter()); parseCompareFilter(compareFilter, true); } } else { throw new UnsupportedFilterException("Unsupported filter: " + filter.getClass().getName()); } } private void adapt(BundleInfo info, boolean optional) throws ParseException { VersionRange range = getVersionRange(); String resolution = optional ? "optional" : null; if (type == null) { throw new ParseException("No requirement actually specified", 0); } BundleRequirement requirement = new BundleRequirement(type, name, range, resolution); info.addRequirement(requirement); if (BundleInfo.EXECUTION_ENVIRONMENT_TYPE.equals(type)) { info.addExecutionEnvironment(name); } } private VersionRange getVersionRange() { VersionRange range = null; if (startVersion != null || endVersion != null) { range = new VersionRange(startExclusive, startVersion, endExclusive, endVersion); } return range; } private void parseCompareFilter(CompareFilter compareFilter, boolean not) throws UnsupportedFilterException, ParseException { String att = compareFilter.getLeftValue(); if (BundleInfo.PACKAGE_TYPE.equals(att) || BundleInfo.BUNDLE_TYPE.equals(att) || BundleInfo.EXECUTION_ENVIRONMENT_TYPE.equals(att) || "symbolicname".equals(att) || BundleInfo.SERVICE_TYPE.equals(att)) { if (not) { throw new UnsupportedFilterException( "Not filter on requirement comparaison is not supported"); } if (type != null) { throw new UnsupportedFilterException("Multiple requirement type are not supported"); } if ("symbolicname".equals(att)) { type = BundleInfo.BUNDLE_TYPE; } else { type = att; } if (compareFilter.getOperator() != Operator.EQUALS) { throw new UnsupportedFilterException( "Filtering is only supported with the operator '='"); } name = compareFilter.getRightValue(); } else if ("version".equals(att)) { String v = compareFilter.getRightValue(); Version version; try { version = new Version(v); } catch (ParseException e) { throw new ParseException("Ill formed version: " + v, 0); } Operator operator = compareFilter.getOperator(); if (not) { if (operator == Operator.EQUALS) { throw new UnsupportedFilterException( "Not filter on equals comparaison is not supported"); } else if (operator == Operator.GREATER_OR_EQUAL) { operator = Operator.LOWER_THAN; } else if (operator == Operator.GREATER_THAN) { operator = Operator.LOWER_OR_EQUAL; } else if (operator == Operator.LOWER_OR_EQUAL) { operator = Operator.GREATER_THAN; } else if (operator == Operator.LOWER_THAN) { operator = Operator.GREATER_OR_EQUAL; } } if (operator == Operator.EQUALS) { if (startVersion != null || endVersion != null) { throw new UnsupportedFilterException( "Multiple version matching is not supported"); } startVersion = version; startExclusive = false; endVersion = version; endExclusive = false; } else if (operator == Operator.GREATER_OR_EQUAL) { if (startVersion != null) { throw new UnsupportedFilterException( "Multiple version matching is not supported"); } startVersion = version; startExclusive = false; } else if (operator == Operator.GREATER_THAN) { if (startVersion != null) { throw new UnsupportedFilterException( "Multiple version matching is not supported"); } startVersion = version; startExclusive = true; } else if (operator == Operator.LOWER_OR_EQUAL) { if (endVersion != null) { throw new UnsupportedFilterException( "Multiple version matching is not supported"); } endVersion = version; endExclusive = false; } else if (operator == Operator.LOWER_THAN) { if (endVersion != null) { throw new UnsupportedFilterException( "Multiple version matching is not supported"); } endVersion = version; endExclusive = true; } } else { throw new UnsupportedFilterException("Unsupported attribute: " + att); } } }