com.liferay.ide.server.remote.RemoteLogStream.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.ide.server.remote.RemoteLogStream.java

Source

/*******************************************************************************
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 *******************************************************************************/

package com.liferay.ide.server.remote;

import com.liferay.ide.core.LiferayCore;
import com.liferay.ide.server.core.LiferayServerCore;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.commons.codec.binary.Base64;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.wst.server.core.IServer;

/**
 * @author Greg Amerson
 * @author Tao Tao
 * @author Simon Jiang
 */
public class RemoteLogStream extends BufferedInputStream {

    @SuppressWarnings("deprecation")
    public static final IEclipsePreferences _defaultPrefs = new DefaultScope().getNode(LiferayServerCore.PLUGIN_ID);

    public static final long LOG_QUERY_RANGE = _defaultPrefs.getLong("log.query.range", 51200); //$NON-NLS-1$

    public final static long OUTPUT_MONITOR_DELAY = _defaultPrefs.getLong("output.monitor.delay", 1000); //$NON-NLS-1$

    protected static URL createBaseUrl(IServer server, IRemoteServer remoteServer,
            IServerManagerConnection connection, String log) {
        try {
            return new URL(getLogURI(connection, log) + getFormatQuery());
        } catch (MalformedURLException e) {
        }

        return null;
    }

    protected static InputStream createInputStream(IServer server, IRemoteServer remoteServer,
            IServerManagerConnection connection, String log) {
        try {
            URL url = createBaseUrl(server, remoteServer, connection, log);

            return openInputStream(connection, url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    protected static String getFormatQuery() {
        return "?format=raw"; //$NON-NLS-1$
    }

    protected static String getLogURI(IServerManagerConnection connection, String log) {
        return connection.getManagerURI() + "/server/log/" + log; //$NON-NLS-1$
    }

    protected static InputStream openInputStream(IServerManagerConnection remote, URL url) throws IOException {
        String username = remote.getUsername();
        String password = remote.getPassword();

        String authString = username + ":" + password; //$NON-NLS-1$
        byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
        String authStringEnc = new String(authEncBytes);
        final IProxyService proxyService = LiferayCore.getProxyService();
        URLConnection conn = null;

        try {
            URI uri = new URI("HTTP://" + url.getHost() + ":" + url.getPort()); //$NON-NLS-1$ //$NON-NLS-2$
            IProxyData[] proxyDataForHost = proxyService.select(uri);

            for (IProxyData data : proxyDataForHost) {
                if (data.getHost() != null) {
                    System.setProperty("http.proxyHost", data.getHost()); //$NON-NLS-1$
                    System.setProperty("http.proxyPort", String.valueOf(data.getPort())); //$NON-NLS-1$

                    break;
                }
            }

            uri = new URI("SOCKS://" + url.getHost() + ":" + url.getPort()); //$NON-NLS-1$ //$NON-NLS-2$
            proxyDataForHost = proxyService.select(uri);

            for (IProxyData data : proxyDataForHost) {
                if (data.getHost() != null) {
                    System.setProperty("socksProxyHost", data.getHost()); //$NON-NLS-1$
                    System.setProperty("socksProxyPort", String.valueOf(data.getPort())); //$NON-NLS-1$

                    break;
                }
            }
        } catch (URISyntaxException e) {
            LiferayServerCore.logError("Could not read proxy data", e); //$NON-NLS-1$
        }

        conn = url.openConnection();
        conn.setRequestProperty("Authorization", "Basic " + authStringEnc); //$NON-NLS-1$ //$NON-NLS-2$
        Authenticator.setDefault(null);
        conn.setAllowUserInteraction(false);

        return conn.getInputStream();
    }

    protected URL baseUrl = null;

    protected IServerManagerConnection connection;

    protected String log;

    protected long range = 0;

    public RemoteLogStream(IServer server, IRemoteServer remoteServer, IServerManagerConnection connection,
            String log) {
        super(createInputStream(server, remoteServer, connection, log), 8192);
        this.baseUrl = createBaseUrl(server, remoteServer, connection, log);
        this.log = log;
        this.connection = connection;
    }

    @Override
    public int read(byte[] b) throws IOException {
        int read = super.read(b);

        if (read < 1) {
            waitOnNewInput();

            read = super.read(b);
        }
        range += read;
        return read;
    }

    @Override
    public synchronized int read(byte[] b, int off, int len) throws IOException {
        int read = super.read(b, off, len);

        if (read < 1) {
            waitOnNewInput();
            read = super.read(b, off, len);
        }
        range += read;
        return read;
    }

    protected void waitOnNewInput() throws IOException {
        // previous input stream was empty, so we need to move the range
        this.in.close();

        // peek at the new stream
        boolean goodUrl = false;

        while (!goodUrl) {
            URL newUrl = new URL(getLogURI(connection, log) + "/" + range + getFormatQuery()); //$NON-NLS-1$

            try {
                goodUrl = urlPeek(newUrl);
            } catch (Exception e) {
                // failed to get a new good url, try again next time
            }

            if (goodUrl) {
                this.in = openInputStream(connection, newUrl);
                return;
            }

            try {
                Thread.sleep(OUTPUT_MONITOR_DELAY);
            } catch (InterruptedException e) {
            }
        }
    }

    boolean urlPeek(URL url) throws IOException {
        byte[] buf = new byte[256];

        int bufRead = new BufferedInputStream(openInputStream(connection, url), 256).read(buf);

        if (bufRead != -1) {
            String peek = new String(buf);

            if (peek != null && (!peek.contains("Error 416: Invalid Range values."))) //$NON-NLS-1$
            {
                return true;
            }
        }

        return false;
    }
}