protected synchronized String readResponse()

in src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java [383:493]


    protected synchronized String readResponse(final boolean sendErrorAsResponse, long timeout)
            throws IOException {
        final StringBuilder response = new StringBuilder();
        final IOException[] exc = new IOException[1];
        final boolean[] done = new boolean[1];
        Runnable r = new Runnable() {
            public void run() {
                synchronized (VsftpRepository.this) {
                    try {
                        int c;
                        boolean getPrompt = false;
                        // the reading is done in a loop making five attempts to read the stream
                        // if we do not reach the next prompt
                        int attempt = 0;
                        while (!getPrompt && attempt < MAX_READ_PROMPT_ATTEMPT) {
                            while ((c = in.read()) != -1) {
                                // we managed to read something, reset number of attempts
                                attempt = 0;
                                response.append((char) c);
                                if (response.length() >= PROMPT.length()
                                        && response.substring(response.length() - PROMPT.length(),
                                            response.length()).equals(PROMPT)) {
                                    response.setLength(response.length() - PROMPT.length());
                                    getPrompt = true;
                                    break;
                                }
                            }
                            if (!getPrompt) {
                                try {
                                    Thread.sleep(PROMPT_SLEEP_TIME);
                                } catch (InterruptedException e) {
                                    break;
                                }
                            }
                            attempt++;
                        }
                        if (getPrompt) {
                            // wait enough for error stream to be fully read
                            if (errorsLastUpdateTime == 0) {
                                // no error written yet, but it may be pending...
                                errorsLastUpdateTime = lastCommand;
                            }

                            while ((System.currentTimeMillis() - errorsLastUpdateTime) < PROMPT_SLEEP_TIME) {
                                try {
                                    Thread.sleep(ERROR_SLEEP_TIME);
                                } catch (InterruptedException e) {
                                    break;
                                }
                            }
                        }
                        if (errors.length() > 0) {
                            if (sendErrorAsResponse) {
                                response.append(errors);
                                errors.setLength(0);
                            } else {
                                throw new IOException(chomp(errors).toString());
                            }
                        }
                        chomp(response);
                        done[0] = true;
                    } catch (IOException e) {
                        exc[0] = e;
                    } finally {
                        VsftpRepository.this.notify();
                    }
                }
            }
        };
        Thread reader = null;
        if (timeout == 0) {
            r.run();
        } else {
            reader = new IvyThread(r);
            reader.start();
            try {
                wait(timeout);
            } catch (InterruptedException e) {
                // nothing to do
            }
        }
        updateLastCommandTime();
        if (exc[0] != null) {
            throw exc[0];
        } else if (!done[0]) {
            if (reader != null && reader.isAlive()) {
                reader.interrupt();
                int attempt = 0;
                while (attempt < MAX_READER_ALIVE_ATTEMPT && reader.isAlive()) {
                    try {
                        Thread.sleep(READER_ALIVE_SLEEP_TIME);
                    } catch (InterruptedException e) {
                        break;
                    }
                    attempt++;
                }
                if (reader.isAlive()) {
                    reader.stop(); // no way to interrupt it non abruptly
                }
            }
            throw new IOException("connection timeout to " + getHost());
        } else {
            if ("Not connected.".equals(response.toString())) {
                Message.info("vsftp connection to " + getHost() + " reset");
                closeConnection();
                throw new IOException("not connected to " + getHost());
            }
            Message.debug("received response '" + response + "' from " + getHost());
            return response.toString();
        }
    }