/** * 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.company.security.csp; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BundleNativeCode { private static final Logger LOGGER = LoggerFactory.getLogger(BundleNativeCode.class); private static String[][] processorAliases = { {"Ignite", "psc1k"}, {"x86", "pentium", "i386", "i486", "i586", "i686"}, {"x86-64", "amd64", "em64t", "x86_64"} }; private static String[][] osNameAliases = { {"Epoc32", "SymbianOS"}, {"HPUX", "hp-ux"}, {"MacOS", "Mac OS"}, {"MacOSX", "Mac OS X"}, {"OS2", "OS/2"}, {"QNX", "procnto"}, {"Windows95", "Win95", "Windows 95", "Win32"}, {"Windows98", "Win98", "Windows 98", "Win32"}, {"WindowsNT", "WinNT", "Windows NT", "Win32"}, {"WindowsCE", "WinCE", "Windows CE"}, {"Windows2000", "Win2000", "Windows 2000", "Win32"}, {"Windows2003", "Win2003", "Windows 2003", "Win32"}, {"WindowsXP", "WinXP", "Windows XP", "Win32"}, {"WindowsVista", "WinVista", "Windows Vista", "Win32"}, {"Windows7", "Win7", "Windows 7", "Win32"}, {"WindowsServer2008", "Windows Server 2008"}, {"Windows8", "Win8", "Windows 8", "Win32"} }; private String bundleNativeCode; private String language; private String osArch; private String osName; private String osVersion; public BundleNativeCode(String bundleNativeCode, String language) { this.bundleNativeCode = bundleNativeCode; this.language = language; this.osArch = System.getProperty("os.arch"); this.osName = System.getProperty("os.name"); this.osVersion = System.getProperty("os.version"); } public String getOsArch() { return osArch; } public void setOsArch(String osArch) { this.osArch = osArch; } public String getOsName() { return osName; } public void setOsName(String osName) { this.osName = osName; } public String getOsVersion() { return osVersion; } public void setOsVersion(String osVersion) { this.osVersion = osVersion; } private Set<String> getProcessorNames(String osarch) { Set<String> names = new HashSet<String>(); for(String[] line : processorAliases) { for(String name : line) { if(osarch.equals(name)) names.add(line[0]); } } if(names.isEmpty()) names.add(osarch); return names; } private Set<String> getOsNames(String osname) { Set<String> names = new HashSet<String>(); for(String[] line : osNameAliases) { for(String name : line) { if(osname.equals(name)) names.add(line[0]); } } if(names.isEmpty()) names.add(osname); return names; } public List<String> match() { ArrayList<String> list = new ArrayList<String>(); StringTokenizer st = new StringTokenizer(bundleNativeCode, ","); if(LOGGER.isDebugEnabled()) { LOGGER.debug("os.name: {}, name:{}", this.osName, getOsNames(this.osName)); LOGGER.debug("os.arch: {}, processor:{}", this.osArch, getProcessorNames(this.osArch)); LOGGER.debug("os.version: {}", this.osVersion); } while(st.hasMoreTokens()) { String nativecode = st.nextToken(); List<String> path = match(nativecode.trim()); if(path != null) list.addAll(path); } return list; } private List<String> match(String nativecode) { List<String> path = new ArrayList<String>(); Set<String> osnames = new HashSet<String>(); Set<String> osversions = new HashSet<String>(); Set<String> processors = new HashSet<String>(); Set<String> langueges = new HashSet<String>(); StringTokenizer st = new StringTokenizer(nativecode, ";"); boolean haveParameter = false; while(st.hasMoreTokens()) { String value = st.nextToken(); int paramSeparator = value.indexOf('='); if(!haveParameter && paramSeparator > 0) haveParameter = true; if(haveParameter) { if(paramSeparator > 0 && paramSeparator != value.length() - 1) { String key = value.substring(0, paramSeparator).trim(); String val = value.substring(paramSeparator + 1).trim(); if(!key.isEmpty() && !val.isEmpty()) { if(key.equals("osname")) { osnames.add(val); } else if(key.equals("osversion")) { osversions.add(val); } else if(key.equals("processor")) { processors.add(val); } else if(key.equals("language")) { langueges.add(val); } } } } else if(paramSeparator < 0) { path.add(value.trim()); } } boolean filter = true; if(osName != null && !osName.isEmpty() && !osnames.isEmpty()) { Set<String> real = getOsNames(osName); Set<String> names = new HashSet<String>(); boolean find = false; for(String val : osnames) { names.addAll(getOsNames(val)); } for(String name : names) { find |= real.contains(name); } filter = find; } if(filter && osVersion != null && !osVersion.isEmpty() && !osversions.isEmpty()) { filter = osversions.isEmpty() || osversions.contains(osVersion); } if(filter && osArch != null && !osArch.isEmpty() && !processors.isEmpty()) { Set<String> real = getProcessorNames(osArch); Set<String> names = new HashSet<String>(); boolean find = false; for(String val : processors) { names.addAll(getProcessorNames(val)); } for(String name : names) { find |= real.contains(name); } filter = find; } if(filter && language != null && !language.isEmpty() && !langueges.isEmpty()) { filter = langueges.contains(language); } if(!filter) path.clear(); if(LOGGER.isDebugEnabled()) { LOGGER.debug("match {} from native library {}", filter, nativecode); } return path; } }