| /** |
| * Copyright (c) 2006 Parity Communications, Inc. |
| * 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: |
| * Sergey Yakovlev - initial API and implementation |
| */ |
| package org.eclipse.ecf.internal.provider.rss.container; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.net.Socket; |
| import java.util.Date; |
| |
| import org.eclipse.ecf.core.util.Trace; |
| import org.eclipse.ecf.internal.provider.rss.RssDebugOptions; |
| import org.eclipse.ecf.internal.provider.rss.RssPlugin; |
| import org.eclipse.ecf.internal.provider.rss.http.HttpRequest; |
| import org.eclipse.ecf.internal.provider.rss.http.HttpResponse; |
| import org.eclipse.ecf.provider.comm.tcp.ISocketAcceptHandler; |
| import org.eclipse.ecf.provider.comm.tcp.Server; |
| import org.eclipse.ecf.provider.generic.SOContainerGroup; |
| |
| /** |
| * |
| */ |
| public class RssServerSOContainerGroup extends SOContainerGroup implements ISocketAcceptHandler { |
| |
| private static final String PRODUCT_NAME = "ECF RSS Server/0.0.1"; |
| private static final String DEFAULT_GROUP_NAME = RssServerSOContainerGroup.class.getName(); |
| |
| protected int port; |
| protected Server listener; |
| protected ThreadGroup threadGroup; |
| private boolean isOnTheAir = false; |
| |
| /** |
| * The constructors |
| * @param port |
| */ |
| public RssServerSOContainerGroup(int port) { |
| this(DEFAULT_GROUP_NAME, null, port); |
| } |
| |
| public RssServerSOContainerGroup(String name, int port) { |
| this(name, null, port); |
| } |
| |
| public RssServerSOContainerGroup(String name, ThreadGroup group, int port) { |
| super(name); |
| threadGroup = group; |
| this.port = port; |
| } |
| |
| protected void trace(String msg) { |
| Trace.trace(RssPlugin.PLUGIN_ID, RssDebugOptions.DEBUG, msg); |
| } |
| |
| protected void dumpStack(String msg, Throwable e) { |
| Trace.catching(RssPlugin.PLUGIN_ID, RssDebugOptions.EXCEPTIONS_CATCHING, this.getClass(), "", e); |
| } |
| |
| public synchronized void putOnTheAir() throws IOException { |
| trace("Group at port " + port + " on the air"); |
| listener = new Server(threadGroup, port, this); |
| port = listener.getLocalPort(); |
| isOnTheAir = true; |
| } |
| |
| public synchronized boolean isOnTheAir() { |
| return isOnTheAir; |
| } |
| |
| public void handleAccept(Socket socket) throws Exception { |
| final HttpRequest request = new HttpRequest(socket.getInputStream()); |
| final RssServerSOContainer con = (RssServerSOContainer) get(String.valueOf(port)); |
| if (con == null) { |
| throw new IOException("Container for port " + port + " not found!"); |
| } |
| trace("Found container: " + con.getID().getName() + " for target " + request.getURLString()); |
| String body = ""; |
| int code = HttpResponse.SERVER_ERROR; |
| String path = request.getPath(); |
| // Tests whether this abstract pathname is absolute. |
| path = path.startsWith("/") ? path.substring(1) : path; |
| final File feedFile = new File(path); |
| Date lastModified = new Date(); |
| if (feedFile.exists() && feedFile.isFile()) { |
| trace("Found feed file: " + feedFile.getAbsolutePath()); |
| code = HttpResponse.OK; |
| body = readFileToString(feedFile); |
| lastModified = new Date(feedFile.lastModified()); |
| } else { |
| code = HttpResponse.NOT_FOUND; |
| } |
| // Create connect response and send it back |
| final HttpResponse response = new HttpResponse(code, body); |
| if (body != null && body.length() > 0) { |
| response.setHeader("Connection", "close"); |
| response.setHeader("Content-Type", "text/xml"); |
| response.setHeader("Server", PRODUCT_NAME); |
| response.setDateHeader("Last-Modified", lastModified); |
| } |
| response.writeToStream(socket.getOutputStream()); |
| } |
| |
| private String readFileToString(File file) throws IOException { |
| final FileInputStream in = new FileInputStream(file); |
| final ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| int n; |
| final byte buffer[] = new byte[8192]; |
| while ((n = in.read(buffer, 0, buffer.length)) > -1) { |
| out.write(buffer, 0, n); |
| out.flush(); |
| } |
| return out.toString(); |
| } |
| |
| public synchronized void takeOffTheAir() { |
| if (listener != null) { |
| trace("Taking " + getName() + " on the air."); |
| try { |
| listener.close(); |
| } catch (final IOException e) { |
| dumpStack("Exception in closeListener", e); |
| } |
| listener = null; |
| } |
| isOnTheAir = false; |
| } |
| |
| public int getPort() { |
| return port; |
| } |
| |
| public String toString() { |
| return super.toString() + ";port:" + port; |
| } |
| } |