1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-16 11:21:18 +03:00

A lot of refactoring on Preferences, custom menus and Boards:

- Merged MapWithSubkeys into PreferencesMap.
- Added TargetBoard class.
- Simplified a bit submenu generation.
This commit is contained in:
Cristian Maglie
2013-03-02 13:24:59 +01:00
parent 373113454d
commit 3c01c5ff77
9 changed files with 366 additions and 260 deletions

View File

@ -30,16 +30,16 @@ import java.util.List;
import javax.swing.*; import javax.swing.*;
import processing.app.debug.TargetBoard;
import processing.app.debug.TargetPackage; import processing.app.debug.TargetPackage;
import processing.app.debug.TargetPlatform; import processing.app.debug.TargetPlatform;
import processing.app.debug.TargetPlatformException;
import processing.app.helpers.FileUtils; import processing.app.helpers.FileUtils;
import processing.app.helpers.Maps;
import processing.app.helpers.PreferencesMap; import processing.app.helpers.PreferencesMap;
import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.helpers.filefilters.OnlyFilesWithExtension; import processing.app.helpers.filefilters.OnlyFilesWithExtension;
import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.packages.Library; import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.packages.Library;
import processing.app.packages.LibraryList; import processing.app.packages.LibraryList;
import processing.app.tools.MapWithSubkeys;
import processing.app.tools.ZipDeflater; import processing.app.tools.ZipDeflater;
import processing.core.*; import processing.core.*;
import static processing.app.I18n._; import static processing.app.I18n._;
@ -116,7 +116,6 @@ public class Base {
static File portableFolder = null; static File portableFolder = null;
static final String portableSketchbookFolder = "sketchbook"; static final String portableSketchbookFolder = "sketchbook";
static public void main(String args[]) throws Exception { static public void main(String args[]) throws Exception {
initPlatform(); initPlatform();
@ -290,6 +289,11 @@ public class Base {
packages = new HashMap<String, TargetPackage>(); packages = new HashMap<String, TargetPackage>();
loadHardware(getHardwareFolder()); loadHardware(getHardwareFolder());
loadHardware(getSketchbookHardwareFolder()); loadHardware(getSketchbookHardwareFolder());
if (packages.size() == 0) {
System.out.println(_("No valid configured cores found! Exiting..."));
System.exit(3);
}
// Setup board-dependent variables. // Setup board-dependent variables.
onBoardOrPortChange(); onBoardOrPortChange();
@ -1180,7 +1184,7 @@ public class Base {
try { try {
libraries = scanLibraries(librariesFolders); libraries = scanLibraries(librariesFolders);
} catch (IOException e) { } catch (IOException e) {
showWarning(_("Error"), _("Error reading preferences"), e); showWarning(_("Error"), _("Error loading libraries"), e);
} }
String currentArch = Base.getTargetPlatform().getName(); String currentArch = Base.getTargetPlatform().getName();
libraries = libraries.filterByArchitecture(currentArch); libraries = libraries.filterByArchitecture(currentArch);
@ -1224,16 +1228,15 @@ public class Base {
// For every package cycle through all platform // For every package cycle through all platform
for (TargetPlatform targetPlatform : targetPackage.platforms()) { for (TargetPlatform targetPlatform : targetPackage.platforms()) {
String platformName = targetPlatform.getName(); String platformName = targetPlatform.getName();
Map<String, PreferencesMap> boards = targetPlatform.getBoards(); PreferencesMap customMenus = targetPlatform.getCustomMenus();
if (targetPlatform.getPreferences().get("name") == null || targetPlatform.getBoards().isEmpty()) { if (targetPlatform.getPreferences().get("name") == null || targetPlatform.getBoards().isEmpty()) {
continue; continue;
} }
// Add a title for each group of boards // Add a title for each group of boards
if (!first) { if (!first)
boardsMenu.add(new JSeparator()); boardsMenu.add(new JSeparator());
}
first = false; first = false;
JMenuItem separator = new JMenuItem(_(targetPlatform.getPreferences().get("name"))); JMenuItem separator = new JMenuItem(_(targetPlatform.getPreferences().get("name")));
@ -1241,70 +1244,70 @@ public class Base {
boardsMenu.add(separator); boardsMenu.add(separator);
// For every platform cycle through all boards // For every platform cycle through all boards
for (final String boardID : targetPlatform.getBoards().keySet()) { for (TargetBoard board : targetPlatform.getBoards().values()) {
// Setup a menu item for the current board // Setup a menu item for the current board
String boardName = boards.get(boardID).get("name"); String boardName = board.getName();
String boardId = board.getId();
@SuppressWarnings("serial") @SuppressWarnings("serial")
Action action = new AbstractAction(boardName) { Action action = new AbstractAction(boardName) {
public void actionPerformed(ActionEvent actionevent) { public void actionPerformed(ActionEvent actionevent) {
selectBoard((String) getValue("b"), editor); selectBoard((String) getValue("b"), editor);
} }
}; };
action.putValue("b", packageName + ":" + platformName + ":" + boardID); action.putValue("b", packageName + ":" + platformName + ":" + boardId);
JRadioButtonMenuItem item = new JRadioButtonMenuItem(action); JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
boardsMenu.add(item); boardsMenu.add(item);
boardsButtonGroup.add(item); boardsButtonGroup.add(item);
if (selBoard.equals(boardID) && selPackage.equals(packageName) if (selBoard.equals(boardId) && selPackage.equals(packageName)
&& selPlatform.equals(platformName)) { && selPlatform.equals(platformName)) {
menuItemsToClickAfterStartup.add(item); menuItemsToClickAfterStartup.add(item);
} }
if (targetPlatform.getCustomMenus() != null) { int i = 0;
List<String> customMenuIDs = new LinkedList<String>(targetPlatform.getCustomMenus().getKeys()); for (final String customMenuId : customMenus.topLevelKeySet()) {
for (int i = 0; i < customMenuIDs.size(); i++) { String title = customMenus.get(customMenuId);
final String customMenuID = customMenuIDs.get(i); JMenu menu = makeOrGetBoardMenu(toolsMenu, _(title));
JMenu menu = makeOrGetBoardMenu(toolsMenu, _(targetPlatform.getCustomMenus().getValueOf(customMenuID)));
MapWithSubkeys customMenu = targetPlatform.getCustomMenus().get(customMenuID);
if (customMenu.getKeys().contains(boardID)) {
MapWithSubkeys boardCustomMenu = customMenu.get(boardID);
final int currentIndex = i + 1 + 1; //plus 1 to skip the first board menu, plus 1 to keep the custom menu next to this one
for (final String customMenuOption : boardCustomMenu.getKeys()) {
@SuppressWarnings("serial")
Action subAction = new AbstractAction(_(boardCustomMenu.getValueOf(customMenuOption))) {
public void actionPerformed(ActionEvent e) { Map<String, PreferencesMap> customMenu = customMenus.subTree(customMenuId).firstLevelMap();
Preferences.set("target_package", (String) getValue("package")); if (customMenu.containsKey(boardId)) {
Preferences.set("target_platform", (String) getValue("platform")); PreferencesMap boardCustomMenu = customMenu.get(boardId);
Preferences.set("board", (String) getValue("board")); final int currentIndex = i + 1 + 1; //plus 1 to skip the first board menu, plus 1 to keep the custom menu next to this one
Preferences.set("custom_" + customMenuID, boardID + "_" + (String) getValue("custom_menu_option")); i++;
for (String customMenuOption : boardCustomMenu.topLevelKeySet()) {
@SuppressWarnings("serial")
Action subAction = new AbstractAction(_(boardCustomMenu.get(customMenuOption))) {
public void actionPerformed(ActionEvent e) {
Preferences.set("target_package", (String) getValue("package"));
Preferences.set("target_platform", (String) getValue("platform"));
Preferences.set("board", (String) getValue("board"));
Preferences.set("custom_" + customMenuId, (String) getValue("board") + "_" + (String) getValue("custom_menu_option"));
filterVisibilityOfSubsequentBoardMenus((String) getValue("board"), currentIndex); filterVisibilityOfSubsequentBoardMenus((String) getValue("board"), currentIndex);
onBoardOrPortChange(); onBoardOrPortChange();
Sketch.buildSettingChanged(); Sketch.buildSettingChanged();
rebuildImportMenu(Editor.importMenu, editor); rebuildImportMenu(Editor.importMenu, editor);
rebuildExamplesMenu(Editor.examplesMenu); rebuildExamplesMenu(Editor.examplesMenu);
}
};
subAction.putValue("board", boardID);
subAction.putValue("custom_menu_option", customMenuOption);
subAction.putValue("package", packageName);
subAction.putValue("platform", platformName);
if (!buttonGroupsMap.containsKey(customMenuID)) {
buttonGroupsMap.put(customMenuID, new ButtonGroup());
} }
};
subAction.putValue("board", boardId);
subAction.putValue("custom_menu_option", customMenuOption);
subAction.putValue("package", packageName);
subAction.putValue("platform", platformName);
item = new JRadioButtonMenuItem(subAction); if (!buttonGroupsMap.containsKey(customMenuId)) {
menu.add(item); buttonGroupsMap.put(customMenuId, new ButtonGroup());
buttonGroupsMap.get(customMenuID).add(item); }
String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuID); item = new JRadioButtonMenuItem(subAction);
if (selBoard.equals(boardID) && (boardID + "_" + customMenuOption).equals(selectedCustomMenuEntry)) { menu.add(item);
menuItemsToClickAfterStartup.add(item); buttonGroupsMap.get(customMenuId).add(item);
}
String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuId);
if (selBoard.equals(boardId) && (boardId + "_" + customMenuOption).equals(selectedCustomMenuEntry)) {
menuItemsToClickAfterStartup.add(item);
} }
} }
} }
@ -1604,7 +1607,13 @@ public class Base {
if (target.equals("tools")) if (target.equals("tools"))
continue; continue;
File subfolder = new File(folder, target); File subfolder = new File(folder, target);
packages.put(target, new TargetPackage(target, subfolder));
try {
packages.put(target, new TargetPackage(target, subfolder));
} catch (TargetPlatformException e) {
System.out.println("WARNING: Error loading hardware folder " + target);
System.out.println(" " + e.getMessage());
}
} }
} }
@ -1921,19 +1930,18 @@ public class Base {
return getTargetPlatform(pack, Preferences.get("target_platform")); return getTargetPlatform(pack, Preferences.get("target_platform"));
} }
static public Map<String, String> getBoardPreferences() { static public PreferencesMap getBoardPreferences() {
TargetPlatform target = getTargetPlatform(); TargetPlatform target = getTargetPlatform();
String board = Preferences.get("board"); String board = Preferences.get("board");
Map<String, String> boardPreferences = Maps.merge(target.getBoards().get(board), new LinkedHashMap<String, String>()); PreferencesMap boardPreferences = new PreferencesMap(target.getBoard(board).getPreferences());
if (target.getCustomMenus() != null) { PreferencesMap customMenus = target.getCustomMenus();
for (String customMenuID : target.getCustomMenus().getKeys()) { for (String customMenuID : customMenus.topLevelKeySet()) {
MapWithSubkeys boardCustomMenu = target.getCustomMenus().get(customMenuID).get(board); PreferencesMap boardCustomMenu = customMenus.subTree(customMenuID).subTree(board);
String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuID); String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuID);
if (boardCustomMenu != null && selectedCustomMenuEntry != null && selectedCustomMenuEntry.startsWith(board)) { if (boardCustomMenu.size() > 0 && selectedCustomMenuEntry != null && selectedCustomMenuEntry.startsWith(board)) {
String menuEntryId = selectedCustomMenuEntry.substring(selectedCustomMenuEntry.indexOf("_") + 1); String menuEntryId = selectedCustomMenuEntry.substring(selectedCustomMenuEntry.indexOf("_") + 1);
Maps.merge(boardCustomMenu.get(menuEntryId).getValues(), boardPreferences); boardPreferences.putAll(boardCustomMenu.subTree(menuEntryId));
boardPreferences.put("name", boardPreferences.get("name") + ", " + boardCustomMenu.getValueOf(menuEntryId)); boardPreferences.put("name", boardPreferences.get("name") + ", " + boardCustomMenu.get(menuEntryId));
}
} }
} }
return boardPreferences; return boardPreferences;

View File

@ -0,0 +1,47 @@
package processing.app.debug;
import processing.app.helpers.PreferencesMap;
public class TargetBoard {
String id;
PreferencesMap prefs;
/**
* Create a TargetBoard based on preferences passed as argument.
*
* @param _prefs
* @return
*/
public TargetBoard(String _id, PreferencesMap _prefs) {
id = _id;
prefs = new PreferencesMap(_prefs);
}
/**
* Get the name of the board.
*
* @return
*/
public String getName() {
return prefs.get("name");
}
/**
* Get the identifier of the board
*
* @return
*/
public String getId() {
return id;
}
/**
* Get the full preferences map of the board with a given identifier
*
* @return
*/
public PreferencesMap getPreferences() {
return prefs;
}
}

View File

@ -25,29 +25,31 @@ package processing.app.debug;
import java.io.File; import java.io.File;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyDirs;
public class TargetPackage { public class TargetPackage {
private final String name; private String name;
Map<String, TargetPlatform> platforms = new HashMap<String, TargetPlatform>(); Map<String, TargetPlatform> platforms = new LinkedHashMap<String, TargetPlatform>();
public TargetPackage(String name, File folder) { public TargetPackage(String packageName, File packageFolder)
this.name = name; throws TargetPlatformException {
name = packageName;
String[] platformsList = folder.list(new OnlyDirs()); File[] folders = packageFolder.listFiles(new OnlyDirs());
if (platformsList != null) { if (folders == null)
for (String platformName : platformsList) { return;
File platformFolder = new File(folder, platformName);
if (platformFolder.exists() && platformFolder.canRead()) { for (File folder : folders) {
TargetPlatform platform = new TargetPlatform(platformName, platformFolder); if (!folder.exists() || !folder.canRead())
platforms.put(platformName, platform); continue;
} String arch = folder.getName();
} TargetPlatform platform = new TargetPlatform(arch, folder);
platforms.put(arch, platform);
} }
} }

View File

@ -24,62 +24,90 @@
package processing.app.debug; package processing.app.debug;
import static processing.app.I18n._; import static processing.app.I18n._;
import static processing.app.I18n.format;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import processing.app.helpers.PreferencesMap; import processing.app.helpers.PreferencesMap;
import processing.app.tools.MapWithSubkeys;
public class TargetPlatform { public class TargetPlatform {
private String name; private String name;
private File folder; private File folder;
private Map<String, PreferencesMap> boards;
private Map<String, PreferencesMap> programmers;
private PreferencesMap preferences;
private MapWithSubkeys customMenus;
public TargetPlatform(String _name, File _folder) { /**
* Contains preferences for every defined board
*/
private Map<String, TargetBoard> boards = new LinkedHashMap<String, TargetBoard>();
/**
* Contains preferences for every defined programmer
*/
private Map<String, PreferencesMap> programmers = new LinkedHashMap<String, PreferencesMap>();
/**
* Contains preferences for platform
*/
private PreferencesMap preferences = new PreferencesMap();
private PreferencesMap customMenus = new PreferencesMap();
public TargetPlatform(String _name, File _folder)
throws TargetPlatformException {
name = _name; name = _name;
folder = _folder; folder = _folder;
boards = new HashMap<String, PreferencesMap>();
programmers = new HashMap<String, PreferencesMap>();
preferences = new PreferencesMap();
// If there is no boards.txt, this is not a valid 1.5 hardware folder
File boardsFile = new File(folder, "boards.txt");
if (!boardsFile.exists() || !boardsFile.canRead())
throw new TargetPlatformException(
format(_("Could not find boards.txt in {0}. Is it pre-1.5?"),
boardsFile.getAbsolutePath()));
// Load boards
try { try {
File boardsFile = new File(_folder, "boards.txt"); PreferencesMap p = new PreferencesMap(boardsFile);
if (boardsFile.exists() && boardsFile.canRead()) { Map<String, PreferencesMap> boardsPreferences = p.firstLevelMap();
PreferencesMap boardPreferences = new PreferencesMap();
boardPreferences.load(boardsFile); // Create custom menus using the key "menu" and its subkeys
boards = boardPreferences.createFirstLevelMap(); if (boardsPreferences.containsKey("menu")) {
customMenus = MapWithSubkeys.createFrom(boards.get("menu")); customMenus = new PreferencesMap(boardsPreferences.get("menu"));
boards.remove("menu"); boardsPreferences.remove("menu");
} }
} catch (Exception e) {
e.printStackTrace(); // Create boards
System.err.println("Error loading boards from boards.txt: " + e); for (String id : boardsPreferences.keySet()) {
PreferencesMap preferences = boardsPreferences.get(id);
boards.put(id, new TargetBoard(id, preferences));
}
} catch (IOException e) {
throw new TargetPlatformException(format(_("Error loading {0}"),
boardsFile.getAbsolutePath()), e);
} }
File platformsFile = new File(folder, "platform.txt");
try { try {
File platformsFile = new File(_folder, "platform.txt");
if (platformsFile.exists() && platformsFile.canRead()) { if (platformsFile.exists() && platformsFile.canRead()) {
preferences.load(platformsFile); preferences.load(platformsFile);
} }
} catch (Exception e) { } catch (IOException e) {
System.err.println("Error loading platforms from platform.txt: " + e); throw new TargetPlatformException(
format(_("Error loading {0}"), platformsFile.getAbsolutePath()), e);
} }
File progFile = new File(folder, "programmers.txt");
try { try {
File programmersFile = new File(_folder, "programmers.txt"); if (progFile.exists() && progFile.canRead()) {
if (programmersFile.exists() && programmersFile.canRead()) {
PreferencesMap prefs = new PreferencesMap(); PreferencesMap prefs = new PreferencesMap();
prefs.load(programmersFile); prefs.load(progFile);
programmers = prefs.createFirstLevelMap(); programmers = prefs.firstLevelMap();
} }
} catch (Exception e) { } catch (IOException e) {
System.err throw new TargetPlatformException(format(_("Error loading {0}"), progFile
.println("Error loading programmers from programmers.txt: " + e); .getAbsolutePath()), e);
} }
} }
@ -91,11 +119,11 @@ public class TargetPlatform {
return folder; return folder;
} }
public Map<String, PreferencesMap> getBoards() { public Map<String, TargetBoard> getBoards() {
return boards; return boards;
} }
public MapWithSubkeys getCustomMenus() { public PreferencesMap getCustomMenus() {
return customMenus; return customMenus;
} }
@ -108,10 +136,14 @@ public class TargetPlatform {
} }
public PreferencesMap getTool(String tool) { public PreferencesMap getTool(String tool) {
return getPreferences().createSubTree("tools").createSubTree(tool); return getPreferences().subTree("tools").subTree(tool);
} }
public PreferencesMap getPreferences() { public PreferencesMap getPreferences() {
return preferences; return preferences;
} }
public TargetBoard getBoard(String boardId) {
return boards.get(boardId);
}
} }

View File

@ -0,0 +1,22 @@
package processing.app.debug;
@SuppressWarnings("serial")
public class TargetPlatformException extends Exception {
public TargetPlatformException() {
super();
}
public TargetPlatformException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public TargetPlatformException(String arg0) {
super(arg0);
}
public TargetPlatformException(Throwable arg0) {
super(arg0);
}
}

View File

@ -1,15 +0,0 @@
package processing.app.helpers;
import java.util.Map;
import java.util.Map.Entry;
public class Maps {
public static <K, V> Map<K, V> merge(Map<K, V> input, Map<K, V> target) {
for (Entry<K, V> entry : input.entrySet()) {
target.put(entry.getKey(), entry.getValue());
}
return target;
}
}

View File

@ -28,17 +28,43 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import processing.app.Base; import processing.app.Base;
import processing.core.PApplet; import processing.core.PApplet;
@SuppressWarnings("serial")
public class PreferencesMap extends LinkedHashMap<String, String> { public class PreferencesMap extends LinkedHashMap<String, String> {
public PreferencesMap(Map<String, String> table) { public PreferencesMap(Map<String, String> table) {
super(table); super(table);
} }
/**
* Create a PreferencesMap and load the content of the file passed as
* argument.
*
* Is equivalent to:
*
* <pre>
* PreferencesMap map = new PreferencesMap();
* map.load(file);
* </pre>
*
* @param file
* @throws IOException
*/
public PreferencesMap(File file) throws IOException {
super();
load(file);
}
public PreferencesMap() { public PreferencesMap() {
super(); super();
} }
@ -75,7 +101,7 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
} }
// This is needed to avoid ConcurrentAccessExceptions // This is needed to avoid ConcurrentAccessExceptions
Set<String> keys = new HashSet<String>(keySet()); Set<String> keys = new LinkedHashSet<String>(keySet());
// Override keys that have OS specific versions // Override keys that have OS specific versions
for (String key : keys) { for (String key : keys) {
@ -95,13 +121,109 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
} }
/** /**
* Create a new Map<String, PreferenceMap> where the keys are the first level * Create a new PreferenceMap that contains all the top level pairs of the
* of the current mapping. E.g. the folowing mapping:<br /> * current mapping. E.g. the folowing mapping:<br />
* *
* <pre> * <pre>
* Map ( * Map (
* alpha = Alpha
* alpha.some.keys = v1 * alpha.some.keys = v1
* alpha.other.keys = v2 * alpha.other.keys = v2
* beta = Beta
* beta.some.keys = v3
* )
* </pre>
*
* will generate the following result:
*
* <pre>
* Map (
* alpha = Alpha
* beta = Beta
* )
* </pre>
*
* @return
*/
public PreferencesMap topLevelMap() {
PreferencesMap res = new PreferencesMap();
for (String key : keySet()) {
if (key.contains("."))
continue;
res.put(key, get(key));
}
return res;
}
/**
* Returns the values of all the top level pairs of the current mapping. E.g.
* the folowing mapping:<br />
*
* <pre>
* Map (
* alpha = Alpha
* alpha.some.keys = v1
* alpha.other.keys = v2
* beta = Beta
* beta.some.keys = v3
* )
* </pre>
*
* will generate the following result:
*
* <pre>
* Collection (
* Alpha
* Beta
* )
* </pre>
*
* @return
*/
public Collection<String> topLevelValues() {
return topLevelMap().values();
}
/**
* Returns a key set of all the top level pairs of the current mapping. E.g.
* the folowing mapping:<br />
*
* <pre>
* Map (
* alpha = Alpha
* alpha.some.keys = v1
* alpha.other.keys = v2
* beta = Beta
* beta.some.keys = v3
* )
* </pre>
*
* will generate the following result:
*
* <pre>
* Set (
* alpha
* beta
* )
* </pre>
*
* @return
*/
public Set<String> topLevelKeySet() {
return topLevelMap().keySet();
}
/**
* Create a new Map<String, PreferenceMap> where keys are the first level of
* the current mapping. Top level pairs are discarded. E.g. the folowing
* mapping:<br />
*
* <pre>
* Map (
* alpha = Alpha
* alpha.some.keys = v1
* alpha.other.keys = v2
* beta = Beta
* beta.some.keys = v3 * beta.some.keys = v3
* ) * )
* </pre> * </pre>
@ -120,7 +242,7 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
* *
* @return * @return
*/ */
public Map<String, PreferencesMap> createFirstLevelMap() { public Map<String, PreferencesMap> firstLevelMap() {
Map<String, PreferencesMap> res = new LinkedHashMap<String, PreferencesMap>(); Map<String, PreferencesMap> res = new LinkedHashMap<String, PreferencesMap>();
for (String key : keySet()) { for (String key : keySet()) {
int dot = key.indexOf('.'); int dot = key.indexOf('.');
@ -138,13 +260,15 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
} }
/** /**
* Create a new PreferenceMap using a subtree of the current mapping. E.g. * Create a new PreferenceMap using a subtree of the current mapping. Top
* with the folowing mapping:<br /> * level pairs are ignored. E.g. with the following mapping:<br />
* *
* <pre> * <pre>
* Map ( * Map (
* alpha = Alpha
* alpha.some.keys = v1 * alpha.some.keys = v1
* alpha.other.keys = v2 * alpha.other.keys = v2
* beta = Beta
* beta.some.keys = v3 * beta.some.keys = v3
* ) * )
* </pre> * </pre>
@ -161,7 +285,7 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
* @param parent * @param parent
* @return * @return
*/ */
public PreferencesMap createSubTree(String parent) { public PreferencesMap subTree(String parent) {
PreferencesMap res = new PreferencesMap(); PreferencesMap res = new PreferencesMap();
parent += "."; parent += ".";
int parentLen = parent.length(); int parentLen = parent.length();
@ -172,5 +296,16 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
return res; return res;
} }
private static final long serialVersionUID = 2330591567444282843L; public String toString(String indent) {
String res = indent + "{\n";
SortedSet<String> treeSet = new TreeSet<String>(keySet());
for (String k : treeSet)
res += indent + k + " = " + get(k) + "\n";
return res;
}
@Override
public String toString() {
return toString("");
}
} }

View File

@ -1,66 +0,0 @@
package processing.app.tools;
import java.util.*;
import java.util.Map.Entry;
public class MapWithSubkeys {
public static MapWithSubkeys createFrom(Map<String, String> input) {
if (input == null) {
return null;
}
MapWithSubkeys target = new MapWithSubkeys();
for (Entry<String, String> entry : input.entrySet()) {
String[] entryParts = entry.getKey().split("\\.");
if (entryParts.length == 1) {
target.put(entryParts[0], entry.getValue());
} else if (entryParts.length == 3) {
target.get(entryParts[0]).get(entryParts[1]).put(entryParts[2], entry.getValue());
} else if (entryParts.length > 3) {
StringBuilder sb = new StringBuilder();
for (int i = 3; i < entryParts.length; i++) {
sb.append(entryParts[i]).append(".");
}
sb.deleteCharAt(sb.length() - 1);
String key = sb.toString();
target.get(entryParts[0]).get(entryParts[1]).get(entryParts[2]).put(key, entry.getValue());
}
}
return target;
}
private final Map<String, String> values;
private final Map<String, MapWithSubkeys> maps;
public MapWithSubkeys() {
this.values = new LinkedHashMap<String, String>();
this.maps = new LinkedHashMap<String, MapWithSubkeys>();
}
public Collection<String> getKeys() {
return values.keySet();
}
public Map<String, String> getValues() {
return values;
}
public String getValueOf(String key) {
return values.get(key);
}
public MapWithSubkeys get(String key) {
if (!maps.containsKey(key)) {
maps.put(key, new MapWithSubkeys());
}
if (!values.containsKey(key)) {
put(key, null);
}
return maps.get(key);
}
public void put(String key, String value) {
values.put(key, value);
}
}

View File

@ -1,59 +0,0 @@
package processing.app.tools;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
public class MapWithSubkeysTest {
private MapWithSubkeys map;
@Before
public void setup() throws Exception {
Map<String, String> input = new HashMap<String, String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(MapWithSubkeysTest.class.getResourceAsStream("test_partial_boards.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
String[] lineParts = line.split("=");
input.put(lineParts[0], lineParts[1]);
}
map = MapWithSubkeys.createFrom(input);
}
@Test
public void shouldListCustomMenusIDs() {
Collection<String> menusIDs = map.getKeys();
assertEquals(2, menusIDs.size());
assertTrue(menusIDs.contains("cpu"));
assertTrue(menusIDs.contains("speed"));
assertEquals("Processor", map.getValueOf("cpu"));
MapWithSubkeys cpu = map.get("cpu");
Collection<String> boards = cpu.getKeys();
assertEquals(1, boards.size());
assertTrue(boards.contains("nano"));
Collection<String> cpuNanoProcessors = cpu.get("nano").getKeys();
assertEquals(2, cpuNanoProcessors.size());
assertTrue(cpuNanoProcessors.contains("atmega168"));
assertTrue(cpuNanoProcessors.contains("atmega328"));
assertEquals("ATmega168", cpu.get("nano").getValueOf("atmega168"));
assertEquals("ATmega328", cpu.get("nano").getValueOf("atmega328"));
MapWithSubkeys atmega168Properties = cpu.get("nano").get("atmega168");
assertEquals(9, atmega168Properties.getKeys().size());
assertTrue(atmega168Properties.getKeys().contains("bootloader.high_fuses"));
}
}