1 /******************************************************************************* 2 * Copyright (c) 2007, 2014 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Rob Harrop - SpringSource Inc. (bug 247522) 14 *******************************************************************************/ 15 package org.eclipse.osgi.internal.resolver; 16 17 import java.util.*; 18 import org.eclipse.osgi.internal.framework.AliasMapper; 19 import org.eclipse.osgi.service.resolver.*; 20 import org.eclipse.osgi.service.resolver.VersionRange; 21 import org.osgi.framework.*; 22 23 public class NativeCodeSpecificationImpl extends VersionConstraintImpl implements NativeCodeSpecification { 24 private static final NativeCodeDescription[] EMPTY_NATIVECODEDESCRIPTIONS = new NativeCodeDescription[0]; 25 private static AliasMapper aliasMapper = new AliasMapper(); 26 private NativeCodeDescription[] possibleSuppliers; 27 private boolean optional; 28 getPossibleSuppliers()29 public NativeCodeDescription[] getPossibleSuppliers() { 30 synchronized (this.monitor) { 31 if (possibleSuppliers == null) 32 return EMPTY_NATIVECODEDESCRIPTIONS; 33 return possibleSuppliers; 34 } 35 } 36 setPossibleSuppliers(NativeCodeDescription[] possibleSuppliers)37 void setPossibleSuppliers(NativeCodeDescription[] possibleSuppliers) { 38 synchronized (this.monitor) { 39 this.possibleSuppliers = possibleSuppliers; 40 } 41 } 42 isOptional()43 public boolean isOptional() { 44 synchronized (this.monitor) { 45 return optional; 46 } 47 } 48 setOptional(boolean optional)49 void setOptional(boolean optional) { 50 synchronized (this.monitor) { 51 this.optional = optional; 52 } 53 } 54 55 @SuppressWarnings("unchecked") 56 @Override isSatisfiedBy(BaseDescription supplier)57 public boolean isSatisfiedBy(BaseDescription supplier) { 58 if (!(supplier instanceof NativeCodeDescription)) 59 return false; 60 State containingState = getBundle().getContainingState(); 61 if (containingState == null) 62 return false; 63 Dictionary<Object, Object>[] platformProps = containingState.getPlatformProperties(); 64 NativeCodeDescription nativeSupplier = (NativeCodeDescription) supplier; 65 Filter filter = nativeSupplier.getFilter(); 66 boolean match = false; 67 for (int i = 0; i < platformProps.length && !match; i++) { 68 @SuppressWarnings("rawtypes") 69 Dictionary props = platformProps[i]; 70 if (filter != null && !filter.matchCase(props)) 71 continue; 72 String[] osNames = nativeSupplier.getOSNames(); 73 if (osNames.length == 0) 74 match = true; 75 else { 76 Collection<?> platformOSAliases; 77 Object platformOS = platformProps[i].get(Constants.FRAMEWORK_OS_NAME); 78 if (platformOS instanceof Collection) { 79 platformOSAliases = (Collection<?>) platformOS; 80 } else if (platformOS instanceof String) { 81 platformOS = aliasMapper.getCanonicalOSName((String) platformOS); 82 platformOSAliases = aliasMapper.getOSNameAliases((String) platformOS); 83 } else { 84 platformOSAliases = platformOS == null ? Collections.emptyList() : Collections.singleton(platformOS); 85 } 86 osNamesLoop: for (String osName : osNames) { 87 String canonicalOSName = aliasMapper.getCanonicalOSName(osName); 88 for (Object osAlias : platformOSAliases) { 89 if (osAlias instanceof String) { 90 match = (((String) osAlias).equalsIgnoreCase(canonicalOSName)); 91 } else { 92 match = osAlias.equals(canonicalOSName); 93 } 94 if (match) { 95 break osNamesLoop; 96 } 97 } 98 } 99 } 100 if (!match) 101 continue; 102 match = false; 103 104 String[] processors = nativeSupplier.getProcessors(); 105 if (processors.length == 0) 106 match = true; 107 else { 108 Collection<?> platformProcessorAliases; 109 Object platformProcessor = platformProps[i].get(Constants.FRAMEWORK_PROCESSOR); 110 if (platformProcessor instanceof Collection) { 111 platformProcessorAliases = (Collection<?>) platformProcessor; 112 } else if (platformProcessor instanceof String) { 113 platformProcessor = aliasMapper.getCanonicalProcessor((String) platformProcessor); 114 platformProcessorAliases = aliasMapper.getProcessorAliases((String) platformProcessor); 115 } else { 116 platformProcessorAliases = platformProcessor == null ? Collections.emptyList() : Collections.singleton(platformProcessor); 117 } 118 processorLoop: for (String processor : processors) { 119 String canonicalProcessor = aliasMapper.getCanonicalProcessor(processor); 120 for (Object processorAlias : platformProcessorAliases) { 121 if (processorAlias instanceof String) { 122 match = ((String) processorAlias).equalsIgnoreCase(canonicalProcessor); 123 } else { 124 match = processorAlias.equals(canonicalProcessor); 125 } 126 if (match) { 127 break processorLoop; 128 } 129 } 130 } 131 } 132 if (!match) 133 continue; 134 match = false; 135 136 String[] languages = nativeSupplier.getLanguages(); 137 if (languages.length == 0) 138 match = true; 139 else { 140 Object platformLanguage = platformProps[i].get(Constants.FRAMEWORK_LANGUAGE); 141 if (platformLanguage != null) 142 for (int j = 0; j < languages.length && !match; j++) { 143 if ((platformLanguage instanceof String) ? ((String) platformLanguage).equalsIgnoreCase(languages[j]) : platformLanguage.equals(languages[j])) 144 match = true; 145 } 146 } 147 if (!match) 148 continue; 149 match = false; 150 151 VersionRange[] osVersions = nativeSupplier.getOSVersions(); 152 if (osVersions.length == 0 || platformProps[i].get(Constants.FRAMEWORK_OS_VERSION) == null) 153 match = true; 154 else { 155 Version osversion; 156 try { 157 osversion = Version.parseVersion((String) platformProps[i].get(Constants.FRAMEWORK_OS_VERSION)); 158 } catch (Exception e) { 159 osversion = Version.emptyVersion; 160 } 161 for (int j = 0; j < osVersions.length && !match; j++) { 162 if (osVersions[j].isIncluded(osversion)) 163 match = true; 164 } 165 } 166 } 167 return match; 168 } 169 170 @Override hasMandatoryAttributes(String[] mandatory)171 protected boolean hasMandatoryAttributes(String[] mandatory) { 172 return true; 173 } 174 175 @Override toString()176 public String toString() { 177 StringBuilder sb = new StringBuilder(); 178 NativeCodeDescription[] suppliers = getPossibleSuppliers(); 179 for (int i = 0; i < suppliers.length; i++) { 180 if (i > 0) 181 sb.append(", "); //$NON-NLS-1$ 182 sb.append(suppliers[i].toString()); 183 } 184 185 return sb.toString(); 186 } 187 188 @Override getInternalDirectives()189 protected Map<String, String> getInternalDirectives() { 190 return Collections.<String, String> emptyMap(); 191 } 192 193 @Override getInteralAttributes()194 protected Map<String, Object> getInteralAttributes() { 195 return Collections.<String, Object> emptyMap(); 196 } 197 198 @Override getInternalNameSpace()199 protected String getInternalNameSpace() { 200 return null; 201 } 202 } 203