| /******************************************************************************* |
| * Copyright (c) 2007, 2018 Alphonse Van Assche. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Alphonse Van Assche - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.linuxtools.internal.rpm.ui.editor; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.TreeMap; |
| |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.preferences.PreferenceConstants; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.scanners.SpecfileScanner; |
| import org.eclipse.linuxtools.rpm.core.utils.Utils; |
| |
| /** |
| * This class is used to retrieve and manage the RPM macro proposals list. |
| * |
| */ |
| public class RpmMacroProposalsList { |
| |
| private static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
| |
| private Map<String, String> macroMap = new HashMap<>(); |
| |
| private String toStringStr; |
| |
| /** |
| * Default contructor |
| */ |
| public RpmMacroProposalsList() { |
| buildMacroList(); |
| } |
| |
| /** |
| * Build the macro list. |
| */ |
| public final void buildMacroList() { |
| for (String definedMacro : SpecfileScanner.DEFINED_MACROS) { |
| macroMap.put(definedMacro, Messages.RpmMacroProposalsList_0); |
| // TODO find way to provide info about buildin macros. |
| } |
| String macroProposalsPaths = Activator.getDefault().getPreferenceStore() |
| .getString(PreferenceConstants.P_MACRO_PROPOSALS_FILESPATH); |
| String[] paths = macroProposalsPaths.split(";"); //$NON-NLS-1$ |
| // paths must be reversed because the last value added |
| // into a Map overwrites the first. |
| paths = reverseStringArray(paths); |
| for (String path : paths) { |
| if (!path.equals(EMPTY_STRING)) { |
| File pathFile = new File(path); |
| if (pathFile.exists()) { |
| if (pathFile.isDirectory()) { |
| File[] macrosFiles = pathFile.listFiles(); |
| for (File macrosFile : macrosFiles) { |
| addMacroToMap(macrosFile.getAbsolutePath()); |
| } |
| } else { |
| addMacroToMap(path); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Add macro definition to the map |
| * |
| * @param filename macro file definition. |
| */ |
| private void addMacroToMap(String filename) { |
| String line = EMPTY_STRING; |
| try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename)))) { |
| line = reader.readLine(); |
| String key = EMPTY_STRING, value = EMPTY_STRING; |
| while (line != null) { |
| if (line.startsWith("%")) { //$NON-NLS-1$ |
| String[] item = line.split("\t+| ", 2); //$NON-NLS-1$ |
| try { |
| // Get values on more than one line |
| if (line.trim().endsWith("\\")) { //$NON-NLS-1$ |
| value = "\n"; //$NON-NLS-1$ |
| boolean isKeyLine = true; |
| while (line.trim().endsWith("\\")) { //$NON-NLS-1$ |
| if (isKeyLine) { |
| isKeyLine = false; |
| key = item[0]; |
| if (item.length > 1) { |
| value += item[1].replace("\\", "\n\n"); //$NON-NLS-1$//$NON-NLS-2$ |
| } |
| } else { |
| value += line.substring(0, line.length() - 1).trim() + "\n\t"; //$NON-NLS-1$ |
| } |
| line = reader.readLine(); |
| } |
| } else { |
| key = item[0]; |
| value = item[1]; |
| } |
| key = key.trim(); |
| value = value.trim(); |
| macroMap.put(key, value); |
| toStringStr += key + ": " + value + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ |
| } catch (Exception e) { |
| line = reader.readLine(); |
| continue; |
| } |
| value = EMPTY_STRING; |
| key = EMPTY_STRING; |
| } |
| line = reader.readLine(); |
| } |
| } catch (IOException e) { |
| SpecfileLog.logError(e); |
| } |
| } |
| |
| /** |
| * Reverse a <code>String</code> array. |
| * |
| * @param stringArrayToReverse the string array to reverse. |
| * @return the reversed <code>String</code> array. |
| */ |
| private String[] reverseStringArray(String[] stringArrayToReverse) { |
| int left = 0; |
| int right = stringArrayToReverse.length - 1; |
| while (left < right) { |
| String tmp = stringArrayToReverse[left]; |
| stringArrayToReverse[left] = stringArrayToReverse[right]; |
| stringArrayToReverse[right] = tmp; |
| left++; |
| right--; |
| } |
| return stringArrayToReverse; |
| } |
| |
| /** |
| * Get proposals for a given prefix |
| * |
| * @param prefix The prefix to search. |
| * @return a <code>Map</code> of proposals. |
| */ |
| public Map<String, String> getProposals(String prefix) { |
| Map<String, String> proposalsMap = new HashMap<>(macroMap.size()); |
| for (Map.Entry<String, String> entry : macroMap.entrySet()) { |
| // Get proposals for macro begin with { char too. |
| if (entry.getKey().startsWith(prefix.replaceFirst("\\{", EMPTY_STRING))) { //$NON-NLS-1$ |
| proposalsMap.put(entry.getKey(), entry.getValue()); |
| } |
| } |
| // Sort proposals |
| return new TreeMap<>(proposalsMap); |
| } |
| |
| /** |
| * Get the value for a given macro. |
| * |
| * @param key Key to retrieve value. |
| * @return a string representation of the value |
| */ |
| public String getValue(String key) { |
| String value = macroMap.get("%" + key); //$NON-NLS-1$ |
| // get proposals for macro contain ? too. |
| if (value == null) { |
| value = macroMap.get(("%" + key).replaceFirst("\\?", EMPTY_STRING)); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return value; |
| } |
| |
| /** |
| * Find a key in the macroMap |
| * |
| * @param keyToFind The key to find. |
| * @return return the value |
| */ |
| public boolean findKey(String keyToFind) { |
| return macroMap.containsKey(keyToFind); |
| } |
| |
| /** |
| * Return the ouput of the <code>rpm --eval</code> command for a given macro. |
| * |
| * @param macroName The macro name to eval. |
| * @return the resolved macro content. |
| */ |
| public static String getMacroEval(String macroName) { |
| String eval = EMPTY_STRING; |
| try { |
| eval = Utils.runCommandToString("rpm", "--eval", macroName); //$NON-NLS-1$//$NON-NLS-2$ |
| } catch (IOException e) { |
| SpecfileLog.logError(e); |
| } |
| return eval.trim(); |
| } |
| |
| @Override |
| public String toString() { |
| return toStringStr; |
| } |
| |
| } |