Java tutorial
/******************************************************************************* * 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; } }