Changeset 29273 in osm


Ignore:
Timestamp:
2013-02-21T23:35:15+01:00 (12 years ago)
Author:
donvip
Message:

[josm_commandline] fix #josm8442 - OSM objects parameter via stdin are not XML since 2 XML documents

Location:
applications/editors/josm/plugins/CommandLine
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/CommandLine/.project

    r25179 r29273  
    11<?xml version="1.0" encoding="UTF-8"?>
    22<projectDescription>
    3         <name>commandline</name>
     3        <name>JOSM-commandline</name>
    44        <comment></comment>
    55        <projects>
  • applications/editors/josm/plugins/CommandLine/build.xml

    r28666 r29273  
    44    <property name="commit.message" value="Moar bugfixes"/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="5459"/>
    7     <!--
    8       ************************************************
    9       ** should not be necessary to change the following properties
    10      -->
    11     <property name="josm" location="../../core/dist/josm-custom.jar"/>
    12     <property name="plugin.build.dir" value="build"/>
    13     <property name="plugin.src.dir" value="src"/>
    14     <!-- this is the directory where the plugin jar is copied to -->
    15     <property name="plugin.dist.dir" value="../../dist"/>
    16     <property name="ant.build.javac.target" value="1.5"/>
    17     <property name="plugin.dist.dir" value="../../dist"/>
    18     <property name="plugin.jar" value="${plugin.dist.dir}/${ant.project.name}.jar"/>
    19     <!--
    20     **********************************************************
    21     ** init - initializes the build
    22     **********************************************************
     6    <property name="plugin.main.version" value="5737"/>
     7
     8    <!-- Configure these properties (replace "..." accordingly).
     9         See http://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins
    2310    -->
    24     <target name="init">
    25         <mkdir dir="${plugin.build.dir}"/>
    26     </target>
    27     <!--
    28     **********************************************************
    29     ** compile - complies the source tree
    30     **********************************************************
    31     -->
    32     <target name="compile" depends="init">
    33         <echo message="compiling sources for  ${plugin.jar} ... "/>
    34         <javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
    35             <compilerarg value="-Xlint:deprecation"/>
    36             <compilerarg value="-Xlint:unchecked"/>
    37         </javac>
    38     </target>
    39     <!--
    40     **********************************************************
    41     ** dist - creates the plugin jar
    42     **********************************************************
    43     -->
    44     <target name="dist" depends="compile,revision">
    45         <echo message="creating ${ant.project.name}.jar ... "/>
    46         <copy todir="${plugin.build.dir}/resources">
    47             <fileset dir="resources"/>
    48         </copy>
    49         <copy todir="${plugin.build.dir}/images">
    50             <fileset dir="images"/>
    51         </copy>
    52         <copy todir="${plugin.build.dir}/data">
    53             <fileset dir="data"/>
    54         </copy>
    55         <copy todir="${plugin.build.dir}">
    56             <fileset dir=".">
    57                 <include name="README"/>
    58                 <include name="LICENSE"/>
    59             </fileset>
    60         </copy>
    61         <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    62             <!--
    63         ************************************************
    64         ** configure these properties. Most of them will be copied to the plugins
    65         ** manifest file. Property values will also show up in the list available
    66         ** plugins: http://josm.openstreetmap.de/wiki/Plugins.
    67         **
    68         ************************************************
    69     -->
    70             <manifest>
    71                 <attribute name="Author" value="Hind"/>
    72                 <attribute name="Plugin-Class" value="CommandLine.CommandLine"/>
    73                 <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
    74                 <attribute name="Plugin-Description" value="Implements a command line and enables to create your commands. See link for standard commands (arc, circle etc.)"/>
    75                 <attribute name="ru_Plugin-Description" value="Реализует командную строку с возможностью создания своих команд. Стандартные команды можно скачать по ссылке."/>
    76                 <attribute name="Plugin-Icon" value="images/commandline.png"/>
    77                 <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/CommandLine"/>
    78                 <attribute name="ru_Plugin-Link" value="http://wiki.openstreetmap.org/wiki/RU:JOSM/Plugins/CommandLine"/>
    79                 <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
    80                 <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    81             </manifest>
    82         </jar>
    83     </target>
    84     <!--
    85     **********************************************************
    86     ** revision - extracts the current revision number for the
    87     **    file build.number and stores it in the XML property
    88     **    version.*
    89     **********************************************************
    90     -->
    91     <target name="revision">
    92         <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
    93             <env key="LANG" value="C"/>
    94             <arg value="info"/>
    95             <arg value="--xml"/>
    96             <arg value="."/>
    97         </exec>
    98         <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
    99         <delete file="REVISION"/>
    100     </target>
    101     <!--
    102     **********************************************************
    103     ** clean - clean up the build environment
    104     **********************************************************
    105     -->
    106     <target name="clean">
    107         <delete dir="${plugin.build.dir}"/>
    108         <delete file="${plugin.jar}"/>
    109     </target>
    110     <!--
    111     **********************************************************
    112     ** install - install the plugin in your local JOSM installation
    113     **********************************************************
    114     -->
    115     <target name="install" depends="dist">
    116         <property environment="env"/>
    117         <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
    118             <and>
    119                 <os family="windows"/>
    120             </and>
    121         </condition>
    122         <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
    123     </target>
    124     <!--
    125     ************************** Publishing the plugin ***********************************
    126     -->
    127     <!--
    128         ** extracts the JOSM release for the JOSM version in ../core and saves it in the
    129         ** property ${coreversion.info.entry.revision}
    130         **
    131         -->
    132     <target name="core-info">
    133         <exec append="false" output="core.info.xml" executable="svn" failifexecutionfails="false">
    134             <env key="LANG" value="C"/>
    135             <arg value="info"/>
    136             <arg value="--xml"/>
    137             <arg value="../../core"/>
    138         </exec>
    139         <xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true"/>
    140         <echo>Building against core revision ${coreversion.info.entry.revision}.</echo>
    141         <echo>Plugin-Mainversion is set to ${plugin.main.version}.</echo>
    142         <delete file="core.info.xml"/>
    143     </target>
    144     <!--
    145         ** commits the source tree for this plugin
    146         -->
    147     <target name="commit-current">
    148         <echo>Commiting the plugin source with message '${commit.message}' ...</echo>
    149         <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
    150             <env key="LANG" value="C"/>
    151             <arg value="commit"/>
    152             <arg value="-m '${commit.message}'"/>
    153             <arg value="."/>
    154         </exec>
    155     </target>
    156     <!--
    157         ** updates (svn up) the source tree for this plugin
    158         -->
    159     <target name="update-current">
    160         <echo>Updating plugin source ...</echo>
    161         <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
    162             <env key="LANG" value="C"/>
    163             <arg value="up"/>
    164             <arg value="."/>
    165         </exec>
    166         <echo>Updating ${plugin.jar} ...</echo>
    167         <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
    168             <env key="LANG" value="C"/>
    169             <arg value="up"/>
    170             <arg value="../dist/${plugin.jar}"/>
    171         </exec>
    172     </target>
    173     <!--
    174         ** commits the plugin.jar
    175         -->
    176     <target name="commit-dist">
    177         <echo>
    178     ***** Properties of published ${plugin.jar} *****
    179     Commit message    : '${commit.message}'                   
    180     Plugin-Mainversion: ${plugin.main.version}
    181     JOSM build version: ${coreversion.info.entry.revision}
    182     Plugin-Version    : ${version.entry.commit.revision}
    183     ***** / Properties of published ${plugin.jar} *****                   
    184                        
    185     Now commiting ${plugin.jar} ...
    186     </echo>
    187         <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
    188             <env key="LANG" value="C"/>
    189             <arg value="-m '${commit.message}'"/>
    190             <arg value="commit"/>
    191             <arg value="${plugin.jar}"/>
    192         </exec>
    193     </target>
    194     <!-- ** make sure svn is present as a command line tool ** -->
    195     <target name="ensure-svn-present">
    196         <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
    197             <env key="LANG" value="C"/>
    198             <arg value="--version"/>
    199         </exec>
    200         <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
    201             <!-- return code not set at all? Most likely svn isn't installed -->
    202             <condition>
    203                 <not>
    204                     <isset property="svn.exit.code"/>
    205                 </not>
    206             </condition>
    207         </fail>
    208         <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
    209             <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
    210             <condition>
    211                 <isfailure code="${svn.exit.code}"/>
    212             </condition>
    213         </fail>
    214     </target>
    215     <target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
    216     </target>
     11    <property name="plugin.author" value="Hind"/>
     12    <property name="plugin.class" value="CommandLine.CommandLine"/>
     13    <property name="plugin.description" value="Implements a command line and enables to create your commands. See link for standard commands (arc, circle etc.)"/>
     14    <property name="plugin.icon" value="images/commandline.png"/>
     15    <property name="plugin.link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/CommandLine"/>
     16    <!--<property name="plugin.early" value="..."/>-->
     17    <!--<property name="plugin.requires" value="..."/>-->
     18    <!--<property name="plugin.stage" value="..."/>-->
     19
     20    <!-- ** include targets that all plugins have in common ** -->
     21    <import file="../build-common.xml"/>
     22
    21723</project>
  • applications/editors/josm/plugins/CommandLine/src/CommandLine/CommandLine.java

    r28618 r29273  
    3838import java.util.ArrayList;
    3939import java.util.Collection;
    40 import java.util.HashMap;
    4140import java.util.List;
    4241
     
    6665import org.openstreetmap.josm.plugins.Plugin;
    6766import org.openstreetmap.josm.plugins.PluginInformation;
     67import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    6868
    6969public class CommandLine extends Plugin {
    70         protected JTextField textField;
    71         protected JTextField historyField;
    72         private String prefix;
    73         private Mode mode;
    74         private ArrayList<Command> commands;
    75         private JMenu commandMenu;
    76         protected Command currentCommand;
    77         protected String commandSymbol;
    78         protected History history;
    79         protected MapFrame currentMapFrame;
    80         protected MapMode previousMode;
    81 
    82         static final String pluginDir = Main.pref.getPluginsDirectory().getAbsolutePath() + "/CommandLine/";
    83 
    84         public CommandLine(PluginInformation info) {
    85                 super(info);
    86                 commandSymbol = ": ";
    87                 history = new History(100);
    88                 historyField = new JTextField();
    89                 textField = new JTextField() {
    90                         @Override
    91                         protected void processKeyEvent(KeyEvent e) {
    92                                 if (e.getID() == KeyEvent.KEY_PRESSED) {
    93                                         String text = textField.getText();
    94                                         int code = e.getKeyCode();
    95                                         if (code == KeyEvent.VK_ENTER) {
    96                                                 String commandText = textField.getText().substring(prefix.length());
    97                                                 switch (mode) {
    98                                                 case IDLE:
    99                                                         if (commandText.isEmpty()) {
    100                                                                 commandText = history.getLastItem();
    101                                                         }
    102                                                         else {
    103                                                                 history.addItem(commandText);
    104                                                         }
    105                                                         Command command = findCommand(commandText, true);
    106                                                         if (command != null) {
    107                                                                 startCommand(command);
    108                                                         }
    109                                                         else
    110                                                                 setMode(Mode.IDLE);
    111                                                         break;
    112                                                 case SELECTION:
    113                                                         if (currentMapFrame.mapMode instanceof WayAction || currentMapFrame.mapMode instanceof NodeAction || currentMapFrame.mapMode instanceof RelationAction || currentMapFrame.mapMode instanceof AnyAction) {
    114                                                                 Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
    115                                                                 if (selected.size() > 0)
    116                                                                         loadParameter(selected, true);
    117                                                         }
    118                                                         else {
    119                                                                 loadParameter(commandText, currentCommand.parameters.get(currentCommand.currentParameterNum).maxInstances == 1);
    120                                                         }
    121                                                         break;
    122                                                 case ADJUSTMENT:
    123                                                         break;
    124                                                 }
    125                                                 e.consume();
    126                                         }
    127                                         else if (code == KeyEvent.VK_UP) {
    128                                                 textField.setText(prefix + history.getPrevItem());
    129                                                 e.consume();
    130                                         }
    131                                         else if (code == KeyEvent.VK_DOWN) {
    132                                                 textField.setText(prefix + history.getNextItem());
    133                                                 e.consume();
    134                                         }
    135                                         else if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
    136                                                 if (textField.getCaretPosition() <= prefix.length())
    137                                                         e.consume();
    138                                         }
    139                                         else if (code == KeyEvent.VK_HOME) {
    140                                                 setCaretPosition(prefix.length());
    141                                                 e.consume();
    142                                         }
    143                                         else if (code == KeyEvent.VK_ESCAPE) {
    144                                                 if (textField.getText().length() == prefix.length() && mode == Mode.IDLE)
    145                                                         deactivate();
    146                                                 else
    147                                                         endInput();
    148                                                 e.consume();
    149                                         }
    150                                         else if (code == KeyEvent.VK_DELETE || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_END) {
    151                                         }
    152                                         else {
    153                                                 e.consume();
    154                                         }
    155                                         if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
    156                                                 e.consume();
    157                                 }
    158                                 if (e.getID() == KeyEvent.KEY_TYPED)
    159                                         if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
    160                                                 e.consume();
    161                                 super.processKeyEvent(e);
    162                                 if (textField.getText().length() < prefix.length()) { // Safe
    163                                         setMode(mode);
    164                                 }
    165                                 if (e.getID() == KeyEvent.KEY_TYPED) {
    166                                         if (e.getKeyChar() > 'A' && e.getKeyChar() < 'z') {
    167                                                 Command command = findCommand(textField.getText().substring(prefix.length()), false);
    168                                                 if (command != null) {
    169                                                         int currentPos = textField.getSelectionStart() == 0 ? textField.getCaretPosition() : textField.getSelectionStart();
    170                                                         textField.setText(prefix + command.name);
    171                                                         textField.setCaretPosition(currentPos);
    172                                                         textField.select(currentPos, prefix.length() + command.name.length());
    173                                                 }
    174                                         }
    175                                 }
    176                         }
    177                         @Override
    178                         protected void processMouseEvent(MouseEvent e) {
    179                                 super.processMouseEvent(e);
    180                                 if (e.getButton() == MouseEvent.BUTTON1 && e.getID() == MouseEvent.MOUSE_RELEASED) {
    181                                         if (textField.getSelectionStart() > 0 && textField.getSelectionStart() < prefix.length())
    182                                                 textField.setSelectionStart(prefix.length());
    183                                         else if (textField.getCaretPosition() < prefix.length())
    184                                                 textField.setCaretPosition(prefix.length());
    185                                 }
    186                         }
    187                 };
    188 
    189                 if ( Main.main.menu != null ) {
    190                         commandMenu = Main.main.menu.addMenu(marktr("Commands") , KeyEvent.VK_M, Main.main.menu.defaultMenuPos, ht("/Plugin/CommandLine"));
    191                         MainMenu.add(Main.main.menu.toolsMenu, new CommandLineAction(this));
    192                 }
    193                 loadCommands();
    194                 setMode(Mode.IDLE);
    195         }
    196 
    197         public void startCommand(String commandName) {
    198                 Command command = findCommand(commandName, true);
    199                 if (command != null) {
    200                         startCommand(command);
    201                 }
    202         }
    203 
    204         protected void startCommand(Command command) {
    205                 if (Main.map == null)
    206                         return;
    207                 DataSet ds = Main.main.getCurrentDataSet();
    208                 if (ds == null)
    209                         return;
    210                 currentCommand = command;
    211                 currentCommand.resetLoading();
    212                 parseSelection(ds.getSelected());
    213                 if (!(Main.map.mapMode instanceof AnyAction || Main.map.mapMode instanceof DummyAction || Main.map.mapMode instanceof LengthAction || Main.map.mapMode instanceof NodeAction || Main.map.mapMode instanceof PointAction || Main.map.mapMode instanceof RelationAction || Main.map.mapMode instanceof WayAction)) {
    214                         previousMode = Main.map.mapMode;
    215                 }
    216                 if (currentCommand.currentParameterNum < currentCommand.parameters.size())
    217                         setMode(Mode.SELECTION);
    218                 else
    219                         runTool();
    220         }
    221 
    222         @Override
    223         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame)
    224         {
    225                 currentMapFrame = newFrame;
    226                 if (oldFrame == null && newFrame != null) {
    227                         JToolBar tb = new JToolBar();
    228                         tb.setLayout(new BorderLayout());
    229                         tb.setFloatable(false);
    230                         tb.setOrientation(JToolBar.HORIZONTAL);
    231                         tb.add(historyField, BorderLayout.NORTH);
    232                         tb.add(textField, BorderLayout.SOUTH);
    233                         currentMapFrame.add(tb, BorderLayout.NORTH);
    234                         printHistory("Loaded CommandLine, version " + getPluginInformation().version);
    235                 }
    236         }
    237 
    238         protected void printHistory(String text) {
    239                 historyField.setText(text);
    240         }
    241 
    242         private void loadCommands() {
    243                 commands = (new Loader(getPluginDir())).load();
    244                 for (Command command : commands) {
    245                         commandMenu.add(new CommandAction(command, this));
    246                 }
    247         }
    248 
    249         private Command findCommand(String text, boolean strict) {
    250                 for (int i = 0; i < commands.size(); i++) {
    251                         if (strict) {
    252                                 if ( commands.get(i).name.equalsIgnoreCase(text) ) {
    253                                         return commands.get(i);
    254                                 }
    255                         }
    256                         else {
    257                                 if ( commands.get(i).name.toLowerCase().startsWith( text.toLowerCase() ) && text.length() > 1 ) {
    258                                         return commands.get(i);
    259                                 }
    260                         }
    261                 }
    262                 return null;
    263         }
    264 
    265         protected void setMode(Mode targetMode) {
    266                 DataSet currentDataSet = Main.main.getCurrentDataSet();
    267                 if (currentDataSet != null) {
    268                         currentDataSet.clearSelection();
    269                         Main.map.mapView.repaint();
    270                 }
    271                 if (targetMode == Mode.IDLE) {
    272                         mode = Mode.IDLE;
    273                         currentCommand = null;
    274                         prefix = tr("Command") + commandSymbol;
    275                         textField.setText(prefix);
    276                 }
    277                 else if (targetMode == Mode.SELECTION) {
    278                         mode = Mode.SELECTION;
    279                         Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
    280                         prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
    281                         if (currentParameter.getRawValue() instanceof Relay)
    282                                 prefix = prefix + " (" + ((Relay)(currentParameter.getRawValue())).getOptionsString() + ")";
    283                         prefix += commandSymbol;
    284                         String value = currentParameter.getValue();
    285                         textField.setText(prefix + value);
    286                         Type currentType = currentParameter.type;
    287                         MapMode action = null;
    288                         switch (currentType) {
    289                         case POINT:
    290                                 action = new PointAction(currentMapFrame, this);
    291                                 break;
    292                         case WAY:
    293                                 action = new WayAction(currentMapFrame, this);
    294                                 break;
    295                         case NODE:
    296                                 action = new NodeAction(currentMapFrame, this);
    297                                 break;
    298                         case RELATION:
    299                                 action = new RelationAction(currentMapFrame, this);
    300                                 break;
    301                         case ANY:
    302                                 action = new AnyAction(currentMapFrame, this);
    303                                 break;
    304                         case LENGTH:
    305                                 action = new LengthAction(currentMapFrame, this);
    306                                 break;
    307                         case USERNAME:
    308                                 loadParameter(Main.pref.get("osm-server.username", null), true);
    309                                 action = new DummyAction(currentMapFrame, this);
    310                                 break;
    311                         case IMAGERYURL:
    312                                 Layer layer = Main.map.mapView.getActiveLayer();
    313                                 if (layer != null) {
    314                                         if (layer instanceof ImageryLayer) {
    315                                         }
    316                                         else {
    317                                                 List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
    318                                                 if (imageryLayers.size() == 1) {
    319                                                         layer = imageryLayers.get(0);
    320                                                 }
    321                                                 else {
    322                                                         endInput();
    323                                                         return;
    324                                                 }
    325                                         }
    326                                 }
    327                                 ImageryInfo info = ((ImageryLayer)layer).getInfo();
    328                                 String url = info.getUrl();
    329                                 String itype = info.getImageryType().getUrlString();
    330                                 loadParameter((url.equals("") ? itype : url), true);
    331                                 action = new DummyAction(currentMapFrame, this);
    332                                 break;
    333                         case IMAGERYOFFSET:
    334                                 Layer olayer = Main.map.mapView.getActiveLayer();
    335                                 if (olayer != null) {
    336                                         if (olayer instanceof ImageryLayer) {
    337                                         }
    338                                         else {
    339                                                 List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
    340                                                 if (imageryLayers.size() == 1) {
    341                                                         olayer = imageryLayers.get(0);
    342                                                 }
    343                                                 else {
    344                                                         endInput();
    345                                                         return;
    346                                                 }
    347                                         }
    348                                 }
    349                                 loadParameter((String.valueOf(((ImageryLayer)olayer).getDx()) + "," + String.valueOf(((ImageryLayer)olayer).getDy())), true);
    350                                 action = new DummyAction(currentMapFrame, this);
    351                                 break;
    352                         default:
    353                                 action = new DummyAction(currentMapFrame, this);
    354                                 break;
    355                         }
    356                         currentMapFrame.selectMapMode(action);
    357                         activate();
    358                         textField.select(prefix.length(), textField.getText().length());
    359                 }
    360                 else if (targetMode == Mode.PROCESSING) {
    361                         mode = Mode.PROCESSING;
    362                         prefix = tr("Processing...");
    363                         textField.setText(prefix);
    364                         Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    365                 }
    366         }
    367 
    368         public void activate() {
    369                 textField.requestFocus();
    370                 textField.setCaretPosition(textField.getText().length());
    371         }
    372 
    373         public void deactivate() {
    374                 Main.map.mapView.requestFocus();
    375         }
    376 
    377         public void abortInput() {
    378                 printHistory(tr("Aborted") + ".");
    379                 endInput();
    380         }
    381 
    382         public void endInput() {
    383                 setMode(Mode.IDLE);
    384                 Main.map.selectMapMode(previousMode);
    385                 Main.map.mapView.repaint();
    386         }
    387 
    388         public void loadParameter(Object obj, boolean next) {
    389                 if (currentCommand.loadObject(obj)) {
    390                         if (currentCommand.hasNextParameter()) {
    391                                 if (next) {
    392                                         Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
    393                                         String prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
    394                                         prefix += commandSymbol;
    395                                         String value = currentParameter.getValue();
    396                                         printHistory(prefix + value);
    397                                         currentCommand.nextParameter();
    398                                         setMode(Mode.SELECTION);
    399                                 }
    400                         }
    401                         else {
    402                                 runTool();
    403                         }
    404                 }
    405                 else {
    406                         System.out.println("Invalid argument");
    407                         endInput();
    408                 }
    409         }
    410 
    411         private void parseSelection(Collection<OsmPrimitive> selection) {
    412                 boolean ok = false;
    413                 for (OsmPrimitive obj : selection) {
    414                         ok = currentCommand.loadObject(obj);
    415                         if (!ok)
    416                                 break;
    417                 }
    418                 if (ok) {
    419                         currentCommand.nextParameter();
    420                 }
    421                 else {
    422                         currentCommand.resetLoading();
    423                 }
    424                 //System.out.println("Selected before " + String.valueOf(currentCommand.currentParameterNum) + "\n");
    425         }
    426 
    427         private class ToolProcess {
    428                 public Process process;
    429                 public volatile boolean running;
    430         }
    431 
    432         // Thanks to Upliner
    433         public void runTool() {
    434                 setMode(Mode.PROCESSING);
    435                 String commandToRun = currentCommand.run;
    436                 final boolean tracks = currentCommand.tracks;
    437                 final ArrayList<Parameter> parameters = currentCommand.parameters;
    438 
    439                 for (Parameter parameter : currentCommand.parameters) {
    440                         commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
    441                 }
    442                 for (Parameter parameter : currentCommand.optParameters) {
    443                         commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
    444                 }
    445                 String[] listToRun = commandToRun.split(" ");
    446 
    447                 // create the process
    448                 final Object syncObj = new Object();
    449 
    450                 ProcessBuilder builder;
    451                 builder = new ProcessBuilder(listToRun);
    452                 builder.directory(new File(getPluginDir()));
    453 
    454                 final StringBuilder debugstr = new StringBuilder();
    455 
    456                 // debug: print resulting cmdline
    457                 for (String s : builder.command())
    458                         debugstr.append(s + " ");
    459                 debugstr.append("\n");
    460                 System.out.print(debugstr.toString());
    461 
    462                 final ToolProcess tp = new ToolProcess();
    463                 try {
    464                         tp.process = builder.start();
    465                 } catch (final IOException e) {
    466                         e.printStackTrace();
    467                         synchronized (debugstr) {
    468                                 System.out.print(
    469                                                 tr("Error executing the script: ") +
    470                                                 debugstr.toString() + e.getMessage() + "\n" + e.getStackTrace());
    471                         }
    472                         return;
    473                 }
    474                 tp.running = true;
    475 
    476                 // redirect child process's stderr to JOSM stderr
    477                 new Thread(new Runnable() {
    478                         @Override
    479                         public void run() {
    480                                 try {
    481                                         byte[] buffer = new byte[1024];
    482                                         InputStream errStream = tp.process.getErrorStream();
    483                                         int len;
    484                                         while ((len = errStream.read(buffer)) > 0) {
    485                                                 synchronized (debugstr) {
    486                                                         debugstr.append(new String(buffer, 0, len));
    487                                                 }
    488                                                 System.err.write(buffer, 0, len);
    489                                         }
    490                                 } catch (IOException e) {
    491                                 }
    492                         }
    493                 }).start();
    494 
    495                 // Write stdin stream
    496                 Thread osmWriteThread = new Thread(new Runnable() {
    497                         @Override
    498                         public void run() {
    499                                 BBox bbox = null;
    500                                 final OutputStream outputStream = tp.process.getOutputStream();
    501                                 PrintWriter printWriter = null;
    502                                 try { printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8")); }
    503                                 catch (Exception e) {e.printStackTrace();}
    504                                 final OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(printWriter, true, null);
    505                                 Collection<OsmPrimitive> refObjects = currentCommand.getDepsObjects();
    506                                 Collection<OsmPrimitive> pObjects;
    507                                 osmWriter.header();
    508                                 for (OsmPrimitive primitive : refObjects) {
    509                                         if (primitive instanceof Node)
    510                                                 osmWriter.visit((Node)primitive);
    511                                         else if (primitive instanceof Way)
    512                                                 osmWriter.visit((Way)primitive);
    513                                         else if (primitive instanceof Relation)
    514                                                 osmWriter.visit((Relation)primitive);
    515                                         if (bbox == null)
    516                                                 bbox = new BBox(primitive.getBBox());
    517                                         else
    518                                                 bbox.addPrimitive(primitive, 0.0);
    519                                 }
    520                                 osmWriter.footer();
    521                                 osmWriter.flush();
    522                                 for (Parameter parameter : parameters) {
    523                                         if (!parameter.isOsm())
    524                                                 continue;
    525                                         osmWriter.header();
    526                                         pObjects = parameter.getParameterObjects();
    527                                         for (OsmPrimitive primitive : pObjects) {
    528                                                 if (primitive instanceof Node)
    529                                                         osmWriter.visit((Node)primitive);
    530                                                 else if (primitive instanceof Way)
    531                                                         osmWriter.visit((Way)primitive);
    532                                                 else if (primitive instanceof Relation)
    533                                                         osmWriter.visit((Relation)primitive);
    534                                                 if (bbox == null)
    535                                                         bbox = new BBox(primitive.getBBox());
    536                                                 else
    537                                                         bbox.addPrimitive(primitive, 0.0);
    538                                         }
    539                                         osmWriter.footer();
    540                                         osmWriter.flush();
    541                                 }
    542                                 if (tracks) {
    543                                         final GpxWriter gpxWriter = new GpxWriter(printWriter);
    544                                         GpxFilter gpxFilter = new GpxFilter();
    545                                         gpxFilter.initBboxFilter(bbox);
    546                                         List<GpxLayer> gpxLayers = Main.map.mapView.getLayersOfType(GpxLayer.class);
    547                                         for (GpxLayer gpxLayer : gpxLayers) {
    548                                                 gpxFilter.addGpxData(gpxLayer.data);
    549                                         }
    550                                         gpxWriter.write(gpxFilter.getGpxData());
    551                                 }
    552                                 osmWriter.close();
    553                                 synchronized (syncObj) {
    554                                         tp.running = false;
    555                                         syncObj.notifyAll();
    556                                 }
    557                         }
    558 
    559                 });
    560 
    561                 // Read stdout stream
    562                 final OsmToCmd osmToCmd = new OsmToCmd(this, Main.main.getCurrentDataSet());
    563                 Thread osmParseThread = new Thread(new Runnable() {
    564                         @Override
    565                         public void run() {
    566                                 try {
    567                                         String commandName = currentCommand.name;
    568                                         HashMap<Long, Long> inexiDMap = new HashMap<Long, Long>();
    569                                         final InputStream inputStream = tp.process.getInputStream();
    570                                         osmToCmd.parseStream(inputStream);
    571                                         final List<org.openstreetmap.josm.command.Command> cmdlist = osmToCmd.getCommandList();
    572                                         if (!cmdlist.isEmpty()) {
    573                                                 SequenceCommand cmd = new SequenceCommand(commandName, cmdlist);
    574                                                 Main.main.undoRedo.add(cmd);
    575                                         }
    576                                 }
    577                                 catch (Exception e) {}
    578                                 finally {
    579                                         synchronized (syncObj) {
    580                                                 tp.running = false;
    581                                                 syncObj.notifyAll();
    582                                         }
    583                                 }
    584                         }
    585 
    586                 });
    587 
    588                 osmParseThread.start();
    589                 osmWriteThread.start();
    590 
    591                 synchronized (syncObj) {
    592                         try {
    593                                 syncObj.wait(10000);
    594                         } catch (InterruptedException e) {
    595                         }
    596                 }
    597                 if (tp.running) {
    598                         new Thread(new PleaseWaitRunnable(currentCommand.name) {
    599                                 @Override
    600                                 protected void realRun() {
    601                                         try {
    602                                                 progressMonitor.indeterminateSubTask(null);
    603                                                 synchronized (syncObj) {
    604                                                         if (tp.running)
    605                                                                 syncObj.wait();
    606                                                 }
    607                                         } catch (InterruptedException e) {
    608                                         }
    609                                 }
    610 
    611                                 @Override
    612                                 protected void cancel() {
    613                                         synchronized (syncObj) {
    614                                                 tp.running = false;
    615                                                 tp.process.destroy();
    616                                                 syncObj.notifyAll();
    617                                                 endInput();
    618                                         }
    619                                 }
    620 
    621                                 @Override
    622                                 protected void finish() {
    623                                 }
    624                         }).start();
    625                 }
    626                 endInput();
    627         }
     70    protected JTextField textField;
     71    protected JTextField historyField;
     72    private String prefix;
     73    private Mode mode;
     74    private ArrayList<Command> commands;
     75    private JMenu commandMenu;
     76    protected Command currentCommand;
     77    protected String commandSymbol;
     78    protected History history;
     79    protected MapFrame currentMapFrame;
     80    protected MapMode previousMode;
     81
     82    static final String pluginDir = Main.pref.getPluginsDirectory().getAbsolutePath() + "/CommandLine/";
     83
     84    @SuppressWarnings("serial")
     85    public CommandLine(PluginInformation info) {
     86        super(info);
     87        commandSymbol = ": ";
     88        history = new History(100);
     89        historyField = new JTextField();
     90        textField = new JTextField() {
     91            @Override
     92            protected void processKeyEvent(KeyEvent e) {
     93                if (e.getID() == KeyEvent.KEY_PRESSED) {
     94                    //String text = textField.getText();
     95                    int code = e.getKeyCode();
     96                    if (code == KeyEvent.VK_ENTER) {
     97                        String commandText = textField.getText().substring(prefix.length());
     98                        switch (mode) {
     99                        case IDLE:
     100                            if (commandText.isEmpty()) {
     101                                commandText = history.getLastItem();
     102                            }
     103                            else {
     104                                history.addItem(commandText);
     105                            }
     106                            Command command = findCommand(commandText, true);
     107                            if (command != null) {
     108                                startCommand(command);
     109                            }
     110                            else
     111                                setMode(Mode.IDLE);
     112                            break;
     113                        case SELECTION:
     114                            if (currentMapFrame.mapMode instanceof WayAction || currentMapFrame.mapMode instanceof NodeAction || currentMapFrame.mapMode instanceof RelationAction || currentMapFrame.mapMode instanceof AnyAction) {
     115                                Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
     116                                if (selected.size() > 0)
     117                                    loadParameter(selected, true);
     118                            }
     119                            else {
     120                                loadParameter(commandText, currentCommand.parameters.get(currentCommand.currentParameterNum).maxInstances == 1);
     121                            }
     122                            break;
     123                        case ADJUSTMENT:
     124                            break;
     125                        }
     126                        e.consume();
     127                    }
     128                    else if (code == KeyEvent.VK_UP) {
     129                        textField.setText(prefix + history.getPrevItem());
     130                        e.consume();
     131                    }
     132                    else if (code == KeyEvent.VK_DOWN) {
     133                        textField.setText(prefix + history.getNextItem());
     134                        e.consume();
     135                    }
     136                    else if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
     137                        if (textField.getCaretPosition() <= prefix.length())
     138                            e.consume();
     139                    }
     140                    else if (code == KeyEvent.VK_HOME) {
     141                        setCaretPosition(prefix.length());
     142                        e.consume();
     143                    }
     144                    else if (code == KeyEvent.VK_ESCAPE) {
     145                        if (textField.getText().length() == prefix.length() && mode == Mode.IDLE)
     146                            deactivate();
     147                        else
     148                            endInput();
     149                        e.consume();
     150                    }
     151                    else if (code == KeyEvent.VK_DELETE || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_END) {
     152                    }
     153                    else {
     154                        e.consume();
     155                    }
     156                    if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
     157                        e.consume();
     158                }
     159                if (e.getID() == KeyEvent.KEY_TYPED)
     160                    if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
     161                        e.consume();
     162                super.processKeyEvent(e);
     163                if (textField.getText().length() < prefix.length()) { // Safe
     164                    setMode(mode);
     165                }
     166                if (e.getID() == KeyEvent.KEY_TYPED) {
     167                    if (e.getKeyChar() > 'A' && e.getKeyChar() < 'z') {
     168                        Command command = findCommand(textField.getText().substring(prefix.length()), false);
     169                        if (command != null) {
     170                            int currentPos = textField.getSelectionStart() == 0 ? textField.getCaretPosition() : textField.getSelectionStart();
     171                            textField.setText(prefix + command.name);
     172                            textField.setCaretPosition(currentPos);
     173                            textField.select(currentPos, prefix.length() + command.name.length());
     174                        }
     175                    }
     176                }
     177            }
     178            @Override
     179            protected void processMouseEvent(MouseEvent e) {
     180                super.processMouseEvent(e);
     181                if (e.getButton() == MouseEvent.BUTTON1 && e.getID() == MouseEvent.MOUSE_RELEASED) {
     182                    if (textField.getSelectionStart() > 0 && textField.getSelectionStart() < prefix.length())
     183                        textField.setSelectionStart(prefix.length());
     184                    else if (textField.getCaretPosition() < prefix.length())
     185                        textField.setCaretPosition(prefix.length());
     186                }
     187            }
     188        };
     189
     190        if ( Main.main.menu != null ) {
     191            commandMenu = Main.main.menu.addMenu(marktr("Commands") , KeyEvent.VK_M, Main.main.menu.defaultMenuPos, ht("/Plugin/CommandLine"));
     192            MainMenu.add(Main.main.menu.toolsMenu, new CommandLineAction(this));
     193        }
     194        loadCommands();
     195        setMode(Mode.IDLE);
     196    }
     197
     198    public void startCommand(String commandName) {
     199        Command command = findCommand(commandName, true);
     200        if (command != null) {
     201            startCommand(command);
     202        }
     203    }
     204
     205    protected void startCommand(Command command) {
     206        if (Main.map == null)
     207            return;
     208        DataSet ds = Main.main.getCurrentDataSet();
     209        if (ds == null)
     210            return;
     211        currentCommand = command;
     212        currentCommand.resetLoading();
     213        parseSelection(ds.getSelected());
     214        if (!(Main.map.mapMode instanceof AnyAction || Main.map.mapMode instanceof DummyAction || Main.map.mapMode instanceof LengthAction || Main.map.mapMode instanceof NodeAction || Main.map.mapMode instanceof PointAction || Main.map.mapMode instanceof RelationAction || Main.map.mapMode instanceof WayAction)) {
     215            previousMode = Main.map.mapMode;
     216        }
     217        if (currentCommand.currentParameterNum < currentCommand.parameters.size())
     218            setMode(Mode.SELECTION);
     219        else
     220            runTool();
     221    }
     222
     223    @Override
     224    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame)
     225    {
     226        currentMapFrame = newFrame;
     227        if (oldFrame == null && newFrame != null) {
     228            JToolBar tb = new JToolBar();
     229            tb.setLayout(new BorderLayout());
     230            tb.setFloatable(false);
     231            tb.setOrientation(JToolBar.HORIZONTAL);
     232            tb.add(historyField, BorderLayout.NORTH);
     233            tb.add(textField, BorderLayout.SOUTH);
     234            currentMapFrame.add(tb, BorderLayout.NORTH);
     235            printHistory("Loaded CommandLine, version " + getPluginInformation().version);
     236        }
     237    }
     238
     239    protected void printHistory(String text) {
     240        historyField.setText(text);
     241    }
     242
     243    private void loadCommands() {
     244        commands = (new Loader(getPluginDir())).load();
     245        for (Command command : commands) {
     246            commandMenu.add(new CommandAction(command, this));
     247        }
     248    }
     249
     250    private Command findCommand(String text, boolean strict) {
     251        for (int i = 0; i < commands.size(); i++) {
     252            if (strict) {
     253                if ( commands.get(i).name.equalsIgnoreCase(text) ) {
     254                    return commands.get(i);
     255                }
     256            }
     257            else {
     258                if ( commands.get(i).name.toLowerCase().startsWith( text.toLowerCase() ) && text.length() > 1 ) {
     259                    return commands.get(i);
     260                }
     261            }
     262        }
     263        return null;
     264    }
     265
     266    protected void setMode(Mode targetMode) {
     267        DataSet currentDataSet = Main.main.getCurrentDataSet();
     268        if (currentDataSet != null) {
     269            currentDataSet.clearSelection();
     270            Main.map.mapView.repaint();
     271        }
     272        if (targetMode == Mode.IDLE) {
     273            mode = Mode.IDLE;
     274            currentCommand = null;
     275            prefix = tr("Command") + commandSymbol;
     276            textField.setText(prefix);
     277        }
     278        else if (targetMode == Mode.SELECTION) {
     279            mode = Mode.SELECTION;
     280            Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
     281            prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
     282            if (currentParameter.getRawValue() instanceof Relay)
     283                prefix = prefix + " (" + ((Relay)(currentParameter.getRawValue())).getOptionsString() + ")";
     284            prefix += commandSymbol;
     285            String value = currentParameter.getValue();
     286            textField.setText(prefix + value);
     287            Type currentType = currentParameter.type;
     288            MapMode action = null;
     289            switch (currentType) {
     290            case POINT:
     291                action = new PointAction(currentMapFrame, this);
     292                break;
     293            case WAY:
     294                action = new WayAction(currentMapFrame, this);
     295                break;
     296            case NODE:
     297                action = new NodeAction(currentMapFrame, this);
     298                break;
     299            case RELATION:
     300                action = new RelationAction(currentMapFrame, this);
     301                break;
     302            case ANY:
     303                action = new AnyAction(currentMapFrame, this);
     304                break;
     305            case LENGTH:
     306                action = new LengthAction(currentMapFrame, this);
     307                break;
     308            case USERNAME:
     309                loadParameter(Main.pref.get("osm-server.username", null), true);
     310                action = new DummyAction(currentMapFrame, this);
     311                break;
     312            case IMAGERYURL:
     313                Layer layer = Main.map.mapView.getActiveLayer();
     314                if (layer != null) {
     315                    if (layer instanceof ImageryLayer) {
     316                    }
     317                    else {
     318                        List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
     319                        if (imageryLayers.size() == 1) {
     320                            layer = imageryLayers.get(0);
     321                        }
     322                        else {
     323                            endInput();
     324                            return;
     325                        }
     326                    }
     327                }
     328                ImageryInfo info = ((ImageryLayer)layer).getInfo();
     329                String url = info.getUrl();
     330                String itype = info.getImageryType().getUrlString();
     331                loadParameter((url.equals("") ? itype : url), true);
     332                action = new DummyAction(currentMapFrame, this);
     333                break;
     334            case IMAGERYOFFSET:
     335                Layer olayer = Main.map.mapView.getActiveLayer();
     336                if (olayer != null) {
     337                    if (olayer instanceof ImageryLayer) {
     338                    }
     339                    else {
     340                        List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
     341                        if (imageryLayers.size() == 1) {
     342                            olayer = imageryLayers.get(0);
     343                        }
     344                        else {
     345                            endInput();
     346                            return;
     347                        }
     348                    }
     349                }
     350                loadParameter((String.valueOf(((ImageryLayer)olayer).getDx()) + "," + String.valueOf(((ImageryLayer)olayer).getDy())), true);
     351                action = new DummyAction(currentMapFrame, this);
     352                break;
     353            default:
     354                action = new DummyAction(currentMapFrame, this);
     355                break;
     356            }
     357            currentMapFrame.selectMapMode(action);
     358            activate();
     359            textField.select(prefix.length(), textField.getText().length());
     360        }
     361        else if (targetMode == Mode.PROCESSING) {
     362            mode = Mode.PROCESSING;
     363            prefix = tr("Processing...");
     364            textField.setText(prefix);
     365            Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
     366        }
     367    }
     368
     369    public void activate() {
     370        textField.requestFocus();
     371        textField.setCaretPosition(textField.getText().length());
     372    }
     373
     374    public void deactivate() {
     375        Main.map.mapView.requestFocus();
     376    }
     377
     378    public void abortInput() {
     379        printHistory(tr("Aborted") + ".");
     380        endInput();
     381    }
     382
     383    public void endInput() {
     384        setMode(Mode.IDLE);
     385        Main.map.selectMapMode(previousMode);
     386        Main.map.mapView.repaint();
     387    }
     388
     389    public void loadParameter(Object obj, boolean next) {
     390        if (currentCommand.loadObject(obj)) {
     391            if (currentCommand.hasNextParameter()) {
     392                if (next) {
     393                    Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
     394                    String prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
     395                    prefix += commandSymbol;
     396                    String value = currentParameter.getValue();
     397                    printHistory(prefix + value);
     398                    currentCommand.nextParameter();
     399                    setMode(Mode.SELECTION);
     400                }
     401            }
     402            else {
     403                runTool();
     404            }
     405        }
     406        else {
     407            System.out.println("Invalid argument");
     408            endInput();
     409        }
     410    }
     411
     412    private void parseSelection(Collection<OsmPrimitive> selection) {
     413        boolean ok = false;
     414        for (OsmPrimitive obj : selection) {
     415            ok = currentCommand.loadObject(obj);
     416            if (!ok)
     417                break;
     418        }
     419        if (ok) {
     420            currentCommand.nextParameter();
     421        }
     422        else {
     423            currentCommand.resetLoading();
     424        }
     425        //System.out.println("Selected before " + String.valueOf(currentCommand.currentParameterNum) + "\n");
     426    }
     427
     428    private class ToolProcess {
     429        public Process process;
     430        public volatile boolean running;
     431    }
     432
     433    // Thanks to Upliner
     434    public void runTool() {
     435        setMode(Mode.PROCESSING);
     436        String commandToRun = currentCommand.run;
     437        final boolean tracks = currentCommand.tracks;
     438        final ArrayList<Parameter> parameters = currentCommand.parameters;
     439
     440        for (Parameter parameter : currentCommand.parameters) {
     441            commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
     442        }
     443        for (Parameter parameter : currentCommand.optParameters) {
     444            commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
     445        }
     446        String[] listToRun = commandToRun.split(" ");
     447
     448        // create the process
     449        final Object syncObj = new Object();
     450
     451        ProcessBuilder builder;
     452        builder = new ProcessBuilder(listToRun);
     453        builder.directory(new File(getPluginDir()));
     454
     455        final StringBuilder debugstr = new StringBuilder();
     456
     457        // debug: print resulting cmdline
     458        for (String s : builder.command())
     459            debugstr.append(s + " ");
     460        debugstr.append("\n");
     461        System.out.print(debugstr.toString());
     462
     463        final ToolProcess tp = new ToolProcess();
     464        try {
     465            tp.process = builder.start();
     466        } catch (final IOException e) {
     467            e.printStackTrace();
     468            synchronized (debugstr) {
     469                System.out.print(
     470                        tr("Error executing the script: ") +
     471                        debugstr.toString() + e.getMessage() + "\n" + e.getStackTrace());
     472            }
     473            return;
     474        }
     475        tp.running = true;
     476
     477        // redirect child process's stderr to JOSM stderr
     478        new Thread(new Runnable() {
     479            @Override
     480            public void run() {
     481                try {
     482                    byte[] buffer = new byte[1024];
     483                    InputStream errStream = tp.process.getErrorStream();
     484                    int len;
     485                    while ((len = errStream.read(buffer)) > 0) {
     486                        synchronized (debugstr) {
     487                            debugstr.append(new String(buffer, 0, len));
     488                        }
     489                        System.err.write(buffer, 0, len);
     490                    }
     491                } catch (IOException e) {
     492                }
     493            }
     494        }).start();
     495
     496        // Write stdin stream
     497        Thread osmWriteThread = new Thread(new Runnable() {
     498            @Override
     499            public void run() {
     500                BBox bbox = null;
     501                final OutputStream outputStream = tp.process.getOutputStream();
     502                PrintWriter printWriter = null;
     503                try { printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8")); }
     504                catch (Exception e) {e.printStackTrace();}
     505                final OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(printWriter, true, null);
     506                Collection<OsmPrimitive> refObjects = currentCommand.getDepsObjects();
     507                Collection<OsmPrimitive> pObjects;
     508                osmWriter.header();
     509                Collection<OsmPrimitive> contents = new ArrayList<OsmPrimitive>();
     510                for (OsmPrimitive primitive : refObjects) {
     511                    contents.add(primitive);
     512                    if (bbox == null)
     513                        bbox = new BBox(primitive.getBBox());
     514                    else
     515                        bbox.addPrimitive(primitive, 0.0);
     516                }
     517                for (Parameter parameter : parameters) {
     518                    if (!parameter.isOsm())
     519                        continue;
     520                    pObjects = parameter.getParameterObjects();
     521                    for (OsmPrimitive primitive : pObjects) {
     522                        contents.add(primitive);
     523                        if (bbox == null)
     524                            bbox = new BBox(primitive.getBBox());
     525                        else
     526                            bbox.addPrimitive(primitive, 0.0);
     527                    }
     528                }
     529                osmWriter.writeNodes(new SubclassFilteredCollection<OsmPrimitive, Node>(contents, OsmPrimitive.nodePredicate));
     530                osmWriter.writeWays(new SubclassFilteredCollection<OsmPrimitive, Way>(contents, OsmPrimitive.wayPredicate));
     531                osmWriter.writeRelations(new SubclassFilteredCollection<OsmPrimitive, Relation>(contents, OsmPrimitive.relationPredicate));
     532                osmWriter.footer();
     533                osmWriter.flush();
     534                if (tracks) {
     535                    final GpxWriter gpxWriter = new GpxWriter(printWriter);
     536                    GpxFilter gpxFilter = new GpxFilter();
     537                    gpxFilter.initBboxFilter(bbox);
     538                    List<GpxLayer> gpxLayers = Main.map.mapView.getLayersOfType(GpxLayer.class);
     539                    for (GpxLayer gpxLayer : gpxLayers) {
     540                        gpxFilter.addGpxData(gpxLayer.data);
     541                    }
     542                    gpxWriter.write(gpxFilter.getGpxData());
     543                }
     544                osmWriter.close();
     545                synchronized (syncObj) {
     546                    tp.running = false;
     547                    syncObj.notifyAll();
     548                }
     549            }
     550
     551        });
     552
     553        // Read stdout stream
     554        final OsmToCmd osmToCmd = new OsmToCmd(this, Main.main.getCurrentDataSet());
     555        Thread osmParseThread = new Thread(new Runnable() {
     556            @Override
     557            public void run() {
     558                try {
     559                    String commandName = currentCommand.name;
     560                    //HashMap<Long, Long> inexiDMap = new HashMap<Long, Long>();
     561                    final InputStream inputStream = tp.process.getInputStream();
     562                    osmToCmd.parseStream(inputStream);
     563                    final List<org.openstreetmap.josm.command.Command> cmdlist = osmToCmd.getCommandList();
     564                    if (!cmdlist.isEmpty()) {
     565                        SequenceCommand cmd = new SequenceCommand(commandName, cmdlist);
     566                        Main.main.undoRedo.add(cmd);
     567                    }
     568                }
     569                catch (Exception e) {}
     570                finally {
     571                    synchronized (syncObj) {
     572                        tp.running = false;
     573                        syncObj.notifyAll();
     574                    }
     575                }
     576            }
     577
     578        });
     579
     580        osmParseThread.start();
     581        osmWriteThread.start();
     582
     583        synchronized (syncObj) {
     584            try {
     585                syncObj.wait(10000);
     586            } catch (InterruptedException e) {
     587            }
     588        }
     589        if (tp.running) {
     590            new Thread(new PleaseWaitRunnable(currentCommand.name) {
     591                @Override
     592                protected void realRun() {
     593                    try {
     594                        progressMonitor.indeterminateSubTask(null);
     595                        synchronized (syncObj) {
     596                            if (tp.running)
     597                                syncObj.wait();
     598                        }
     599                    } catch (InterruptedException e) {
     600                    }
     601                }
     602
     603                @Override
     604                protected void cancel() {
     605                    synchronized (syncObj) {
     606                        tp.running = false;
     607                        tp.process.destroy();
     608                        syncObj.notifyAll();
     609                        endInput();
     610                    }
     611                }
     612
     613                @Override
     614                protected void finish() {
     615                }
     616            }).start();
     617        }
     618        endInput();
     619    }
    628620}
Note: See TracChangeset for help on using the changeset viewer.