source: osm/applications/editors/josm/plugins/comfort0/src/net/simon04/comfort0/EditLevel0LAction.java@ 35304

Last change on this file since 35304 was 35304, checked in by donvip, 4 years ago

log exceptions

File size: 4.8 KB
Line 
1package net.simon04.comfort0;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.event.ActionEvent;
6import java.io.BufferedReader;
7import java.io.IOException;
8import java.nio.charset.Charset;
9import java.nio.file.Files;
10import java.nio.file.Path;
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.List;
14import java.util.Objects;
15
16import net.simon04.comfort0.level0l.parsergen.Level0LParser;
17import net.simon04.comfort0.level0l.parsergen.ParseException;
18import org.openstreetmap.josm.actions.JosmAction;
19import org.openstreetmap.josm.command.ChangePropertyCommand;
20import org.openstreetmap.josm.command.Command;
21import org.openstreetmap.josm.command.SequenceCommand;
22import org.openstreetmap.josm.data.UndoRedoHandler;
23import org.openstreetmap.josm.data.osm.DataSet;
24import org.openstreetmap.josm.data.osm.OsmPrimitive;
25import org.openstreetmap.josm.data.osm.PrimitiveData;
26import org.openstreetmap.josm.data.osm.RelationData;
27import org.openstreetmap.josm.data.osm.WayData;
28import org.openstreetmap.josm.gui.MainApplication;
29import org.openstreetmap.josm.gui.util.GuiHelper;
30import org.openstreetmap.josm.tools.Logging;
31
32/**
33 * Edit the selected objects in an external editor in the Level0L format.
34 */
35public class EditLevel0LAction extends JosmAction {
36
37 private static final Charset CHARSET = Charset.defaultCharset();
38
39 /**
40 * Constructs a new {@link EditLevel0LAction}.
41 */
42 public EditLevel0LAction() {
43 super(tr("Edit as Level0L"),
44 "theta",
45 tr("Edit the selected objects in an external editor in the Level0L format"),
46 null, false);
47 }
48
49 @Override
50 public void actionPerformed(ActionEvent e) {
51 try {
52 editLevel0();
53 } catch (Exception ex) {
54 Logging.error(ex);
55 }
56 }
57
58 private void editLevel0() throws IOException {
59 final DataSet dataSet = MainApplication.getLayerManager().getEditDataSet();
60 final Path path = writeLevel0(dataSet);
61 final Process editor = new EditorLauncher(path).launch();
62 Logging.info("Comfort0: Launching editor on file {0}", path);
63 new Thread(() -> awaitEditing(dataSet, path, editor), path.getFileName().toString()).start();
64 }
65
66 private Path writeLevel0(DataSet dataSet) throws IOException {
67 final byte[] level0 = new OsmToLevel0L().visit(dataSet.getSelected())
68 .toString()
69 .replace("\u200E", "")
70 .replace("\u200F", "")
71 .getBytes(CHARSET);
72 final Path path = Files.createTempFile("josm_level0_", ".txt");
73 Files.write(path, level0);
74 return path;
75 }
76
77 private void awaitEditing(DataSet dataSet, Path path, Process editor) {
78 try {
79 editor.waitFor();
80 Logging.info("Comfort0: Editing of file {0} done", path);
81 readLevel0(path, dataSet);
82 Files.delete(path);
83 } catch (Exception ex) {
84 Logging.error(ex);
85 }
86 }
87
88 private void readLevel0(Path path, final DataSet dataSet) throws IOException, ParseException {
89 final List<PrimitiveData> primitives;
90 try (BufferedReader reader = Files.newBufferedReader(path, CHARSET)) {
91 primitives = new Level0LParser(reader).primitives();
92 }
93 Logging.info("Comfort0: Reading file {0} yielded {1} primitives", path, primitives.size());
94
95 buildChangeCommands(dataSet, primitives);
96 }
97
98 private void buildChangeCommands(DataSet dataSet, List<PrimitiveData> primitives) {
99 final List<Command> commands = new ArrayList<>();
100 for (PrimitiveData fromLevel0L : primitives) {
101 final OsmPrimitive fromDataSet = dataSet.getPrimitiveById(fromLevel0L);
102
103 // TODO handle way nodes, relation members
104 if (fromLevel0L instanceof WayData) {
105 ((WayData) fromLevel0L).setNodeIds(Collections.emptyList());
106 } else if (fromLevel0L instanceof RelationData) {
107 ((RelationData) fromLevel0L).setMembers(Collections.emptyList());
108 }
109
110 final OsmPrimitive newInstance = fromLevel0L.getType().newVersionedInstance(fromDataSet.getUniqueId(), fromDataSet.getVersion());
111 newInstance.load(fromLevel0L);
112
113 final boolean equalKeys = Objects.equals(newInstance.getKeys(), fromDataSet.getKeys());
114 if (!equalKeys) {
115 final ChangePropertyCommand command = new ChangePropertyCommand(Collections.singleton(fromDataSet), newInstance.getKeys());
116 commands.add(command);
117 }
118 }
119
120 Logging.info("Comfort0: Changing {0} primitives", commands.size());
121 if (commands.isEmpty()) {
122 return;
123 }
124 final SequenceCommand command = new SequenceCommand("Comfort0", commands);
125 GuiHelper.runInEDT(() -> UndoRedoHandler.getInstance().add(command));
126 }
127}
Note: See TracBrowser for help on using the repository browser.