| /* |
| * Copyright (c) 2008, 2009, 2011, 2012 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.net4j.internal.http; |
| |
| import org.eclipse.net4j.http.internal.common.HTTPConnector; |
| import org.eclipse.net4j.util.concurrent.Worker; |
| import org.eclipse.net4j.util.io.ExtendedDataInputStream; |
| import org.eclipse.net4j.util.io.ExtendedDataOutputStream; |
| import org.eclipse.net4j.util.io.ExtendedIOAdapter; |
| import org.eclipse.net4j.util.io.ExtendedIOHandler; |
| import org.eclipse.net4j.util.io.IORuntimeException; |
| import org.eclipse.net4j.util.lifecycle.LifecycleUtil; |
| import org.eclipse.net4j.util.om.log.OMLogger; |
| |
| import org.eclipse.spi.net4j.InternalChannel; |
| |
| import org.apache.commons.httpclient.HttpClient; |
| import org.apache.commons.httpclient.HttpException; |
| import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; |
| import org.apache.commons.httpclient.methods.PostMethod; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.text.MessageFormat; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class HTTPClientConnector extends HTTPConnector |
| { |
| private String url; |
| |
| private HttpClient httpClient; |
| |
| private int maxIdleTime = UNKNOWN_MAX_IDLE_TIME; |
| |
| private int pollInterval = DEFAULT_POLL_INTERVAL; |
| |
| private long lastRequest = System.currentTimeMillis(); |
| |
| private boolean requesting; |
| |
| private Worker poller = new Worker() |
| { |
| @Override |
| protected void work(WorkContext context) throws Exception |
| { |
| boolean moreBuffers = tryOperationsRequest(); |
| context.nextWork(moreBuffers ? 0 : 1000); |
| } |
| }; |
| |
| public HTTPClientConnector() |
| { |
| } |
| |
| @Override |
| public Location getLocation() |
| { |
| return Location.CLIENT; |
| } |
| |
| @Override |
| public String getURL() |
| { |
| return url; |
| } |
| |
| public void setURL(String url) |
| { |
| this.url = url; |
| } |
| |
| public int getMaxIdleTime() |
| { |
| return maxIdleTime; |
| } |
| |
| public int getPollInterval() |
| { |
| return pollInterval; |
| } |
| |
| public void setPollInterval(int pollInterval) |
| { |
| this.pollInterval = pollInterval; |
| } |
| |
| @Override |
| public void multiplexChannel(InternalChannel channel) |
| { |
| super.multiplexChannel(channel); |
| tryOperationsRequest(); |
| } |
| |
| @Override |
| public String toString() |
| { |
| if (getUserID() == null) |
| { |
| return MessageFormat.format("HTTPClientConnector[{0}]", getURL()); //$NON-NLS-1$ |
| } |
| |
| return MessageFormat.format("HTTPClientConnector[{1}@{0}]", getURL(), getUserID()); //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected void doBeforeActivate() throws Exception |
| { |
| super.doBeforeActivate(); |
| checkArg(url, "url == null"); //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected void doActivate() throws Exception |
| { |
| super.doActivate(); |
| poller.setDaemon(true); |
| poller.activate(); |
| httpClient = createHTTPClient(); |
| doConnect(); |
| } |
| |
| @Override |
| protected void doDeactivate() throws Exception |
| { |
| doDisconnect(); |
| LifecycleUtil.deactivate(poller, OMLogger.Level.WARN); |
| httpClient = null; |
| super.doDeactivate(); |
| } |
| |
| protected HttpClient createHTTPClient() |
| { |
| return new HttpClient(); |
| } |
| |
| protected PostMethod createHTTPMethod(String url) |
| { |
| return new PostMethod(url); |
| } |
| |
| private void doConnect() throws IOException |
| { |
| request(new ExtendedIOHandler() |
| { |
| public void handleOut(ExtendedDataOutputStream out) throws IOException |
| { |
| out.writeByte(OPCODE_CONNECT); |
| out.writeString(getUserID()); |
| } |
| |
| public void handleIn(ExtendedDataInputStream in) throws IOException |
| { |
| String connectorID = in.readString(); |
| maxIdleTime = in.readInt(); |
| |
| setConnectorID(connectorID); |
| leaveConnecting(); |
| } |
| }); |
| } |
| |
| private void doDisconnect() throws IOException |
| { |
| request(new ExtendedIOAdapter() |
| { |
| @Override |
| public void handleOut(ExtendedDataOutputStream out) throws IOException |
| { |
| out.writeByte(OPCODE_DISCONNECT); |
| out.writeString(getConnectorID()); |
| } |
| }); |
| } |
| |
| private void request(ExtendedIOHandler handler) throws IOException, HttpException |
| { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| ExtendedDataOutputStream out = new ExtendedDataOutputStream(baos); |
| handler.handleOut(out); |
| out.flush(); |
| |
| PostMethod method = createHTTPMethod(url); |
| method.setRequestEntity(new ByteArrayRequestEntity(baos.toByteArray())); |
| |
| try |
| { |
| httpClient.executeMethod(method); |
| InputStream bodyInputStream = method.getResponseBodyAsStream(); |
| ExtendedDataInputStream in = new ExtendedDataInputStream(bodyInputStream); |
| handler.handleIn(in); |
| } |
| finally |
| { |
| method.releaseConnection(); |
| } |
| } |
| |
| private boolean tryOperationsRequest() |
| { |
| synchronized (poller) |
| { |
| if (requesting) |
| { |
| return false; |
| } |
| |
| if (getOutputQueue().isEmpty() && System.currentTimeMillis() - lastRequest < pollInterval) |
| { |
| return false; |
| } |
| |
| requesting = true; |
| } |
| |
| try |
| { |
| final boolean moreOperations[] = { false }; |
| request(new ExtendedIOHandler() |
| { |
| public void handleOut(ExtendedDataOutputStream out) throws IOException |
| { |
| out.writeByte(OPCODE_OPERATIONS); |
| out.writeString(getConnectorID()); |
| moreOperations[0] = writeOutputOperations(out); |
| } |
| |
| public void handleIn(ExtendedDataInputStream in) throws IOException |
| { |
| readInputOperations(in); |
| } |
| }); |
| |
| lastRequest = System.currentTimeMillis(); |
| return moreOperations[0]; |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| finally |
| { |
| synchronized (poller) |
| { |
| requesting = false; |
| } |
| } |
| } |
| } |