| /******************************************************************************* |
| * Copyright (c) 2007, 2014 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Rob Harrop - SpringSource Inc. (bug 247522) |
| *******************************************************************************/ |
| package org.eclipse.osgi.internal.resolver; |
| |
| import java.util.*; |
| import org.eclipse.osgi.internal.framework.AliasMapper; |
| import org.eclipse.osgi.service.resolver.*; |
| import org.eclipse.osgi.service.resolver.VersionRange; |
| import org.osgi.framework.*; |
| |
| public class NativeCodeSpecificationImpl extends VersionConstraintImpl implements NativeCodeSpecification { |
| private static final NativeCodeDescription[] EMPTY_NATIVECODEDESCRIPTIONS = new NativeCodeDescription[0]; |
| private static AliasMapper aliasMapper = new AliasMapper(); |
| private NativeCodeDescription[] possibleSuppliers; |
| private boolean optional; |
| |
| public NativeCodeDescription[] getPossibleSuppliers() { |
| synchronized (this.monitor) { |
| if (possibleSuppliers == null) |
| return EMPTY_NATIVECODEDESCRIPTIONS; |
| return possibleSuppliers; |
| } |
| } |
| |
| void setPossibleSuppliers(NativeCodeDescription[] possibleSuppliers) { |
| synchronized (this.monitor) { |
| this.possibleSuppliers = possibleSuppliers; |
| } |
| } |
| |
| public boolean isOptional() { |
| synchronized (this.monitor) { |
| return optional; |
| } |
| } |
| |
| void setOptional(boolean optional) { |
| synchronized (this.monitor) { |
| this.optional = optional; |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public boolean isSatisfiedBy(BaseDescription supplier) { |
| if (!(supplier instanceof NativeCodeDescription)) |
| return false; |
| State containingState = getBundle().getContainingState(); |
| if (containingState == null) |
| return false; |
| Dictionary<Object, Object>[] platformProps = containingState.getPlatformProperties(); |
| NativeCodeDescription nativeSupplier = (NativeCodeDescription) supplier; |
| Filter filter = nativeSupplier.getFilter(); |
| boolean match = false; |
| for (int i = 0; i < platformProps.length && !match; i++) { |
| @SuppressWarnings("rawtypes") |
| Dictionary props = platformProps[i]; |
| if (filter != null && !filter.matchCase(props)) |
| continue; |
| String[] osNames = nativeSupplier.getOSNames(); |
| if (osNames.length == 0) |
| match = true; |
| else { |
| Collection<?> platformOSAliases; |
| Object platformOS = platformProps[i].get(Constants.FRAMEWORK_OS_NAME); |
| if (platformOS instanceof Collection) { |
| platformOSAliases = (Collection<?>) platformOS; |
| } else if (platformOS instanceof String) { |
| platformOS = aliasMapper.getCanonicalOSName((String) platformOS); |
| platformOSAliases = aliasMapper.getOSNameAliases((String) platformOS); |
| } else { |
| platformOSAliases = platformOS == null ? Collections.emptyList() : Collections.singleton(platformOS); |
| } |
| osNamesLoop: for (String osName : osNames) { |
| String canonicalOSName = aliasMapper.getCanonicalOSName(osName); |
| for (Object osAlias : platformOSAliases) { |
| if (osAlias instanceof String) { |
| match = (((String) osAlias).equalsIgnoreCase(canonicalOSName)); |
| } else { |
| match = osAlias.equals(canonicalOSName); |
| } |
| if (match) { |
| break osNamesLoop; |
| } |
| } |
| } |
| } |
| if (!match) |
| continue; |
| match = false; |
| |
| String[] processors = nativeSupplier.getProcessors(); |
| if (processors.length == 0) |
| match = true; |
| else { |
| Collection<?> platformProcessorAliases; |
| Object platformProcessor = platformProps[i].get(Constants.FRAMEWORK_PROCESSOR); |
| if (platformProcessor instanceof Collection) { |
| platformProcessorAliases = (Collection<?>) platformProcessor; |
| } else if (platformProcessor instanceof String) { |
| platformProcessor = aliasMapper.getCanonicalProcessor((String) platformProcessor); |
| platformProcessorAliases = aliasMapper.getProcessorAliases((String) platformProcessor); |
| } else { |
| platformProcessorAliases = platformProcessor == null ? Collections.emptyList() : Collections.singleton(platformProcessor); |
| } |
| processorLoop: for (String processor : processors) { |
| String canonicalProcessor = aliasMapper.getCanonicalProcessor(processor); |
| for (Object processorAlias : platformProcessorAliases) { |
| if (processorAlias instanceof String) { |
| match = ((String) processorAlias).equalsIgnoreCase(canonicalProcessor); |
| } else { |
| match = processorAlias.equals(canonicalProcessor); |
| } |
| if (match) { |
| break processorLoop; |
| } |
| } |
| } |
| } |
| if (!match) |
| continue; |
| match = false; |
| |
| String[] languages = nativeSupplier.getLanguages(); |
| if (languages.length == 0) |
| match = true; |
| else { |
| Object platformLanguage = platformProps[i].get(Constants.FRAMEWORK_LANGUAGE); |
| if (platformLanguage != null) |
| for (int j = 0; j < languages.length && !match; j++) { |
| if ((platformLanguage instanceof String) ? ((String) platformLanguage).equalsIgnoreCase(languages[j]) : platformLanguage.equals(languages[j])) |
| match = true; |
| } |
| } |
| if (!match) |
| continue; |
| match = false; |
| |
| VersionRange[] osVersions = nativeSupplier.getOSVersions(); |
| if (osVersions.length == 0 || platformProps[i].get(Constants.FRAMEWORK_OS_VERSION) == null) |
| match = true; |
| else { |
| Version osversion; |
| try { |
| osversion = Version.parseVersion((String) platformProps[i].get(Constants.FRAMEWORK_OS_VERSION)); |
| } catch (Exception e) { |
| osversion = Version.emptyVersion; |
| } |
| for (int j = 0; j < osVersions.length && !match; j++) { |
| if (osVersions[j].isIncluded(osversion)) |
| match = true; |
| } |
| } |
| } |
| return match; |
| } |
| |
| @Override |
| protected boolean hasMandatoryAttributes(String[] mandatory) { |
| return true; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| NativeCodeDescription[] suppliers = getPossibleSuppliers(); |
| for (int i = 0; i < suppliers.length; i++) { |
| if (i > 0) |
| sb.append(", "); //$NON-NLS-1$ |
| sb.append(suppliers[i].toString()); |
| } |
| |
| return sb.toString(); |
| } |
| |
| @Override |
| protected Map<String, String> getInternalDirectives() { |
| return Collections.<String, String> emptyMap(); |
| } |
| |
| @Override |
| protected Map<String, Object> getInteralAttributes() { |
| return Collections.<String, Object> emptyMap(); |
| } |
| |
| @Override |
| protected String getInternalNameSpace() { |
| return null; |
| } |
| } |