blob: 0bff770df106ad758596b16a03d8bce350814cf9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2017 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
*******************************************************************************/
package org.eclipse.osgi.internal.framework;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.util.Tokenizer;
/**
* This class maps aliases.
*/
public class AliasMapper {
private static final Map<String, Collection<String>> processorAliasTable = new HashMap<>();
private static final Map<String, String> processorCanonicalTable = new HashMap<>();
private static final Map<String, Collection<String>> osnameAliasTable = new HashMap<>();
private static final Map<String, String> osnameCanonicalTable = new HashMap<>();
static {
getTables("osname.aliases", osnameAliasTable, osnameCanonicalTable); //$NON-NLS-1$
getTables("processor.aliases", processorAliasTable, processorCanonicalTable); //$NON-NLS-1$
}
private static void getTables(String resourceName, Map<String, Collection<String>> aliasTable, Map<String, String> canonicalTable) {
InputStream in = AliasMapper.class.getResourceAsStream(resourceName);
if (in != null) {
try {
initAliases(in, aliasTable, canonicalTable);
} finally {
try {
in.close();
} catch (IOException ee) {
// nothing
}
}
}
}
/**
* Return the master alias for the processor.
*
* @param processor Input name
* @return aliased name (if any)
*/
public Collection<String> getProcessorAliases(String processor) {
return getAlias(processor.toLowerCase(), processorAliasTable);
}
/**
* Return the master alias for the osname.
*
* @param osname Input name
* @return aliased name (if any)
*/
public Collection<String> getOSNameAliases(String osname) {
return getAlias(osname.toLowerCase(), osnameAliasTable);
}
public String getCanonicalOSName(String osname) {
String lowerName = osname.toLowerCase();
String result = osnameCanonicalTable.get(lowerName);
if (result == null) {
if (lowerName.startsWith("windows")) { //$NON-NLS-1$
return "win32"; //$NON-NLS-1$
}
}
return result == null ? osname : result;
}
public String getCanonicalProcessor(String processor) {
String result = processorCanonicalTable.get(processor.toLowerCase());
return result == null ? processor : result;
}
private Collection<String> getAlias(String name, Map<String, Collection<String>> aliasMap) {
if (name == null) {
return Collections.emptyList();
}
Collection<String> aliases = aliasMap == null ? null : aliasMap.get(name);
if (aliases != null) {
return Collections.unmodifiableCollection(aliases);
}
return Collections.singletonList(name.toLowerCase());
}
/**
* Read alias data and populate a Map.
*
* @param in InputStream from which to read alias data.
* @return Map of aliases.
*/
private static Map<String, Collection<String>> initAliases(InputStream in, Map<String, Collection<String>> aliasTable, Map<String, String> canonicalTable) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
Map<String, Set<String>> multiMaster = new HashMap<>();
while (true) {
String line = br.readLine();
if (line == null) /* EOF */ {
break; /* done */
}
Tokenizer tokenizer = new Tokenizer(line);
String master = tokenizer.getString("# \t"); //$NON-NLS-1$
if (master != null) {
String masterLower = master.toLowerCase();
canonicalTable.put(masterLower, master);
Collection<String> aliasLine = new ArrayList<>(1);
aliasLine.add(master);
parseloop: while (true) {
String alias = tokenizer.getString("# \t"); //$NON-NLS-1$
if (alias == null) {
break parseloop;
}
aliasLine.add(alias);
String aliasLower = alias.toLowerCase();
if (!canonicalTable.containsKey(aliasLower)) {
canonicalTable.put(aliasLower, master);
} else {
// the alias has multiple masters just make its canonical name be the alias
String existingMaster = canonicalTable.put(aliasLower, alias);
Set<String> masters = multiMaster.get(aliasLower);
if (masters == null) {
masters = new HashSet<>();
multiMaster.put(aliasLower, masters);
masters.add(existingMaster.toLowerCase());
}
masters.add(masterLower);
}
}
aliasTable.put(masterLower, aliasLine);
}
}
Map<String, Set<String>> multiMasterAliases = new HashMap<>(multiMaster.size());
for (Entry<String, Set<String>> entry : multiMaster.entrySet()) {
Set<String> aliases = new HashSet<>();
for (String master : entry.getValue()) {
aliases.addAll(aliasTable.get(master));
}
multiMasterAliases.put(entry.getKey(), aliases);
}
aliasTable.putAll(multiMasterAliases);
} catch (IOException e) {
Debug.printStackTrace(e);
}
return aliasTable;
}
}