Initial work on multi-server

Also add help topics and have a preference panel that allows disabling of URLs

Signed-off-by: Taylor Smock <taylor.smock@kaart.com>
pull/1/head v0.1.16
Taylor Smock 2019-11-13 07:33:55 -07:00
rodzic af841278c7
commit 466a1a188c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
19 zmienionych plików z 733 dodań i 182 usunięć

Wyświetl plik

@ -7,21 +7,21 @@ import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import org.openstreetmap.josm.actions.ExpertToggleAction;
@ -30,45 +30,58 @@ import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
import org.openstreetmap.josm.gui.preferences.advanced.PrefEntry;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper;
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.DataUrl;
import org.openstreetmap.josm.spi.preferences.StringSetting;
import org.openstreetmap.josm.tools.GBC;
public class MapWithAIPreferences implements SubPreferenceSetting {
private final JComboBox<String> possibleMapWithAIApiUrl;
private final JCheckBox switchLayerCheckBox;
private final JCheckBox mergeBuildingAddressCheckBox;
private final JSpinner maximumAdditionSpinner;
private final ReplacementPreferenceTable table;
private final List<PrefEntry> displayData;
private final ReplacementPreferenceTable replacementPreferenceTable;
private final MapWithAIURLPreferenceTable mapwithaiUrlPreferenceTable;
private final List<PrefEntry> replacementTableDisplayData;
private final List<DataUrl> mapwithaiurlTableDisplayData;
private static final int MAX_SELECTED_TO_EDIT = 1;
private static final String SOURCE = "source";
public MapWithAIPreferences() {
possibleMapWithAIApiUrl = new JComboBox<>();
switchLayerCheckBox = new JCheckBox();
maximumAdditionSpinner = new JSpinner(
new SpinnerNumberModel(MapWithAIPreferenceHelper.getMaximumAddition(), 0, 100, 1));
mergeBuildingAddressCheckBox = new JCheckBox();
displayData = new ArrayList<>();
fillDisplayData(displayData);
table = new ReplacementPreferenceTable(displayData);
replacementTableDisplayData = new ArrayList<>();
fillReplacementTagDisplayData(replacementTableDisplayData);
replacementPreferenceTable = new ReplacementPreferenceTable(replacementTableDisplayData);
mapwithaiurlTableDisplayData = new ArrayList<>();
fillMapWithAIURLTableDisplayData(mapwithaiurlTableDisplayData);
mapwithaiUrlPreferenceTable = new MapWithAIURLPreferenceTable(mapwithaiurlTableDisplayData);
}
private static void fillDisplayData(List<PrefEntry> list) {
private static void fillReplacementTagDisplayData(List<PrefEntry> list) {
final Map<String, String> current = new TreeMap<>(MapWithAIPreferenceHelper.getReplacementTags());
for (final Entry<String, String> entry : current.entrySet()) {
list.add(new PrefEntry(entry.getKey(), new StringSetting(entry.getValue()), new StringSetting(null), false));
}
}
private static void fillMapWithAIURLTableDisplayData(List<DataUrl> list) {
MapWithAIPreferenceHelper.getMapWithAIURLs()
.forEach(
entry -> list
.add(new DataUrl(entry.get(SOURCE), entry.get("url"),
Boolean.valueOf(entry.get("enabled")))));
}
@Override
public void addGui(PreferenceTabbedPane gui) {
final JLabel mapWithAIApiUrl = new JLabel(tr("{0} API URL", MapWithAIPlugin.NAME));
int width = 200;
int height = 200;
final JLabel mapWithAIApiUrl = new JLabel(tr("{0} API URLs", MapWithAIPlugin.NAME));
final JLabel switchLayer = new JLabel(tr("Automatically switch layers"));
final JLabel maximumAddition = new JLabel(tr("Maximum features (add)"));
final JLabel mergeBuildingWithAddress = new JLabel(tr("Merge address nodes and buildings"));
final JPanel nonExpert = new JPanel(new GridBagLayout());
nonExpert.setAlignmentY(Component.TOP_ALIGNMENT);
nonExpert.setAlignmentX(Component.LEFT_ALIGNMENT);
mapWithAIApiUrl.setToolTipText(tr("The URL that will be called to get data from"));
switchLayer.setToolTipText(
@ -80,93 +93,97 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
mergeBuildingWithAddress.setToolTipText(tr(
"If checked, automatically merge address nodes onto added buildings, if and only if one address is withing the building boundary"));
possibleMapWithAIApiUrl.setEditable(true);
possibleMapWithAIApiUrl.setPrototypeDisplayValue("https://example.url/some/end/point");
final Component textField = possibleMapWithAIApiUrl.getEditor().getEditorComponent();
if (textField instanceof JTextField) {
((JTextField) textField).setColumns(24);
}
for (final String url : MapWithAIPreferenceHelper.getMapWithAIURLs()) {
possibleMapWithAIApiUrl.addItem(url);
}
possibleMapWithAIApiUrl.setSelectedItem(MapWithAIPreferenceHelper.getMapWithAIUrl());
switchLayerCheckBox.setSelected(MapWithAIPreferenceHelper.isSwitchLayers());
mergeBuildingAddressCheckBox.setSelected(MapWithAIPreferenceHelper.isMergeBuildingAddress());
nonExpert.add(mapWithAIApiUrl);
final JPanel pane = new JPanel(new GridBagLayout());
pane.setAlignmentY(Component.TOP_ALIGNMENT);
pane.setAlignmentX(Component.LEFT_ALIGNMENT);
nonExpert.add(possibleMapWithAIApiUrl, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
GBC first = GBC.std().weight(0, 1).anchor(GridBagConstraints.WEST);
GBC second = GBC.eol().fill(GridBagConstraints.HORIZONTAL);
GBC buttonInsets = GBC.std().insets(5, 5, 0, 0);
nonExpert.add(switchLayer);
pane.add(mapWithAIApiUrl, first);
nonExpert.add(switchLayerCheckBox, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
final JScrollPane scroll1 = new JScrollPane(mapwithaiUrlPreferenceTable);
pane.add(scroll1, GBC.eol().fill(GridBagConstraints.BOTH));
scroll1.setPreferredSize(new Dimension(width, height));
nonExpert.add(maximumAddition);
nonExpert.add(maximumAdditionSpinner, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
pane.add(switchLayer, first);
nonExpert.add(mergeBuildingWithAddress);
nonExpert.add(mergeBuildingAddressCheckBox, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
pane.add(switchLayerCheckBox, second);
final JPanel expert = new JPanel(new GridBagLayout());
expert.add(Box.createHorizontalGlue(), GBC.std().fill(GridBagConstraints.HORIZONTAL));
final JScrollPane scroll = new JScrollPane(table);
expert.add(scroll, GBC.eol().fill(GridBagConstraints.BOTH));
scroll.setPreferredSize(new Dimension(400, 200));
pane.add(maximumAddition, first);
pane.add(maximumAdditionSpinner, second);
pane.add(mergeBuildingWithAddress, first);
pane.add(mergeBuildingAddressCheckBox, second);
final Component expertHorizontalGlue = Box.createHorizontalGlue();
pane.add(expertHorizontalGlue, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
final JLabel replacementTags = new JLabel(tr("Replacement Tags"));
pane.add(replacementTags, first);
final JScrollPane scroll2 = new JScrollPane(replacementPreferenceTable);
pane.add(scroll2, GBC.eol().fill(GridBagConstraints.BOTH));
scroll2.setPreferredSize(new Dimension(width, height));
pane.add(new JLabel(), first);
JPanel replaceAddEditDelete = new JPanel(new GridBagLayout());
pane.add(replaceAddEditDelete, second);
final JButton add = new JButton(tr("Add"));
expert.add(Box.createHorizontalGlue(), GBC.std().fill(GridBagConstraints.HORIZONTAL));
expert.add(add, GBC.std().insets(0, 5, 0, 0));
replaceAddEditDelete.add(add, buttonInsets);
add.addActionListener(e -> {
final PrefEntry pe = table.addPreference(gui);
final PrefEntry pe = replacementPreferenceTable.addPreference(gui);
if (pe != null && pe.getValue() instanceof StringSetting) {
displayData.add(pe);
Collections.sort(displayData);
table.fireDataChanged();
replacementTableDisplayData.add(pe);
Collections.sort(replacementTableDisplayData);
replacementPreferenceTable.fireDataChanged();
}
});
final JButton edit = new JButton(tr("Edit"));
expert.add(edit, GBC.std().insets(5, 5, 0, 0));
replaceAddEditDelete.add(edit, buttonInsets);
edit.addActionListener(e -> {
final List<PrefEntry> toEdit = table.getSelectedItems();
final List<PrefEntry> toEdit = replacementPreferenceTable.getSelectedItems();
if (toEdit.size() == MAX_SELECTED_TO_EDIT) {
table.editPreference(gui);
replacementPreferenceTable.editPreference(gui);
}
});
final JButton delete = new JButton(tr("Delete"));
expert.add(delete, GBC.std().insets(5, 5, 0, 0));
replaceAddEditDelete.add(delete, buttonInsets);
delete.addActionListener(e -> {
final List<PrefEntry> toRemove = table.getSelectedItems();
final List<PrefEntry> toRemove = replacementPreferenceTable.getSelectedItems();
if (!toRemove.isEmpty()) {
displayData.removeAll(toRemove);
replacementTableDisplayData.removeAll(toRemove);
}
table.fireDataChanged();
replacementPreferenceTable.fireDataChanged();
});
ExpertToggleAction.addVisibilitySwitcher(expert);
final JPanel pane = new JPanel(new GridBagLayout());
pane.add(nonExpert, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
pane.add(expert);
Arrays.asList(replaceAddEditDelete, scroll2, expertHorizontalGlue, replacementTags)
.forEach(ExpertToggleAction::addVisibilitySwitcher);
getTabPreferenceSetting(gui).addSubTab(this, MapWithAIPlugin.NAME, pane);
}
@Override
public boolean ok() {
MapWithAIPreferenceHelper.setMapWithAIUrl((String) possibleMapWithAIApiUrl.getSelectedItem(), true);
MapWithAIPreferenceHelper.setMapWithAIURLs(convertUrlPrefToMap(mapwithaiurlTableDisplayData));
MapWithAIPreferenceHelper.setSwitchLayers(switchLayerCheckBox.isSelected(), true);
final Object value = maximumAdditionSpinner.getValue();
if (value instanceof Number) {
MapWithAIPreferenceHelper.setMaximumAddition(((Number) value).intValue(), true);
}
MapWithAIPreferenceHelper.setReplacementTags(convertPrefToMap(displayData));
MapWithAIPreferenceHelper.setReplacementTags(convertReplacementPrefToMap(replacementTableDisplayData));
return false;
}
private static Map<String, String> convertPrefToMap(List<PrefEntry> displayData) {
private static List<Map<String, String>> convertUrlPrefToMap(List<DataUrl> displayData) {
return displayData.stream().map(DataUrl::getMap).collect(Collectors.toList());
}
private static Map<String, String> convertReplacementPrefToMap(List<PrefEntry> displayData) {
final Map<String, String> returnMap = displayData.isEmpty() ? Collections.emptyMap() : new TreeMap<>();
displayData.forEach(entry -> returnMap.put(entry.getKey(), entry.getValue().getValue().toString()));
return returnMap;
@ -182,13 +199,6 @@ public class MapWithAIPreferences implements SubPreferenceSetting {
return gui.getPluginPreference();
}
/**
* @return {@code JComboBox} with possible MapWithAI api urls
*/
public JComboBox<String> getPossibleMapWithAIApiUrl() {
return possibleMapWithAIApiUrl;
}
/**
* @return The {@code JCheckBox} for whether or not we are switching layers.
*/

Wyświetl plik

@ -0,0 +1,342 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import org.openstreetmap.josm.gui.ExtendedDialog;
import org.openstreetmap.josm.gui.preferences.advanced.ListEditor;
import org.openstreetmap.josm.gui.preferences.advanced.ListListEditor;
import org.openstreetmap.josm.gui.preferences.advanced.MapListEditor;
import org.openstreetmap.josm.gui.preferences.advanced.PrefEntry;
import org.openstreetmap.josm.gui.preferences.advanced.StringEditor;
import org.openstreetmap.josm.gui.widgets.JosmTextField;
import org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation.DataUrl;
import org.openstreetmap.josm.spi.preferences.ListListSetting;
import org.openstreetmap.josm.spi.preferences.ListSetting;
import org.openstreetmap.josm.spi.preferences.MapListSetting;
import org.openstreetmap.josm.spi.preferences.Setting;
import org.openstreetmap.josm.spi.preferences.StringSetting;
import org.openstreetmap.josm.tools.GBC;
/**
* Component for editing list of preferences as a table.
* @since 6021
*/
public class MapWithAIURLPreferenceTable extends JTable {
private static final long serialVersionUID = -6221760175084963950L;
private final URLTableModel model;
private final transient List<DataUrl> displayData;
/**
* Constructs a new {@code PreferencesTable}.
* @param displayData The list of preferences entries to display
*/
public MapWithAIURLPreferenceTable(List<DataUrl> displayData) {
this.displayData = displayData;
model = new URLTableModel();
setModel(model);
putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(new JosmTextField()));
getColumnModel().getColumn(0)
.setPreferredWidth(getFontMetrics(getFont()).stringWidth(MapWithAIPlugin.NAME) + 5);
getColumnModel().getColumn(0).setMaxWidth(getColumnModel().getColumn(0).getPreferredWidth() * 2);
getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JosmTextField()));
getColumnModel().getColumn(2).setMaxWidth(getFontMetrics(getFont()).stringWidth("ENABLED"));
getColumnModel().getColumn(3).setMaxWidth(getFontMetrics(getFont()).stringWidth("Parameters"));
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
editPreference(MapWithAIURLPreferenceTable.this);
}
}
});
}
/**
* This method should be called when displayed data was changed form external code
*/
public void fireDataChanged() {
model.fireTableDataChanged();
}
/**
* The list of currently selected rows
* @return newly created list of PrefEntry
*/
public List<PrefEntry> getSelectedItems() {
List<PrefEntry> entries = new ArrayList<>();
for (int row : getSelectedRows()) {
PrefEntry p = (PrefEntry) model.getValueAt(row, -1);
entries.add(p);
}
return entries;
}
/**
* Call this to edit selected row in preferences table
* @param gui - parent component for messagebox
* @return true if editing was actually performed during this call
*/
public boolean editPreference(final JComponent gui) {
if (getSelectedRowCount() != 1) {
JOptionPane.showMessageDialog(
gui,
tr("Please select the row to edit."),
tr("Warning"),
JOptionPane.WARNING_MESSAGE
);
return false;
}
final Object e = model.getValueAt(getSelectedRow(), 1);
Setting<?> stg = e instanceof PrefEntry ? ((PrefEntry) e).getValue() : null;
boolean ok = false;
if (stg instanceof StringSetting || e instanceof String || e instanceof Boolean) {
editCellAt(getSelectedRow(), getSelectedColumn());
Component editor = getEditorComponent();
if (editor != null) {
editor.requestFocus();
}
} else if (stg instanceof ListSetting) {
ok = doEditList(gui, (PrefEntry) e, (ListSetting) stg);
} else if (stg instanceof ListListSetting) {
ok = doEditListList(gui, (PrefEntry) e, (ListListSetting) stg);
} else if (stg instanceof MapListSetting) {
ok = doEditMapList(gui, (PrefEntry) e, (MapListSetting) stg);
}
return ok;
}
private static boolean doEditList(final JComponent gui, final PrefEntry e, ListSetting lSetting) {
ListEditor lEditor = new ListEditor(gui, e, lSetting);
lEditor.showDialog();
if (lEditor.getValue() == 1) {
List<String> data = lEditor.getData();
if (!lSetting.equalVal(data)) {
e.setValue(new ListSetting(data));
return true;
}
}
return false;
}
private static boolean doEditListList(final JComponent gui, final PrefEntry e, ListListSetting llSetting) {
ListListEditor llEditor = new ListListEditor(gui, e, llSetting);
llEditor.showDialog();
if (llEditor.getValue() == 1) {
List<List<String>> data = llEditor.getData();
if (!llSetting.equalVal(data)) {
e.setValue(new ListListSetting(data));
return true;
}
}
return false;
}
private static boolean doEditMapList(final JComponent gui, final PrefEntry e, MapListSetting mlSetting) {
MapListEditor mlEditor = new MapListEditor(gui, e, mlSetting);
mlEditor.showDialog();
if (mlEditor.getValue() == 1) {
List<Map<String, String>> data = mlEditor.getData();
if (!mlSetting.equalVal(data)) {
e.setValue(new MapListSetting(data));
return true;
}
}
return false;
}
/**
* Add new preference to the table
* @param gui - parent component for asking dialogs
* @return newly created entry or null if adding was cancelled
*/
public PrefEntry addPreference(final JComponent gui) {
JPanel p = new JPanel(new GridBagLayout());
p.add(new JLabel(tr("Key")), GBC.std().insets(0, 0, 5, 0));
JosmTextField tkey = new JosmTextField("", 50);
p.add(tkey, GBC.eop().insets(5, 0, 0, 0).fill(GridBagConstraints.HORIZONTAL));
p.add(new JLabel(tr("Select Setting Type:")), GBC.eol().insets(5, 15, 5, 0));
JRadioButton rbString = new JRadioButton(tr("Simple"));
JRadioButton rbList = new JRadioButton(tr("List"));
JRadioButton rbListList = new JRadioButton(tr("List of lists"));
JRadioButton rbMapList = new JRadioButton(tr("List of maps"));
ButtonGroup group = new ButtonGroup();
group.add(rbString);
group.add(rbList);
group.add(rbListList);
group.add(rbMapList);
p.add(rbString, GBC.eol());
p.add(rbList, GBC.eol());
p.add(rbListList, GBC.eol());
p.add(rbMapList, GBC.eol());
rbString.setSelected(true);
PrefEntry pe = null;
boolean ok = false;
if (askAddSetting(gui, p)) {
if (rbString.isSelected()) {
StringSetting sSetting = new StringSetting(null);
pe = new PrefEntry(tkey.getText(), sSetting, sSetting, false);
ok = doAddSimple(gui, pe, sSetting);
} else if (rbList.isSelected()) {
ListSetting lSetting = new ListSetting(null);
pe = new PrefEntry(tkey.getText(), lSetting, lSetting, false);
ok = doAddList(gui, pe, lSetting);
} else if (rbListList.isSelected()) {
ListListSetting llSetting = new ListListSetting(null);
pe = new PrefEntry(tkey.getText(), llSetting, llSetting, false);
ok = doAddListList(gui, pe, llSetting);
} else if (rbMapList.isSelected()) {
MapListSetting mlSetting = new MapListSetting(null);
pe = new PrefEntry(tkey.getText(), mlSetting, mlSetting, false);
ok = doAddMapList(gui, pe, mlSetting);
}
}
return ok ? pe : null;
}
private static boolean askAddSetting(JComponent gui, JPanel p) {
return new ExtendedDialog(gui, tr("Add setting"), tr("OK"), tr("Cancel"))
.setContent(p).setButtonIcons("ok", "cancel").showDialog().getValue() == 1;
}
private static boolean doAddSimple(final JComponent gui, PrefEntry pe, StringSetting sSetting) {
StringEditor sEditor = new StringEditor(gui, pe, sSetting);
sEditor.showDialog();
if (sEditor.getValue() == 1) {
String data = sEditor.getData();
if (!Objects.equals(sSetting.getValue(), data)) {
pe.setValue(new StringSetting(data));
return true;
}
}
return false;
}
private static boolean doAddList(final JComponent gui, PrefEntry pe, ListSetting lSetting) {
ListEditor lEditor = new ListEditor(gui, pe, lSetting);
lEditor.showDialog();
if (lEditor.getValue() == 1) {
List<String> data = lEditor.getData();
if (!lSetting.equalVal(data)) {
pe.setValue(new ListSetting(data));
return true;
}
}
return false;
}
private static boolean doAddListList(final JComponent gui, PrefEntry pe, ListListSetting llSetting) {
ListListEditor llEditor = new ListListEditor(gui, pe, llSetting);
llEditor.showDialog();
if (llEditor.getValue() == 1) {
List<List<String>> data = llEditor.getData();
if (!llSetting.equalVal(data)) {
pe.setValue(new ListListSetting(data));
return true;
}
}
return false;
}
private static boolean doAddMapList(final JComponent gui, PrefEntry pe, MapListSetting mlSetting) {
MapListEditor mlEditor = new MapListEditor(gui, pe, mlSetting);
mlEditor.showDialog();
if (mlEditor.getValue() == 1) {
List<Map<String, String>> data = mlEditor.getData();
if (!mlSetting.equalVal(data)) {
pe.setValue(new MapListSetting(data));
return true;
}
}
return false;
}
/**
* Reset selected preferences to their default values
* @param gui - parent component to display warning messages
*/
public void resetPreferences(final JComponent gui) {
if (getSelectedRowCount() == 0) {
JOptionPane.showMessageDialog(
gui,
tr("Please select the row to delete."),
tr("Warning"),
JOptionPane.WARNING_MESSAGE
);
return;
}
for (int row : getSelectedRows()) {
DataUrl e = displayData.get(row);
e.reset();
}
fireDataChanged();
}
final class URLTableModel extends DefaultTableModel {
private static final long serialVersionUID = 2435772137483913278L;
URLTableModel() {
super();
setColumnIdentifiers(new String[] { tr("Source"), tr("URL"), tr("Enabled"), tr("Parameters") });
}
@Override
public Class<?> getColumnClass(int column) {
return getRowCount() == 0 ? Object.class : getValueAt(0, column).getClass();
}
@Override
public int getRowCount() {
return displayData.size();
}
@Override
public Object getValueAt(int row, int column) {
return displayData.get(row).getDataList().get(column);
}
@Override
public void setValueAt(Object o, int row, int column) {
List<Object> setList = new ArrayList<>(displayData.get(row).getDataList());
if (!o.equals(setList.get(column))) {
setList.remove(column);
setList.add(column, o);
displayData.get(row).setDataList(setList);
if (o instanceof String && ((String) o).isEmpty()) {
displayData.get(row).reset();
displayData.remove(row);
fireTableRowsDeleted(row, row);
} else {
fireTableCellUpdated(row, column);
}
}
}
}
}

Wyświetl plik

@ -0,0 +1,17 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai;
import org.openstreetmap.josm.gui.preferences.advanced.PrefEntry;
import org.openstreetmap.josm.spi.preferences.Setting;
/**
* @author Taylor Smock
*
*/
public class TriPrefEntry extends PrefEntry {
public TriPrefEntry(String key, Setting<?> value, Setting<?> defaultValue, boolean isDefault) {
super(key, value, defaultValue, isDefault);
}
}

Wyświetl plik

@ -5,6 +5,7 @@ import static org.openstreetmap.josm.tools.I18n.tr;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.util.ArrayList;
@ -13,6 +14,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.RecursiveTask;
@ -49,7 +51,7 @@ import org.openstreetmap.josm.tools.Pair;
public class GetDataRunnable extends RecursiveTask<DataSet> implements CancelListener {
private static final long serialVersionUID = 258423685658089715L;
private final List<BBox> bbox;
private static HttpClient client;
private static List<HttpClient> clients;
private final transient DataSet dataSet;
private final transient ProgressMonitor monitor;
@ -307,59 +309,69 @@ public class GetDataRunnable extends RecursiveTask<DataSet> implements CancelLis
* @return A dataset with the data from the bbox
*/
private static DataSet getDataReal(BBox bbox, ProgressMonitor monitor) {
// Logging.error(bbox.toStringCSV(","));
InputStream inputStream = null;
final DataSet dataSet = new DataSet();
String urlString = MapWithAIPreferenceHelper.getMapWithAIUrl();
List<Map<String, String>> urlMaps = MapWithAIPreferenceHelper.getMapWithAIUrl().stream()
.map(map -> new TreeMap<>(map)).collect(Collectors.toList());
if (DetectTaskingManagerUtils.hasTaskingManagerLayer()) {
urlString += "&crop_bbox={crop_bbox}";
urlMaps.forEach(map -> map.put("url", map.get("url").concat("&crop_bbox={crop_bbox}")));
}
dataSet.setUploadPolicy(UploadPolicy.DISCOURAGED);
try {
final URL url = new URL(urlString.replace("{bbox}", bbox.toStringCSV(",")).replace("{crop_bbox}",
DetectTaskingManagerUtils.getTaskingManagerBBox().toStringCSV(",")));
client = HttpClient.create(url);
client.setReadTimeout(DEFAULT_TIMEOUT);
final StringBuilder defaultUserAgent = new StringBuilder();
defaultUserAgent.append(client.getHeaders().get("User-Agent"));
if (defaultUserAgent.toString().trim().length() == 0) {
defaultUserAgent.append("JOSM");
clients = new ArrayList<>();
urlMaps.forEach(map -> {
try {
clients.add(HttpClient.create(new URL(map.get("url").replace("{bbox}", bbox.toStringCSV(","))
.replace("{crop_bbox}", DetectTaskingManagerUtils.getTaskingManagerBBox().toStringCSV(",")))));
} catch (MalformedURLException e1) {
Logging.debug(e1);
}
defaultUserAgent.append(tr("/ {0} {1}", MapWithAIPlugin.NAME, MapWithAIPlugin.getVersionInfo()));
client.setHeader("User-Agent", defaultUserAgent.toString());
if (!monitor.isCanceled()) {
});
clients.forEach(client -> clientCall(client, dataSet, monitor));
dataSet.setUploadPolicy(UploadPolicy.BLOCKED);
return dataSet;
}
private static void clientCall(HttpClient client, DataSet dataSet, ProgressMonitor monitor) {
final StringBuilder defaultUserAgent = new StringBuilder();
client.setReadTimeout(DEFAULT_TIMEOUT);
defaultUserAgent.append(client.getHeaders().get("User-Agent"));
if (defaultUserAgent.toString().trim().length() == 0) {
defaultUserAgent.append("JOSM");
}
defaultUserAgent.append(tr("/ {0} {1}", MapWithAIPlugin.NAME, MapWithAIPlugin.getVersionInfo()));
client.setHeader("User-Agent", defaultUserAgent.toString());
if (!monitor.isCanceled()) {
InputStream inputStream = null;
try {
Logging.debug("{0}: Getting {1}", MapWithAIPlugin.NAME, client.getURL().toString());
final Response response = client.connect();
inputStream = response.getContent();
final DataSet mergeData = OsmReaderCustom.parseDataSet(inputStream, null, true);
dataSet.mergeFrom(mergeData);
response.disconnect();
}
} catch (SocketException e) {
if (!monitor.isCanceled()) {
Logging.debug(e);
}
} catch (UnsupportedOperationException | IllegalDataException | IOException e) {
Logging.debug(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (final IOException e) {
} catch (SocketException e) {
if (!monitor.isCanceled()) {
Logging.debug(e);
}
} catch (UnsupportedOperationException | IllegalDataException | IOException e) {
Logging.debug(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (final IOException e) {
Logging.debug(e);
}
}
}
dataSet.setUploadPolicy(UploadPolicy.BLOCKED);
}
return dataSet;
}
@Override
public void operationCanceled() {
if (client != null) {
client.disconnect();
if (clients != null) {
clients.parallelStream().filter(Objects::nonNull).forEach(HttpClient::disconnect);
}
}

Wyświetl plik

@ -1,6 +1,7 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.event.ActionEvent;
@ -36,6 +37,7 @@ public class MapWithAIAction extends JosmAction {
Shortcut.registerShortcut("data:mapWithAI", tr("Data: {0}", MapWithAIPlugin.NAME), KeyEvent.VK_R,
Shortcut.CTRL),
true);
setHelpId(ht("Plugin/MapWithAI#BasicUsage"));
}
@Override

Wyświetl plik

@ -52,6 +52,7 @@ public class MapWithAIArbitraryAction extends JosmAction {
Shortcut.registerShortcut("data:arbitrarymapwithai",
tr("Data: Arbitrary {0} Data", tr(ARBITRARY_DATA_STRING)), KeyEvent.VK_R,
Shortcut.ALT_CTRL_SHIFT), true);
setHelpId(ht("Plugin/MapWithAI#BasicUsage"));
}
@Override
@ -65,7 +66,7 @@ public class MapWithAIArbitraryAction extends JosmAction {
MapWithAIArbitraryDialog(String[] buttons, JPanel panel) {
super(MainApplication.getMainFrame(), tr(ARBITRARY_DATA_STRING), buttons);
setButtonIcons("ok", "cancel");
configureContextsensitiveHelp(ht("/Action/DownloadArbitraryMapWithAIData"), true);
configureContextsensitiveHelp(ht("Plugin/MapWithAI#BasicUsage"), true);
setContent(panel);
setCancelButton(2);
}

Wyświetl plik

@ -1,6 +1,7 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
@ -15,6 +16,7 @@ import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.UndoRedoHandler;
@ -27,6 +29,7 @@ import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
import org.openstreetmap.josm.gui.mappaint.StyleSource;
@ -63,7 +66,7 @@ public final class MapWithAIDataUtils {
"https://gitlab.com/smocktaylor/rapid/raw/master/src/resources/styles/standard/rapid.mapcss",
"resource://styles/standard/mapwithai.mapcss");
new ArrayList<>(MapPaintStyles.getStyles().getStyleSources()).parallelStream()
.filter(style -> oldUrls.contains(style.url))
.filter(style -> oldUrls.contains(style.url))
.forEach(MapPaintStyles::removeStyle);
if (!checkIfMapWithAIPaintStyleExists()) {
@ -152,15 +155,30 @@ public final class MapWithAIDataUtils {
public static DataSet getData(List<BBox> bbox) {
final DataSet dataSet = new DataSet();
final List<BBox> realBBoxes = bbox.stream().filter(BBox::isValid).distinct().collect(Collectors.toList());
if (realBBoxes.size() < TOO_MANY_BBOXES || ConditionalOptionPaneUtil.showConfirmationDialog(
MapWithAIPlugin.NAME.concat(".alwaysdownload"), null,
tr("You are going to make {0} requests to the MapWithAI server. This may take some time. <br /> Continue?",
realBBoxes.size()),
null, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.YES_OPTION)) {
final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor();
getForkJoinPool().invoke(new GetDataRunnable(realBBoxes, dataSet, monitor));
monitor.finishTask();
monitor.close();
if (MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.anyMatch(map -> Boolean.valueOf(map.getOrDefault("enabled", "false")))) {
if (realBBoxes.size() < TOO_MANY_BBOXES || ConditionalOptionPaneUtil.showConfirmationDialog(
MapWithAIPlugin.NAME.concat(".alwaysdownload"), null,
tr("You are going to make {0} requests to the MapWithAI server. This may take some time. <br /> Continue?",
realBBoxes.size()),
null, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.YES_OPTION)) {
final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor();
getForkJoinPool().invoke(new GetDataRunnable(realBBoxes, dataSet, monitor));
monitor.finishTask();
monitor.close();
}
} else {
Notification noUrls = MapWithAIPreferenceHelper.getMapWithAIURLs().isEmpty()
? new Notification(tr("There are no defined URLs. To get the defaults, restart JOSM"))
: new Notification(tr("No URLS are enabled"));
noUrls.setDuration(Notification.TIME_DEFAULT);
noUrls.setIcon(JOptionPane.INFORMATION_MESSAGE);
noUrls.setHelpTopic(ht("Plugin/MapWithAI#Preferences"));
if (SwingUtilities.isEventDispatchThread()) {
noUrls.show();
} else {
SwingUtilities.invokeLater(noUrls::show);
}
}
return dataSet;
}

Wyświetl plik

@ -1,5 +1,6 @@
package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.event.ActionEvent;
@ -35,6 +36,7 @@ public class MapWithAIMoveAction extends JosmAction {
KeyEvent.VK_A,
Shortcut.SHIFT),
true);
setHelpId(ht("Plugin/MapWithAI#BasicUsage"));
}
@Override

Wyświetl plik

@ -7,17 +7,26 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import org.openstreetmap.josm.actions.ExpertToggleAction;
import org.openstreetmap.josm.data.osm.Tag;
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
import org.openstreetmap.josm.spi.preferences.Config;
public final class MapWithAIPreferenceHelper {
public static final String DEFAULT_MAPWITHAI_API = "https://www.facebook.com/maps/ml_roads?conflate_with_osm=true&theme=ml_road_vector&collaborator=josm&token=ASb3N5o9HbX8QWn8G_NtHIRQaYv3nuG2r7_f3vnGld3KhZNCxg57IsaQyssIaEw5rfRNsPpMwg4TsnrSJtIJms5m&hash=ASawRla3rBcwEjY4HIY&bbox={bbox}";
protected static final String DEFAULT_MAPWITHAI_API_BUILDING = DEFAULT_MAPWITHAI_API
.concat("&result_type=road_building_vector_xml");
private static final int DEFAULT_MAXIMUM_ADDITION = 5;
private static final String AUTOSWITCHLAYERS = MapWithAIPlugin.NAME.concat(".autoswitchlayers");
private static final String MERGEBUILDINGADDRESSES = MapWithAIPlugin.NAME.concat(".mergebuildingaddresses");
private static final String MAXIMUMSELECTION = MapWithAIPlugin.NAME.concat(".maximumselection");
private static final String API_CONFIG = MapWithAIPlugin.NAME.concat(".apis");
private static final String API_MAP_CONFIG = API_CONFIG.concat("map");
private static final String URL_STRING = "url";
private static final String SOURCE_STRING = "source";
private static final String ENABLED_STRING = "enabled";
private MapWithAIPreferenceHelper() {
// Hide the constructor
@ -31,33 +40,65 @@ public final class MapWithAIPreferenceHelper {
}
/**
* Get the current MapWithAI url
* Get the current MapWithAI urls
*
* @return A MapWithAI url
* @return A list of enabled MapWithAI urls
*/
public static String getMapWithAIUrl() {
public static List<Map<String, String>> getMapWithAIUrl() {
final MapWithAILayer layer = MapWithAIDataUtils.getLayer(false);
String url = Config.getPref().get(MapWithAIPlugin.NAME.concat(".current_api"), DEFAULT_MAPWITHAI_API);
if (layer == null || layer.getMapWithAIUrl() == null) {
final List<String> urls = getMapWithAIURLs();
if (!urls.contains(url)) {
url = DEFAULT_MAPWITHAI_API;
setMapWithAIUrl(DEFAULT_MAPWITHAI_API, true);
}
} else {
url = layer.getMapWithAIUrl();
}
return url;
return layer != null && layer.getMapWithAIUrl() != null
? getMapWithAIURLs().parallelStream().filter(map -> layer.getMapWithAIUrl().equals(map.get(URL_STRING)))
.collect(Collectors.toList())
: getMapWithAIURLs().stream()
.filter(map -> Boolean.valueOf(map.getOrDefault(ENABLED_STRING, Boolean.FALSE.toString())))
.collect(Collectors.toList());
}
/**
* Get the MapWithAI urls (or the default)
* Get all of the MapWithAI urls (or the default)
*
* @return The urls for MapWithAI endpoints
*/
public static List<String> getMapWithAIURLs() {
return Config.getPref().getList(MapWithAIPlugin.NAME.concat(".apis"),
new ArrayList<>(Arrays.asList(DEFAULT_MAPWITHAI_API)));
public static List<Map<String, String>> getMapWithAIURLs() {
List<Map<String, String>> returnMap = Config.getPref().getListOfMaps(API_MAP_CONFIG, new ArrayList<>()).stream()
.map(map -> new TreeMap<>(map)).collect(Collectors.toList());
if (returnMap.isEmpty()) {
List<String> defaultAPIs = ExpertToggleAction.isExpert()
? Arrays.asList(DEFAULT_MAPWITHAI_API, DEFAULT_MAPWITHAI_API_BUILDING)
: Collections.singletonList(DEFAULT_MAPWITHAI_API);
List<String> defaultList = Config.getPref().getList(API_CONFIG).isEmpty()
? defaultAPIs
: Config.getPref().getList(API_CONFIG);
returnMap.addAll(defaultList.stream().map(string -> {
TreeMap<String, String> map = new TreeMap<>();
map.put(URL_STRING, string);
return map;
}).collect(Collectors.toList()));
} else if (ExpertToggleAction.isExpert() && returnMap.parallelStream()
.noneMatch(map -> DEFAULT_MAPWITHAI_API_BUILDING.equals(map.get(URL_STRING)))) {
Map<String, String> building = returnMap.parallelStream()
.filter(map -> DEFAULT_MAPWITHAI_API_BUILDING.equals(map.get(URL_STRING))).findFirst()
.orElse(new TreeMap<>());
returnMap.add(building);
building.putIfAbsent(URL_STRING, DEFAULT_MAPWITHAI_API_BUILDING);
building.putIfAbsent(ENABLED_STRING, Boolean.TRUE.toString());
}
returnMap.parallelStream().forEach(map -> {
String url = map.get(URL_STRING);
if (DEFAULT_MAPWITHAI_API.equals(url) || DEFAULT_MAPWITHAI_API_BUILDING.equals(url)) {
map.putIfAbsent(SOURCE_STRING, MapWithAIPlugin.NAME);
}
if (DEFAULT_MAPWITHAI_API_BUILDING.equals(url)) {
map.putIfAbsent(ENABLED_STRING, Boolean.toString(ExpertToggleAction.isExpert()));
} else if (DEFAULT_MAPWITHAI_API.equals(url)) {
map.putIfAbsent(ENABLED_STRING, Boolean.toString(!ExpertToggleAction.isExpert()));
} else {
map.putIfAbsent(SOURCE_STRING, url);
map.putIfAbsent(ENABLED_STRING, Boolean.FALSE.toString());
}
});
return returnMap;
}
/**
@ -67,8 +108,7 @@ public final class MapWithAIPreferenceHelper {
*/
public static int getMaximumAddition() {
final MapWithAILayer mapWithAILayer = MapWithAIDataUtils.getLayer(false);
Integer defaultReturn = Config.getPref().getInt(MAXIMUMSELECTION,
getDefaultMaximumAddition());
Integer defaultReturn = Config.getPref().getInt(MAXIMUMSELECTION, getDefaultMaximumAddition());
if (mapWithAILayer != null && mapWithAILayer.getMaximumAddition() != null) {
defaultReturn = mapWithAILayer.getMaximumAddition();
}
@ -98,24 +138,31 @@ public final class MapWithAIPreferenceHelper {
/**
* Set the MapWithAI url
*
* @param source The source tag for the url
* @param url The url to set as the default
* @param enabled {@code true} if the url should be used for downloads
* @param permanent {@code true} if we want the setting to persist between
* sessions
*/
public static void setMapWithAIUrl(String url, boolean permanent) {
public static void setMapWithAIUrl(String source, String url, boolean enabled, boolean permanent) {
final MapWithAILayer layer = MapWithAIDataUtils.getLayer(false);
String setUrl = url;
if (permanent) {
final List<String> urls = new ArrayList<>(getMapWithAIURLs());
if (!urls.contains(url)) {
urls.add(url);
setMapWithAIURLs(urls);
}
if (DEFAULT_MAPWITHAI_API.equals(url)) {
setUrl = "";
}
Config.getPref().put(MapWithAIPlugin.NAME.concat(".current_api"), setUrl);
} else if (layer != null) {
final List<Map<String, String>> urls = new ArrayList<>(getMapWithAIURLs());
Map<String, String> addOrModifyMap = urls.parallelStream()
.filter(map -> map.getOrDefault(URL_STRING, "").equals(url)).findFirst().orElse(new TreeMap<>());
if (addOrModifyMap.isEmpty()) {
urls.add(addOrModifyMap);
} else {
urls.remove(addOrModifyMap);
addOrModifyMap = new TreeMap<>(addOrModifyMap);
urls.add(addOrModifyMap);
}
addOrModifyMap.put(URL_STRING, url);
addOrModifyMap.put(SOURCE_STRING, source);
addOrModifyMap.put(ENABLED_STRING, Boolean.toString(permanent));
setMapWithAIURLs(urls);
if (layer != null && !permanent && enabled) {
layer.setMapWithAIUrl(setUrl);
}
}
@ -124,9 +171,21 @@ public final class MapWithAIPreferenceHelper {
* Set the MapWithAI urls
*
* @param urls A list of URLs
* @return true if the configuration changed
*/
public static void setMapWithAIURLs(List<String> urls) {
Config.getPref().putList(MapWithAIPlugin.NAME.concat(".apis"), urls);
public static boolean setMapWithAIURLs(List<Map<String, String>> urls) {
List<Map<String, String>> setUrls = urls;
if (urls.isEmpty()) {
TreeMap<String, String> defaultAPIMap = new TreeMap<>();
TreeMap<String, String> defaultBuildingAPIMap = new TreeMap<>();
defaultAPIMap.put(URL_STRING, DEFAULT_MAPWITHAI_API);
defaultAPIMap.put(ENABLED_STRING, Boolean.TRUE.toString());
defaultAPIMap.put(SOURCE_STRING, MapWithAIPlugin.NAME);
defaultBuildingAPIMap.put(URL_STRING, DEFAULT_MAPWITHAI_API_BUILDING);
defaultBuildingAPIMap.put(ENABLED_STRING, Boolean.TRUE.toString());
defaultBuildingAPIMap.put(SOURCE_STRING, MapWithAIPlugin.NAME);
}
return Config.getPref().putListOfMaps(API_MAP_CONFIG, setUrls);
}
/**

Wyświetl plik

@ -24,12 +24,14 @@ public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHan
private Integer maxObj;
private Boolean switchLayer;
private String url;
private String source;
private static final String MAX_OBJ = "max_obj";
private static final String SWITCH_LAYER = "switch_layer";
private static final String BBOX = "bbox";
private static final String CROP_BBOX = "crop_bbox";
private static final String URL_STRING = "url";
private static final String SOURCE_STRING = "source";
public MapWithAIRemoteControl() {
super();
@ -53,6 +55,9 @@ public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHan
// Ensure the URL_STRING is valid
url = new URL(urlString).toString();
}
if (args.containsKey(SOURCE_STRING)) {
source = args.get(SOURCE_STRING);
}
if (args.containsKey(SWITCH_LAYER)) {
switchLayer = Boolean.parseBoolean(args.get(SWITCH_LAYER));
}
@ -92,7 +97,9 @@ public class MapWithAIRemoteControl extends RequestHandler.RawURLParseRequestHan
MapWithAIPreferenceHelper.setMaximumAddition(maxObj, false);
}
if (url != null) {
MapWithAIPreferenceHelper.setMapWithAIUrl(url, false);
// TODO make option for permanent url
String tSource = source == null ? url : source;
MapWithAIPreferenceHelper.setMapWithAIUrl(url, tSource, true, false);
}
if (switchLayer != null) {
MapWithAIPreferenceHelper.setSwitchLayers(switchLayer, false);

Wyświetl plik

@ -2,6 +2,7 @@
package org.openstreetmap.josm.plugins.mapwithai.backend;
import java.util.Map;
import java.util.stream.Collectors;
import org.openstreetmap.josm.actions.UploadAction;
import org.openstreetmap.josm.actions.upload.UploadHook;
@ -34,12 +35,16 @@ public class MapWithAIUploadHook implements UploadHook, Destroyable {
if (DetectTaskingManagerUtils.hasTaskingManagerLayer()) {
sb.append(";task=").append(DetectTaskingManagerUtils.getTaskingManagerBBox().toStringCSV(","));
}
if (!MapWithAIPreferenceHelper.getMapWithAIUrl()
.equalsIgnoreCase(MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API)) {
sb.append(";url=").append(MapWithAIPreferenceHelper.getMapWithAIUrl());
if (MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream().anyMatch(
map -> !MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API.equalsIgnoreCase(map.get("url")))) {
sb.append(";url=")
.append(String.join(";url=",
MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.filter(map -> map.containsKey("url")).map(map -> map.get("url"))
.filter(url -> !MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API.equalsIgnoreCase(url))
.collect(Collectors.toList())));
}
tags.put("mapwithai:options", sb.toString());
}
}

Wyświetl plik

@ -1,6 +1,7 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.event.ActionEvent;
@ -31,7 +32,7 @@ public class MergeDuplicateWaysAction extends JosmAction {
tr(DESCRIPTION), KeyEvent.VK_EXCLAMATION_MARK,
Shortcut.ALT_CTRL_SHIFT),
true);
setHelpId(ht("Plugin/MapWithAI"));
}
@Override

Wyświetl plik

@ -0,0 +1,47 @@
package org.openstreetmap.josm.plugins.mapwithai.backend.commands.conflation;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class DataUrl {
private List<Object> dataList;
public DataUrl(String source, String url, Boolean enabled) {
this(source, url, enabled, Collections.emptyMap());
}
public DataUrl(String source, String url, Boolean enabled, Map<String, Map<String, Boolean>> parameters) {
setDataList(Arrays.asList(source, url, enabled, parameters));
}
/**
* @return the dataList (source, url, enabled)
*/
public List<Object> getDataList() {
return dataList;
}
/**
* @param dataList the dataList to set
*/
public void setDataList(List<Object> dataList) {
if (this.dataList == null || dataList != null && dataList.size() == this.dataList.size()) {
this.dataList = dataList;
}
}
public void reset() {
dataList = Arrays.asList("", "", false);
}
public Map<String, String> getMap() {
Map<String, String> map = new TreeMap<>();
map.put("source", dataList.get(0).toString());
map.put("url", dataList.get(1).toString());
map.put("enabled", dataList.get(2).toString());
return map;
}
}

Wyświetl plik

@ -69,8 +69,6 @@ public class MapWithAIPreferencesTest {
Assert.assertNotEquals(spinnerModel.getNumber().intValue(), MapWithAIPreferenceHelper.getMaximumAddition());
preferences.ok();
Assert.assertEquals(spinnerModel.getNumber().intValue(), MapWithAIPreferenceHelper.getMaximumAddition());
Assert.assertNotNull(preferences.getPossibleMapWithAIApiUrl().getSelectedItem());
}
/**

Wyświetl plik

@ -7,7 +7,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
@ -28,6 +30,7 @@ import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
import org.openstreetmap.josm.gui.mappaint.StyleSource;
import org.openstreetmap.josm.testutils.JOSMTestRules;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -39,12 +42,23 @@ public class MapWithAIDataUtilsTest {
@Rule
public WireMockRule wireMockRule = new WireMockRule(options().usingFilesUnderDirectory("test/resources/wiremock"));
WireMockServer wireMockServer;
@Before
public void setUp() {
String URL = MapWithAIPreferenceHelper.getMapWithAIUrl().replace("https://www.facebook.com",
wireMockRule.baseUrl());
MapWithAIPreferenceHelper.setMapWithAIUrl(URL, true);
MapWithAIPreferenceHelper.setMapWithAIURLs(MapWithAIPreferenceHelper.getMapWithAIURLs().stream().map(map -> {
map.put("url", getDefaultMapWithAIAPIForTest(
map.getOrDefault("url", MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API_BUILDING)));
return map;
}).collect(Collectors.toList()));
}
private String getDefaultMapWithAIAPIForTest(String url) {
return getDefaultMapWithAIAPIForTest(url, "https://www.facebook.com");
}
private String getDefaultMapWithAIAPIForTest(String url, String wireMockReplace) {
return url.replace(wireMockReplace, wireMockRule.baseUrl());
}
/**
@ -140,20 +154,26 @@ public class MapWithAIDataUtilsTest {
@Test
public void testMapWithAIURLPreferences() {
final String fakeUrl = "https://fake.url";
Assert.assertNotEquals(fakeUrl, MapWithAIPreferenceHelper.getMapWithAIUrl());
MapWithAIPreferenceHelper.setMapWithAIUrl(fakeUrl, true);
Assert.assertEquals(fakeUrl, MapWithAIPreferenceHelper.getMapWithAIUrl());
final List<String> urls = new ArrayList<>(MapWithAIPreferenceHelper.getMapWithAIURLs());
Assert.assertEquals(3, urls.size());
MapWithAIPreferenceHelper.setMapWithAIUrl(MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API, true);
Assert.assertEquals(MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API,
MapWithAIPreferenceHelper.getMapWithAIUrl());
MapWithAIPreferenceHelper.setMapWithAIUrl(fakeUrl, true);
Assert.assertEquals(fakeUrl, MapWithAIPreferenceHelper.getMapWithAIUrl());
urls.remove(fakeUrl);
MapWithAIPreferenceHelper.setMapWithAIURLs(urls);
Assert.assertEquals(MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API,
MapWithAIPreferenceHelper.getMapWithAIUrl());
Assert.assertTrue(MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.noneMatch(map -> fakeUrl.equals(map.get("url"))));
MapWithAIPreferenceHelper.setMapWithAIUrl("Fake", fakeUrl, true, true);
Assert.assertTrue(MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.anyMatch(map -> fakeUrl.equals(map.get("url"))));
final List<Map<String, String>> urls = new ArrayList<>(MapWithAIPreferenceHelper.getMapWithAIURLs());
Assert.assertEquals(2, urls.size());
MapWithAIPreferenceHelper.setMapWithAIUrl("MapWithAI", MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API, true,
true);
Assert.assertTrue(MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.anyMatch(map -> MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API.equals(map.get("url"))));
MapWithAIPreferenceHelper.setMapWithAIUrl("Fake2", fakeUrl, true, true);
Assert.assertEquals(1, MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.filter(map -> fakeUrl.equals(map.get("url"))).count());
MapWithAIPreferenceHelper.setMapWithAIURLs(urls.parallelStream()
.filter(map -> !fakeUrl.equalsIgnoreCase(map.getOrDefault("url", ""))).collect(Collectors.toList()));
Assert.assertEquals(1, MapWithAIPreferenceHelper.getMapWithAIUrl().size());
Assert.assertTrue(MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.anyMatch(map -> getDefaultMapWithAIAPIForTest(MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API)
.equals(map.get("url"))));
}
@Test

Wyświetl plik

@ -10,6 +10,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.swing.JLabel;
import javax.swing.JPanel;
@ -53,9 +54,11 @@ public class MapWithAILayerTest {
@Before
public void setUp() {
String URL = MapWithAIPreferenceHelper.getMapWithAIUrl().replace("https://www.facebook.com",
wireMockRule.baseUrl());
MapWithAIPreferenceHelper.setMapWithAIUrl(URL, true);
MapWithAIPreferenceHelper.setMapWithAIURLs(MapWithAIPreferenceHelper.getMapWithAIURLs().stream().map(map -> {
map.put("url", map.getOrDefault("url", MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API)
.replace("https://www.facebook.com", wireMockRule.baseUrl()));
return map;
}).collect(Collectors.toList()));
layer = new MapWithAILayer(new DataSet(), "test", null);
}

Wyświetl plik

@ -5,6 +5,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
import static org.awaitility.Awaitility.await;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
@ -45,9 +46,13 @@ public class MapWithAIRemoteControlTest {
@Before
public void setUp() {
String URL = MapWithAIPreferenceHelper.getMapWithAIUrl().replace("https://www.facebook.com",
wireMockRule.baseUrl());
MapWithAIPreferenceHelper.setMapWithAIUrl(URL, true);
MapWithAIPreferenceHelper.setMapWithAIURLs(MapWithAIPreferenceHelper.getMapWithAIURLs().stream()
.map(map -> {
map.put("url",
map.getOrDefault("url", MapWithAIPreferenceHelper.DEFAULT_MAPWITHAI_API)
.replace("https://www.facebook.com", wireMockRule.baseUrl()));
return map;
}).collect(Collectors.toList()));
}
private static MapWithAIRemoteControl newHandler(String url) throws RequestHandlerBadRequestException {
@ -80,7 +85,8 @@ public class MapWithAIRemoteControlTest {
*/
@Test
public void testNominalRequest() throws Exception {
newHandler("https://localhost?url=" + Utils.encodeUrl(MapWithAIPreferenceHelper.getMapWithAIUrl())).handle();
newHandler("https://localhost?url="
+ Utils.encodeUrl(MapWithAIPreferenceHelper.getMapWithAIUrl().get(0).get("url"))).handle();
Assert.assertFalse(MainApplication.getLayerManager().getLayersOfType(MapWithAILayer.class).isEmpty());
Assert.assertTrue(MapWithAIDataUtils.getLayer(false).getDataSet().getDataSourceBounds().isEmpty());
@ -88,19 +94,20 @@ public class MapWithAIRemoteControlTest {
@Test
public void testTemporaryUrl() throws Exception {
String badUrl = "https://bad.url";
final String badUrl = "https://bad.url";
newHandler("https://localhost?url=" + Utils.encodeUrl(badUrl)).handle();
Assert.assertFalse(MainApplication.getLayerManager().getLayersOfType(MapWithAILayer.class).isEmpty());
Assert.assertEquals(badUrl, MapWithAIPreferenceHelper.getMapWithAIUrl());
Assert.assertTrue(MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream()
.anyMatch(map -> badUrl.equals(map.get("url"))));
MainApplication.getLayerManager().removeLayer(MapWithAIDataUtils.getLayer(false));
Assert.assertNotEquals(badUrl, MapWithAIPreferenceHelper.getMapWithAIUrl());
badUrl = "NothingToSeeHere";
final String badUrl2 = "NothingToSeeHere";
thrown.expect(RequestHandlerBadRequestException.class);
thrown.expectMessage("MalformedURLException: no protocol: " + badUrl);
thrown.expectMessage("MalformedURLException: no protocol: " + badUrl2);
newHandler("https://localhost?url=" + Utils.encodeUrl(badUrl)).handle();
newHandler("https://localhost?url=" + Utils.encodeUrl(badUrl2)).handle();
}
@Test

Wyświetl plik

@ -78,7 +78,7 @@ public class MapWithAIUploadHookTest {
Assert.assertTrue(
Arrays.asList(tags.get("mapwithai:options").split(";")).contains("version=".concat(info.localversion)));
MapWithAIPreferenceHelper.setMapWithAIUrl("false-url", false);
MapWithAIPreferenceHelper.setMapWithAIUrl("False URL", "false-url", true, true);
tags.clear();